不韋 呂 / Mbed 2 deprecated DSP_VariableLHpfB

Dependencies:   mbed SerialTxRxIntr DSP_MultirateLinearphase

Files at this revision

API Documentation at this revision

Comitter:
MikamiUitOpen
Date:
Fri Feb 25 02:26:41 2022 +0000
Child:
1:2d08a91b6bf2
Commit message:
1

Changed in this revision

DSP_MultirateLinearphase.lib Show annotated file Show diff for this revision Revisions of this file
IirVariable/Biquad.hpp Show annotated file Show diff for this revision Revisions of this file
IirVariable/IIR_Cascade.hpp Show annotated file Show diff for this revision Revisions of this file
IirVariable/IirVariable.hpp Show annotated file Show diff for this revision Revisions of this file
SerialTxRxIntr.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DSP_MultirateLinearphase.lib	Fri Feb 25 02:26:41 2022 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/MikamiUitOpen/code/DSP_MultirateLinearphase/#f7bfe38c93ab
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IirVariable/Biquad.hpp	Fri Feb 25 02:26:41 2022 +0000
@@ -0,0 +1,52 @@
+//--------------------------------------------------------------
+//  縦続形 IIR フィルタの構成要素として使う 2 次の IIR フィルタ
+//      b0 は 1 と仮定している
+//
+//  2022/02/19, Copyright (c) 2022 MIKAMI, Naoki
+//--------------------------------------------------------------
+
+#ifndef IIR_BIQUAD_HPP
+#define IIR_BIQUAD_HPP
+
+#include "mbed.h"
+
+namespace Mikami
+{
+    class Biquad
+    {
+    public:
+        // フィルタの係数をまとめて扱うための構造体
+        struct Coefs { float a1, a2, b1, b2; };
+
+        // デフォルト・コンストラクタ
+        //      係数は構造体 Ceofs で与える
+        Biquad(const Coefs ck = (Coefs){0, 0, 0, 0})
+            : c_(ck), vn1_(0), vn2_(0) {}
+
+        // 2 次のフィルタを実行する
+        float Execute(float xn)
+        {
+            float vn = xn + c_.a1*vn1_ + c_.a2*vn2_;
+            float yn = vn + c_.b1*vn1_ + c_.b2*vn2_;
+        
+            vn2_ = vn1_;
+            vn1_ = vn;
+ 
+            return yn;
+        }
+
+        // 係数を設定する
+        void SetCoefs(const Coefs ck) { c_ = ck; }
+
+        // 内部変数(遅延器)のクリア
+        void Clear() { vn1_ = vn2_ = 0; }
+
+    private:
+        Coefs c_;
+        float vn1_, vn2_;
+
+        // コピー・コンストラクタ禁止のため
+        Biquad(const Biquad&);
+    };
+}
+#endif  // IIR_BIQUAD_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IirVariable/IIR_Cascade.hpp	Fri Feb 25 02:26:41 2022 +0000
@@ -0,0 +1,56 @@
+//---------------------------------------------------
+//  縦続形 IIR フィルタ
+//
+//  2022/02/19, Copyright (c) 2022 MIKAMI, Naoki
+//---------------------------------------------------
+
+#ifndef IIR_CASCADE_HPP
+#define IIR_CASCADE_HPP
+
+#include "Biquad.hpp"
+#include "Array.hpp"    // Array クラスが定義されている
+
+namespace Mikami
+{
+    class IirCascade
+    {
+    public:
+        // コンストラクタ
+        IirCascade(int order = 0, const Biquad hk[] = NULL, float g0 = 1)
+            : order_(order), hn_((order+1)/2, hk), g0_(g0) {}
+
+        // フィルタ処理を実行する
+        float Execute(float xn)
+        {
+            float yn = g0_*xn;
+            for (int k=0; k<(order_+1)/2; k++) yn = hn_[k].Execute(yn);
+            return yn;
+        }
+
+        // 係数の設定
+        void SetCoefs(int order, const Biquad::Coefs ck[], float g0)
+        {
+            if (order_ != order)
+            {
+                order_ = order;
+                hn_.SetSize((order+1)/2);
+            }
+            g0_ = g0;
+            for (int k=0; k<(order+1)/2; k++) hn_[k].SetCoefs(ck[k]);
+        }
+
+        // 内部変数(遅延器)のクリア
+        void Clear()
+        {   for (int k=0; k<(order_+1)/2; k++) hn_[k].Clear(); }
+
+    private:
+        int order_;         // 次数
+        Array<Biquad> hn_;  // Biquad クラスのオブジェクトの配列
+        float g0_;          // 利得定数
+
+        // コピー・コンストラクタ,代入演算子禁止禁止のため
+        IirCascade(const IirCascade&);
+        IirCascade& operator=(const IirCascade&);
+    };
+}
+#endif  // IIR_CASCADE_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IirVariable/IirVariable.hpp	Fri Feb 25 02:26:41 2022 +0000
@@ -0,0 +1,63 @@
+//--------------------------------------------------------------
+//  可変 IIR フィルタのクラス
+//
+//  2022/02/21, Copyright (c) 2022 MIKAMI, Naoki
+//--------------------------------------------------------------
+
+#include "IIR_Cascade.hpp"
+
+#ifndef VARIABLE_IIR_FILTER_HPP
+#define VARIABLE_IIR_FILTER_HPP
+
+namespace Mikami
+{
+    class VariableIir
+    {
+    public:
+        // コンストラクタ
+        VariableIir() : fPtr2_(&VariableIir::Off)
+        {   
+            SetOff();   // 最初は出力 Off       
+            Validate(); // フィルタ処理有効
+        }
+
+        // IIR フィルタの実行
+        float Execute(float xn) { return (this->*fPtr_)((this->*fPtr2_)(xn)); }
+
+        // IIR フィルタの係数を設定する
+        void SetCoefficients(int order, const Biquad::Coefs ck[], float g0)
+        {   iirFilter_.SetCoefs(order, ck, g0); }
+
+        // フィルタの遅延器をクリア
+        void Clear() { iirFilter_.Clear(); }
+
+        // IIR フィルタの処理を有効にする
+        void Validate() { fPtr_ = &VariableIir::Filtering; }
+
+        // IIR フィルタの処理を無効にする
+        void Invalidate() { fPtr_ = &VariableIir::Through; }
+
+        // 出力を On にする    
+        void SetOn() { fPtr2_ = &VariableIir::On; }
+
+        // 出力を Off にする
+        void SetOff() { fPtr2_ = &VariableIir::Off; }
+            
+    private:
+        IirCascade iirFilter_;
+
+        float (VariableIir::*fPtr_)(float);     // フィルタ処理タの有無
+        float (VariableIir::*fPtr2_)(float);    // 出力の On/Off
+        
+        float Through(float xn) { return xn; }  // そのまま出力
+        float Filtering(float xn)               // フィルタを実行して出力
+        {   return iirFilter_.Execute(xn); }
+        float On(float xn) { return xn; }       // 出力: On
+        float Off(float xn) { return 0; }       // 出力: Off
+
+        // コピー・コンストラクタ,代入演算子禁止禁止のため
+        VariableIir(const VariableIir&);
+        VariableIir& operator=(const VariableIir&);
+    };
+}
+#endif  // VARIABLE_IIR_FILTER_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SerialTxRxIntr.lib	Fri Feb 25 02:26:41 2022 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/MikamiUitOpen/code/SerialTxRxIntr/#268977533f95
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Fri Feb 25 02:26:41 2022 +0000
@@ -0,0 +1,96 @@
+//------------------------------------------------------------------
+//  遮断周波数可変 IIR フィルタ(LPF, HPF)
+//      DA 出力はアップサンプリング使用
+//
+//  PC 側のプログラム: F446_VariableLHpfB
+//
+//  2022/02/21, Copyright (c) 2022 MIKAMI, Naoki
+//------------------------------------------------------------------
+
+#include "MultirateLiPh.hpp"    // DA でアップサンプリング
+#include "SerialRxTxIntr.hpp"
+#include "IirVariable.hpp"
+#include <cctype>           // isalpha(), isdigit() で使用
+using namespace Mikami;
+
+const float FS_ = 44.1f;    // 入力の標本化周波数: 44.1 kHz
+MultirateLiPh myAdDa_(FS_); // 出力標本化周波数を4倍にするオブジェクト
+
+// 縦続形 IIR フィルタによる可変フィルタのオブジェクト, 次数: 10 次
+VariableIir filter_;
+
+void Select(string str);    // 有効,無効,出力 On/Off に対応する処理の選択
+void NumericCtrl(string str);   // フィルタ係数の更新
+
+// LPF/HPF の信号処理
+void AdcIsr()
+{
+    float xn = myAdDa_.Input();     // 入力
+    float yn = filter_.Execute(xn); // IIR フィルタの実行
+    myAdDa_.Output(yn);             // 出力
+}
+
+int main()
+{   
+    SerialRxTxIntr rx(150); // PC との通信用,バッファサイズ:150,9600 baud
+
+    NVIC_SetPriority(ADC_IRQn, 0);  // AD変換終了割り込みの優先度が最高
+    NVIC_SetPriority(USART2_IRQn, 1);   
+
+    myAdDa_.Start(&AdcIsr);     // 標本化を開始する
+    while (true)
+    {
+        if (rx.IsEol())         // PC からの指令に対応する処理
+        {
+            string str = rx.GetBuffer();
+            if (str == "VrFcB")
+            {
+                rx.TxString("ACK\n");   // "ACK" を送り返す
+                wait_ms(10);
+                rx.Baud(115300);        // 以降は 115,300 baud
+            }
+            else
+            {
+                if (isalpha(str[0])) Select(str);
+                else                 NumericCtrl(str);
+            }
+        }
+    }
+}
+
+// 有効,無効,出力 On/Off に対応する処理の選択
+void Select(string str)
+{
+    if (str == "ACTIVE")  filter_.Validate();   // フィルタ処理有効
+    if (str == "THROUGH") filter_.Invalidate(); // フィルタ処理無効
+    if (str == "ON")      filter_.SetOn();      // 出力を On
+    if (str == "OFF")     filter_.SetOff();     // 出力を Off
+}
+
+// フィルタ係数の設定
+void NumericCtrl(string str)
+{
+    static char typeOld = 'L';  // 最初は LPF
+    char type;                  // LPF/HPF の区別
+    
+    const int N = 5;        // 次数の 1/2
+    const int L0 = 13;      // 一つの係数当たりの文字数
+    float a1, a2;
+    Biquad::Coefs cfs[N];   // 転送された文字列から変換された係数
+
+    float b1 = atof(str.substr(0, 2).c_str());
+    type = (b1 > 0)? 'L' : 'H';
+
+    for (int n=0; n<N; n++)
+    {
+        a1 = atof(str.substr(n*2*L0+2, L0).c_str());
+        a2 = atof(str.substr((n*2+1)*L0+2, L0).c_str());
+        cfs[n] = (Biquad::Coefs){a1, a2, b1, 1};
+    }
+    float g0 = atof(str.substr(N*2*L0+2, L0).c_str());
+    filter_.SetCoefficients(2*N, cfs, g0);  // 係数設定
+
+    // LPF と HPF が切り替わった場合フィルタの遅延器をクリア
+    if (type != typeOld) filter_.Clear();
+    typeOld = type;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Fri Feb 25 02:26:41 2022 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/mbed_official/code/mbed/builds/65be27845400
\ No newline at end of file