Fondamenti di Segnali e Trasmissione Terzo laboratorio Trasformata di Fourier di segnali continui in MATLAB La funzione MATLAB che calcola la sequenza che approssima la trasformata di Fourier di un segnale è: X=fft(x)*dt; Il termine moltiplicativo dt permette di avere ampiezze congruenti con la definizione di trasformata di Fourier di segnali continui. La lunghezza del vettore X, trasformata di Fourier, è uguale alla lunghezza del segnale nei tempi (sequenza x). L’operazione di trasformazione di Fourier inversa è invece: x=ifft(X)/dt; I segnali discreti (sequenze nel tempo con passo di discretizzazione dt) che possono essere rappresentate in MATLAB, hanno trasformate periodiche in frequenza, di periodo 1/dt. La sequenza X, output della funzione fft() rappresenta l’osservazione su un solo periodo della trasformata di Fourier. Le frequenze su cui è definita la sequenza X vanno quindi da –1/(2*dt) a +1/(2*dt). Il primo estremo è incluso solo se la lunghezza del vettore x è un numero pari, mentre entrambi gli estremi sono esclusi per lunghezze dispari. Le convenzioni adottate da MATLAB sono che il primo campione di x, x(1), è quello che corrisponde a t=0, ed il primo campione di X, X(1) è quello che corrisponde a f=0. Esiste però la funzione fftshift() che permette di riordinare le frequenze. Quindi per poter calcolare la trasformata di Fourier del segnale x(t) (approssimato dalla sequenza x): » N=length(x); » X=fftshift(fft(x))*dt; » df=1/(N*dt); » f=[-N/2+[0:N-1]]*df; % se N è pari » f=[-(N-1)/2+[0:N-1]]*df; % se N è dispari Per visualizzare il risultato è importante ricordare che la trasformata X sarà sempre un vettore complesso. Quindi si potranno mostrare modulo e fase: » subplot(2,1,1), plot(f,abs(X)); » subplot(2,1,2), plot(f,angle(X)); oppure parte reale e parte immaginaria: » subplot(2,1,1), plot(f,real(X)); » subplot(2,1,2), plot(f,imag(X)); Esercizio 0: La TDF del rettangolo ritardato Si consideri il segnale rettangolare tempo continuo: s(t)=A*rect( (t-T/2)/T ) dove A=3 e T=0.1 s. Si generi tale segnale tramite Matlab, ricorrendo alla funzione rect() definita nelle lezioni precedenti. Di tale segnale, si calcoli quindi la Trasformata di Fourier e se ne visualizzi il modulo e la fase. Si confronti, infine, quanto ottenuto con il risultato teorico. Come asse temporale si definisca il vettore t=[0:0.001:4], espresso in secondi. Per la risoluzione dell’esercizio, viene proposto il seguente codice Matlab: dt=.001; % passo di discretizzazione asse temporale T=0.1; % durata del rettangolo A =3; % ampiezza del rettangolo t =[0:dt:4]; R =A*rect(t,0,T-dt); % il rettangolo nei tempi Rf=fftshift(fft(R))*dt; N =length(t); df=1/(N*dt); f=[-(N-1)/2+[0:N-1]]*df; % asse delle frequenze RfT=(A*T*sin(pi*f*T)./(pi*f*T)).*exp(-j*2*pi*f*((T-dt)/2)); % TDF teorica RfT((length(f)+1)/2)=A*T; % MATLAB non risolve limiti notevoli!! figure, subplot(2,1,1), plot(f,abs(RfT),'-b'), hold on, plot(f,abs(Rf),'.r'), title('Modulo') subplot(2,1,2), plot(f,angle(RfT),'-b'), hold on, plot(f,angle(Rf),'.r'), title('Fase') xlabel('Frequenza [Hz]'); Modulo 0.4 0.3 0.2 0.1 0 -500 -400 -300 -200 -100 0 100 200 300 400 500 -100 0 100 Frequenza [Hz] 200 300 400 500 Fase 4 2 0 -2 -4 -500 -400 -300 -200 Esercizio 1: L’onda quadra Note teoriche. Si consideri un’onda quadra di periodo 2T con duty cycle = 50% e media 1/2. Tale segnale può essere generato replicando a passo 2T il segnale rect(t/T). Dalla teoria, è noto che la trasformata di Fourier del segnale periodico così generato si ottiene campionando a passo 1/2T e opportunamente scalando la trasformata di Fourier del segnale originale. Quanto detto è espresso meglio nel grafico seguente: T -2T -T T 2T media − − 5 2T 3 2T 3 2T − 1 2T 1 2T 5 2T Come si può notare, la sua trasformata di Fourier è composta da un numero infinito di armoniche dispari, ossia di posizione in frequenza pari a 1//2T), 3/(2T), 5/(2T), … Si produca tramite Matlab un codice per la generazione di un’onda quadra a media nulla, duty cycle 50% e periodo 2 s. Si studi in primo luogo la risposta in frequenza di tale segnale. Cosa succederebbe se si riducesse il numero di armoniche della risposta in frequenza? Per produrre l’onda quadra desiderata, si propone la soluzione seguente. Si scrivano le funzioni Matlab: function y=even(x) L=length(x(:)); % lunghezza del vettore y=zeros(size(x)); for k=1:L, if (floor(x(k)/2)==x(k)/2), y(k)=1; end end function y=ondaquadra(x,T), % T è il semiperiodo y=-ones(size(x)); % ones(r,c) crea una matrice inizializzata a 1 set=find(even(floor(x/T))==1); y(set)=1; Si generi quindi l’onda quadra con i comandi: dt=0.001; t=[0:dt:8]; y=ondaquadra(t,1); Onda quadra 1 0.8 0.6 0.4 0.2 0 -0.2 -0.4 -0.6 -0.8 -1 0 1 2 3 4 tempo [s] 5 Si visualizzi quindi la TDF di y: Y=fftshift(fft(y))*dt; N=length(t); df=1/(N*dt); asse_frequenze=[-(N-1)/2+[0:N-1]]*df; % N dispari figure plot(asse_frequenze,abs(Y)); title('Modulo della TDF') xlabel('Frequenze [Hz]') 6 7 8 Modulo della TDF 5 4.5 4 3.5 3 2.5 2 1.5 1 0.5 0 0 1 2 3 4 5 6 Frequenze [Hz] 7 8 9 10 Per ridurre il numero di armoniche, per esempio alle prime 5, si utilizzi il seguente codice: filter=[ones(1,41),zeros(1,length(Y)-81),ones(1,40)]; % prime 5 armoniche Y_filtered=fft(y)*dt.*filter; y_filtered=ifft(Y_filtered)/dt; figure(4) plot(t,y,'r') % onda quadra originale hold on plot(t,y_filtered) % onda quadra filtrata Si utilizzi poi il codice appena scritto per filtrare diversi numeri di armoniche. Onda quadra con prime 5 armoniche 1.5 1 0.5 0 -0.5 -1 -1.5 0 1 2 3 4 tempo [s] 5 6 7 8 7 8 Onda quadra con prime 10 armoniche 1.5 1 0.5 0 -0.5 -1 -1.5 0 1 2 3 4 tempo [s] 5 6 Onda quadra con prime 30 armoniche 1.5 1 0.5 0 -0.5 -1 -1.5 0 1 2 3 4 tempo [s] 5 6 7 8 Esercizio 2: Chiamata telefonica: Dual-Tone Multi Frequency Le cifre del telefono a toni sono codificate con una coppia di sinusoidi. Premendo un tasto viene generato il segnale: y(t)=cos(2πfrt)+cos(2πfct)+w(t) dove si assume la presenza di un disturbo casuale gaussiano a media nulla con varianza σ2. Inoltre il tasto premuto è identificato dal valore delle due frequenze secondo lo schema seguente: Si assuma che il segnale a tempo continuo venga campionato con la frequenza f0 = 8kHz, e che si osservi il segnale per un periodo di osservazione Toss= 128 ms (corrispondente al tempo di pressione del tasto). Per identificare il tasto premuto a partire dal segnale y(t), se ne può valutare la risposta nel dominio della frequenza e selezionare i massimi (due in questo caso) che corrispondono alle due sinusoidi Come applicazione, si vuole simulare in Matlab la pressione di un dato tasto. Si consideri ad esempio il tasto 4. Dai parametri precedenti la sequenza ha N=128ms*8kHz=1024 campioni. Il codice seguente simula la pressione del tasto 4: f0=8000; sigma2=2; dt=1/f0; fr=[697 770 852 941]; fc=[1209 1336 1477 1633]; frn=fr/f0; fcn=fc/f0; r=2; c=1; % Tasto 4 N=1024; n=[0:N-1]; w=sqrt(sigma2)*randn(1,N); % Simulazione del rumore y1=sin(2*pi*frn(r)*n) % simulazione della prima sinusoide y2=sin(2*pi*fcn(c)*n) % simulazione della seconda sinusoide y=y1+y2+w; sound(y,f0); % Generazione del suono (si provi anche con y1 e y2) Si determini visualizzi ora il contenuto in frequenza del segnale y(t), e se ne valuti il contenuto nel caso senza rumore e con rumore (gaussiano a media nulla e varianza due) dt=1/f0; df=1/(N*dt); f=[-(N)/2+[0:N-1]]*df; % N è pari Y=fftshift(fft(y))*dt; Modulo della risposta in frequenza 0.06 0.05 0.04 0.03 0.02 0.01 0 -4000 -3000 -2000 -1000 0 1000 frequenze [Hz] 2000 3000 4000 Si carichi ora il file y_es3 tramite il seguente comando: load y_es3 A seguito di questa operazione, nel Workspace di Matlab viene caricato il vettore y. Esso corrisponde alla pressione di un tasto incognito (come prima, f0=8000Hz, N=1024 campioni). Si applichi quanto detto fino ad ora per determinare il tasto premuto. Esercizio 3: Effetto Doppler Lo scopo di questo esercizio è di valutare con un esempio pratico l’effetto Doppler. Caricate il file siren.mat con il comando load siren A seguito di tale comando, nel workspace vengono caricate due variabili: sir1 e sir2. Tali sequenze possono essere ascoltate con i comandi fc=44100; sound(sir1,fc) sound(sir2,fc) dove fc=44100Hz è la frequenza di campionamento di segnali audio di qualità CD. Come potete sentire, si tratta di una sirena che si sta avvicinando all’ascoltatore (sir1) per poi allontanarsi (sir2). Per effetto Doppler, mentre la sirena si avvicina la frequenza del segnale percepito dall’ascoltatore cresce mentre decresce quando la sirena si allontana. Si verifichi quanto detto eseguendo un’analisi spettrale del segnale tramite TDF. Il risultato è riportato nella figura seguente (legenda: in rosso il modulo della TDF di sir2 e in blu il modulo della TDF di sir1). Spunto di soluzione: dt=1/fc; N=length(sir1); df=1/(N*dt); f=[-(N/2)+[0:(N-1)]]*df; S1=fftshift(fft(sir1))*dt; S2=fftshift(fft(sir2))*dt; figure(5) plot(f,abs(S1)) hold on plot(f,abs(S2),'r') -3 2 Effetto Doppler x 10 1.8 1.6 1.4 1.2 1 0.8 0.6 0.4 0.2 0 -6000 -4000 -2000 0 frequenza [Hz] 2000 4000 6000 Esercizio 4: Handel's Hallelujah Chorus Si carichi e si ascolti il brano musicale Handel's Hallelujah Chorus (presente nelle librerie di Matlab) tramite il comando: fc=8192; load handel sound(y,fc) Si visualizzi il modulo della trasformata di Fourier. Si filtri poi la sequenza musicale con un filtro a media mobile del tipo filt=ones(1,20)/20. Si ascolti il segnale risultato dal filtraggio e se ne visualizzi il comportamento in frequenza, confrontandolo con il precedente. Modulo delle TDF 0.09 0.08 0.07 0.06 0.05 0.04 0.03 0.02 0.01 0 -5000 -4000 -3000 -2000 -1000 0 1000 frequenza [Hz] 2000 3000 4000 5000
© Copyright 2025 ExpyDoc