Пример #1
0
        /// <summary>
        /// Butterworth highpass filtering with parameters calculated from
        /// <paramref name="passbandFrequency"/>, <paramref name="stopbandFrequency"/>, <paramref name="passbandAttenuation"/> and <paramref name="stopbandAttenuation"/>.
        /// </summary>
        /// <param name="audio">Audio to filter.</param>
        /// <param name="samplingRate">Sampling Rate of the audio to be processed.</param>
        /// <param name="passbandFrequency">The ordinary frequency of the passband.</param>
        /// <param name="stopbandFrequency">The ordinary frequency of the stopband.</param>
        /// <param name="passbandAttenuation">The attenuation in dB of the passband.</param>
        /// <param name="stopbandAttenuation">The attenuation in dB of the stopband.</param>
        /// <returns>Returns the filtered version of <paramref name="audio"/></returns>
        static public double[] HighpassFiltering(double[] audio, uint samplingRate, uint passbandFrequency, uint stopbandFrequency, float passbandAttenuation, float stopbandAttenuation)
        {
            const double PI = Math.PI;

            uint   fPass = passbandFrequency;
            uint   fStop = stopbandFrequency;
            float  aPass = passbandAttenuation;
            float  aStop = stopbandAttenuation;
            double wPass;
            double wStop;
            double omegaPass;
            double omegaStop;
            double ePass;
            double eStop;
            double w;
            double passE;
            double nExact;
            int    nUsed;
            double omega0;

            double[] theta;
            double[] thetaD;

            double[] filterCoefficientG;
            double[,] filterCoefficientA;
            double[,] filterCoefficientB;

            wPass     = (2 * PI * fPass) / samplingRate; //same problem with negative N's as with the highpass filter
            wStop     = (2 * PI * fStop) / samplingRate;
            omegaPass = MathSupport.Cot(wPass / 2);
            omegaStop = MathSupport.Cot(wStop / 2);
            ePass     = Math.Sqrt(Math.Pow(10, (aPass / 10)) - 1);
            eStop     = Math.Sqrt(Math.Pow(10, (aStop / 10)) - 1);
            w         = omegaStop / omegaPass;
            passE     = eStop / ePass;
            nExact    = Math.Abs(Math.Log(passE) / Math.Log(w));
            nUsed     = (int)Math.Ceiling(nExact);
            int k = (int)Math.Floor(nUsed / 2d);

            theta  = new double[k];
            omega0 = omegaPass / (Math.Pow(ePass, 1d / (double)nUsed));
            thetaD = new double[2 * nUsed - 1];

            for (int i = 0; i < k; i++)
            {
                theta[i] = (PI / (2 * nUsed)) * (nUsed - 1 + (2 * (i + 1)));
            }
            for (int t = 0; t < k; t++)
            {
                thetaD[t] = -2 * Math.Cos(theta[t]);
            }
            if (nUsed % 2 == 1)
            {
                thetaD[0] = 1 + omega0;
            }

            filterCoefficientG = new double[(int)k + 1];
            filterCoefficientA = new double[(int)k + 1, 2];
            filterCoefficientB = new double[(int)k + 1, 3];

            double[] matrixBHelp =
            {
                1,
                -1,
                0
            };

            for (int i = 0; i < k; i++)
            {
                filterCoefficientG[i + 1]    = Math.Pow(omega0, 2) / (1 - 2 * omega0 * Math.Cos(theta[i]) + Math.Pow(omega0, 2));
                filterCoefficientA[i + 1, 0] = -(2 * (Math.Pow(omega0, 2) - 1)) / (1 - 2 * omega0 * Math.Cos(theta[i]) + Math.Pow(omega0, 2));
                filterCoefficientA[i + 1, 1] = (1 + 2 * omega0 * Math.Cos(theta[i]) + Math.Pow(omega0, 2)) / (1 - 2 * omega0 * Math.Cos(theta[i]) + Math.Pow(omega0, 2));
                filterCoefficientB[i + 1, 0] = filterCoefficientG[i + 1] * 1;
                filterCoefficientB[i + 1, 1] = filterCoefficientG[i + 1] * -2;
                filterCoefficientB[i + 1, 2] = filterCoefficientG[i + 1] * 1;
            }
            if (nUsed % 2 != 0)
            {
                filterCoefficientG[0]    = omega0 / (omega0 + 1);
                filterCoefficientA[0, 0] = -(omega0 - 1) / (omega0 + 1);
                filterCoefficientA[0, 1] = 0;
                for (int i = 0; i < 2; i++)
                {
                    filterCoefficientB[0, i] = filterCoefficientG[0] * matrixBHelp[i];
                }
            }
            return(FilteringClass.SOSFiltering(audio, filterCoefficientA, filterCoefficientB, nUsed));
        }
Пример #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="audio"></param>
        /// <param name="samplingRate"></param>
        /// <param name="passbandFrequencyA"></param>
        /// <param name="passbandFrequencyB"></param>
        /// <param name="stopbandFrequencyA"></param>
        /// <param name="stopbandFrequencyB"></param>
        /// <param name="passbandAttenuation"></param>
        /// <param name="stopbandAttenuation"></param>
        /// <returns></returns>
        public static double[] BandpassFiltering(double[] audio, uint samplingRate, uint passbandFrequencyA, uint passbandFrequencyB, uint stopbandFrequencyA, uint stopbandFrequencyB, float passbandAttenuation, float stopbandAttenuation)
        { //page 753
            const double PI        = Math.PI;
            double       wPassA    = 2 * PI * passbandFrequencyA / samplingRate;
            double       wPassB    = 2 * PI * passbandFrequencyB / samplingRate;
            double       c         = (Math.Sin(wPassA + wPassB)) / (Math.Sin(wPassA) + Math.Sin(wPassB));
            double       omegaPass = Math.Abs((c - Math.Cos(wPassB)) / (Math.Sin(wPassB)));

            double wStopA     = 2 * PI * stopbandFrequencyA / samplingRate;
            double wStopB     = 2 * PI * stopbandFrequencyB / samplingRate;
            double omegaStopA = (c - Math.Cos(wStopA)) / (Math.Sin(wStopA));
            double omegaStopB = (c - Math.Cos(wStopB)) / (Math.Sin(wStopB));
            double omegaStop  = Math.Abs(omegaStopA) < Math.Abs(omegaStopB) ? Math.Abs(omegaStopA) : Math.Abs(omegaStopB);

            double ePass  = Math.Sqrt(Math.Pow(10, (passbandAttenuation / 10)) - 1);
            double eStop  = Math.Sqrt(Math.Pow(10, (stopbandAttenuation / 10)) - 1);
            double passE  = eStop / ePass;
            double w      = omegaStop / omegaPass;
            double nExact = Math.Abs(Math.Log(passE) / Math.Log(w));
            int    nUsed  = (int)Math.Ceiling(nExact);
            int    k      = (int)Math.Floor(nUsed / 2d);
            double omega0 = omegaPass / (Math.Pow(ePass, 1d / (double)nUsed));

            double[] theta = new double[k];
            for (int i = 0; i < k; i++)
            {
                theta[i] = (PI / (2 * nUsed)) * (nUsed - 1 + (2 * (i + 1)));
            }

            double[] filterCoefficientG = new double[(int)k + 1];
            double[,] filterCoefficientA = new double[(int)k + 1, 4];
            double[,] filterCoefficientB = new double[(int)k + 1, 5];

            for (int i = 0; i < k; i++)
            {
                filterCoefficientG[i + 1] = Math.Pow(omega0, 2) / (1 - 2 * omega0 * Math.Cos(theta[i]) + Math.Pow(omega0, 2));
            }
            for (int i = 0; i < k; i++)
            {
                filterCoefficientA[i + 1, 0] = (4 * c * (omega0 * Math.Cos(theta[i]) - 1)) / (1 - 2 * omega0 * Math.Cos(theta[i]) + Math.Pow(omega0, 2));
                filterCoefficientA[i + 1, 1] = (2 * (2 * Math.Pow(c, 2) + 1 - Math.Pow(omega0, 2))) / (1 - 2 * omega0 * Math.Cos(theta[i]) + Math.Pow(omega0, 2));
                filterCoefficientA[i + 1, 2] = -(4 * c * (omega0 * Math.Cos(theta[i]) + 1)) / (1 - 2 * omega0 * Math.Cos(theta[i]) + Math.Pow(omega0, 2));
                filterCoefficientA[i + 1, 3] = (1 + 2 * omega0 * Math.Cos(theta[i]) + Math.Pow(omega0, 2)) / (1 - 2 * omega0 * Math.Cos(theta[i]) + Math.Pow(omega0, 2));
                double[] filter =
                {
                    1,
                    0, //(s-1)*c
                    -1 //-s
                };
                double[] vector =
                {
                    1,
                    0, //(s-1)*c
                    -1 //-s
                };
                double[] result = MathSupport.Convolution(vector, filter);
                filterCoefficientB[i + 1, 0] = filterCoefficientG[i + 1] * result[0];
                filterCoefficientB[i + 1, 1] = filterCoefficientG[i + 1] * result[1];
                filterCoefficientB[i + 1, 2] = filterCoefficientG[i + 1] * result[2];
                filterCoefficientB[i + 1, 3] = filterCoefficientG[i + 1] * result[3];
                filterCoefficientB[i + 1, 4] = filterCoefficientG[i + 1] * result[4];
            }

            double[] matrixBHelp =
            {
                1,
                0,  //(s-1)*c
                -1, //-s, s is 1 for band, -1 for stop
                0,
                0
            };
            if (nUsed % 2 != 0)
            {
                filterCoefficientG[0]    = omega0 / (omega0 + 1);
                filterCoefficientA[0, 0] = -(2 * c) / (omega0 + 1);
                filterCoefficientA[0, 1] = (1 - omega0) / (1 + omega0);
                filterCoefficientA[0, 2] = 0;
                filterCoefficientA[0, 3] = 0;
                for (int i = 0; i < 5; i++)
                {
                    filterCoefficientB[0, i] = filterCoefficientG[0] * matrixBHelp[i];
                }
            }

            return(FilteringClass.FOSFiltering(audio, filterCoefficientA, filterCoefficientB, nUsed));
        }