1 FIR-Filter mit dem Fenster-Verfahren Tiefpass 1 Hochpass 1 -π -Ωg Ωg π Ω -π - Ωg Ωg π Bandpass 1 Bandsperre 1 Ω π Ω 2 Ω π Ω 1 Ω 1 Ω π Ω 2 Ω 1 Ω π Ω 2 1 Ω 2 idealen Frequenzgänge der vier grundlegenden Filterfunktionen. Ω = 2π f/f s = normierte Kreisfrequenz (f s = f sample =Abtastfrequenz) Frequenzgang Fourier-Transformierten der Impulsantwort inverse Fourier-Transformation Impulsantwort FIR-Filterkoeffizienten.
2 Berechnung für den idealen Tiefpass (Rechteck) f g = Grenzfrequenz (Ω g = normierten Kreisfrequenz) Frequenzgang symmetrisch zu Ω = Impulsantwort symmetrisch zu t=; Bestimmung der Koeffizienten: ( Ωgn) Ωg ( Ωgn) 1 1 1sin sin jωn Ωg hn [] = H( Ω) e dω= cos( Ωn) dω= = 2 Ωgn Mit ergibt sich: In SCILAB 3.: In MATLAB: π π π π π n π 2π fg Ω g = und s f scilabsinc (x)= n sin(2 π x) π x 2π fn g 2π fn g sin sin 2π f g f s f g f s fg f hn [] = = = scilabsinc π fs 2π fn fs π fn fs n f fs fs g g s sin( x) scilab3sinc(x) = fg f ist somit: hn [] 2 scilab3sinc 2 g x f s fs g n = n π sin( x π ) matlabsinc(x) = fg f ist somit: hn [] = 2 matlabsinc 2 g x π f s fs n
3 Die Funktion sinc Anders als in MATLAB (hier gilt: sinc(x) = si (π*x) mit si(α) = (sin (α))/α ) bedeutet in SCILAB2 b=sinc(n,fg) : for k=-(n-1)/2:(n-1)/2 b(k-(n-1)/2)=2*fg*si(2*π*fg*k) Mit der SCILAB-Funktion können keine Einzelwerte, sondern nur der Vektor b mit n Werten zu der auf die Abtastfrequenz f a =1/T bezogen Grenzfrequenz F g =f g /f s, welche im Bereich..,5 liegen darf (entspricht einer auf 2π bezogenen normierten Kreisfrequenz, und nicht auf π, wie bei Matlab). Auf die Eingabe von b = sinc(5,) antwortet SCILAB2.X: {in SCILAB3. b = *sinc((-2:2)**%pi) } b =!.935489.32737.4.32737.935489! Die folgenden Zeilen dienen zur Berechnung der Übertragungsfunktion bz=poly(b,'z','c'); // Polynom mit b als Koeffizienten f=(:.1:.5); // Normierte Frequenz 1 == fs hf=freq(bz,1,exp(2*%pi*%i*f)); // Berechnung des Frequenzganges plot(f,hf); // Darstellung des Frequenzganges In SCILAB 3. gibt es eine neue sinc-funktion: sinc(x) = (sin (x))/x (noch nicht ganz MATLAB-kompatibel) (die komfortable alte sinc-funktion mit 2 Parametern steht in SCILAB3 vorerst noch zur Verfügung)
4 Darstellung des Frequenzgangs eines FIR 5. Ordnung 1.2.1.3.5
5 Darstellung des Frequenzgangs eines FIR 15. Ordnung 1.2.1.3.5
6 Mit window können verschiedenen Fensterformen generiert werden können [win,cwp]=window(wtype,n,par) Wtype : (re=rectangle, tr=triangle, hn=hanning, hm=hamming, kr=kaiser,ch=chebychev), n = Fensterlänge, par = zusätzliche Angaben (Vektor mit 2 Elementen) kaiser window: par(1) = beta > ( bis ca. 12) Chebychev window par(1) = dp =main lobe width ( <dp<.5 ) win = Vektor, n Fensterwerte, cpw ist nur bei Typ ch relevant. par(2) = df =side lobe height ( df> ) fpar(1)>, fpar(2)< or fpar(1)<, < fpar(2) <.5
7 [win,cwp]=window('tr',15,[ ]); plot(win); xtitle('dreieck-window'); Dreieck-Window.9.7.5.3.1 1 3 5 7 9 11 13 15
8 SINC-FIR 15. Ordnung mit Dreieck-Fenster b = sinc(15,) // SCILAB 2.7.9.7.5.3.1.1.3.5 //b = *sinc(*(-7:7)) // MATLAB //b = *sinc(*%pi*(-7:7)) // SCILAB 3. [win,cwp]=window('tr',15,[ ]); b = b.* win; bz=poly(b,'z','c'); f=(:.1:.5); hf=freq(bz,1,exp(2*%pi*%i*f)); plot(f,hf);
9 Hamming-Window 15. Ordnung Hanning-Window.9.7.5.3.1 1 3 5 7 9 11 13 15
1 SINC-FIR 15. Ordnung mit Hannig-Fenster.9.7.5.3.1.1.3.5
11 Andere Filtertypen durch Transformation erzeugen Filterfunktion Tiefpass Hochpass Bandpass Bandsperre Koeffizienten h[n], n Ωg Ωg si n π π π Ω Ω g - si n π π π Ω 2 2 1 1 si n π Ω Ω si n π Ω π π π π Ω1 Ω1 Ω2 Ω2 si n π si n π π π π π g Koeffizient h[] 1 SCILAB2.x-Befehle Ω g b = sinc(order,); π // fg/fs = Ωg π Ω Ω 2 1 π Ω Ω 1 π 2 1 b = sinc(order,); b = -b; b(ho+1) = 1+b(ho+1); b = sinc(order,); b2 = sinc(order,.3); b = b2 - b; b = sinc(order,); b2 = sinc(order,.3); b = b b2;
12 Filter der Ordnung (55) erstellt (Beispiel FIR_SINC_ENTWURF.sci) 1.2 1.2.1.3.5 f/fs.1.3.5 f/fs 1.2 1.2.1.3.5 f/fs.1.3.5 f/fs
13 //FIR_SINC_ENTWURF.sci (C) f.hoppe@fhtw-berlin.de modus=4; // 1=Tiefpass, 2=Hochpass, 3=Bandpass, 4= Bandsperre halforder = 3; // 2 max f. Tasking eval version sprungantwort = ; // =nein, 1=ja ; Darstellung der Sprungantwort koeffdatei = 1; // =nein, 1=ja ; Ausgeben der Koeffizientendatei koeffdateiname = "C:\dspt35\firkoeff.h"; Fenster = 1; // Verbesserung der Filtereigenschaften mit der Window-Methode ZeigeFenster = ; // Fenstertyp = "ch"; // re=rechteck,tr=dreieck,hn=hanning,hm=hamming,kr=kaiser,ch=chebychev par1 =.5; par2=-1; // kr: par1 = 5; ch: par1=.5, par2=-1 (nicht relevant) ug = ; // normierte untere Grenzfrequenz, bzw. normierte Grenzfrequenz og =.3; // normierte untere Grenzfrequenz (nur bei BP- und SB-Filtern) // ********************* Ende der Benutzer-Eingaben *********************** order=2*halforder+1; // 55 titelstr3=sprintf(" %3d. Ordnung",order); titelstr2=" Tiefpass"; titelstr1="fir "; b=2*ug*sinc((-halforder:halforder)*2*ug*%pi); // SCILAB 3. sinc ist nicht (ganz) MATLAB-kompatibel if modus > 2 then b2=2*og*sinc(2*og*%pi*(-halforder:halforder)); // SCILAB 3. sinc ist nicht (ganz) MATLAB-kompatibel end if modus == 2 then titelstr2=" Hochpass"; b = -b; // Tiefpass-Hochpass-Transformation b(halforder+1) = 1 + b(halforder+1); // b[]= 1-b[] end; if modus == 3 then titelstr2 = " Bandpass"; b = b2 - b; // Tiefpass-Bandpass-Transformation end if modus == 4 then titelstr2=" Bandsperre "; b = b - b2; // Tiefpass-Bandsperre-Transformation b(halforder+1) = 1 + b(halforder+1); end titelstr4=" "; if Fenster <> then titelstr4=" (mit "+ Fenstertyp +"-Fenster)";
14 [win,cwp] = window(fenstertyp,order,[par1 par2]); // das Fenster erstellen b = b.* win; // Anwendung des Fensters, elementweise multiplizieren end bz=poly(b,'z','c'); // Polynom mit b als Koeffizienten, smbolische Variable z f=(:.1:.5); // Normierte Frequenz-Achse 1 == fs xset("window",);xbasc(); xset("font",2,4);xset("thickness",2); // Plotfenster einstellen hf=freq(bz,1,exp(2*%pi*%i*f)); // Berechnung des Frequenzganges plot(f,abs(hf)); // Frequenzgang plotten xtitle(["sinc-fir-"+titelstr2+titelstr3+titelstr4],"f/fs",""); // Plot-Titel if sprungantwort <> then t=(:1:4*order); x=ones(t); // Sprung {Impuls wäre: x=zeros(t); x(1) = 1;} y = convol(b,x); // Sprungantwort durch Faltung berechnen xset("window",1);xbasc();xset("font",2,4);xset("thickness",2);xset("mark size",4); tp=order+4; // Ausgabelänge plot2d2("onn",t(1:tp),y(1:tp)); // h[n] als Treppe xset("thickness",1); plot2d([ tp-1]',[ ]',[1],""); // Nullinie plot2d([ tp-1]',[1 1]',[1],""); // Einslinie xtitle(["sprungantwort" + titelstr2+titelstr3+titelstr4]); end // if if (ZeigeFenster) <> then xset("window",2);xbasc();xset("font",2,4);xset("thickness",2);xset("mark size",4); plot(win); xtitle(["fensterform: " + Fenstertyp]); end // if if koeffdatei <> then koeff_file=file('open',koeffdateiname,'unknown'); // Datei öffnen fprintf(koeff_file," // %s %s-filter %s\n",titelstr1,titelstr2,titelstr3); // Kommentar fprintf(koeff_file," static int ordnung=%d;\n", order); // Filterordnung fprintf(koeff_file," static _circ _fract X[%d]={}; \n", order); // X-Speicher fprintf(koeff_file," static _circ _fract _Y B[%d]={ \n", order); // Koeff-Speicher def. for i=1:1:order fprintf(koeff_file," %15.12f, \n",b(i)); end // Koeff. Werte ausgeben fprintf(koeff_file," } ;\n"); // Definition abschiessen file('close',koeff_file); // Datei schliessen end // if