Audio singal input and output example for DISCO-F746. Input: MEMS mic, Output: CN10 OUT, Acoustic effect: echo and frequency shift. DISCO-F746 によるオーディオ信号入出力.入力:MEMS マイク,出力:CN10 OUT,音響効果:エコー,周波数変換.

Dependencies:   F746_GUI F746_SAI_IO

Revision:
10:56f2f01df983
Parent:
9:1221ba81a1bb
--- a/main.cpp	Fri Mar 17 01:26:25 2017 +0000
+++ b/main.cpp	Mon Apr 10 13:44:13 2017 +0000
@@ -1,104 +1,89 @@
 //--------------------------------------------------------------
 //  MEMS マイクの入力に対して音響効果を与える
-//      音響効果:エコー生成,周波数シフト
+//      音響効果:残響生成,周波数シフト
 //
-//  2017/03/17, Copyright (c) 2017 MIKAMI, Naoki
+//  2017/04/10, Copyright (c) 2017 MIKAMI, Naoki
 //--------------------------------------------------------------
 
-#include "EffectorInitializeGUI.hpp"
+#include "InitializeGUI.hpp"
 #include "SAI_InOut.hpp"
-#include "Echo.hpp"
+#include "Reverberator.hpp"
 #include "WeaverModulator.hpp"
-#include "Array.hpp"
-
+#include "GuiChanger.hpp"
 using namespace Mikami;
 
 int main()
 {
-    const int FS = AUDIO_FREQUENCY_16K; // 標本化周波数: 16 kHz
-    SaiIO mySai(SaiIO::BOTH, 256, FS, INPUT_DEVICE_DIGITAL_MICROPHONE_2);
+    const int FS = AUDIO_FREQUENCY_16K;    // 標本化周波数: 16 kHz
+    // 入出力の準備
+    SaiIO mySai(SaiIO::BOTH, 256, FS,
+                INPUT_DEVICE_DIGITAL_MICROPHONE_2);
 
-    ButtonGroup *onOff;     // "ON", "OFF"
-    ButtonGroup *menu;      // "THROUGH", "ECHO", "F_SHIFTER"
-    SeekBar *barEcho, *barFqCh;
+    ButtonGroup *onOff; // "ON", "OFF"
+    ButtonGroup *menu;  // "THROUGH", "REVERB", "F_SHIFTER"
+    SeekBar *barReverb, *barFqCh;
     NumericLabel<int> *frqLabel;
     WaveformDisplay *displayIn, *displayOut;
-
-    EffectorInitializeGUI(onOff, menu, barEcho, barFqCh,
-                          frqLabel, displayIn, displayOut);
-
-    ProcessingBase through; // 0: 信号処理なしで出力
-    EchoSystem echo;        // 1: エコー生成
-    FrqShifter shifter(FS); // 2: 周波数シフト
-    ProcessingBase *func[3] = { &through, &echo, &shifter };
-    shifter.SetFrequensy(100);  // 周波数シフタの初期値:100 Hz
+    // GUI 部品の初期化
+    InitializeGUI(onOff, menu, barReverb, barFqCh,
+                  frqLabel, displayIn, displayOut);
+    // 処理に応じて GUI 部品の状態を変更する関数の割り当て
+    void (*fPtr[])(SeekBar*, SeekBar*, NumericLabel<int>*)
+        = { SetThrough, SetReverb, SetFrqShifter };
 
-    int runStop = 1;
-    int menuNum = 0;
+    ProcessingBase through;     // 0: 信号処理なしで出力
+    Reverberator reverb;        // 1: 残響生成
+    WeaverMod shifter(FS, 100); // 2: 周波数シフト(シフトの初期値:100 Hz)
+    ProcessingBase *func[3] = { &through,
+                                &reverb,
+                                &shifter };
 
-    // 入出力の波形表示で使用
-    Array<int16_t> snIn(mySai.GetLength());
-    Array<int16_t> snOut(mySai.GetLength());
+    Array<int16_t> snIn(mySai.GetLength());     // 入力波形表示で使用
+    Array<int16_t> snOut(mySai.GetLength());    // 出力波形表示で使用
 
-    mySai.RecordIn();
-    mySai.PlayOut();
-    mySai.PauseOut();
+    mySai.RecordIn();   // 入力開始
+    mySai.PlayOut();    // 出力開始
+    mySai.PauseOut();   // 出力一時停止
 
+    int menuNum = 0;
     while (true)
     {
         // On/OFF の設定
         int num;
-
-        if ( (onOff->GetTouchedNumber(num)) && (runStop != num) )
+        if (onOff->GetTouchedNumber(num))
         {
-            if (num == 0) mySai.ResumeOut();
+            if (num == 0) mySai.ResumeOut();    // 出力再開
             else          mySai.PauseOut();
-            runStop = num;
         }
 
-        // エコーの長さを設定
-        if ( (menuNum == 1) && (barEcho->Slide()) )
-            echo.SetDelay(6000 - barEcho->GetIntValue());
+        // 信号処理の種類の切り替えに対応する GUI 部品の状態の設定
+        if (menu->GetTouchedNumber(menuNum))
+            fPtr[menuNum](barReverb, barFqCh, frqLabel);
+
+        // 残響の長さを設定
+        if ( (menuNum == 1) && (barReverb->Slide()) )
+            reverb.SetDelay(barReverb->GetIntValue());
 
         // 周波数シフトの値の設定
         if ( (menuNum == 2) && (barFqCh->Slide()) )
         {
             frqLabel->Draw(barFqCh->GetIntValue());
-            shifter.SetFrequensy(barFqCh->GetIntValue());
+            shifter.SetFrequency(barFqCh->GetIntValue());
         }
 
-        // 信号処理の種類の切り替え
-        if (menu->GetTouchedNumber(menuNum))
-            switch (menuNum)
-            {
-                case 0: barEcho->Inactivate();  // Through
-                        barFqCh->Inactivate();
-                        frqLabel->Redraw(GuiBase::ENUM_INACTIVE_TEXT);
-                        break;
-                case 1: barEcho->Activate();    // Echo
-                        barFqCh->Inactivate();
-                        frqLabel->Redraw(GuiBase::ENUM_INACTIVE_TEXT);
-                        break;
-                case 2: barEcho->Inactivate();  // Frequency shifter
-                        barFqCh->Activate();
-                        frqLabel->Redraw(GuiBase::ENUM_TEXT);
-                        break;
-            }
-
         //---------------------------------------------
         // 1フレーム分の信号処理を行い,その結果を出力する
-        if ( mySai.IsCompleted())
+        if (mySai.IsCompleted())
         {
             for (int n=0; n<mySai.GetLength(); n++)
             {
                 int16_t xL, xR;
                 mySai.Input(xL, xR);
                 int16_t xn = xL + xR;
-                snIn[n] = xn;   // 表示用      
+                snIn[n] = xn;   // 表示用
 
                 //-------------------------------------------------------
-                // 信号処理実行
-                int16_t yn = (int16_t)func[menuNum]->Execute((float)xn);
+                int16_t yn = func[menuNum]->Execute(xn);    // 信号処理実行
                 //-------------------------------------------------------
 
                 mySai.Output(yn, yn);   // 左右チャンネルに同じ信号を出力