DewDSPMasterNET
FractionalFirImpulse Routine
Summary
Design an oversampled FIR filter with rectangular window.

Unit
SignalUtils

Declaration
Procedure FractionalFirImpulse(Length: integer; H: TVec; const W: array of TSample; Offset, Step: TSample; FilterType: TFilterType; FS: TSample = 2);

Description
Compute a FIR impulse response filter (no window applied) and place the result in H. The transition regions are defined with the W array. There must be at least one (lowpass, highpass) and at most two (bandpass, bandstop) transition regions (2 or 4 elements). Filter type is defined with TFilterType. 20*Log10(Ripple) is also the required attenuation of the stop band in decibel. FS is the sampling frequency. Length specifies the length of the original filter and Step defines the oversampling factor. The actual length of the impulse response vector is computed like this: H.Length := Round(Length/Step) Step and offset must be bigger then 0. If the Offest is 0 and step is 1, the routine returns the same result as FirImpulse. The resulting H vector contains FIR type impulse response, which can be passed to an interpolation routine (linear, cubic, lagrange, etc..). Oversampled FIR filters are used for resampling with an arbitrary sampling frequency and, if Offset > 0 and Step = 1, fractional delay FIR filters can be implemented. If Step = 1 then the resulting impulse response can be passed directly to the FirInit and FirFilter routines. If Step <> 1 then the resulting impulse response must be passed to the FractionalFirInit and FractionalFirFilter routines. When setting Step bigger then 1, the filter designed must also work as an anti-aliasing filter (low-pass) or aliasing will occur.
Categories
FIR filter design routines
 See Also 
FirImpulse 
KaiserImpulse 
FractionalKaiserImpulse 

Example 1

Filter interpolation.
uses MtxExpr, Math387, MtxVec, SignalUtils, MtxVecTee, MtxVecEdit; procedure TForm1.Button1Click(Sender: TObject); var h,X: Vector; Step,FS: TSample; begin FS := 2; Step := 1; //interpolate by 1x FractionalFirImpulse(30,H,[0.5,0.6],0,Step,ftLowPass,FS); X := Ramp(H.Length,0,1.0/H.Length); DrawIt(X,H,'Interpolate by 1x'); Step := 0.5; //interpolate by 2x FractionalFirImpulse(30,H,[0.5,0.6],0,Step,ftLowPass,FS); X := Ramp(H.Length,0,1.0/H.Length); DrawIt(X,H,'Interpolate by 2x'); Step := 0.25; //interpolate by 4x FractionalFirImpulse(30,H,[0.5,0.6],0,Step,ftLowPass,FS); X := Ramp(H.Length,0,1.0/H.Length); DrawIt(X,H,'Interpolate by 4x'); Step := 0.125; //interpolate by 8x FractionalFirImpulse(30,H,[0.5,0.6],0,Step,ftLowPass,FS); X := Ramp(H.Length,0,1.0/H.Length); DrawIt(X,H,'Interpolate by 8x'); end;
#include "MtxVecCPP.h" //MtxVecCPP.cpp must be included in the project #include "MtxVecEdit.hpp" #include "MtxVecTee.hpp" #include "SignalUtils.hpp" void __fastcall TForm1::BitBtn1Click(TObject *Sender) { Vector H,X; double FS = 2; double Step = 1; //interpolate by 1x FractionalFirImpulse(30,H,OPENARRAY(double,(0.5,0.6)),0,Step,ftLowPass,FS); X = Ramp(H->Length,0,1.0/H->Length); DrawIt(X,H,"Interpolate by 1x",false); Step = 0.5; //interpolate by 2x FractionalFirImpulse(30,H,OPENARRAY(double,(0.5,0.6)),0,Step,ftLowPass,FS); X = Ramp(H->Length,0,1.0/H->Length); DrawIt(X,H,"Interpolate by 2x",false); Step = 0.25; //interpolate by 4x FractionalFirImpulse(30,H,OPENARRAY(double,(0.5,0.6)),0,Step,ftLowPass,FS); X = Ramp(H->Length,0,1.0/H->Length); DrawIt(X,H,"Interpolate by 4x",false); Step = 0.125; //interpolate by 8x FractionalFirImpulse(30,H,OPENARRAY(double,(0.5,0.6)),0,Step,ftLowPass,FS); X = Ramp(H->Length,0,1.0/H->Length); DrawIt(X,H,"Interpolate by 8x",false); }
using Dew.Math; using Dew.Math.Editors; 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 x = new Vector(0); double FS = 2; double Step = 1; //interpolate by 1x Step = 1; SignalUtils.FractionalFirImpulse(30,h,new double[2] {0.5,0.6},0,Step,TFilterType.ftLowPass,FS); x = MtxExpr.Ramp(h.Length,0,1.0/h.Length); TeeChart.DrawIt(x,h,"Interpolate by 1x",false); Step = 0.5; //interpolate by 2x SignalUtils.FractionalFirImpulse(30,h,new double[2] {0.5,0.6},0,Step,TFilterType.ftLowPass,FS); x = MtxExpr.Ramp(h.Length,0,1.0/h.Length); TeeChart.DrawIt(x,h,"Interpolate by 2x",false); Step = 0.25; //interpolate by 4x SignalUtils.FractionalFirImpulse(30,h,new double[2] {0.5,0.6},0,Step,TFilterType.ftLowPass,FS); x = MtxExpr.Ramp(h.Length,0,1.0/h.Length); TeeChart.DrawIt(x,h,"Interpolate by 4x",false); Step = 0.125; //interpolate by 8x SignalUtils.FractionalFirImpulse(30,h,new double[2] {0.5,0.6},0,Step,TFilterType.ftLowPass,FS); x = MtxExpr.Ramp(h.Length,0,1.0/h.Length); TeeChart.DrawIt(x,h,"Interpolate by 8x",false); }

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