public override double[] FilterDo(double[] inPcm) { var pcmF = mOverlappedFft.ForwardFft(inPcm); int idx20Hz = (int)(20.0 * mFftLength / mPcmFormat.SampleRate); int idx40Hz = (int)(40.0 * mFftLength / mPcmFormat.SampleRate); for (int i = 0; i < idx40Hz - idx20Hz; ++i) { // 正の周波数 { var v = pcmF[i + idx40Hz]; v.Mul(Gain); pcmF[i + idx20Hz].Add(v); } // 負の周波数 { var v = pcmF[mFftLength - (i + idx40Hz)]; v.Mul(Gain); pcmF[mFftLength - (i + idx20Hz)].Add(v); } } return(mOverlappedFft.InverseFft(pcmF)); }
public override double[] FilterDo(double[] inPcm) { var pcmF = mOverlappedFft.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].Mul(scale); } return(mOverlappedFft.InverseFft(pcmF)); }