/* apply filter to an array of values, modifying the array in place */
 public static void ApplyButterworthBandpassVectorModify(
     ButterworthBandpassRec Filter1,
     ButterworthBandpassRec Filter2,
     ButterworthBandpassRec Filter3,
     ButterworthBandpassRec Filter4,
     float[] Vector,
     int VectorOffset1,
     int VectorOffset2,
     int VectorOffset3,
     int VectorOffset4,
     int VectorLength)
 {
     IIR2DirectI_Parallel4(
         ref Filter1.iir,
         ref Filter2.iir,
         ref Filter3.iir,
         ref Filter4.iir,
         Vector,
         VectorOffset1,
         VectorOffset2,
         VectorOffset3,
         VectorOffset4,
         Vector,
         VectorOffset1,
         VectorOffset2,
         VectorOffset3,
         VectorOffset4,
         VectorLength);
 }
            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, modifying the array in place */
 public static void ApplyButterworthBandpassVectorModify(
     ButterworthBandpassRec Filter,
     float[] Vector,
     int VectorOffset,
     int VectorLength)
 {
     IIR2DirectI(
         ref Filter.iir,
         Vector,
         VectorOffset,
         Vector,
         VectorOffset,
         VectorLength);
 }
            public static void SetButterworthBandpassCoefficients(
                ButterworthBandpassRec Filter,
                double Cutoff,
                double Bandwidth,
                double SamplingRate)
            {
                if ((Cutoff == Filter.OldCutoff) && (Bandwidth == Filter.OldBandwidth))
                {
                    return;
                }
                Filter.OldCutoff    = Cutoff;
                Filter.OldBandwidth = Bandwidth;

                ComputeButterworthBandpassCoefficients(
                    ref Filter.iir,
                    Cutoff,
                    Bandwidth,
                    SamplingRate);
            }
            /* 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)
            {
                ButterworthBandpassRec Filter = this;

                IIR2DirectIMAcc(
                    ref Filter.iir,
                    XinVector,
                    XInVectorOffset,
                    YoutVector,
                    YoutVectorOffset,
                    VectorLength,
                    OutputScaling);
            }
 /* apply filter to an array of values, adding result to output array */
 public static void Apply4(
     ButterworthBandpassRec Filter1,
     ButterworthBandpassRec Filter2,
     ButterworthBandpassRec Filter3,
     ButterworthBandpassRec Filter4,
     float[] XinVector,
     int XInVectorOffset1,
     int XInVectorOffset2,
     int XInVectorOffset3,
     int XInVectorOffset4,
     float[] YoutVector,
     int YoutVectorOffset,
     int VectorLength,
     float OutputScaling1,
     float OutputScaling2,
     float OutputScaling3,
     float OutputScaling4,
     SynthParamRec SynthParams)
 {
     IIR2DirectIMAcc_Parallel4(
         ref Filter1.iir,
         ref Filter2.iir,
         ref Filter3.iir,
         ref Filter4.iir,
         XinVector,
         XInVectorOffset1,
         XInVectorOffset2,
         XInVectorOffset3,
         XInVectorOffset4,
         YoutVector,
         YoutVectorOffset,
         VectorLength,
         OutputScaling1,
         OutputScaling2,
         OutputScaling3,
         OutputScaling4);
 }
예제 #7
0
            /* apply filter matrix to vector */
            private static void ApplyVocoderMatrix(
                VocoderRec Vocoder,
                ButterworthBandpassRec[] BandMatrix,
                int BandMatrixOffset,
                float[] CombinedGainFactorVector,
                int CombinedGainFactorVectorOffset,
                float[] Vector,
                int VectorOffset,
                float[] SourceBase,
                int SourceOffset,
                float[] MangleBase,
                int MangleOffset,
                int Length,
                SynthParamRec SynthParams)
            {
                int BandCount  = Vocoder.BandCount;
                int OrderCount = Vocoder.OrderCount;

                /* build source and initialize vector for output */
                FloatVectorCopy(
                    Vector,
                    VectorOffset,
                    SourceBase,
                    SourceOffset,
                    Length);
                FloatVectorZero(
                    Vector,
                    VectorOffset,
                    Length);

                int i = 0;

#if VECTOR
                if (EnableVector)
                {
#if DEBUG
                    Debug.Assert(!SynthParams.ScratchWorkspace2InUse);
                    Debug.Assert(!SynthParams.ScratchWorkspace4InUse);
                    SynthParams.ScratchWorkspace2InUse = true;
                    SynthParams.ScratchWorkspace4InUse = true;
#endif
                    int MangleOffset2 = SynthParams.ScratchWorkspace2LOffset;
                    int MangleOffset3 = SynthParams.ScratchWorkspace2ROffset;
                    int MangleOffset4 = SynthParams.ScratchWorkspace4LOffset;

                    /* process matrix */
                    for (; i <= BandCount - 4; i += 4)
                    {
                        /* initialize mangle vector with raw data */
                        FloatVectorCopy(
                            SourceBase,
                            SourceOffset,
                            MangleBase,
                            MangleOffset,
                            Length);
                        FloatVectorCopy(
                            SourceBase,
                            SourceOffset,
                            MangleBase,
                            MangleOffset2,
                            Length);
                        FloatVectorCopy(
                            SourceBase,
                            SourceOffset,
                            MangleBase,
                            MangleOffset3,
                            Length);
                        FloatVectorCopy(
                            SourceBase,
                            SourceOffset,
                            MangleBase,
                            MangleOffset4,
                            Length);

                        /* apply filters to succession, copying out on the last one */
                        for (int j = 0; j < OrderCount; j++)
                        {
                            if (j != OrderCount - 1)
                            {
                                /* interior filters modify the buffer, with unity gain */
                                ButterworthBandpassRec.ApplyButterworthBandpassVectorModify(
                                    BandMatrix[BandMatrixOffset + (i + 0) * OrderCount + j],
                                    BandMatrix[BandMatrixOffset + (i + 1) * OrderCount + j],
                                    BandMatrix[BandMatrixOffset + (i + 2) * OrderCount + j],
                                    BandMatrix[BandMatrixOffset + (i + 3) * OrderCount + j],
                                    MangleBase,
                                    MangleOffset,
                                    MangleOffset2,
                                    MangleOffset3,
                                    MangleOffset4,
                                    Length);
                            }
                            else
                            {
                                /* final filter adds to output */
                                ButterworthBandpassRec.Apply4(
                                    BandMatrix[BandMatrixOffset + (i + 0) * OrderCount + j],
                                    BandMatrix[BandMatrixOffset + (i + 1) * OrderCount + j],
                                    BandMatrix[BandMatrixOffset + (i + 2) * OrderCount + j],
                                    BandMatrix[BandMatrixOffset + (i + 3) * OrderCount + j],
                                    MangleBase,
                                    MangleOffset,
                                    MangleOffset2,
                                    MangleOffset3,
                                    MangleOffset4,
                                    Vector,
                                    VectorOffset,
                                    Length,
                                    CombinedGainFactorVector[CombinedGainFactorVectorOffset + i + 0],
                                    CombinedGainFactorVector[CombinedGainFactorVectorOffset + i + 1],
                                    CombinedGainFactorVector[CombinedGainFactorVectorOffset + i + 2],
                                    CombinedGainFactorVector[CombinedGainFactorVectorOffset + i + 3],
                                    SynthParams);
                            }
                        }
                    }

#if DEBUG
                    SynthParams.ScratchWorkspace2InUse = false;
                    SynthParams.ScratchWorkspace4InUse = false;
#endif
                }
#endif

                /* process matrix */
                for (; i < BandCount; i++)
                {
                    /* initialize mangle vector with raw data */
                    FloatVectorCopy(
                        SourceBase,
                        SourceOffset,
                        MangleBase,
                        MangleOffset,
                        Length);

                    /* apply filters to succession, copying out on the last one */
                    for (int j = 0; j < OrderCount; j++)
                    {
                        if (j != OrderCount - 1)
                        {
                            /* interior filters modify the buffer, with unity gain */
                            ButterworthBandpassRec.ApplyButterworthBandpassVectorModify(
                                BandMatrix[BandMatrixOffset + i * OrderCount + j],
                                MangleBase,
                                MangleOffset,
                                Length);
                        }
                        else
                        {
                            /* final filter adds to output */
                            BandMatrix[BandMatrixOffset + i * OrderCount + j].Apply(
                                MangleBase,
                                MangleOffset,
                                Vector,
                                VectorOffset,
                                Length,
                                CombinedGainFactorVector[CombinedGainFactorVectorOffset + i],
                                SynthParams);
                        }
                    }
                }
            }
예제 #8
0
            /* update a filter matrix given a wave table index and matrix base pointer */
            /* first element in the list is the lowest ordered element in the wave table. */
            /* wave index is scaled from 1 to #waves - 1 */
            private static void VocoderUpdateMatrix(
                VocoderRec Vocoder,
                ButterworthBandpassRec[] BandMatrix,
                int BandMatrixOffset,
                float[] CombinedGainFactorVector,
                int CombinedGainFactorVectorOffset,
                SynthParamRec SynthParams)
            {
                int BandCount  = Vocoder.BandCount;
                int OrderCount = Vocoder.OrderCount;

                float[][] WaveMatrix  = Vocoder.WaveTableMatrix;
                float     OverallGain = (float)Vocoder.CurrentOutputScaling;

#if DEBUG
                if ((Vocoder.CurrentWaveTableIndex < 0) || (Vocoder.CurrentWaveTableIndex > Vocoder.NumberOfTablesMinus1))
                {
                    // table index out of range
                    Debug.Assert(false);
                    throw new InvalidOperationException();
                }
#endif

                if (((int)(Vocoder.CurrentWaveTableIndex) == Vocoder.NumberOfTablesMinus1) ||
                    !Vocoder.EnableCrossWaveTableInterpolation)
                {
                    /* end interpolation */

                    float[] WaveData = WaveMatrix[(int)(Vocoder.CurrentWaveTableIndex)];

                    /* start at the beginning */
                    for (int i = 0; i < BandCount; i++)
                    {
                        /* L+F(R-L) */

                        /* consult wave table for center frequency */
                        float RawCenterFreq = WaveData[i * VOC_FIELDCOUNT + 0];

                        /* consult wave table for bandwidth */
                        float RawBandWidth = WaveData[i * VOC_FIELDCOUNT + 1];

                        /* consult wave table for gain */
                        float RawUncombinedGain = WaveData[i * VOC_FIELDCOUNT + 2];

                        /* do the mappings */
                        CombinedGainFactorVector[CombinedGainFactorVectorOffset + i] = RawUncombinedGain * OverallGain;
                        double CookedCenterFreq = (VOC_MAXFREQ * 0.5) * (1 + (double)RawCenterFreq);
                        double CookedBandWidth  = (VOC_MAXFREQ * 0.5) * (1 + (double)RawBandWidth);

                        /* set the settings */
                        for (int j = 0; j < OrderCount; j++)
                        {
                            ButterworthBandpassRec.SetButterworthBandpassCoefficients(
                                BandMatrix[BandMatrixOffset + i * OrderCount + j],
                                CookedCenterFreq,
                                CookedBandWidth,
                                SynthParams.dSamplingRate);
                        }
                    }
                }
                else
                {
                    /* compute table weighting */
                    float Wave1Weight = (float)(Vocoder.CurrentWaveTableIndex - (int)(Vocoder.CurrentWaveTableIndex));

                    /* full interpolation */

                    float[] WaveData0 = WaveMatrix[(int)(Vocoder.CurrentWaveTableIndex)];
                    float[] WaveData1 = WaveMatrix[(int)(Vocoder.CurrentWaveTableIndex) + 1];

                    /* start at the beginning */
                    for (int i = 0; i < BandCount; i++)
                    {
                        float Wave0Value, Wave1Value;

                        /* L+F(R-L) */

                        /* consult wave table for center frequency */
                        Wave0Value = WaveData0[i * VOC_FIELDCOUNT + 0];
                        Wave1Value = WaveData1[i * VOC_FIELDCOUNT + 0];
                        float RawCenterFreq = Wave0Value + (Wave1Weight * (Wave1Value - Wave0Value));

                        /* consult wave table for bandwidth */
                        Wave0Value = WaveData0[i * VOC_FIELDCOUNT + 1];
                        Wave1Value = WaveData1[i * VOC_FIELDCOUNT + 1];
                        float RawBandWidth = Wave0Value + (Wave1Weight * (Wave1Value - Wave0Value));

                        /* consult wave table for gain */
                        Wave0Value = WaveData0[i * VOC_FIELDCOUNT + 2];
                        Wave1Value = WaveData1[i * VOC_FIELDCOUNT + 2];
                        float RawUncombinedGain = Wave0Value + (Wave1Weight * (Wave1Value - Wave0Value));

                        /* do the mappings */
                        CombinedGainFactorVector[CombinedGainFactorVectorOffset + i] = RawUncombinedGain * OverallGain;
                        double CookedCenterFreq = (VOC_MAXFREQ * 0.5) * (1 + (double)RawCenterFreq);
                        double CookedBandWidth  = (VOC_MAXFREQ * 0.5) * (1 + (double)RawBandWidth);

                        /* set the settings */
                        for (int j = 0; j < OrderCount; j++)
                        {
                            ButterworthBandpassRec.SetButterworthBandpassCoefficients(
                                BandMatrix[BandMatrixOffset + i * OrderCount + j],
                                CookedCenterFreq,
                                CookedBandWidth,
                                SynthParams.dSamplingRate);
                        }
                    }
                }
            }