private double Convolution() { double v = 0.0; // FIRフィルター係数が左右対称なので参考文献[3]の方法で乗算回数を半分に削減できる。 int center = mCoeffs.Length / 2; for (int i = 0; i < center; ++i) { v += mCoeffs[i] * ( mDelay.GetNthDelayedSampleValue(i) + mDelay.GetNthDelayedSampleValue(mCoeffs.Length - i - 1)); } v += mCoeffs[center] * mDelay.GetNthDelayedSampleValue(center); return(v); }
public double[] Filter(double[] inPcm) { var outPcm = new double[inPcm.Length]; if (mParity == WWMath.WWParity.Odd) { int lastOffs = mHalfCoeffs.Length * 2 - 2; for (int pos = 0; pos < inPcm.Length; ++pos) { double x = inPcm[pos]; mDelay.Filter(x); double y = 0; for (int i = 0; i < mHalfCoeffs.Length - 1; ++i) { y += mHalfCoeffs[i] * (mDelay.GetNthDelayedSampleValue(i) + mDelay.GetNthDelayedSampleValue(lastOffs - i)); } y += mHalfCoeffs[mHalfCoeffs.Length - 1] * mDelay.GetNthDelayedSampleValue(mHalfCoeffs.Length - 1); outPcm[pos] = y; } } else { int lastOffs = mHalfCoeffs.Length * 2 - 1; for (int pos = 0; pos < inPcm.Length; ++pos) { double x = inPcm[pos]; mDelay.Filter(x); double y = 0; for (int i = 0; i < mHalfCoeffs.Length; ++i) { y += mHalfCoeffs[i] * (mDelay.GetNthDelayedSampleValue(i) + mDelay.GetNthDelayedSampleValue(lastOffs - i)); } outPcm[pos] = y; } } return(outPcm); }