/// <summary> /// 線形位相バンドパスフィルタの係数を計算する。 /// 右側半分のみを計算。 /// </summary> /// <param name="type">フィルタタイプ</param> /// <param name="n">タップ数=2n+1</param> /// <param name="w">遮断周波数(BPF の場合は遮断帯域幅、HPF の場合は π-遮断周波数)</param> /// <param name="w0">(BPF のみ) 中心周波数</param> /// <param name="window">窓関数</param> /// <returns>係数の右側半分を計算したもの</returns> public static void CalcLinearBPFCoefficient(FirFilterType type, double[] coef, double w, double w0, WindowFunction window) { int n = coef.Length; double sum; sum = coef[0] = window(0) * w; for(int i=1; i<n; ++i) { double tmp = window(i) * Math.Sin(w * i) / i; sum += tmp * 2; if(type == FirFilterType.LPF) { coef[i] = tmp; } else if(type == FirFilterType.HPF) { if(i%2 != 0) coef[i] = -tmp; else coef[i] = tmp; } else { coef[i] = 2 * Math.Cos(w0 * i) * tmp; } } for(int i=0; i<n; ++i) { coef[i] /= sum; } }//GetLinearBPFCoefficient
public static string ToFriendlyString(this FirFilterType type) { switch (type) { case FirFilterType.LowPass: return("Низкочастотный фильтр"); case FirFilterType.HighPass: return("Высокочастотный фильтр"); default: throw new Exception(); break; } }
public static IFirFilter CalcLinearBPFCoefficient(FirFilterType type, double w, double w0, int taps, WindowType window) { double[] coef; if (taps % 2 == 1) { coef = new double[(taps + 1) / 2]; CalcOddLinearBPFCoefficient(type, coef, w, w0, GetWindow(window, taps)); return(new OddLinearFir(coef)); } else { coef = new double[taps / 2]; CalcEvenLinearBPFCoefficient(type, coef, w, w0, GetWindow(window, taps)); return(new EvenLinearFir(coef)); } }
public static IFirFilter CalcLinearBPFCoefficient(FirFilterType type, double w, double w0, int taps, WindowType window) { double[] coef; if(taps % 2 == 1) { coef = new double[(taps + 1) / 2]; CalcOddLinearBPFCoefficient(type, coef, w, w0, GetWindow(window, taps)); return new OddLinearFir(coef); } else { coef = new double[taps / 2]; CalcEvenLinearBPFCoefficient(type, coef, w, w0, GetWindow(window, taps)); return new EvenLinearFir(coef); } }
} //GetOddLinearBPFCoefficient /// <summary> /// 線形位相バンドパスフィルタ(奇数タップ)の係数を計算する。 /// 右側半分のみを計算。 /// </summary> /// <param name="type">フィルタタイプ</param> /// <param name="coef">係数の格納先</param> /// <param name="w">遮断周波数(BPF の場合は遮断帯域幅、HPF の場合は π-遮断周波数)</param> /// <param name="w0">(BPF のみ) 中心周波数</param> /// <param name="window">窓関数</param> public static void CalcEvenLinearBPFCoefficient(FirFilterType type, double[] coef, double w, double w0, WindowFunction window) { int n = coef.Length - 1; double sum; sum = 0; for (int i = 0; i <= n; ++i) { double x = i + 0.5; double tmp = window(x) * Math.Sin(w * x) / x; sum += tmp * 2; if (type == FirFilterType.LPF) { coef[n - i] = tmp; } else if (type == FirFilterType.HPF) { if (i % 2 != 0) { coef[n - i] = -tmp; } else { coef[n - i] = tmp; } } else { coef[n - i] = 2 * Math.Cos(w0 * x) * tmp; } } for (int i = 0; i < n; ++i) { coef[i] /= sum; } } //GetEvenLinearBPFCoefficient
/// <summary> /// 線形位相バンドパスフィルタ(奇数タップ)の係数を計算する。 /// 右側半分のみを計算。 /// </summary> /// <param name="type">フィルタタイプ</param> /// <param name="coef">係数の格納先</param> /// <param name="w">遮断周波数(BPF の場合は遮断帯域幅、HPF の場合は π-遮断周波数)</param> /// <param name="w0">(BPF のみ) 中心周波数</param> /// <param name="window">窓関数</param> public static void CalcOddLinearBPFCoefficient(FirFilterType type, double[] coef, double w, double w0, WindowFunction window) { int n = coef.Length - 1; double sum; sum = coef[n] = window(0) * w; for (int i = 1; i <= n; ++i) { double tmp = window(i) * Math.Sin(w * i) / i; sum += tmp * 2; if (type == FirFilterType.LPF) { coef[n - i] = tmp; } else if (type == FirFilterType.HPF) { if (i % 2 != 0) { coef[n - i] = -tmp; } else { coef[n - i] = tmp; } } else { coef[n - i] = 2 * Math.Cos(w0 * i) * tmp; } } for (int i = 0; i <= n; ++i) { coef[i] /= sum; } } //GetOddLinearBPFCoefficient
}//GetOddLinearBPFCoefficient /// <summary> /// 線形位相バンドパスフィルタ(奇数タップ)の係数を計算する。 /// 右側半分のみを計算。 /// </summary> /// <param name="type">フィルタタイプ</param> /// <param name="coef">係数の格納先</param> /// <param name="w">遮断周波数(BPF の場合は遮断帯域幅、HPF の場合は π-遮断周波数)</param> /// <param name="w0">(BPF のみ) 中心周波数</param> /// <param name="window">窓関数</param> public static void CalcEvenLinearBPFCoefficient(FirFilterType type, double[] coef, double w, double w0, WindowFunction window) { int n = coef.Length - 1; double sum; sum = 0; for(int i=0; i<=n; ++i) { double x = i + 0.5; double tmp = window(x) * Math.Sin(w * x) / x; sum += tmp * 2; if(type == FirFilterType.LPF) { coef[n - i] = tmp; } else if(type == FirFilterType.HPF) { if(i%2 != 0) coef[n - i] = -tmp; else coef[n - i] = tmp; } else { coef[n - i] = 2 * Math.Cos(w0 * x) * tmp; } } for(int i=0; i<n; ++i) { coef[i] /= sum; } }//GetEvenLinearBPFCoefficient
public static double[] ImpulseCharacteristic(double hz, int n, double threshold, FirFilterType impulseCharacteristicType = FirFilterType.LowPass, FirWindowType windowType = FirWindowType.Rectangle) { double[] h; double[] w = WindowCoef(windowType, n); double fc = threshold / (hz); switch (impulseCharacteristicType) { case FirFilterType.LowPass: h = BaseImpulseCharacteristic(threshold, hz, n); break; case FirFilterType.HighPass: h = BaseImpulseCharacteristic(threshold, hz, n).Select(x => (-x)).ToArray(); h[n / 2] = 1 - 2 * fc; break; default: throw new Exception(); } double[] result = new double[n]; for (int i = 0; i < n; i++) { result[i] = h[i] * w[i]; } return(result); }
public static double[] FirFilter(double[] data, double hz, int n, double threshold0, double threshold1, FirFilterType type = FirFilterType.LowPass, FirWindowType windowType = FirWindowType.Rectangle) { double[] h = ImpulseCharacteristic(hz, n, threshold0, threshold1, type, windowType); return(BaseFirFilter(data, h)); }
public static double[] ImpulseCharacteristic(double hz, int n, double threshold0, double threshold1, FirFilterType impulseCharacteristicType = FirFilterType.LowPass, FirWindowType windowType = FirWindowType.Rectangle) { double[] h0, h1, h; double[] w = WindowCoef(windowType, n); double fc0 = threshold0 / (hz); double fc1 = threshold1 / (hz); switch (impulseCharacteristicType) { case FirFilterType.BandPass: h = new double[n]; h0 = BaseImpulseCharacteristic(threshold0, hz, n); h1 = BaseImpulseCharacteristic(threshold1, hz, n); for (int i = 0; i < n; i++) { h[i] = h1[i] - h0[i]; h[n / 2] = 2 * (fc1 - fc0); } break; case FirFilterType.NotchPass: h = new double[n]; h0 = BaseImpulseCharacteristic(threshold0, hz, n); h1 = BaseImpulseCharacteristic(threshold1, hz, n); for (int i = 0; i < n; i++) { h[i] = h0[i] - h1[i]; h[n / 2] = 1 - 2 * (fc1 - fc0); } break; default: throw new Exception(); } double[] result = new double[n]; for (int i = 0; i < n; i++) { result[i] = h[i] * w[i]; } return(result); }