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
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
Generated on Wed Jul 13 2022 03:37:09 by 1.7.2