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
            }