DewDSPMasterNET
DcFilter Routines
Summary
Design a DC filter.

Unit
SignalUtils

Declaration
Procedure DcFilter(TransitionBandwidth, FS: TSample; num, den: TVec);

Description
Design a DC filter with TransitionBandwidth and place the transfer function in Num (numerator) and Den (denominator). You can then use this transfer function to initialize an IIR filter with a call to IirInit. A DC filtered signal will be centered around zero. This DC filter is a simple differentiator/integrator pair. Transition bandwidth is the width of the frequency band where the amplitude is not yet completely attenuated. With DC filters, the transition band starts at 0 Hz. Narrow transition band (TransitionBandwidth/FS ratio is small) will result in filters with longer delays. FS is the sampling frequency. The filter implements the following difference equation:
y[i] = x[i] - x[i-1] + alpha*y[i-1] x.. input signal y.. output signal alpha.. parameter
Alpha paremeter can control the 3dB frequency of the transition bandwidth:
alpha := 1-(TransitionBandwidth/FS)*Pi; FS.. sampling frequency TransitionBandwidth.. frequency up to which will the filter have more then 3dB attenuation. Must be less then FS/2.

Declaration
Procedure DcFilter(alpha: TSample; num, den: TVec);

Description
Design a DC filter with alpha parameter and place the transfer function in Num (numerator) and Den (denominator). This transfer function can be used to initialize an IIR filter with a call to IirInit. A DC filtered signal will be centered around zero. The DC filter is a simple differentiator/integrator pair. alpha is typically between 0.99 and 0.9999 and must be < 1. A bigger alpha will cause longer filter delay.
Declaration
Function DcFilter(NewValue: TSample; var State: TCplx; alpha: TSample = 0.99): TSample;

Description
State parameter holds the filter state. NewValue is the next sample and alpha is typically between 0.99 and 0.9999 and must be < 1. Big alpha will cause longer filter delay and more ringing. State should be initialized to zero before the routine is called for the first time.
Categories
IIR filter design routines
 See Also 
RemoveDC 
IirFilter 
ButterFilter 
ChebyshevIFilter 
ChebyshevIIFilter 
EllipticFilter 
RemezImpulse 

Example 1

DC filtering.
uses MtxExpr, Math387, MtxVec, SignalUtils, MtxVecTee, MtxVecEdit; procedure TForm1.Button1Click(Sender: TObject); var b,c,Response,num,den,X: Vector; n,i: integer; IirState: TIirState; DCState: TCplx; begin Tone(b,300,5/300,0,1); //generate sine with 5 periods in 300 samples // Alternative: // b.RandGauss; b := b + 2; c.Copy(b); n := 10; DCFilter(0.95,num,den); IirInit(num,den,IirState); for i := 0 to b.Length div n-1 do //only to test the streaming begin b.SetSubRange(i*n,n); c.SetSubRange(i*n,n); IirFilter(b,c,IirState); end; b.SetFullRange; c.SetFullRange; DrawIt([b,c],['Unfiltered','Filtered'],'DC filter'); FrequencyResponse(num,den,Response,64); DrawIt(Response,'Frequency response'); DcFilter(0.05,2,num,den); IirInit(num,den,IirState); for i := 0 to b.Length div n-1 do // the loop is only to test the streaming begin b.SetSubRange(i*n,n); c.SetSubRange(i*n,n); IirFilter(b,c,IirState); end; b.SetFullRange; c.SetFullRange; DrawIt([b,c],['Unfiltered','Filtered']); FrequencyResponse(num,den,Response,64); DrawIt(Response,'Frequency response'); DCState := C_ZERO; for i := 0 to b.Length -1 do c.Values[i] := DcFilter(b.Values[i],DcState,0.95); DrawIt([b,c],['Unfiltered','Filtered']); end;
#include "MtxVecCPP.h" //MtxVecCPP.cpp must be included in the project #include "MtxVecEdit.hpp" #include "MtxVecTee.hpp" #include "SignalUtils.hpp" #include <string.h> void __fastcall TForm1::BitBtn1Click(TObject *Sender) { Vector num,den,b,c,Response; int n,i; TIirState IirState; double State = 0; TCplx DCState; Tone(b,300,5.0/300,0,1); //generate sine with 5 periods in 300 samples // Alternative: // b->RandGauss(); b += 2; //add 2 to vector c = b; //delayed deep copy n = 10; DcFilter(0.95,num,den); //specify alfa memset(&IirState,0,sizeof(IirState)); IirInit(num,den,IirState); for (i = 0; i < (b->Length/n); i++) //streaming test 1 IirFilter(b(i*n,i*n+n-1),c(i*n,i*n+n-1),IirState); DrawIt(OPENARRAY(TVec*,(b,c)),OPENARRAY(AnsiString,("Unfiltered","Filtered"))); FrequencyResponse(num,den,Response,64); DrawIt(Response,"Frequency response"); DcFilter(0.05,2,num,den); //specify transition bandwidth and FS IirInit(num,den,IirState); for (i = 0; i < (b->Length/n); i++) //streaming test 1 IirFilter(b(i*n,i*n+n-1),c(i*n,i*n+n-1),IirState); DrawIt(OPENARRAY(TVec*,(b,c)),OPENARRAY(AnsiString,("Unfiltered","Filtered"))); FrequencyResponse(num,den,Response,64); DrawIt(Response,"Frequency response"); DCState = C_ZERO; for (i = 0; i < b->Length; i++) //streaming test 1 c.Values(i) = DcFilter(b.Values(i),DCState,0.95); DrawIt(OPENARRAY(TVec*,(b,c)),OPENARRAY(AnsiString,("Unfiltered","Filtered"))); }
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 b = new Vector(0); Vector c = new Vector(0); Vector num = new Vector(0); Vector x = new Vector(0); Vector den = new Vector(0); Vector Response = new Vector(0); int n; int i; TIirState IirState = new TIirState(); TCplx DCState; SignalUtils.Tone(b,300,5.0/300,0,1,false); //generate sine with 5 periods in 300 samples // Alternative: // b.RandGauss; b = b + 2; c.Copy(b); n = 10; SignalUtils.DcFilter(0.95,num,den); SignalUtils.IirInit(num,den,ref IirState,false); int bLength = b.Length; for (i = 0; i < (bLength/n); i++) //only to test the streaming { b.SetSubRange(i*n,n); c.SetSubRange(i*n,n); SignalUtils.IirFilter(b,c,ref IirState); } b.SetFullRange(); c.SetFullRange(); TeeChart.DrawIt(new TVec[2] { b, c }, new string[2] { "Unfiltered", "Filtered" }, "DC IirFilter", false); SignalUtils.FrequencyResponse(num,den,Response,64,false,TSignalWindowType.wtRectangular,0); TeeChart.DrawIt(Response,"Frequency response",false); SignalUtils.DcFilter(0.05,2,num,den); SignalUtils.IirInit(num,den,ref IirState,false); bLength = b.Length; for (i = 0; i < (bLength/n); i++) //only to test the streaming { b.SetSubRange(i*n,n); c.SetSubRange(i*n,n); SignalUtils.IirFilter(b,c,ref IirState); } b.SetFullRange(); c.SetFullRange(); TeeChart.DrawIt(new TVec[2] { b, c }, new string[2] { "Unfiltered", "Filtered" }, "DC IirFilter", false); SignalUtils.FrequencyResponse(num,den,Response,64,false,TSignalWindowType.wtRectangular,0); TeeChart.DrawIt(Response,"Frequency response",false); DCState = Math387.C_ZERO; for (i = 0; i < (b.Length); i++) //only to test the streaming { c.Values[i] = SignalUtils.DcFilter(b.Values[i],ref DCState,0.95); } TeeChart.DrawIt(new TVec[2] { b, c }, new string[2] { "Unfiltered", "Filtered" }, "DC IirFilter", false); }

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