Randomise phase when using dsp.STFT / ISTFT real time?

4 vues (au cours des 30 derniers jours)
Angeliki Mourgela
Angeliki Mourgela le 15 Juil 2020
Commenté : jibrahim le 23 Juil 2020
Hi,
I would like to create a plugin that performs STFT on the input and then randomises the phases before ISTFT-ing again. I tried to implement this using the dsp.STFT & dsp.ISTFT objects combined with the code for phase randomisation suggested here: https://uk.mathworks.com/matlabcentral/answers/451578-fft-and-ifft-random-phases but it doesn't work (sounds choppy). When I run this I am also getting this message on the command window: Warning: Integer operands are required for colon operator when used as index.
Is there something obvious I am missing and if not is there any other way to implement this ?
I attach a snippet of a real-time processing stream I created to test this, below :
%Create amplitude modulated sine
fs = 44100;
t = 0:1/fs:5;
t = t';
x = (1+cos(2*pi*50*t)).*cos(2*pi*1000*t);
audiowrite('amplmodesine.wav',x,fs)
%---------------------------------------------------
%create real-time audio objects
FrameLength = 512;
afr = dsp.AudioFileReader('amplmodsine.wav',...
'SamplesPerFrame',FrameLength);
adw = audioDeviceWriter('SampleRate',afr.SampleRate);
%----------------------------------------------------
%create stft and istft objects
WindowLength = FrameLength;
HopLength = 16;
numHopsPerFrame = FrameLength / 16;
FFTLength = 1024;
win = hamming(WindowLength,'periodic');
stf = dsp.STFT(win,WindowLength-HopLength,FFTLength);
istf = dsp.ISTFT(win,WindowLength-HopLength,1,0);
%-----------------------------------------------------
%processing stream
while ~isDone(afr)
cleanAudio = afr();
y = zeros(FrameLength,1);
for index = 1:numHopsPerFrame
X = stf(cleanAudio((index-1)*HopLength+1:index*HopLength));
[N,L]=size(X);
% Add random phases
rnd_theta= -pi+pi.*rand(N,L/2-1);
X(:,2:L/2)=X(:,2:L/2).*exp(1i*rnd_theta);
X(:,L/2+2:L)=X(:,L/2+2:L).*exp(-1i*flip(rnd_theta,2));
% Convert back to time-domain
y((index-1)*HopLength+1:index*HopLength) = istf(X);
end
% Listen
adw(y);
end

Réponse acceptée

jibrahim
jibrahim le 20 Juil 2020
Hi Angeliki,
I think you need to invert the order here:
[N,L] size(X);
With the STFT object, the second dimension is the number of channels, so L is equal to 1 in your code. I think you want L to be equal to 1024 (fft length) and N to be equal to 1.
The dimensions of rnd_theta would have to change accordingly.
  7 commentaires
Angeliki Mourgela
Angeliki Mourgela le 23 Juil 2020
Oh my I'm gonna cry, it actually works now! Thank you ever so much
jibrahim you have been extremely helpful! :)
jibrahim
jibrahim le 23 Juil 2020
You are welcome!

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Audio Plugin Creation and Hosting dans Help Center et File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by