Randomise phase when using dsp.STFT / ISTFT real time?
1 回表示 (過去 30 日間)
古いコメントを表示
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
0 件のコメント
採用された回答
jibrahim
2020 年 7 月 20 日
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 件のコメント
その他の回答 (0 件)
参考
カテゴリ
Help Center および File Exchange で Audio Plugin Creation and Hosting についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!