www.musicdsp.org files filters004
DESCRIPTION
programTRANSCRIPT
-
06/05/2015 www.musicdsp.org/files/filters004.txt
http://www.musicdsp.org/files/filters004.txt 1/10
//filefilterIIR00.cbegin/*[email protected](Zxform)*/
#include#include#include
/**************************************************************************
FILTER.CSourcecodeforfilterfunctions
iir_filterIIRfilterfloatssamplebysample(realtime)
*************************************************************************/
/*FILTERINFORMATIONSTRUCTUREFORFILTERROUTINES*/
typedefstruct{unsignedintlength;/*sizeoffilter*/float*history;/*pointertohistoryinfilter*/float*coef;/*pointertocoefficientsoffilter*/}FILTER;
#defineFILTER_SECTIONS2/*2filtersectionsfor24db/octfilter*/
typedefstruct{doublea0,a1,a2;/*numeratorcoefficients*/doubleb0,b1,b2;/*denominatorcoefficients*/}BIQUAD;
BIQUADProtoCoef[FILTER_SECTIONS];/*Filterprototypecoefficients,1foreachfiltersection*/
voidszxform(double*a0,double*a1,double*a2,/*numeratorcoefficients*/double*b0,double*b1,double*b2,/*denominatorcoefficients*/doublefc,/*Filtercutofffrequency*/doublefs,/*samplingrate*/double*k,/*overallgainfactor*/float*coef);/*pointerto4iircoefficients*/
/****iir_filterPerformIIRfilteringsamplebysampleonfloats**ImplementscascadeddirectformIIsecondordersections.*RequiresFILTERstructureforhistoryandcoefficients.*Thelengthinthefilterstructurespecifiesthenumberofsections.*Thesizeofthehistoryarrayis2*iir>length.*Thesizeofthecoefficientarrayis4*iir>length+1because*thefirstcoefficientistheoverallscalefactorforthefilter.*Returnsoneoutputsampleforeachinputsample.Allocateshistory*arrayifnotpreviouslyallocated.**floatiir_filter(floatinput,FILTER*iir)
-
06/05/2015 www.musicdsp.org/files/filters004.txt
http://www.musicdsp.org/files/filters004.txt 2/10
**floatinputnewfloatinputsample*FILTER*iirpointertoFILTERstructure**Returnsfloatvaluegivingthecurrentoutput.**Allocationerrorscauseanerrormessageandacalltoexit.**/floatiir_filter(input,iir)floatinput;/*newinputsample*/FILTER*iir;/*pointertoFILTERstructure*/{unsignedinti;float*hist1_ptr,*hist2_ptr,*coef_ptr;floatoutput,new_hist,history1,history2;
/*allocatehistoryarrayifdifferentsizethanlastcall*/
if(!iir>history){iir>history=(float*)calloc(2*iir>length,sizeof(float));if(!iir>history){printf("\nUnabletoallocatehistoryarrayiniir_filter\n");exit(1);}}
coef_ptr=iir>coef;/*coefficientpointer*/
hist1_ptr=iir>history;/*firsthistory*/hist2_ptr=hist1_ptr+1;/*nexthistory*/
/*1stnumberofcoefficientsarrayisoverallinputscalefactor,*orfiltergain*/output=input*(*coef_ptr++);
for(i=0;ilength;i++){history1=*hist1_ptr;/*historyvalues*/history2=*hist2_ptr;
output=outputhistory1*(*coef_ptr++);new_hist=outputhistory2*(*coef_ptr++);/*poles*/
output=new_hist+history1*(*coef_ptr++);output=output+history2*(*coef_ptr++);/*zeros*/
*hist2_ptr++=*hist1_ptr;*hist1_ptr++=new_hist;hist1_ptr++;hist2_ptr++;}
return(output);}
/****main()
-
06/05/2015 www.musicdsp.org/files/filters004.txt
http://www.musicdsp.org/files/filters004.txt 3/10
**Examplemainfunctiontoshowhowtoupdatefiltercoefficients.*Wecreatea4thorderfilter(24db/octroloff),consisting*oftwosecondordersections.**/intmain(){FILTERiir;float*coef;doublefs,fc;/*Samplingfrequency,cutofffrequency*/doubleQ;/*Resonance>1.0
-
06/05/2015 www.musicdsp.org/files/filters004.txt
http://www.musicdsp.org/files/filters004.txt 4/10
a0=ProtoCoef[nInd].a0;a1=ProtoCoef[nInd].a1;a2=ProtoCoef[nInd].a2;
b0=ProtoCoef[nInd].b0;b1=ProtoCoef[nInd].b1/Q;/*DividebyresonanceorQ*/b2=ProtoCoef[nInd].b2;szxform(&a0,&a1,&a2,&b0,&b1,&b2,fc,fs,&k,coef);coef+=4;/*Pointtonextfiltersection*/}
/*Updateoverallfiltergainincoefarray*/iir.coef[0]=k;
/*Displayfiltercoefficients*/for(nInd=0;nInd
Repostingbilinear.cjustincasetheotheronewasnotthelatestversion.
//filebilinear.cbegin/***bilinear.c**Performbilineartransformationonsdomaincoefficients*of2ndorderbiquadsection.*Firstdesignananalogfilterandusesdomaincoefficients*asinputtoszxform()toconvertthemtozdomain.**Here'sthebutterworthpolinomialsfor2nd,4thand6thordersections.*Whenweconstructa24db/octfilter,wetaketo2ndorder*sectionsandcomputethecoefficientsseparatelyforeachsection.**nPolinomials**2s^2+1.4142s+1*4(s^2+0.765367s+1)(s^2+1.847759s+1)*6(s^2+0.5176387s+1)(s^2+1.414214+1)(s^2+1.931852s+1)**Wherenisafilterorder.*Forn=4,ortwosecondordersections,wehavefollowingequasionsforeach*2ndorderstage:**(1/(s^2+(1/Q)*0.765367s+1))*(1/(s^2+(1/Q)*1.847759s+
-
06/05/2015 www.musicdsp.org/files/filters004.txt
http://www.musicdsp.org/files/filters004.txt 5/10
1))**WhereQisfilterqualityfactorintherangeof*1to1000.TheoverallfilterQisaproductofall*2ndorderstages.Forexample,the6thorderfilter*(3stages,orbiquads)withindividualQof2will*havefilterQ=2*2*2=8.**Thenominatorpartisjust1.*Thedenominatorcoefficientsforstage1offilterare:*b2=1;b1=0.765367;b0=1;*numeratoris*a2=0;a1=0;a0=1;**Thedenominatorcoefficientsforstage1offilterare:*b2=1;b1=1.847759;b0=1;*numeratoris*a2=0;a1=0;a0=1;**Thesecoefficientsareuseddirectlybytheszxform()*andbilinear()functions.Forallstagesthenumerator*isthesameandtheonlythingthatisdifferentbetween*differentstagesis1stordercoefficient.Therestof*coefficientsarethesameforanystageandequalto1.**Anyfiltercouldbeconstructedusingthisapproach.**References:*VanValkenburg,"AnalogFilterDesign"*OxfordUniversityPress1982*ISBN0195107349**CLanguageAlgorithmsforDigitalSignalProcessing*PaulEmbree,BruceKimble*PrenticeHall,1991*ISBN0131334069**DigitalFilterDesigner'sHandbook*WithC++Algorithms*BrittonRorabaugh*McGrawHill,1997*ISBN0070538069**/
#include
voidprewarp(double*a0,double*a1,double*a2,doublefc,doublefs);voidbilinear(doublea0,doublea1,doublea2,/*numeratorcoefficients*/doubleb0,doubleb1,doubleb2,/*denominatorcoefficients*/double*k,/*overallgainfactor*/doublefs,/*samplingrate*/float*coef);/*pointerto4iircoefficients*/
/***Prewarpthecoefficientsofanumeratorordenominator.*Notethata0isassumedtobe1,sothereisnowrapping*ofit.
-
06/05/2015 www.musicdsp.org/files/filters004.txt
http://www.musicdsp.org/files/filters004.txt 6/10
**/voidprewarp(double*a0,double*a1,double*a2,doublefc,doublefs){doublewp,pi;
pi=4.0*atan(1.0);wp=2.0*fs*tan(pi*fc/fs);
*a2=(*a2)/(wp*wp);*a1=(*a1)/wp;}
/***bilinear()**Transformthenumeratoranddenominatorcoefficients*ofsdomainbiquadsectionintocorresponding*zdomaincoefficients.**Storethe4IIRcoefficientsinarraypointedbycoef*infollowingorder:*beta1,beta2(denominator)*alpha1,alpha2(numerator)**Arguments:*a0a2sdomainnumeratorcoefficients*b0b2sdomaindenominatorcoefficients*kfiltergainfactor.initiallysetto1*andmodifiedbyeachbiquadsectioninsuch*away,astomakeitthecoefficientby*whichtomultiplytheoverallfiltergain*inordertoachieveadesiredoverallfiltergain,*specifiedininitialvalueofk.*fssamplingrate(Hz)*coefarrayofzdomaincoefficientstobefilledin.**Return:*Onreturn,setcoefzdomaincoefficients**/voidbilinear(doublea0,doublea1,doublea2,/*numeratorcoefficients*/doubleb0,doubleb1,doubleb2,/*denominatorcoefficients*/double*k,/*overallgainfactor*/doublefs,/*samplingrate*/float*coef/*pointerto4iircoefficients*/){doublead,bd;
/*alpha(Numeratorinsdomain)*/ad=4.*a2*fs*fs+2.*a1*fs+a0;/*beta(Denominatorinsdomain)*/bd=4.*b2*fs*fs+2.*b1*fs+b0;
-
06/05/2015 www.musicdsp.org/files/filters004.txt
http://www.musicdsp.org/files/filters004.txt 7/10
/*updategainconstantforthissection*/*k*=ad/bd;
/*Denominator*/*coef++=(2.*b08.*b2*fs*fs)/bd;/*beta1*/*coef++=(4.*b2*fs*fs2.*b1*fs+b0)/bd;/*beta2*/
/*Nominator*/*coef++=(2.*a08.*a2*fs*fs)/ad;/*alpha1*/*coef=(4.*a2*fs*fs2.*a1*fs+a0)/ad;/*alpha2*/}
/***Transformfromstozdomainusingbilineartransform*withprewarp.**Arguments:*Forargumentdescriptionlookatbilinear()**coefpointertoarrayoffloatingpointcoefficients,*correspondingtooutputofbilineartransofrm*(zdomain).**Note:frequenciesareinHz.**/voidszxform(double*a0,double*a1,double*a2,/*numeratorcoefficients*/double*b0,double*b1,double*b2,/*denominatorcoefficients*/doublefc,/*Filtercutofffrequency*/doublefs,/*samplingrate*/double*k,/*overallgainfactor*/float*coef)/*pointerto4iircoefficients*/{/*Calculatea1anda2andoverwritetheoriginalvalues*/prewarp(a0,a1,a2,fc,fs);prewarp(b0,b1,b2,fc,fs);bilinear(*a0,*a1,*a2,*b0,*b1,*b2,k,fs,coef);}
//filebilinear.cend
Andhereishowitallworks.
//filefilter.txtbeginHowtoconstructakewllowpassresonantfilter?
Letsassumewewanttocreateafilterforanalogsynth.Thefilterrolloffis24db/oct,whichcorrespondsto4thorderfilter.FilteroffirstorderisequivalenttoRCcircuitandhasmaxrolloffof6db/oct.
WewilluseclassicalButterworthIIRfilterdesign,asitexactlycorrespondstoourrequirements.
-
06/05/2015 www.musicdsp.org/files/filters004.txt
http://www.musicdsp.org/files/filters004.txt 8/10
Acommonpracticeistochainseveral2ndordersections,orbiquads,astheycommonlycalled,inordertoachiveahigherorderfilter.Each2ndordersectionisa2ndorderfilter,whichhas12db/octroloff.So,weneed2ofthosesectionsinseries.
Tocomputethosesections,weusestandardButterworthpolinomials,orsocalledsdomainrepresentationandconvertitintozdomain,ordigitaldomain.Thereasonweneedtodothisisbecausethefiltertheoryexistsforanalogfiltersforalongtimeandthereexistnotheoryofworkingindigitaldomaindirectly.Sothecommonpracticeistotakestandardanalogfilterdesignandusesocalledbilineartransformtoconvertthebutterworthequasioncoefficientsintozdomain.
Oncewecomputethezdomaincoefficients,wecanusetheminaverysimpletransferfunction,suchasiir_filter()inourCsourcecode,inordertoperformthefilteringfunction.Thefilteritselfisthesimpliestthingintheworld.Themostcomplicatedthingiscomputingthecoefficientsforzdomain.
Ok,letslookatbutterworthpolynomials,arrangedasaseriesof2ndordersections:
*Note:nisfilterorder.**nPolynomials**2s^2+1.4142s+1*4(s^2+0.765367s+1)*(s^2+1.847759s+1)*6(s^2+0.5176387s+1)*(s^2+1.414214+1)*(s^2+1.931852s+1)**Forn=4wehavefollowingequasionforthefiltertransferfunction:**11*T(s)=**s^2+(1/Q)*0.765367s+1s^2+(1/Q)*1.847759s+1*
Thefilterconsistsoftwo2ndordersecionssincehighestspoweris2.Nowwecantakethecoefficients,orthenumbersbywhichsismultipliedandplugthemintoastandardformulatobeusedbybilineartransform.
Ourstandardformforeach2ndordersecionis:
a2*s^2+a1*s+a0H(s)=b2*s^2+b1*s+b0
Notethatbutterworthnominatoris1forallfiltersections,whichmeanss^2=0ands^1=0
Letsconvertstandardbutterworthpolinomialsintothisform:
0+0+10+0+1*1+((1/Q)*0.765367)+11+((1/Q)*1.847759)+1
Section1:
-
06/05/2015 www.musicdsp.org/files/filters004.txt
http://www.musicdsp.org/files/filters004.txt 9/10
a2=0;a1=0;a0=1;b2=1;b1=0.5176387;b0=1;
Section2:a2=0;a1=0;a0=1;b2=1;b1=1.847759;b0=1;
ThatQisfilterqualityfactororresonance,intherangeof1to1000.TheoverallfilterQisaproductofall2ndorderstages.Forexample,the6thorderfilter(3stages,orbiquads)withindividualQof2willhavefilterQ=2*2*2=8.
Theseaandbcoefficientsareuseddirectlybytheszxform()andbilinear()functions.
Thetransferfunctionforzdomainis:
1+alpha1*z^(1)+alpha2*z^(2)H(z)=1+beta1*z^(1)+beta2*z^(2)
Whenyouneedtochangethefilterfrequencycutofforresonance,orQ,youcalltheszxform()functionwithproperaandbcoefficientsandthenewfiltercutofffrequencyorresonance.Youalsoneedtosupplythesamplingrateandfiltergainyouwanttoachive.Forourpurposesthegain=1.
Wecallszxform()function2timesbecasewehave2filtersections.Eachcallprovidesdifferentcoefficients.
Thegainargumenttoszxform()isapointertodesiredfiltergainvariable.
doublek=1.0;/*overallgainfactor*/
Uponreturnfromeachcall,thekargumentwillbesettoavalue,bywhichtomultiplyouractualsignalinorderforthegaintobeone.Onsecondcalltoszxform()weprovidekthatwaschangedbytheprevioussection.Duringactualaudiofilteringfunctioniir_filter()willusethisk
Summary:
Ourfilterisprettyclosetoidealintermsofallrelevantparametersandfilterstabilityevenwithextremelylargevaluesofresonance.Thisfilterdesignhasbeenverifiedunderallvariationsofparametersanditallappearstoworkasadvertized.
Goodluckwithit.IfyouevermakeadirectXwrapperforit,postittocomp.dsp.
***References:*VanValkenburg,"AnalogFilterDesign"*OxfordUniversityPress1982*ISBN0195107349**CLanguageAlgorithmsforDigitalSignalProcessing*PaulEmbree,BruceKimble
-
06/05/2015 www.musicdsp.org/files/filters004.txt
http://www.musicdsp.org/files/filters004.txt 10/10
*PrenticeHall,1991*ISBN0131334069**DigitalFilterDesigner'sHandbook*WithC++Algorithms*BrittonRorabaugh*McGrawHill,1997*ISBN0070538069*