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
main.cpp
- Committer:
- MikamiUitOpen
- Date:
- 2016-04-16
- Revision:
- 2:f963cb0d323f
- Parent:
- 1:e891c9b4f980
- Child:
- 5:4a99dabc9180
File content as of revision 2:f963cb0d323f:
//-------------------------------------------------------------- // フィルタ処理付き SD オーディオプレーヤー // SD のファイル // 先頭から 4 バイト: データ数に対応する (int32_t 型) // それ以降 2 バイトごと: int16_t のモノラルデータが続く // データ: 標本化周波数 16 kHz のもの // 拡張子: "*.bin", "*.BIN" // IIR フィルタ ---- 低域通過および高域通過フィルタ // // 2016/04/16, 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 のファイルのクローズ } }