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

1 view (last 30 days)
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

Accepted Answer

jibrahim
jibrahim on 20 Jul 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 Comments
Angeliki Mourgela
Angeliki Mourgela on 23 Jul 2020
Oh my I'm gonna cry, it actually works now! Thank you ever so much
jibrahim you have been extremely helpful! :)

Sign in to comment.

More Answers (0)

Categories

Find more on Audio Plugin Creation and Hosting in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!