public override WWUtil.LargeArray <double> FilterDo(WWUtil.LargeArray <double> inPcmLA)
        {
            if (inPcmLA.LongLength == 0)
            {
                return(new WWUtil.LargeArray <double>(0));
            }

            var inPcm = inPcmLA.ToArray();
            var pcmF  = mFFT.ForwardFft(inPcm);

            double scaleLsb     = Math.Pow(10, LsbScalingDb / 20.0);
            double maxMagnitude = FFT_LENGTH / 2;

            for (int i = 0; i < pcmF.Length; ++i)
            {
                /*   -144 dBより小さい: そのまま
                 *   -144 dB: scaleLsb倍
                 *   -72 dB: scaleLsb/2倍
                 *    0 dB: 1倍
                 * になるようなスケーリングをする。
                 * 出力データは音量が増えるので、後段にノーマライズ処理を追加すると良い。
                 */

                // magnitudeは0.0~1.0の範囲の値。
                double magnitude = pcmF[i].Magnitude() / maxMagnitude;

                double db = float.MinValue;
                if (float.Epsilon < magnitude)
                {
                    db = 20.0 * Math.Log10(magnitude);
                }

                double scale = 1.0;
                if (db < LSB_DECIBEL)
                {
                    scale = 1.0;
                }
                else if (0 <= db)
                {
                    scale = 1.0;
                }
                else
                {
                    scale = 1.0 + db * (scaleLsb - 1) / LSB_DECIBEL;
                }

                pcmF[i] = WWComplex.Mul(pcmF[i], scale);
            }

            return(new WWUtil.LargeArray <double>(mFFT.InverseFft(pcmF)));
        }
Beispiel #2
0
        public override WWUtil.LargeArray <double> FilterDo(WWUtil.LargeArray <double> inPcmLA)
        {
            System.Diagnostics.Debug.Assert(inPcmLA.LongLength == NumOfSamplesNeeded());
            var inPcm = inPcmLA.ToArray();

            // inPcmTをFFTしてinPcmFを得る。
            // inPcmFを0で水増ししたデータoutPcmFを作って逆FFTしoutPcmを得る。

            var inPcmF = mFFT.ForwardFft(inPcm);

            var outPcmF = new WWComplex[UpsampleFftLength];

            for (int i = 0; i < outPcmF.Length; ++i)
            {
                if (i <= FftLength / 2)
                {
                    outPcmF[i] = inPcmF[i];
                }
                else if (UpsampleFftLength - FftLength / 2 <= i)
                {
                    int pos = i + FftLength - UpsampleFftLength;
                    outPcmF[i] = inPcmF[pos];
                }
                else
                {
                    outPcmF[i] = WWComplex.Zero();
                }
            }
            inPcmF = null;

            var outPcm = mFFT.InverseFft(outPcmF);

            outPcmF = null;

            return(new WWUtil.LargeArray <double>(outPcm));
        }