Cours S.S.I.I., , n°8, Créer des filtres pour compresser Cours S.S.I.I., , n°8, : Créer des filtres pour compresser Page 1 Mise en œuvre de la méthode de création de filtres de réponse fréquentielle donnée Jean-Paul Stromboni, SI3, novembre 2013 On cherche les R coefficients hk réels dun filtre dans le vecteur h= [hk, k= 0 … R-1], Léquation du filtre est un produit de convolution On a vu que : h contient la réponse impulsionnelle du filtre H = fft (h) est la réponse fréquentielle du filtre, h H= fft(H)= [Hk, k=0 … R-1], avec Réciproquement, h= ifft(H); Doù le principe de calcul du filtre : on impose la réponse fréquentielle du filtre dans un vecteur H de taille R, et on en déduit les R coefficients du filtre dans le vecteur h= ifft(H). Attention ! H(f) doit être réelle et symétrique par rapport à f=fe/2, ou encore H k = H R-k, condition suffisante pour assurer des coefficients réels pour le filtre dans h Attention ! h= ifft(H) est périodique, de période R, mieux vaut choisir la période de h entre –R/2 et R/2-1 quentre 0 et R-1, pour minimiser lécart entre H imposé et H(f) entre les fréquences fk imposées.
Cours S.S.I.I., , n°8, Créer des filtres pour compresser Cours S.S.I.I., , n°8, : Créer des filtres pour compresser Page 2 Constitution de la réponse fréquentielle dans le vecteur H On reprend lexemple du filtre de réponse fréquentielle H2 : R= 64, fe= 8000Hz, filtre passe bande de gain 4 entre fb=1000Hz et fh= 2000Hz : Quel est k tel que fk= k fe /R ? Réponse, k= R fb / fe, soit k= R/8 = 8 Doù le vecteur H défini ci-dessous. H est il symétrique par rapport à fe/2 ? H= HR-k fe=8000; R=64; // spécification de la réponse fréquentielle H=[zeros(1,R/8),4*ones(1,R/8),zeros(1,R/2),4*ones(1,R/8),zeros(1,R/8)]; f=[0:R-1]*fe/R; plot2d3(f,H) a=gca(); xtitle(["tracé de H sur ",string(R)," points."],"fréquence (Hz)","gain") a.data_bounds=[0,0;(R-1)*fe/R,5];
Cours S.S.I.I., , n°8, Créer des filtres pour compresser Cours S.S.I.I., , n°8, : Créer des filtres pour compresser Page 3 Tracé de real(ifft(H)) et de imag(ifft(H)) //étude de h=ifft(H) h=ifft(H); t=[0:R-1]/fe; clf() plot2d(t',[real(h'),imag(h')]) e=gce(); e.children(1).thickness=3; xgrid(); xtitle("tracé de h=real(ifft(H)) et de imag(ifft(H))", … "temps (s)","tracé de h") h1=legend(['real(h)';'imag(h)']) Le vecteur h nest pas réel, corriger le vecteur H sur le tracé de la page pré- cédente afin davoir une réponse fréquentielle symétrique par rapport à fe/2 // spécification de la réponse fréquentielle corrigée H=4*[zeros(1,R/8),ones(1,1+R/8),zeros(1,-1+R/2),ones(1,1+R/8),zeros(1,-1+R/8)];
Cours S.S.I.I., , n°8, Créer des filtres pour compresser Cours S.S.I.I., , n°8, : Créer des filtres pour compresser Page 4 Détaillons la réponse fréquentielle du filtre de réponse impulsionnelle : h=real(ifft(H)) Traçons la réponse fréquentielle du filtre, soit H=fft(h) : Traçons la réponse fréquentielle entre les R points imposés au départ (en Scilab, il suffit de compléter h par des zéros, cf. ci-dessous), quel est le problème ?
Cours S.S.I.I., , n°8, Créer des filtres pour compresser Cours S.S.I.I., , n°8, : Créer des filtres pour compresser Page 5 Réponse fréquentielle du filtre de réponse impulsionnelle : h=fftshift(real(ifft(H))) Cest mieux, pourquoi ? clf(); M=16*R; h=fftshift(ifft(H)); fM=[0:M-1]*fe/M; hM=zeros(1,M); hM(1:R)=real(h); plot2d3(f,H) plot2d(fM,abs(fft(hM))) xgrid(); xtitle(["tracé de abs(fft(fftshift(real(ifft(H))))),", string(M)," points"],"fréquence (Hz)","H")
Cours S.S.I.I., , n°8, Créer des filtres pour compresser Cours S.S.I.I., , n°8, : Créer des filtres pour compresser Page 6 Que réalise au juste la fonction fftshift ? Comparons h= real(ifft(H) et h= fftshift(real(ifft(H))) Comparons les tracés de h= real(ifft(H) et h= fftshift(real(ifft(H)))
Cours S.S.I.I., , n°8, Créer des filtres pour compresser Cours S.S.I.I., , n°8, : Créer des filtres pour compresser Page 7 Une explication de leffet de fftshift En fait, la réponse impulsionnelle h du filtre est périodique, de période R points (ou RTe), voici deux périodes ci-dessous :
Cours S.S.I.I., , n°8, Créer des filtres pour compresser Cours S.S.I.I., , n°8, : Créer des filtres pour compresser Page 8 En arrondissant la réponse fréquentielle comme ci-dessous, on obtient mieux : Aux fréquences de coupure haute et basse de H, on impose un gain du filtre de 0.5 au lieu de 1, soit : H=4*[zeros(1,R/8),0.5,ones(1,R/8-1),0.5, … zeros(1,-1+R/2),0.5,ones(1,R/8-1),0.5,zeros(1,-1+R/8)];
Cours S.S.I.I., , n°8, Créer des filtres pour compresser Cours S.S.I.I., , n°8, : Créer des filtres pour compresser Page 9 Mieux encore si on arrondit plus encore la réponse fréquentielle H (cf. bancs de filtres) H=4*[zeros(1,R/8-1),0.1,0.5,0.9,ones(1,R/8-3),0.9,0.5,0.1,zeros(1,-3+R/2), ,0.5,0.9,ones(1,R/8-3),0.9,0.5,0.1,zeros(1,-2+R/8)];
Cours S.S.I.I., , n°8, Créer des filtres pour compresser Cours S.S.I.I., , n°8, : Créer des filtres pour compresser Page 10 Application, à la deuxième question de TD 6 On demande de compresser dans un rapport 2 et de décompresser le signal tiré du fichier signal2.wav: Pour cela, on créera deux filtres H2 et H3 pour séparer le signal tiré de signal2.wav en deux signaux s2 et s3 dont les spectres sétendent : Entre 1000 et 2000Hz pour s2. Entre 2000Hz et 3000Hz pour s3 on vérifiera que les réponses impulsionnelles h2 et h3 des deux filtres sont bien réelles On vérifiera la réponse fréquentielle des deux filtres entre les R fréquences imposées on compressera s2 et s3 séparément dans un rapport 4, et on les décompressera, Comparer les énergies de s2, s3 et celle du signal de départ. Lénergie dun signal s=[sk, k=0..R-1] est la demi-somme des carrés des échantillons sk, Selon le temps disponible : avec Goldwave, créer les filtres H2 et H3, à appliquer à signal2.wav, Appliquer à dautres signaux
Cours S.S.I.I., , n°8, Créer des filtres pour compresser Cours S.S.I.I., , n°8, : Créer des filtres pour compresser Page 11 Et pourquoi imag(ifft(H)) est-elle non nulle ? Cest parce que H doit être symétrique par rapport à la demi fréquence déchantillonnage, fe/2 Pour comprendre, par exemple avec R=16, soit fe/R=500Hz, on trace H=4*[0,0,1,1,0,0,0,0, 0,0,0,0,1,1,0,0] Vérification, prenons maintenant un vecteur H symétrique par rapport à fe/2, soit H=4*[0,0,1,1,1,0,0,0, 0,0,0,0,1,1,1,0]