开发者

FFT and changing frequency and vectorizing a FOR loop

开发者 https://www.devze.com 2023-02-21 09:40 出处:网络
FFT and changing frequency and vectorizing for loop Greetings All I can increase and decrease the frequency of a

FFT and changing frequency and vectorizing for loop

Greetings All

I can increase and decrease the frequency of a signal using the combination of fft and a Fourier series expansion FOR loop in the code below but if the signal/array is to large it becomes extremely slow (an array that's 1x44100 takes about 2 mins to complete) I'm sure it has to do with the for loop but I'm not exactly sure how to vectorize it to improve performance. Please note that this will be used with audio signals that are 3 to 6 mins long. The 1x44100 array is only a second and it takes about 2 mins to complete

Any recommendations

%create signal
clear all, clc,clf,tic
x= linspace(0,2*pi,44100)';

%Used in exporting to ycalc audio file make sure in sync with above
freq_orig=1;
freq_new=4
vertoff=0;
vertoffConj=0;
vertoffInv=0;
vertoffInvConj=0;
phaseshift=(0)*pi/180 ; %can use mod to limit to 180 degr开发者_如何转开发ees

y=sin(freq_orig*(x));
[size_r,size_c]=size(y);

N=size_r; %to test make 50
T=2*pi;
dt=T/N;
t=linspace(0,T-dt,N)';
phase = 0;
f0 = 1/T; % Exactly, one period

y=(y/max(abs(y))*.8)/2; %make the max amplitude here
C = fft(y)/N; % No semicolon to display output


A = real(C);
B = imag(C)*-1; %I needed to multiply by -1 to get the correct sign

% Single-Sided (f >= 0)
An = [A(1); 2*A(2:round(N/2)); A(round(N/2)+1)]; 
Bn = [B(1); 2*B(2:round(N/2)); B(round(N/2)+1)];

pmax=N/2;
ycalc=zeros(N,1); %preallocating space for ycalc
w=0;

for p=2:pmax
               %
       %%1 step) re-create signal using equation
        ycalc=ycalc+An(p)*cos(freq_new*(p-1).*t-phaseshift)
+Bn(p)*sin(freq_new*(p-1).*t-phaseshift)+(vertoff/pmax);
        w=w+(360/(pmax-1)); %used to create phaseshift
        phaseshift=w;

end;

fprintf('\n- Completed in %4.4fsec or %4.4fmins\n',toc,toc/60);

subplot(2,1,1), plot(y),title('Orginal Signal');
subplot(2,1,2),plot(ycalc),title('FFT new signal');

Here's a pic of the plot if some one wants to see the output, which is correct the FOR loop is just really really slow

FFT and changing frequency and vectorizing a FOR loop


It appears as though you are basically shifting the signal upwards in the frequency domain, and then your "series expansion" is simply implementing the inverse DFT on the shifted version. As you have seen, the naive iDFT is going to be exceedingly slow. Try changing that entire loop into a call to ifft, and you should be able to get a tremendous speedup.

0

精彩评论

暂无评论...
验证码 换一张
取 消