2011-04-02 6 views
3

FFT et changement de fréquence et vectorisation boucleFFT et changement de fréquence et vectorisation une boucle FOR

salutations Tous les

Je peux augmenter et diminuer la fréquence d'un signal en utilisant la combinaison de fft et une série de Fourier expansion FOR boucle le code ci-dessous mais si le signal/tableau est trop grand, il devient extrêmement lent (un tableau qui est 1x44100 prend environ 2 minutes pour terminer) Je suis sûr il a à voir avec la boucle for mais Je ne sais pas exactement comment le vectoriser pour améliorer performance. Veuillez noter que ceci sera utilisé avec des signaux audio de 3 à 6 minutes. Le tableau de 1x44100 est seulement une seconde et il faut environ 2 minutes pour compléter

Toutes les recommandations

%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 degrees 

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'); 

Voici une photo de l'intrigue si quelqu'un veut voir la sortie, ce qui est correct la boucle FOR est vraiment vraiment lent

enter image description here

Répondre

1

Il semble que vous décalez essentiellement le signal vers le haut dans le domaine de fréquence, puis votre « expansion de la série » est implémentez simplement l'inverse DFT sur le v déplacé ersion. Comme vous l'avez vu, l'iDFT naïf va être extrêmement lent. Essayez de changer cette boucle entière en un appel à ifft, et vous devriez être en mesure d'obtenir une accélération considérable.

+0

Oui J'utilise la "expansion série Fourier" (sin/cos) pour faire une DFT inverse. J'ai trouvé que pour moi, il est beaucoup plus facile de comprendre et de contrôler complètement tous les aspects de la modification du nouveau signal. J'ai utilisé le fft/ifft pour prendre un signal du domaine temporel au domaine fréquentiel. La chose est que je ne suis pas sûr de savoir par où commencer pour ce problème en augmentant/diminuant la fréquence et/ou en ajustant la phase en utilisant ifft. Quelqu'un at-il des exemples à ce sujet? –