Synthese de filtre FIR par fenetrage
Contents
Preliminaires
close all;clear;clc;
Lecture du fichier audio (stereo). On convertit le signal stereo en signal mono
[signal, fe] = audioread('music.wav');
signal = 0.5*signal(:,1) + 0.5*signal(:,2);
Ecoute du signal
%sound(signal,fe);
Recuperation de sa taille et creation de l'echelle temporelle en seconde
T = length(signal) ; Time = linspace(0,T/fe,T);
Affichage des echantillons avec une echelle adaptee
figure; plot(Time,signal); title('Echantillons temporels du signal audio'); xlabel('Temps (s)'); ylabel('Amplitude');
Calcul de la fft du signal et du spectre
fft_signal = fft(signal); spectre_signal = abs(fft_signal);
Creation de l'echelle frequentielle adaptee
Frequences = linspace(-fe/2,fe/2,T);
Affichage du spectre
figure plot(Frequences,fftshift(spectre_signal)); title('Spectre du signal'); xlabel('frequence (Hz)'); ylabel('Amplitude');
Filtre ideal
Choix de la frequence de coupure du filtre
fc = 8000;
Creation du filtre ideal valant 1 dans la bande passante et 0 dans la bande coupee
H_ideal = zeros(T,1); index_fc = fix(fc/fe*T); H_ideal(1:index_fc) = 1; H_ideal(end-index_fc+1:end) = 1;
Affichage du gain de la fonction de transfert du filtre ideal
figure plot(Frequences,fftshift(H_ideal)); title('Module de la fonction de transfert du filtre ideal'); xlabel('frequence (Hz)'); ylabel('Amplification');
Calcul de la reponse impulsionnelle ideale correspondant a la fonction de transfert precedente:
h_ideal = fftshift(ifft(H_ideal,'symmetric')); % le filtre sera centree en t=0, car non causal
Affichage de la reponse impulsionnelle ideale, avec une echelle de temps adaptee
Time_filter = linspace(-T/fe/2,T/fe/2,T); % echelle de temps [-inf,+inf] figure; plot(Time_filter,h_ideal); xlabel('Temps (s)'); ylabel('Amplitude');
Fenetrage
Choix de l'ordre du filtre FIR et construction de la fenetre
ordre = 1000; % ordre du filtre fenetre='hann'; %choix de la fenetre fen = zeros(T,1); switch fenetre case 'rectangle' fen(1:ordre/2) = 1; fen(end-ordre/2+1:end) = 1; case'triangle' fen(1:ordre/2) = linspace(1-2/ordre,0,ordre/2); fen(end-ordre/2+1:end) = linspace(2/ordre,1,ordre/2); case 'hann' t1 = ordre/2+1:ordre; fen(1:ordre/2) = 0.5 - 0.5*cos(2*pi*t1/ordre); t2 = 1:ordre/2; fen(end-ordre/2+1:end) = 0.5 - 0.5*cos(2*pi*t2/ordre); case 'hamming' t1 = ordre/2+1:ordre; fen(1:ordre/2) = 0.54 - 0.46*cos(2*pi*t1/ordre); t2 = 1:ordre/2; fen(end-ordre/2+1:end) = 0.54 - 0.46*cos(2*pi*t2/ordre); case 'blackman' t1 = ordre/2+1:ordre; fen(1:ordre/2) = 0.42 - 0.5*cos(2*pi*t1/ordre) + 0.08*cos(4*pi*t1/ordre); t2 = 1:ordre/2; fen(end-ordre/2+1:end) = 0.42 - 0.5*cos(2*pi*t2/ordre) + 0.08*cos(4*pi*t2/ordre); end fen = fftshift(fen); %fenetre centree en t=0
Affichage de la fenetre choisie
figure; plot(-length(fen)/2+1:length(fen)/2,fen) title(['Allure de la fenetre de troncature: fenetre ', fenetre]) xlabel('Indice') ylabel('Amplitude de la fenetre')
Fenetrage de la RI ideale
h_trunc = fen.*h_ideal;
Affichage de la reponse impulsionnelle tronquee superposee a la reponse impulsionnelle ideale
plot(Time_filter,h_ideal,'b',Time_filter,h_trunc,'r'); plot(linspace(0,T/fe,T),h_ideal,'b',linspace(0,T/fe,T),h_trunc,'r'); xlabel('Temps (s)'); ylabel('Amplitude');
Decalage
Recuperation des coefficients de l'equation aux differences a partir de la reponse impulsionnelle
FIRcoeff = zeros(ordre,1); %creation du vecteur de coefficient h_truncshift = ifftshift(h_trunc); % on reordonne les coefficients selon "matlab" FIRcoeff(1:ordre/2) = h_truncshift(1:ordre/2); % on recupere les valeurs "positives" FIRcoeff(ordre/2+1:end) = h_truncshift(end-ordre/2+1:end); % puis les valeurs "positives" FIRcoeff = fftshift(FIRcoeff); % on reordonne les coefficients
Affichage des differents coefficients de l'equation aux differences du filtre
plot(FIRcoeff) title(['Valeur des ',num2str(ordre),' coefficients de l''equation aux differences du filtre']); xlabel('Numero du coeff'); ylabel('Valeur du coeff');
Analyse spectrale du filtre FIR
Calcul du spectre de la reponse impulsionnelle ainsi tronquee correspondant donc a la fonction de transfert reelle
H_trunc = abs(fft(h_trunc));
Affichage du module de cette fonction de transfert
plot(Frequences,fftshift(H_ideal),'b',Frequences,fftshift(H_trunc),'r') title('Module de la fonction de transfert reelle du filtre correspondant a la reponse impulsionnelle tronquee'); xlabel('Frequence (Hz)'); ylabel('Amplification');
Affichage du gain de la fonction de transfert du filtre
FTfiltre = 20*log10(H_trunc); semilogx(Frequences,fftshift(FTfiltre)) title('Gain du filtre reel obtenu par troncature avec une fenetre ') xlabel('frequence(Hz)') ylabel('Gain(dB)')
Warning: Negative data ignored
Filtrage du signal
tic signal_FIR = zeros(T,1); signal_zeropad = zeros(T+ordre,1); signal_zeropad(ordre+1:end) = signal;
Implementation de la convolution (non circulaire ici, on veut du temps reel)
for n=1:T for k=1:ordre signal_FIR(n) = signal_FIR(n) + FIRcoeff(k) * signal_zeropad(n-k+ordre+1); end end toc
Elapsed time is 8.288698 seconds.
ou convolution matlab
%signal_FIR_matlab = conv(signal,FIRcoeff,'same'); % attention, l'ordre des vecteurs a son importance ici
Calcul de la representation spectrale du son filtre
fft_signal_FIR = fft(signal_FIR); spectre_signal_FIR = abs(fft_signal_FIR);
Affichage du spectre du son filtre
figure; plot(Frequences,fftshift(spectre_signal),'b',Frequences,fftshift(spectre_signal_FIR),'r'); title('Spectre du son filtre'); xlabel('frequence (Hz)'); ylabel('Amplitude');
Ecoute du signal filtre
sound(signal_FIR,fe);