Nucleo-F446 による残響生成器 . DA変換器にデータを送る際は 4 倍にアップ・サンプリング.

Dependencies:   mbed SerialTxRxIntr F446_AD_DA_Multirate

Files at this revision

API Documentation at this revision

Comitter:
MikamiUitOpen
Date:
Sun Jan 20 10:46:15 2019 +0000
Child:
1:47d242cf3d19
Commit message:
1

Changed in this revision

F446_AD_DA_Multirate.lib 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
reverb_unit.hpp Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/F446_AD_DA_Multirate.lib	Sun Jan 20 10:46:15 2019 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/MikamiUitOpen/code/F446_AD_DA_Multirate/#9429fb179c38
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SerialTxRxIntr.lib	Sun Jan 20 10:46:15 2019 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/MikamiUitOpen/code/SerialTxRxIntr/#190d94fba10d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun Jan 20 10:46:15 2019 +0000
@@ -0,0 +1,81 @@
+//----------------------------------------------------------------------
+//  残響発生器
+//      残響発生処理の有効/無効の切り替え:PC の "F446_AD_DA_OnOff.exe"
+//
+//  2019/01/20, Copyright (c) 2019 MIKAMI, Naoki
+//----------------------------------------------------------------------
+
+#include "F446_Multirate.hpp"
+#include "reverb_unit.hpp"      // 残響生成ユニット
+#include "SerialRxTxIntr.hpp"
+#pragma diag_suppress 870   // マルチバイト文字使用の警告抑制のため
+
+using namespace Mikami;
+
+int main()
+{
+    printf("\r\n残響生成器を開始します.\r\n");
+
+    SerialRxTxIntr rxTx;    // Serial クラスの受送信割込み用オブジェクト
+    F446_Multirate myAdDa;  // 出力標本化周波数を4倍にするオブジェクト
+    const int FS = 10000;   // 入力の標本化周波数: 10 kHz
+
+    const float G_C = 0.8f;
+    const float G_A = 0.6f;
+    const float G0 = 1.0f - G_C;
+    CombFilter<887>    cm1(G_C);    // 櫛形フィルタによる残響生成ユニット
+    CombFilter<1153>   cm2(G_C);    // 櫛形フィルタによる残響生成ユニット
+    CombFilter<1499>   cm3(G_C);    // 櫛形フィルタによる残響生成ユニット
+    AllpassFilter<97>  ap1(G_A);    // 全域通過フィルタによる残響生成ユニット
+    AllpassFilter<131> ap2(G_A);    // 全域通過フィルタによる残響生成ユニット
+
+    bool sw = true;     // 残響生成有効/無効のスイッチ
+
+    // F446_Multirate::Start() と F446_Multirate::Input() の間に
+    // printf() のように重い処理は実行しないこと.
+    myAdDa.Start(FS);   // 標本化を開始する
+
+    while (true)
+    {
+        //------------------------------------------------------------
+        // ここにディジタルフィルタ等の処理を記述する
+        float xn = myAdDa.Input();      // 入力
+        float xn2 = G0*xn;
+
+        // 櫛形フィルタの並列接続部
+        float yn = cm1.Execute(xn2) + cm2.Execute(xn2)
+                 + cm3.Execute(xn2);
+
+        // 全域通過フィルタの縦続接続部
+        yn = ap2.Execute(ap1.Execute(yn));
+
+        // 入力信号(遅延なし)を加算
+        yn = yn + xn2;
+
+        if (sw) myAdDa.Output(yn);      // 出力:残響付き
+        else    myAdDa.Output(xn);      // 出力:入力そのまま
+        //------------------------------------------------------------
+
+        //------------------------------------------------------------
+        // PC からの指令に対応する処理
+        if (rxTx.IsEol())           // 受信バッファのデータが有効になった場合の処理
+        {
+            string str = rxTx.GetBuffer();
+            if (str == "ENQ")
+                rxTx.Tx("ACK\n");   // PC からの "ENQ" に対して "ACK" を送信する
+            else    // "ENQ" 以外の処理
+            {
+                if (str == "ST")    // PC から sw の状態の問い合わせ
+                {
+                    if (sw) rxTx.Tx("EN");     // 残響発生器が有効であることを返信
+                    else    rxTx.Tx("DS");     // 残響発生器が無効であることを返信
+                }
+                if (str == "ON")  sw = true;
+                if (str == "OFF") sw = false;  
+            }
+        }
+        // PC からの指令に対応する処理はここまで
+        //------------------------------------------------------------
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Sun Jan 20 10:46:15 2019 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/mbed_official/code/mbed/builds/3a7713b1edbc
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/reverb_unit.hpp	Sun Jan 20 10:46:15 2019 +0000
@@ -0,0 +1,74 @@
+//--------------------------------------------------------------
+// 残響生成器で使うフィルタ
+//
+// 2018/07/11, Copyright (c) 2018 MIKAMI, Naoki
+//--------------------------------------------------------------
+
+#ifndef REVERB_UNIT_HPP
+#define REVERB_UNIT_HPP
+
+#include "mbed.h"
+
+// 残響生成ユニットのための基底クラス
+template<int delay> class Reverb
+{
+private:
+    int ptr_;
+    float un_[delay];    // for delay
+protected:
+    float Get() { return un_[ptr_]; }
+    void Set(float x)
+    {
+        un_[ptr_] = x;   
+        if (++ptr_ >=  delay) ptr_ = 0;
+    }
+public:
+    // コンストラクタ
+    Reverb() : ptr_(0) { Clear(); }
+
+    // 残響生成フィルタの実行(純粋仮想関数)
+    virtual float Execute(float x) = 0;
+
+    // 内部遅延器のクリア
+    void Clear()
+    { for (int n=0; n<delay; n++) un_[n] = 0; }
+};    
+   
+// 櫛形フィルタによる残響生成ユニット
+template<int delay> class CombFilter : public Reverb<delay>
+{
+private:
+    const float GC_;
+public:
+    // コンストラクタ
+    CombFilter(float g) : GC_(g) {}
+
+    // 櫛形フィルタの実行
+    virtual float Execute(float x)
+    {
+        float yn = Reverb<delay>::Get();
+        Reverb<delay>::Set(x + GC_*yn);
+        return yn;
+     }
+};
+
+// 全域通過フィルタによる残響生成ユニット
+template<int delay> class AllpassFilter : public Reverb<delay>
+{
+private:
+    const float G0_;
+public:
+    // コンストラクタ
+    AllpassFilter(float g) : G0_(g) {}
+
+    // 全域通過フィルタの実行
+    virtual float Execute(float x)
+    {
+        float un = x + G0_*Reverb<delay>::Get();
+        float yn = -G0_*un + Reverb<delay>::Get();
+        Reverb<delay>::Set(un);
+        return yn;
+     }
+};
+
+#endif  // REVERB_UNIT_HPP