filtres ideaux, FIR et IIR
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
fmax = fe/2; Frequences = linspace(-fmax,fmax,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');
Synthese FIR par fenetrage
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');
Choix de l'ordre du filtre FIR et construction de la fenetre
ordre = 256; % 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 % Fenetrage du filtre ideal 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'); xlabel('Temps (s)'); ylabel('Amplitude');
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 ', 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 2.228945 seconds.
ou convolution matlab
%signal_FIR_matlab = conv(signal,FIRcoeff,'same'); % attention, l'ordre des vecteurs a son importance ici % % ou filtrage matlab % %signal_FIR = filter(FIRcoeff,1,signal);
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);
Filtres IIR: butterworth
Choix de l'ordre du filtre.
ordre = 4;
generation des coefficients A=[a_0,...,a_N] et B = [b_0,...,b_N]
[B,A] = butter(ordre,fc/fmax);
generation de la reponse en frequence du filtre a partir de sa fonction de transfert H(z) = B(z)/A(z)
[H,W] = freqz(B,A,T,fe);
Affichage du gain de la fonction de transfert du filtre
FTfiltre = 20*log10(abs(H)); plot(W,FTfiltre) title('Gain du filtre de Butterworth obtenu ') xlabel('frequence(Hz)') ylabel('Gain(dB)')
Filtres IIR: Tchebycheff I
Choix de l'ordre du filtre.
ordre = 4;
generation des coefficients A=[a_0,...,a_N] et B = [b_0,...,b_N]
[B,A] = cheby1(ordre,0.05,fc/fmax);
generation de la reponse en frequence du filtre a partir de sa fonctoin de transfert H(z) = B(z)/A(z)
[H,W] = freqz(B,A,T,fe);
Affichage du gain de la fonction de transfert du filtre
FTfiltre = 20*log10(abs(H)); plot(W,FTfiltre) title('Gain du filtre de Tchebycheff I obtenu ') xlabel('frequence(Hz)') ylabel('Gain(dB)')
Filtres IIR: Tchebycheff II
Choix de l'ordre du filtre.
ordre = 4;
generation des coefficients A=[a_0,...,a_N] et B = [b_0,...,b_N]
[B,A] = cheby2(ordre,50,fc/fmax);
generation de la reponse en frequence du filtre a partir de sa fonctoin de transfert H(z) = B(z)/A(z)
[H,W] = freqz(B,A,T,fe);
Affichage du gain de la fonction de transfert du filtre
FTfiltre = 20*log10(abs(H)); plot(W,FTfiltre) title('Gain du filtre de Tchebycheff II obtenu ') xlabel('frequence(Hz)') ylabel('Gain(dB)')
Filtres IIR: Elliptique
Choix de l'ordre du filtre.
ordre = 5;
generation des coefficients A=[a_0,...,a_N] et B = [b_0,...,b_N]
[B,A] = ellip(ordre,0.05,50,fc/fmax);
generation de la reponse en frequence du filtre a partir de sa fonctoin de transfert H(z) = B(z)/A(z)
[H,W] = freqz(B,A,T,fe);
Affichage du gain de la fonction de transfert du filtre
FTfiltre = 20*log10(abs(H)); plot(W,FTfiltre) title('Gain du filtre elliptique obtenu ') xlabel('frequence(Hz)') ylabel('Gain(dB)')
Filtrage
signal_filtre = filter(B,A,signal); % % % Comparaison des spectres spectre_signal_filtre = fftshift(abs(fft(signal_filtre))); plot(Frequences,fftshift(spectre_signal),'b',Frequences,spectre_signal_filtre,'r');