Chapter003_TRobot
Dependencies: F746_GUI Array_Matrix TS_DISCO_F746NG mbed LCD_DISCO_F746NG BSP_DISCO_F746NG SDFileSystem_Warning_Fixed FrequencyResponseDrawer F746_SAI_IO
Diff: main.cpp
- Revision:
- 0:04b43b777fae
- Child:
- 1:cc2669b9d1e2
diff -r 000000000000 -r 04b43b777fae main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Apr 19 09:46:11 2016 +0000 @@ -0,0 +1,166 @@ +//-------------------------------------------------------------- +// フィルタ処理付き SD オーディオプレーヤー +// SD のファイル: *.wav +// PCM,16 ビットステレオ,標本化周波数 44.1 kHz +// IIR フィルタ ---- 低域通過および高域通過フィルタ +// +// 2016/04/19, 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 = AUDIO_FREQUENCY_44K; // 標本化周波数: 44.1 kHz + SaiIO_O mySai(2048, FS); + + SD_WavReader sdReader(mySai.GetLength()); // SD カード読み込み用オブジェクト + const int MAX_FILES = 7; + FileSelector selector(4, 28, MAX_FILES, 34, 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( + 45, // グラフの左端の位置 + 230, // グラフの下端の位置 + 30, // 10 dB 当たりのピクセル数 + FS, // 標本化周波数 + ORDER, // フィルタの次数 + 400, // 最初に与える遮断周波数 + 200, // 遮断周波数の最小値 + 10000, // 遮断周波数の最大値 + 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 のファイルのクローズ + } +}