DewDSPMasterNET
RemezImpulse Routines
Summary
Design an optimal equiripple FIR filter with Parks-McClellan algorithm.

Unit
OptimalFir

Declaration
Function RemezImpulse(H: TVec; const W: array of TSample; FilterType: TFilterType; Gain: TSample = 1; FS: TSample = 2): boolean;

Description
Required length of the filter must be preset by setting H.Length. H vectors holds the impulse response on exit.
Categories
FIR filter design routines
 See Also 
KaiserImpulse 
SavGolayImpulse 
Remez 
FirImpulse 

Example 1

RemezImpulse examples. Comment out the filter setup that you need.
uses MtxExpr, Math387, MtxVec, SignalUtils, MtxVecTee, MtxVecEdit, OptimalFIR; procedure TForm1.Button1Click(Sender: TObject); var H,Response: Vector; TransBW, Ripple: TSample; begin //Assumed sampling frequency = 2 TransBW := 0.02; //transition bandwidth in Hz. Ripple := 0.001; //Lowpass filter RemezImpulse(H,[0.3,0.3+TransBW],Ripple, ftLowpass); //Highpass filter // RemezImpulse(H,[0.3,0.3+TransBW],Ripple, ftHighpass); //Bandpass filter // RemezImpulse(H,[0.3,0.3+TransBW, 0.5-TransBW,0.5],Ripple, ftBandpass); //Bandstop filter // RemezImpulse(H,[0.3,0.3+TransBW, 0.5-TransBW,0.5],Ripple, ftBandstop); // Type III Hilbert transformer // RemezImpulse(H,[TransBW,1-TransBW],Ripple, ftHilbertIII); // Type IV Hilbert transformer // RemezImpulse(H,[TransBW,1],Ripple, ftHilbertIV); // Type III linear phase differentiator filter // KaiserImpulse(H,[1-TransBW,1],Ripple, ftDifferentiatorIII); // H.Scale(2); //Scale by sampling frequency // Type IV linear phase differentiator filter // KaiserImpulse( H,[1-TransBW,1],Ripple, ftDifferentiatorIV); // H.Scale(2); //Scale by sampling frequency // Type III differentiator filter // RemezImpulse(H,[0,1-TransBW],Ripple, ftDifferentiatorIII); // H.Scale(2); //Scale by sampling frequency // Type IV differentiator filter // RemezImpulse( H,[0,1-TransBW],Ripple, ftDifferentiatorIV); // H.Scale(2); //Scale by sampling frequency // Type III 2x differentiator filter (remez) // RemezImpulse(H,[0,1-TransBW],Ripple, ftDoubleDifferentiatorIII); // H.Scale(Sqr(2)); //Scale by sampling frequency // Type IV 2x differentiator filter (remez) // RemezImpulse(H,[0,1-TransBW],Ripple, ftDoubleDifferentiatorIV); // H.Scale(Sqr(2)); //Scale by sampling frequency // Type III integrator filter (remez).'; // RemezImpulse(H,[TransBW,1-TransBW],Ripple, ftIntegratorIII); // H.Scale(1/2); //Scale by sampling frequency // Type IV integrator filter (remez).'; // RemezImpulse(H,[TransBW,1],Ripple, ftIntegratorIV); // H.Scale(1/2); //Scale by sampling frequency // Type III 2x integrator filter (remez).'; // RemezImpulse(H,[TransBW,1-TransBW],Ripple, ftDoubleIntegratorIII); // H.Scale(Sqr(1/2)); //Scale by sampling frequency // Type IV 2x integrator filter (remez).'; // RemezImpulse(H,[TransBW,1],Ripple, ftDoubleIntegratorIV); // H.Scale(Sqr(1/2)); //Scale by sampling frequency FrequencyResponse(h,nil,Response); DrawIt(Response); end;
#include "MtxVecCPP.h" //MtxVecCPP.cpp must be included in the project #include "MtxVecEdit.hpp" #include "MtxVecTee.hpp" #include "SignalUtils.hpp" #include "OptimalFIR.hpp" void __fastcall TForm1::BitBtn1Click(TObject *Sender) { Vector H,Response; TSample TransBW, Ripple; //Assumed sampling frequency = 2 TransBW = 0.02; //transition bandwidth in Hz. Ripple = 0.001; //Lowpass filter // RemezImpulse(H,OPENARRAY(double,(0.3,0.3+TransBW)),Ripple, ftLowPass); //Highpass filter // RemezImpulse(H,OPENARRAY(double,(0.3,0.3+TransBW)),Ripple, ftHighPass); //Bandpass filter // RemezImpulse(H,OPENARRAY(double,(0.3,0.3+TransBW, 0.5-TransBW,0.5)),Ripple, ftBandPass); //Bandstop filter // RemezImpulse(H,OPENARRAY(double,(0.3,0.3+TransBW, 0.5-TransBW,0.5)),Ripple, ftBandStop); // Type III Hilbert transformer // RemezImpulse(H,OPENARRAY(double,(TransBW,1-TransBW)),Ripple, ftHilbertIII); // Type IV Hilbert transformer // RemezImpulse(H,OPENARRAY(double,(TransBW,1)),Ripple, ftHilbertIV); // Type III linear phase differentiator filter // KaiserImpulse(H,OPENARRAY(double,(1-TransBW,1)),Ripple, ftDifferentiatorIII); // H->Scale(2); //Scale by sampling frequency // Type IV linear phase differentiator filter // KaiserImpulse( H,OPENARRAY(double,(1-TransBW,1)),Ripple, ftDifferentiatorIV); // H->Scale(2); //Scale by sampling frequency // Type III differentiator filter // RemezImpulse(H,OPENARRAY(double,(0,1-TransBW)),Ripple, ftDifferentiatorIII); // H->Scale(2); //Scale by sampling frequency // Type IV differentiator filter // RemezImpulse( H,OPENARRAY(double,(0,1-TransBW)),Ripple, ftDifferentiatorIV); // H->Scale(2); //Scale by sampling frequency // Type III 2x differentiator filter (remez) // RemezImpulse(H,OPENARRAY(double,(0,1-TransBW)),Ripple, ftDoubleDifferentiatorIII); // H->Scale(2*2); //Scale by sampling frequency // Type IV 2x differentiator filter (remez) // RemezImpulse(H,OPENARRAY(double,(0,1-TransBW)),Ripple, ftDoubleDifferentiatorIV); // H->Scale(2*2); //Scale by sampling frequency // Type III integrator filter (remez).'; // RemezImpulse(H,OPENARRAY(double,(TransBW,1-TransBW)),Ripple, ftIntegratorIII); // H->Scale(1.0/2); //Scale by sampling frequency // Type IV integrator filter (remez).'; // RemezImpulse(H,OPENARRAY(double,(TransBW,1)),Ripple, ftIntegratorIV); // H->Scale(1.0/2); //Scale by sampling frequency // Type III 2x integrator filter (remez).'; // RemezImpulse(H,OPENARRAY(double,(TransBW,1-TransBW)),Ripple, ftDoubleIntegratorIII); // H->Scale(1.0/(2*2)); //Scale by sampling frequency // Type IV 2x integrator filter (remez).'; // RemezImpulse(H,OPENARRAY(double,(TransBW,1)),Ripple, ftDoubleIntegratorIV); // H->Scale(1.0/(2*2)); //Scale by sampling frequency FrequencyResponse(H,NULL,Response); DrawIt(Response); }
using Dew.Math; using Dew.Math.Units; using Dew.Signal; using Dew.Signal.Units; using Dew.Math.Tee; using Dew.Signal.Tee; private void button1_Click(object sender, EventArgs e) { Vector H = new Vector(0); Vector Response = new Vector(0); //Assumed sampling frequency = 2 double FS = 2; double TransBW = 0.02; //transition bandwidth in Hz. double Ripple = 0.001; //Lowpass filter OptimalFir.RemezImpulse(H,new double[2] {0.3,0.3+TransBW},Ripple, TFilterType.ftLowPass,1,FS,false); //Highpass filter OptimalFir.RemezImpulse(H,new double[2] {0.3,0.3+TransBW},Ripple, TFilterType.ftHighPass,1,FS,false); //Bandpass filter OptimalFir.RemezImpulse(H,new double[4] {0.3,0.3+TransBW, 0.5-TransBW,0.5},Ripple, TFilterType.ftBandPass,1,FS,false); //Bandstop filter OptimalFir.RemezImpulse(H,new double[4] {0.3,0.3+TransBW, 0.5-TransBW,0.5},Ripple, TFilterType.ftBandStop, 1,FS,false); // Type III Hilbert transformer OptimalFir.RemezImpulse(H,new double[2] {TransBW,1-TransBW},Ripple, TFilterType.ftHilbertIII,1,FS,false); // Type IV Hilbert transformer OptimalFir.RemezImpulse(H,new double[2] {TransBW,1},Ripple, TFilterType.ftHilbertIV,1,FS,false); // Type III linear phase differentiator filter SignalUtils.KaiserImpulse(H,new double[2] {1-TransBW,1},Ripple, TFilterType.ftDifferentiatorIII,1,FS,false); H.Scale(FS); //Scale by sampling frequency // Type IV linear phase differentiator filter SignalUtils.KaiserImpulse( H,new double[2] {1-TransBW,1},Ripple, TFilterType.ftDifferentiatorIV,1,FS,false); H.Scale(FS); //Scale by sampling frequency // Type III differentiator filter OptimalFir.RemezImpulse(H,new double[2] {0,1-TransBW},Ripple, TFilterType.ftDifferentiatorIII,1,FS,false); H.Scale(FS); //Scale by sampling frequency // Type IV differentiator filter OptimalFir.RemezImpulse( H,new double[2] {0,1-TransBW},Ripple, TFilterType.ftDifferentiatorIV,1,FS,false); H.Scale(FS); //Scale by sampling frequency // Type III 2x differentiator filter (remez) OptimalFir.RemezImpulse(H,new double[2] {0,1-TransBW},Ripple, TFilterType.ftDoubleDifferentiatorIII,1,FS,false); H.Scale(FS*FS); //Scale by sampling frequency // Type IV 2x differentiator filter (remez) OptimalFir.RemezImpulse(H,new double[2] {0,1-TransBW},Ripple, TFilterType.ftDoubleDifferentiatorIV,1,FS,false); H.Scale(FS*FS); //Scale by sampling frequency // Type III integrator filter (remez).'; OptimalFir.RemezImpulse(H,new double[2] {TransBW,1-TransBW},Ripple, TFilterType.ftIntegratorIII,1,FS,false); H.Scale(1/FS); //Scale by sampling frequency // Type IV integrator filter (remez).'; OptimalFir.RemezImpulse(H,new double[2] {TransBW,1},Ripple, TFilterType.ftIntegratorIV,1,FS,false); H.Scale(1/FS); //Scale by sampling frequency // Type III 2x integrator filter (remez).'; OptimalFir.RemezImpulse(H,new double[2] {TransBW,1-TransBW},Ripple, TFilterType.ftDoubleIntegratorIII,1,FS,false); H.Scale(Math.Sqrt(1/FS)); //Scale by sampling frequency // Type IV 2x integrator filter (remez).'; OptimalFir.RemezImpulse(H,new double[2] {TransBW,1},Ripple, TFilterType.ftDoubleIntegratorIV,1,FS,false); H.Scale(Math.Sqrt(1/FS)); //Scale by sampling frequency SignalUtils.FrequencyResponse(H,null,Response,16,false,TSignalWindowType.wtRectangular,0); TeeChart.DrawIt(Response,"",false);


Declaration
Function RemezImpulse(H: TVec; const W: array of TSample; Ripple: TSample; FilterType: TFilterType; Gain: TSample = 1; FS: TSample = 2; EnsureOdd: boolean = True): boolean;

Description
The resulting impulse response is placed in H. Length of the filter is automatically estimated from the required Ripple and transition bandwidth. H vector holds the impulse response on exit, Ripple is the required linear ripple of the passband and 20*Log10(Ripple) is the required attenuation of the stop band. FilterType parameter defines the filter type. Gain specifies the gain of the passband and FS is the sampling frequency used to normalize transition band edges defined in the W array. Default value for FS is 2. W array can hold only 2 (highpass/lowpass definition) or 4(bandpass/bandstop definition) parameters. Function returns True, if the filter was succesfully designed. This does not guarantee that filter specifications have been meet.

This routine is a simplified version of Remez and can be used to design: Lowpass, bandpass, bandstop, highpass, differentiators and hilbert transformers.

RemezImpulse routine designes FIR filters about 10-20% shorter than the KaiserImpulse routine.

 See Also 
Remez 

Copyright 2008 Dew Research
http://www.dewresearch.com