Nucleo-F446 による遮断周波数可変 LPF/HPF .DA変換器にデータを送る際は 4 倍にアップ・サンプリング.
Dependencies: mbed SerialTxRxIntr F446_AD_DA_MultirateSWI
IIR_Design/BilinearDesignLH.cpp@0:89d173001e82, 2018-06-05 (annotated)
- Committer:
- MikamiUitOpen
- Date:
- Tue Jun 05 11:20:57 2018 +0000
- Revision:
- 0:89d173001e82
1
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
MikamiUitOpen | 0:89d173001e82 | 1 | //------------------------------------------------------------------------ |
MikamiUitOpen | 0:89d173001e82 | 2 | // 双一次z変換によるバタワースフィルタの設計 |
MikamiUitOpen | 0:89d173001e82 | 3 | // LPF, HPF のみ |
MikamiUitOpen | 0:89d173001e82 | 4 | // |
MikamiUitOpen | 0:89d173001e82 | 5 | // 2018/05/14, Copyright (c) 2018 MIKAMI, Naoki |
MikamiUitOpen | 0:89d173001e82 | 6 | //------------------------------------------------------------------------ |
MikamiUitOpen | 0:89d173001e82 | 7 | |
MikamiUitOpen | 0:89d173001e82 | 8 | #include "BilinearDesignLH.hpp" |
MikamiUitOpen | 0:89d173001e82 | 9 | |
MikamiUitOpen | 0:89d173001e82 | 10 | namespace Mikami |
MikamiUitOpen | 0:89d173001e82 | 11 | { |
MikamiUitOpen | 0:89d173001e82 | 12 | // 設計の実行 |
MikamiUitOpen | 0:89d173001e82 | 13 | // 入力 |
MikamiUitOpen | 0:89d173001e82 | 14 | // fc: 遮断周波数 |
MikamiUitOpen | 0:89d173001e82 | 15 | // pb: 通過域 (LPF or HPF) |
MikamiUitOpen | 0:89d173001e82 | 16 | // output |
MikamiUitOpen | 0:89d173001e82 | 17 | // c : 縦続形の Biquad 構造の係数 |
MikamiUitOpen | 0:89d173001e82 | 18 | // g : 利得定数 |
MikamiUitOpen | 0:89d173001e82 | 19 | void BilinearDesign::Execute(float fc, Type pb, Biquad::Coefs c[], float& g) |
MikamiUitOpen | 0:89d173001e82 | 20 | { |
MikamiUitOpen | 0:89d173001e82 | 21 | Butterworth(); |
MikamiUitOpen | 0:89d173001e82 | 22 | Bilinear(fc); |
MikamiUitOpen | 0:89d173001e82 | 23 | ToCascade(pb); |
MikamiUitOpen | 0:89d173001e82 | 24 | GetGain(pb); |
MikamiUitOpen | 0:89d173001e82 | 25 | GetCoefs(c, g); |
MikamiUitOpen | 0:89d173001e82 | 26 | } |
MikamiUitOpen | 0:89d173001e82 | 27 | |
MikamiUitOpen | 0:89d173001e82 | 28 | // バタワース特性の極を取得 |
MikamiUitOpen | 0:89d173001e82 | 29 | void BilinearDesign::Butterworth() |
MikamiUitOpen | 0:89d173001e82 | 30 | { |
MikamiUitOpen | 0:89d173001e82 | 31 | float pi_2order = PI_/(2.0f*ORDER_); |
MikamiUitOpen | 0:89d173001e82 | 32 | for (int j=0; j<ORDER_/2; j++) // 虚部 >= 0 である極を求める |
MikamiUitOpen | 0:89d173001e82 | 33 | { |
MikamiUitOpen | 0:89d173001e82 | 34 | float theta = (2.0f*j + 1.0f)*pi_2order; |
MikamiUitOpen | 0:89d173001e82 | 35 | sP_[j] = Complex(-cosf(theta), sinf(theta)); |
MikamiUitOpen | 0:89d173001e82 | 36 | } |
MikamiUitOpen | 0:89d173001e82 | 37 | } |
MikamiUitOpen | 0:89d173001e82 | 38 | |
MikamiUitOpen | 0:89d173001e82 | 39 | // 双一次z変換 |
MikamiUitOpen | 0:89d173001e82 | 40 | // fc: 遮断周波数 |
MikamiUitOpen | 0:89d173001e82 | 41 | void BilinearDesign::Bilinear(float fc) |
MikamiUitOpen | 0:89d173001e82 | 42 | { |
MikamiUitOpen | 0:89d173001e82 | 43 | float wc = tanf(fc*PI_FS_); |
MikamiUitOpen | 0:89d173001e82 | 44 | for (int k=0; k<ORDER_/2; k++) |
MikamiUitOpen | 0:89d173001e82 | 45 | zP_[k] = (1.0f + wc*sP_[k])/(1.0f - wc*sP_[k]); |
MikamiUitOpen | 0:89d173001e82 | 46 | } |
MikamiUitOpen | 0:89d173001e82 | 47 | |
MikamiUitOpen | 0:89d173001e82 | 48 | // 縦続形の Biquad 構造の係数に変換 |
MikamiUitOpen | 0:89d173001e82 | 49 | void BilinearDesign::ToCascade(Type pb) |
MikamiUitOpen | 0:89d173001e82 | 50 | { |
MikamiUitOpen | 0:89d173001e82 | 51 | for (int j=0; j<ORDER_/2; j++) |
MikamiUitOpen | 0:89d173001e82 | 52 | { |
MikamiUitOpen | 0:89d173001e82 | 53 | ck_[j].a1 = 2.0f*real(zP_[j]); // a1m |
MikamiUitOpen | 0:89d173001e82 | 54 | ck_[j].a2 = -norm(zP_[j]); // a2m |
MikamiUitOpen | 0:89d173001e82 | 55 | ck_[j].b1 = (pb == LPF) ? 2.0f : -2.0f; // b1m |
MikamiUitOpen | 0:89d173001e82 | 56 | ck_[j].b2 = 1.0f; // b2m |
MikamiUitOpen | 0:89d173001e82 | 57 | } |
MikamiUitOpen | 0:89d173001e82 | 58 | } |
MikamiUitOpen | 0:89d173001e82 | 59 | |
MikamiUitOpen | 0:89d173001e82 | 60 | // 利得定数の計算 |
MikamiUitOpen | 0:89d173001e82 | 61 | void BilinearDesign::GetGain(Type pb) |
MikamiUitOpen | 0:89d173001e82 | 62 | { |
MikamiUitOpen | 0:89d173001e82 | 63 | float u = (pb == LPF) ? 1.0f : -1.0f; // u: inverse of z |
MikamiUitOpen | 0:89d173001e82 | 64 | gain_ = 1.0f; |
MikamiUitOpen | 0:89d173001e82 | 65 | for (int k=0; k<ORDER_/2; k++) |
MikamiUitOpen | 0:89d173001e82 | 66 | gain_ = gain_*(1.0f - (ck_[k].a1 + ck_[k].a2*u)*u)/ |
MikamiUitOpen | 0:89d173001e82 | 67 | (1.0f + (ck_[k].b1 + ck_[k].b2*u)*u); |
MikamiUitOpen | 0:89d173001e82 | 68 | } |
MikamiUitOpen | 0:89d173001e82 | 69 | |
MikamiUitOpen | 0:89d173001e82 | 70 | // 係数の取得 |
MikamiUitOpen | 0:89d173001e82 | 71 | void BilinearDesign::GetCoefs(Biquad::Coefs c[], float& gain) |
MikamiUitOpen | 0:89d173001e82 | 72 | { |
MikamiUitOpen | 0:89d173001e82 | 73 | for (int k=0; k<ORDER_/2; k++) c[k] = ck_[k]; |
MikamiUitOpen | 0:89d173001e82 | 74 | gain = gain_; |
MikamiUitOpen | 0:89d173001e82 | 75 | } |
MikamiUitOpen | 0:89d173001e82 | 76 | } |