コード例 #1
0
        /// <summary>
        /// Calculate the FIR coefficients realizing the given cutoff-frequency.
        /// </summary>
        private void CalculateCoeffs()
        {
            double temp;

            Debug.Assert(_length >= 2);
            Debug.Assert(_length % 4 == 0);
            Debug.Assert(_cutoffFreq >= 0);
            Debug.Assert(_cutoffFreq <= 0.5);

            ArrayPtr <double>      work   = new double[_length];
            ArrayPtr <TSampleType> coeffs = new TSampleType[_length];

            double wc        = 2.0 * Math.PI * _cutoffFreq;
            double tempCoeff = (Math.PI * 2) / _length;

            double sum = 0;

            for (int i = 0; i < _length; i++)
            {
                double cntTemp = i - ((double)_length / 2);

                temp = cntTemp * wc;
                double h;
                if (temp != 0)
                {
                    h = Math.Sin(temp) / temp;                     // sinc function
                }
                else
                {
                    h = 1.0;
                }
                double w = 0.54 + 0.46 * Math.Cos(tempCoeff * cntTemp);

                temp    = w * h;
                work[i] = temp;

                // calc net sum of coefficients
                sum += temp;
            }

            // ensure the sum of coefficients is larger than zero
            Debug.Assert(sum > 0);

            // ensure we've really designed a lowpass filter...
            Debug.Assert(work[_length / 2] > 0);
            Debug.Assert(work[_length / 2 + 1] > -1e-6);
            Debug.Assert(work[_length / 2 - 1] > -1e-6);

            // Calculate a scaling coefficient in such a way that the result can be
            // divided by 16384
            double scaleCoeff = 16384.0f / sum;

            for (int i = 0; i < _length; i++)
            {
                temp = work[i] * scaleCoeff;
                // scale & round to nearest integer
                temp += (temp >= 0) ? 0.5 : -0.5;
                // ensure no overfloods
                Debug.Assert(temp >= -32768 && temp <= 32767);
                coeffs[i] = (TSampleType)Convert.ChangeType(temp, typeof(TSampleType));
            }

            // Set coefficients. Use divide factor 14 => divide result by 2^14 = 16384
            _firFilter.SetCoefficients(coeffs, _length, 14);

            DebugSaveAntiAliasFilterCoefficients(coeffs, _length);
        }