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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 //--------------------------------------------------------------
00002 //  フィルタ処理付き SD オーディオプレーヤー
00003 //      SD のファイル
00004 //          先頭から 4 バイト:  データ数に対応する (int32_t 型)
00005 //          それ以降 2 バイトごと: int16_t のモノラルデータが続く
00006 //          データ: 標本化周波数 16 kHz のもの
00007 //          拡張子: "*.bin", "*.BIN"
00008 //      IIR フィルタ ---- 低域通過および高域通過フィルタ
00009 //
00010 //  2016/04/17, Copyright (c) 2016 MIKAMI, Naoki
00011 //--------------------------------------------------------------
00012 
00013 #include "MyFunctions.hpp"
00014 #include "BlinkLabel.hpp"
00015 
00016 using namespace Mikami;
00017 
00018 int main()
00019 {
00020     Label myLabel(80, 4, "SD Card Audio Player", Label::LEFT, Font16);
00021 
00022     const int FS = I2S_AUDIOFREQ_16K;   // 標本化周波数: 16 kHz
00023     SaiIO_O mySai(1024, FS);
00024 
00025     SD_BinaryReader sdReader;   // SD カード読み込み用オブジェクト
00026     const int MAX_FILES = 7;
00027     FileSelector selector(4, 28, MAX_FILES, 32, sdReader);
00028     if (!selector.CreateTable())
00029         BlinkLabel errLabel(240, 100, "SD CARD ERROR", Label::CENTER);
00030 
00031     // ボタン用の定数
00032     const uint16_t BG_LEFT = 390;
00033     const uint16_t BG_WIDTH = 80;
00034     const uint16_t BG_HEIGHT = 36;
00035 
00036     // ButtonGroup: "OPEN", "PLAY", "PAUSE", "RESUME", "STOP"
00037     const string MENU[5] = {"OPEN", "PLAY", "PAUSE", "RESUME", "STOP"};
00038     ButtonGroup menu(BG_LEFT, 2, BG_WIDTH, BG_HEIGHT,
00039                      5, MENU, 0, 2, 1);
00040     // OPEN のみアクティブ
00041     menu.Activate(0);
00042     for (int n=1; n<5; n++) menu.Inactivate(n);
00043 
00044     // ButtonGroup: "LPF", "HPF"
00045     const string LP_HP[2] = {"LPF", "HPF"};
00046     ButtonGroup lpHp(BG_LEFT, 197, BG_WIDTH/2, BG_HEIGHT,
00047                      2, LP_HP, 0, 0, 2, 0);
00048 
00049     // ButtonGroup: "ON", "OFF"
00050     const string ON_OFF[2] = {"ON", "OFF"};
00051     ButtonGroup onOff(BG_LEFT, 235, BG_WIDTH/2, BG_HEIGHT,
00052                       2, ON_OFF, 0, 0, 2, 1);
00053 
00054     // フィルタの設計と周波数特性描画用
00055     const int ORDER = 6;        // フィルタの次数
00056     DesignerDrawer drawerObj(
00057                      60,        // グラフの左端の位置
00058                      230,       // グラフの下端の位置
00059                      30,        // 10 dB 当たりのピクセル数
00060                      FS,        // 標本化周波数
00061                      ORDER,     // フィルタの次数
00062                      400,       // 最初に与える遮断周波数
00063                      200,       // 遮断周波数の最小値
00064                      5000,      // 遮断周波数の最大値
00065                      BilinearDesign::LPF);  // 低域通過フィルタ
00066 
00067     // フィルタの準備
00068     Biquad::Coefs ck[ORDER/2];
00069     float g0;
00070     drawerObj.GetCoefficients(ck, g0);
00071     Biquad hn[ORDER/2];
00072     for (int k=0; k<ORDER/2; k++) hn[k] = Biquad(ck[k]);
00073 
00074     int32_t frameSize = mySai.GetLength();
00075     int16_t *sn = new int16_t[frameSize+1]; // フレームバッファ
00076     bool playOk = false;
00077     bool filterOn = false;
00078     bool whileFirst = true;
00079     string fileName;
00080     int32_t loopCount;
00081 
00082     while (true)
00083     {
00084         if (!playOk)
00085         {
00086             if (whileFirst)
00087             {
00088                 whileFirst = false;
00089                 while (!menu.Touched(0))    // OPEN がタッチされるまで待つ
00090                     ModifyFilter(drawerObj, lpHp, onOff,
00091                                  hn, ck, g0, filterOn);
00092                 SelectFile(menu, selector, myLabel, fileName);
00093             }
00094             else
00095             {
00096                 menu.Activate(1);       // PLAY 有効
00097                 int touch10;
00098                 while (!menu.GetTouchedNumber(touch10))
00099                     ModifyFilter(drawerObj, lpHp, onOff,
00100                                  hn, ck, g0, filterOn);
00101                 if (touch10 == 0)
00102                     SelectFile(menu, selector, myLabel, fileName);
00103             }
00104 
00105             loopCount = SD_Open(sdReader, fileName, frameSize);
00106             while (!menu.Touched(1))    // PLAY がタッチされるまで待つ
00107                 ModifyFilter(drawerObj, lpHp, onOff,
00108                              hn, ck, g0, filterOn);
00109         }
00110         else
00111             loopCount = SD_Open(sdReader, fileName, frameSize);
00112 
00113         selector.Erase(BG_LEFT-4, 244);
00114         myLabel.Draw("IIR Butterworth filter");
00115         drawerObj.DrawResponse();
00116         menu.Inactivate(0); // OPEN 無効
00117         menu.Activate(2);   // PAUSE 有効
00118         menu.Activate(4);   // STOP 有効
00119 
00120         playOk = false;
00121         bool stopOk = false;
00122         mySai.InitCodecOut();   // SAI の初期化
00123 
00124         // IIR フィルタの内部の遅延器のクリア
00125         for (int k=0; k<ORDER/2; k++) hn[k].Clear();
00126 
00127         for (int k=0; k<loopCount; k++)
00128         {
00129             int touch42 = -1;
00130             menu.GetTouchedNumber(touch42);
00131             if (touch42 == 4) break;    // STOP
00132             if (touch42 == 2)           // PAUSE
00133             {
00134                 menu.Inactivate(2); // PAUSE 無効
00135                 menu.Activate(3);   // RESUME 有効
00136                 mySai.Pause();
00137 
00138                 // PLAY か RESUME か STOP がタッチされるまで待つ
00139                 int touch134 = -1;
00140                 while (!menu.GetTouchedNumber(touch134))
00141                     ModifyFilter(drawerObj, lpHp, onOff,
00142                                  hn, ck, g0, filterOn);
00143                 switch (touch134)
00144                 {
00145                     case 1: playOk = true;  // 最初から PLAY
00146                             break;
00147                     case 3: mySai.Resume(); // PAUSE したところから PLAY 再開
00148                             menu.Activate(2);
00149                             menu.Inactivate(3);
00150                             menu.TouchedColor(1);
00151                             break;
00152                     case 4: stopOk = true;  // STOP
00153                             break;
00154                 }
00155             }
00156             if (playOk || stopOk) break;
00157 
00158             ModifyFilter(drawerObj, lpHp, onOff, hn, ck, g0, filterOn);
00159             // 1フレーム分の信号処理 (IIR フィルタ) の実行
00160             ProcessSignal(sdReader, mySai, sn, g0, hn, ORDER, filterOn);
00161         }
00162         mySai.Stop();
00163         menu.Activate(0);               // OPEN 有効
00164         if (!playOk) menu.Activate(1);  // PLAY 有効
00165         for (int n=2; n<5; n++)         // その他は無効
00166             menu.Inactivate(n);
00167         sdReader.Close();   // SD のファイルのクローズ
00168     }
00169 }
00170