public static void SetResonantLowpassCoefficients( ResonantLowpassRec Filter, double Cutoff, double Bandwidth, double Gain, double SamplingRate) { if ((Cutoff == Filter.OldCutoff) && (Bandwidth == Filter.OldBandwidth) && (Gain == Filter.OldGain)) { return; } Filter.OldCutoff = Cutoff; Filter.OldBandwidth = Bandwidth; Filter.OldGain = Gain; if (Filter.NumLowpassSections != 0) { /* initialize first one */ ButterworthLowpassRec.ComputeButterworthLowpassCoefficients( ref Filter.iir[0], Cutoff, SamplingRate); /* copy to the others */ for (int i = 1; i < Filter.NumLowpassSections; i += 1) { Filter.iir[i].A0 = Filter.iir[0].A0; Filter.iir[i].A1 = Filter.iir[0].A1; Filter.iir[i].A2 = Filter.iir[0].A2; Filter.iir[i].B1 = Filter.iir[0].B1; Filter.iir[i].B2 = Filter.iir[0].B2; } } if (Filter.NumBandpassSections != 0) { /* initialize first one */ ButterworthBandpassRec.ComputeButterworthBandpassCoefficients( ref Filter.iir[Filter.NumLowpassSections + 0], Cutoff, Bandwidth, SamplingRate); /* copy to the others */ for (int i = 1; i < Filter.NumBandpassSections; i += 1) { Filter.iir[Filter.NumLowpassSections + i].A0 = Filter.iir[Filter.NumLowpassSections + 0].A0; Filter.iir[Filter.NumLowpassSections + i].A1 = Filter.iir[Filter.NumLowpassSections + 0].A1; Filter.iir[Filter.NumLowpassSections + i].A2 = Filter.iir[Filter.NumLowpassSections + 0].A2; Filter.iir[Filter.NumLowpassSections + i].B1 = Filter.iir[Filter.NumLowpassSections + 0].B1; Filter.iir[Filter.NumLowpassSections + i].B2 = Filter.iir[Filter.NumLowpassSections + 0].B2; } } Filter.BandpassGain = (float)Gain; }
/* apply filter to an array of values, adding result to output array */ public void Apply( float[] XinVector, int XInVectorOffset, float[] YoutVector, int YoutVectorOffset, int VectorLength, float OutputScaling, SynthParamRec SynthParams) { ResonantLowpassRec Filter = this; // ScratchWorkspace1* is used in ApplyUnifiedFilterArray() #if DEBUG Debug.Assert(!SynthParams.ScratchWorkspace2InUse); SynthParams.ScratchWorkspace2InUse = true; #endif float[] ScratchVector1 = XinVector /*sic*/; // SourceCopy int ScratchVector1Offset = SynthParams.ScratchWorkspace2LOffset; float[] ScratchVector2 = XinVector /*sic*/; // Workspace int ScratchVector2Offset = SynthParams.ScratchWorkspace2ROffset; FloatVectorCopy( XinVector, XInVectorOffset, ScratchVector1, // SourceCopy ScratchVector1Offset, VectorLength); FloatVectorZero( YoutVector, YoutVectorOffset, VectorLength); /* lowpass section */ if (Filter.NumLowpassSections == 0) { } else if (Filter.NumLowpassSections == 1) { IIR2DirectIMAcc( ref Filter.iir[0], ScratchVector1, // SourceCopy ScratchVector1Offset, YoutVector, YoutVectorOffset, VectorLength, OutputScaling); } else { IIR2DirectI( ref Filter.iir[0], ScratchVector1, // SourceCopy ScratchVector1Offset, ScratchVector2, // Workspace ScratchVector2Offset, VectorLength); int i; for (i = 1; i < Filter.NumLowpassSections - 1; i += 1) { IIR2DirectI( ref Filter.iir[i], ScratchVector2, // Workspace ScratchVector2Offset, ScratchVector2, // Workspace ScratchVector2Offset, VectorLength); } IIR2DirectIMAcc( ref Filter.iir[i], ScratchVector2, // Workspace ScratchVector2Offset, YoutVector, YoutVectorOffset, VectorLength, OutputScaling); } /* bandpass section */ if (Filter.NumBandpassSections == 0) { } else if (Filter.NumBandpassSections == 1) { IIR2DirectIMAcc( ref Filter.iir[Filter.NumLowpassSections + 0], ScratchVector1, // SourceCopy ScratchVector1Offset, YoutVector, YoutVectorOffset, VectorLength, Filter.BandpassGain * OutputScaling); } else { IIR2DirectI( ref Filter.iir[Filter.NumLowpassSections + 0], ScratchVector1, // SourceCopy ScratchVector1Offset, ScratchVector2, // Workspace ScratchVector2Offset, VectorLength); int i; for (i = 1; i < Filter.NumBandpassSections - 1; i += 1) { IIR2DirectI( ref Filter.iir[Filter.NumLowpassSections + i], ScratchVector2, // Workspace ScratchVector2Offset, ScratchVector2, // Workspace ScratchVector2Offset, VectorLength); } IIR2DirectIMAcc( ref Filter.iir[Filter.NumLowpassSections + i], ScratchVector2, // Workspace ScratchVector2Offset, YoutVector, YoutVectorOffset, VectorLength, Filter.BandpassGain * OutputScaling); } #if DEBUG SynthParams.ScratchWorkspace2InUse = false; #endif }