Main Archive Specials Wiki | FAQ Links Submit Forum

 Another 4-pole lowpass...Type : 4-pole LP/HPReferences : Posted by fuzzpilz [AT] gmx [DOT] netNotes : Vaguely based on the Stilson/Smith Moog paper, but going in a rather different direction from others I've seen here. The parameters are peak frequency and peak magnitude (g below); both are reasonably accurate for magnitudes above 1. DC gain is 1. The filter has some undesirable properties - e.g. it's unstable for low peak freqs if implemented in single precision (haven't been able to cleanly separate it into biquads or onepoles to see if that helps), and it responds so strongly to parameter changes that it's not advisable to update the coefficients much more rarely than, say, every eight samples during sweeps, which makes it somewhat expensive. I like the sound, however, and the accuracy is nice to have, since many filters are not very strong in that respect. I haven't looked at the HP again for a while, but IIRC it had approximately the same good and bad sides.Code : double coef[9]; double d[4]; double omega; //peak freq double g; //peak mag // calculating coefficients: double k,p,q,a; double a0,a1,a2,a3,a4; k=(4.0*g-3.0)/(g+1.0); p=1.0-0.25*k;p*=p; // LP: a=1.0/(tan(0.5*omega)*(1.0+p)); p=1.0+a; q=1.0-a; a0=1.0/(k+p*p*p*p); a1=4.0*(k+p*p*p*q); a2=6.0*(k+p*p*q*q); a3=4.0*(k+p*q*q*q); a4= (k+q*q*q*q); p=a0*(k+1.0); coef[0]=p; coef[1]=4.0*p; coef[2]=6.0*p; coef[3]=4.0*p; coef[4]=p; coef[5]=-a1*a0; coef[6]=-a2*a0; coef[7]=-a3*a0; coef[8]=-a4*a0; // or HP: a=tan(0.5*omega)/(1.0+p); p=a+1.0; q=a-1.0; a0=1.0/(p*p*p*p+k); a1=4.0*(p*p*p*q-k); a2=6.0*(p*p*q*q+k); a3=4.0*(p*q*q*q-k); a4= (q*q*q*q+k); p=a0*(k+1.0); coef[0]=p; coef[1]=-4.0*p; coef[2]=6.0*p; coef[3]=-4.0*p; coef[4]=p; coef[5]=-a1*a0; coef[6]=-a2*a0; coef[7]=-a3*a0; coef[8]=-a4*a0; // per sample: out=coef[0]*in+d[0]; d[0]=coef[1]*in+coef[5]*out+d[1]; d[1]=coef[2]*in+coef[6]*out+d[2]; d[2]=coef[3]*in+coef[7]*out+d[3]; d[3]=coef[4]*in+coef[8]*out;

 CommentsAdded on : 04/04/05 by Christian[ AT ]savioursofsoul[ DOT ]deComment : Yet untested object pascal translation: unit T4PoleUnit; interface type TFilterType=(ftLowPass, ftHighPass);      T4Pole=class(TObject)      private        fGain     : Double;        fFreq     : Double;        fSR       : Single;      protected        fCoeffs     : array[0..8] of Double;        d           : array[0..3] of Double;        fFilterType : TFilterType;        procedure SetGain(s:Double);        procedure SetFrequency(s:Double);        procedure SetFilterType(v:TFilterType);        procedure Calc;      public        constructor Create;        function Process(s:single):single;      published        property Gain: Double read fGain write SetGain;        property Frequency: Double read fFreq write SetFrequency;        property SampleRate: Single read fSR write fSR;        property FilterType: TFilterType read fFilterType write SetFilterType;      end; implementation uses math; const kDenorm = 1.0e-25; constructor T4Pole.Create; begin inherited create; fFreq:=1000; fSR:=44100; Calc; end; procedure T4Pole.SetFrequency(s:Double); begin fFreq:=s; Calc; end; procedure T4Pole.SetGain(s:Double); begin fGain:=s; Calc; end; procedure T4Pole.SetFilterType(v:TFilterType); begin fFilterType:=v; Calc; end; procedure T4Pole.Calc; var k,p,q,b,s : Double;     a         : array[0..4] of Double; begin fGain:=1; if fFilterType=ftLowPass   then s:=1   else s:=-1; // calculating coefficients: k:=(4.0*fGain-3.0)/(fGain+1.0); p:=1.0-0.25*k; p:=p*p; if fFilterType=ftLowPass   then b:=1.0/(tan(pi*fFreq/fSR)*(1.0+p))   else b:=tan(pi*fFreq/fSR)/(1.0+p); p:=1.0+b; q:=s*(1.0-b); a[0] := 1.0/(  k+p*p*p*p); a[1] := 4.0*(s*k+p*p*p*q); a[2] := 6.0*(  k+p*p*q*q); a[3] := 4.0*(s*k+p*q*q*q); a[4] :=     (  k+q*q*q*q); p    := a[0]*(k+1.0); fCoeffs[0]:=p; fCoeffs[1]:=4.0*p*s; fCoeffs[2]:=6.0*p; fCoeffs[3]:=4.0*p*s; fCoeffs[4]:=p; fCoeffs[5]:=-a[1]*a[0]; fCoeffs[6]:=-a[2]*a[0]; fCoeffs[7]:=-a[3]*a[0]; fCoeffs[8]:=-a[4]*a[0]; end; function T4Pole.Process(s:single):single; begin Result:=fCoeffs[0]*s+d[0]; d[0]:=fCoeffs[1]*s+fCoeffs[5]*Result+d[1]; d[1]:=fCoeffs[2]*s+fCoeffs[6]*Result+d[2]; d[2]:=fCoeffs[3]*s+fCoeffs[7]*Result+d[3]; d[3]:=fCoeffs[4]*s+fCoeffs[8]*Result; end; end.              Added on : 19/03/15 by super_peter1980[ AT ]gmx[ DOT ]deComment : so bad that this filter is so unstable. i tested it and is has a really nice sound. but frequencies below 200 hz are not possible. :-(

 Add your own comment Comments are displayed in fixed width, no HTML code allowed! Email: Comment: Are you human?

Site created and maintained by Bram
Graphic design by line.out | Server sponsered by fxpansion