Frequency shifter using Weaver modulator for ST Nucleo F401RE.
Dependencies: UITDSP_ADDA mbed
IIR_Cascade.hpp@0:c17cb8371b55, 2015-07-25 (annotated)
- Committer:
- MikamiUitOpen
- Date:
- Sat Jul 25 07:56:36 2015 +0000
- Revision:
- 0:c17cb8371b55
1
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
MikamiUitOpen | 0:c17cb8371b55 | 1 | //------------------------------------------------------------------------------ |
MikamiUitOpen | 0:c17cb8371b55 | 2 | // 縦続形 IIR フィルタのクラス |
MikamiUitOpen | 0:c17cb8371b55 | 3 | // 2015/03/16, Copyright (c) 2015 MIKAMI, Naoki |
MikamiUitOpen | 0:c17cb8371b55 | 4 | //------------------------------------------------------------------------------ |
MikamiUitOpen | 0:c17cb8371b55 | 5 | |
MikamiUitOpen | 0:c17cb8371b55 | 6 | #ifndef IIR_CASCADE_HPP |
MikamiUitOpen | 0:c17cb8371b55 | 7 | #define IIR_CASCADE_HPP |
MikamiUitOpen | 0:c17cb8371b55 | 8 | |
MikamiUitOpen | 0:c17cb8371b55 | 9 | #include "Biquad.hpp" |
MikamiUitOpen | 0:c17cb8371b55 | 10 | |
MikamiUitOpen | 0:c17cb8371b55 | 11 | namespace Mikami |
MikamiUitOpen | 0:c17cb8371b55 | 12 | { |
MikamiUitOpen | 0:c17cb8371b55 | 13 | template<int order> class IIR_Cascade |
MikamiUitOpen | 0:c17cb8371b55 | 14 | { |
MikamiUitOpen | 0:c17cb8371b55 | 15 | public: |
MikamiUitOpen | 0:c17cb8371b55 | 16 | |
MikamiUitOpen | 0:c17cb8371b55 | 17 | // コンストラクタ |
MikamiUitOpen | 0:c17cb8371b55 | 18 | IIR_Cascade(const Biquad::Coefs ck[], float g0) : g0_(g0) |
MikamiUitOpen | 0:c17cb8371b55 | 19 | { |
MikamiUitOpen | 0:c17cb8371b55 | 20 | for (int n=0; n<order/2; n++) |
MikamiUitOpen | 0:c17cb8371b55 | 21 | hk_[n] = new Biquad(ck[n]); |
MikamiUitOpen | 0:c17cb8371b55 | 22 | Clear(); |
MikamiUitOpen | 0:c17cb8371b55 | 23 | } |
MikamiUitOpen | 0:c17cb8371b55 | 24 | |
MikamiUitOpen | 0:c17cb8371b55 | 25 | // ~IIR_Cascade() { delete[] hk_; } |
MikamiUitOpen | 0:c17cb8371b55 | 26 | |
MikamiUitOpen | 0:c17cb8371b55 | 27 | // 過去の計算結果を格納する配列のクリア |
MikamiUitOpen | 0:c17cb8371b55 | 28 | void Clear() |
MikamiUitOpen | 0:c17cb8371b55 | 29 | { |
MikamiUitOpen | 0:c17cb8371b55 | 30 | for (int k=0; k<order/2; k++) hk_[k]->Clear(); |
MikamiUitOpen | 0:c17cb8371b55 | 31 | } |
MikamiUitOpen | 0:c17cb8371b55 | 32 | |
MikamiUitOpen | 0:c17cb8371b55 | 33 | // フィルタ処理の実行 |
MikamiUitOpen | 0:c17cb8371b55 | 34 | float Execute(float xn) |
MikamiUitOpen | 0:c17cb8371b55 | 35 | { |
MikamiUitOpen | 0:c17cb8371b55 | 36 | float yn = g0_*xn; |
MikamiUitOpen | 0:c17cb8371b55 | 37 | for (int k=0; k<order/2; k++) yn = hk_[k]->Execute(yn); |
MikamiUitOpen | 0:c17cb8371b55 | 38 | return yn; |
MikamiUitOpen | 0:c17cb8371b55 | 39 | } |
MikamiUitOpen | 0:c17cb8371b55 | 40 | |
MikamiUitOpen | 0:c17cb8371b55 | 41 | private: |
MikamiUitOpen | 0:c17cb8371b55 | 42 | Biquad* hk_[order/2]; // 2 次の IIR フィルタ |
MikamiUitOpen | 0:c17cb8371b55 | 43 | const float g0_; // 利得定数 |
MikamiUitOpen | 0:c17cb8371b55 | 44 | }; |
MikamiUitOpen | 0:c17cb8371b55 | 45 | } |
MikamiUitOpen | 0:c17cb8371b55 | 46 | /* |
MikamiUitOpen | 0:c17cb8371b55 | 47 | template<int order> class IIR_Cascade |
MikamiUitOpen | 0:c17cb8371b55 | 48 | { |
MikamiUitOpen | 0:c17cb8371b55 | 49 | public: |
MikamiUitOpen | 0:c17cb8371b55 | 50 | struct Coefs { float a1, a2, b1, b2; }; // フィルタ係数のための構造体 |
MikamiUitOpen | 0:c17cb8371b55 | 51 | |
MikamiUitOpen | 0:c17cb8371b55 | 52 | // コンストラクタ |
MikamiUitOpen | 0:c17cb8371b55 | 53 | IIR_Cascade(const Coefs ck[], float g0) : ck_(ck), g0_(g0) |
MikamiUitOpen | 0:c17cb8371b55 | 54 | { |
MikamiUitOpen | 0:c17cb8371b55 | 55 | Clear(); |
MikamiUitOpen | 0:c17cb8371b55 | 56 | } |
MikamiUitOpen | 0:c17cb8371b55 | 57 | |
MikamiUitOpen | 0:c17cb8371b55 | 58 | // 過去の計算結果を格納する配列のクリア |
MikamiUitOpen | 0:c17cb8371b55 | 59 | void Clear() |
MikamiUitOpen | 0:c17cb8371b55 | 60 | { |
MikamiUitOpen | 0:c17cb8371b55 | 61 | for (int k=0; k<order/2; k++) // 過去の入力信号が格納される配列をクリア |
MikamiUitOpen | 0:c17cb8371b55 | 62 | { |
MikamiUitOpen | 0:c17cb8371b55 | 63 | uk_[k].u1 = 0; |
MikamiUitOpen | 0:c17cb8371b55 | 64 | uk_[k].u2 = 0; |
MikamiUitOpen | 0:c17cb8371b55 | 65 | } |
MikamiUitOpen | 0:c17cb8371b55 | 66 | } |
MikamiUitOpen | 0:c17cb8371b55 | 67 | |
MikamiUitOpen | 0:c17cb8371b55 | 68 | // フィルタ処理の実行 |
MikamiUitOpen | 0:c17cb8371b55 | 69 | float Execute(float xn) |
MikamiUitOpen | 0:c17cb8371b55 | 70 | { |
MikamiUitOpen | 0:c17cb8371b55 | 71 | float yn = g0_*xn; |
MikamiUitOpen | 0:c17cb8371b55 | 72 | for (int k=0; k<order/2; k++) |
MikamiUitOpen | 0:c17cb8371b55 | 73 | { |
MikamiUitOpen | 0:c17cb8371b55 | 74 | // 差分方程式に対応する計算 |
MikamiUitOpen | 0:c17cb8371b55 | 75 | float un = ck_[k].a1*uk_[k].u1 + ck_[k].a2*uk_[k].u2 + yn; |
MikamiUitOpen | 0:c17cb8371b55 | 76 | yn = un + ck_[k].b1*uk_[k].u1 + ck_[k].b2*uk_[k].u2; |
MikamiUitOpen | 0:c17cb8371b55 | 77 | // 計算結果の移動 |
MikamiUitOpen | 0:c17cb8371b55 | 78 | uk_[k].u2 = uk_[k].u1; |
MikamiUitOpen | 0:c17cb8371b55 | 79 | uk_[k].u1 = un; |
MikamiUitOpen | 0:c17cb8371b55 | 80 | } |
MikamiUitOpen | 0:c17cb8371b55 | 81 | return yn; |
MikamiUitOpen | 0:c17cb8371b55 | 82 | } |
MikamiUitOpen | 0:c17cb8371b55 | 83 | |
MikamiUitOpen | 0:c17cb8371b55 | 84 | private: |
MikamiUitOpen | 0:c17cb8371b55 | 85 | struct Un { float u1, u2; }; // 過去の計算結果格納のための構造体 |
MikamiUitOpen | 0:c17cb8371b55 | 86 | Un uk_[order/2]; // 過去の計算結果を格納する配列 |
MikamiUitOpen | 0:c17cb8371b55 | 87 | const Coefs *const ck_; // フィルタの係数 |
MikamiUitOpen | 0:c17cb8371b55 | 88 | const float g0_; // 利得定数 |
MikamiUitOpen | 0:c17cb8371b55 | 89 | }; |
MikamiUitOpen | 0:c17cb8371b55 | 90 | */ |
MikamiUitOpen | 0:c17cb8371b55 | 91 | #endif // IIR_CASCADE_HPP |