Output the audio signal (*.bin) with filtering by IIR filter in the SD card using onboard CODEC. For *.wav file, F746_SD_WavPlayer and F746_SD_GraphicEqualiser are published on mbed. SD カードのオーディオ信号 (*.bin) を遮断周波数可変の IIR フィルタを通して,ボードに搭載されているCODEC で出力する.*.wav 形式のファイル用には,F746_SD_WavPlayer と F746_SD_GraphicEqualiser を mbed で公開している.

Dependencies:   BSP_DISCO_F746NG_patch_fixed F746_GUI LCD_DISCO_F746NG SDFileSystem_Warning_Fixed TS_DISCO_F746NG mbed

Revision:
0:6748e3332e85
Child:
1:e891c9b4f980
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Fri Apr 08 13:11:53 2016 +0000
@@ -0,0 +1,169 @@
+//--------------------------------------------------------------
+//  フィルタ処理付き SD オーディオプレーヤー
+//      SD のファイル
+//          先頭から 4 バイト:  データ数に対応する (int32_t 型)
+//          それ以降 2 バイトごと: int16_t のモノラルデータが続く
+//          データ: 標本化周波数 16 kHz のもの
+//          拡張子: "*.bin", "*.BIN"
+//      IIR フィルタ ---- 低域通過および高域通過フィルタ
+//
+//  2016/04/08, Copyright (c) 2016 MIKAMI, Naoki
+//--------------------------------------------------------------
+
+#include "MyFunctions.hpp"
+#include "BlinkLabel.hpp"
+
+using namespace Mikami;
+
+int main()
+{
+    Label myLabel(80, 4, "SD Card Audio Player", Label::LEFT, Font16);
+
+    const int FS = I2S_AUDIOFREQ_16K;   // 標本化周波数: 16 kHz
+    SaiIO_O mySai(1024, FS);
+
+    SD_BinaryReader sdReader;   // SD カード読み込み用オブジェクト
+    const int MAX_FILES = 7;
+    FileSelector selector(4, 28, MAX_FILES, 32, sdReader);
+    if (!selector.CreateTable())
+        BlinkLabel errLabel(240, 100, "SD CARD ERROR", Label::CENTER);
+
+    // ボタン用の定数
+    const uint16_t BG_LEFT = 390;
+    const uint16_t BG_WIDTH = 80;
+    const uint16_t BG_HEIGHT = 36;
+
+    // ButtonGroup: "OPEN", "PLAY", "PAUSE", "RESUME", "STOP"
+    const string MENU[5] = {"OPEN", "PLAY", "PAUSE", "RESUME", "STOP"};
+    ButtonGroup menu(BG_LEFT, 2, BG_WIDTH, BG_HEIGHT,
+                     5, MENU, 0, 2, 1);
+    // OPEN のみアクティブ
+    menu.Activate(0);
+    for (int n=1; n<5; n++) menu.Inactivate(n);
+
+    // ButtonGroup: "LPF", "HPF"
+    const string LP_HP[2] = {"LPF", "HPF"};
+    ButtonGroup lpHp(BG_LEFT, 197, BG_WIDTH/2, BG_HEIGHT,
+                     2, LP_HP, 0, 0, 2, 0);
+
+    // ButtonGroup: "ON", "OFF"
+    const string ON_OFF[2] = {"ON", "OFF"};
+    ButtonGroup onOff(BG_LEFT, 235, BG_WIDTH/2, BG_HEIGHT,
+                      2, ON_OFF, 0, 0, 2, 1);
+
+    // フィルタの設計と周波数特性描画用
+    const int ORDER = 6;        // フィルタの次数
+    DesignerDrawer drawerObj(
+                     60,        // グラフの左端の位置
+                     230,       // グラフの下端の位置
+                     30,        // 10 dB 当たりのピクセル数
+                     FS,        // 標本化周波数
+                     ORDER,     // フィルタの次数
+                     400,       // 最初に与える遮断周波数
+                     200,       // 遮断周波数の最小値
+                     5000,      // 遮断周波数の最大値
+                     BilinearDesign::LPF);  // 低域通過フィルタ
+
+    // フィルタの準備
+    Biquad::Coefs ck[ORDER/2];
+    float g0;
+    drawerObj.GetCoefficients(ck, g0);
+    Biquad hn[ORDER/2];
+    for (int k=0; k<ORDER/2; k++) hn[k] = Biquad(ck[k]);
+
+    int32_t frameSize = mySai.GetLength();
+    int16_t *sn = new int16_t[frameSize+1]; // フレームバッファ
+    bool playOk = false;
+    bool filterOn = false;
+    bool whileFirst = true;
+    string fileName;
+    int32_t loopCount;
+
+    while (true)
+    {
+        if (!playOk)
+        {
+            if (whileFirst)
+            {
+                whileFirst = false;
+                while (!menu.Touched(0))    // OPEN がタッチされるまで待つ
+                    ModifyFilter(drawerObj, lpHp, onOff,
+                                 hn, ck, g0, filterOn);
+                SelectFile(menu, selector, myLabel, fileName);
+            }
+            else
+            {
+                menu.Activate(1);       // PLAY 有効
+                int touch10;
+                while (!menu.GetTouchedNumber(touch10))
+                    ModifyFilter(drawerObj, lpHp, onOff,
+                                 hn, ck, g0, filterOn);
+                if (touch10 == 0)
+                    SelectFile(menu, selector, myLabel, fileName);
+            }
+
+            loopCount = SD_Open(sdReader, fileName, frameSize);
+            while (!menu.Touched(1))    // PLAY がタッチされるまで待つ
+                ModifyFilter(drawerObj, lpHp, onOff,
+                             hn, ck, g0, filterOn);
+        }
+        else
+            loopCount = SD_Open(sdReader, fileName, frameSize);
+
+        selector.Erase(BG_LEFT-4, 244);
+        myLabel.Draw("IIR Butterworth filter");
+        drawerObj.DrawResponse();
+        menu.Inactivate(0); // OPEN 無効
+        menu.Activate(2);   // PAUSE 有効
+        menu.Activate(4);   // STOP 有効
+
+        playOk = false;
+        bool stopOk = false;
+        mySai.InitCodecOut();   // SAI の初期化
+
+        // IIR フィルタの内部の遅延器のクリア
+        for (int k=0; k<ORDER/2; k++) hn[k].Clear();
+
+        for (int k=0; k<loopCount; k++)
+        {
+            int touch42 = -1;
+            menu.GetTouchedNumber(touch42);
+            if (touch42 == 4) break;    // STOP
+            if (touch42 == 2)           // PAUSE
+            {
+                menu.Inactivate(2); // PAUSE 無効
+                menu.Activate(3);   // RESUME 有効
+                mySai.Pause();
+
+                // PLAY か RESUME か STOP がタッチされるまで待つ
+                int touch134 = -1;
+                while (!menu.GetTouchedNumber(touch134))
+                    ModifyFilter(drawerObj, lpHp, onOff,
+                                 hn, ck, g0, filterOn);
+                switch (touch134)
+                {
+                    case 1: playOk = true;  // 最初から PLAY
+                            break;
+                    case 3: mySai.Resume(); // PAUSE したところから PLAY 再開
+                            menu.Activate(2);
+                            menu.Inactivate(3);
+                            menu.TouchedColor(1);
+                            break;
+                    case 4: stopOk = true;  // STOP
+                            break;
+                }
+            }
+            if (playOk || stopOk) break;
+
+            ModifyFilter(drawerObj, lpHp, onOff, hn, ck, g0, filterOn);
+            // 1フレーム分の信号処理 (IIR フィルタ) の実行
+            ProcessSignal(sdReader, mySai, sn, g0, hn, ORDER, filterOn);
+        }
+        mySai.Stop();
+        menu.Activate(0);               // OPEN 有効
+        if (!playOk) menu.Activate(1);  // PLAY 有効
+        for (int n=2; n<5; n++)         // その他は無効
+            menu.Inactivate(n);
+        sdReader.Close();   // SD のファイルのクローズ
+    }
+}