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

Committer:
MikamiUitOpen
Date:
Fri Apr 08 13:11:53 2016 +0000
Revision:
0:6748e3332e85
Child:
1:e891c9b4f980
1

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MikamiUitOpen 0:6748e3332e85 1 //--------------------------------------------------------------
MikamiUitOpen 0:6748e3332e85 2 // フィルタ処理付き SD オーディオプレーヤー
MikamiUitOpen 0:6748e3332e85 3 // SD のファイル
MikamiUitOpen 0:6748e3332e85 4 // 先頭から 4 バイト: データ数に対応する (int32_t 型)
MikamiUitOpen 0:6748e3332e85 5 // それ以降 2 バイトごと: int16_t のモノラルデータが続く
MikamiUitOpen 0:6748e3332e85 6 // データ: 標本化周波数 16 kHz のもの
MikamiUitOpen 0:6748e3332e85 7 // 拡張子: "*.bin", "*.BIN"
MikamiUitOpen 0:6748e3332e85 8 // IIR フィルタ ---- 低域通過および高域通過フィルタ
MikamiUitOpen 0:6748e3332e85 9 //
MikamiUitOpen 0:6748e3332e85 10 // 2016/04/08, Copyright (c) 2016 MIKAMI, Naoki
MikamiUitOpen 0:6748e3332e85 11 //--------------------------------------------------------------
MikamiUitOpen 0:6748e3332e85 12
MikamiUitOpen 0:6748e3332e85 13 #include "MyFunctions.hpp"
MikamiUitOpen 0:6748e3332e85 14 #include "BlinkLabel.hpp"
MikamiUitOpen 0:6748e3332e85 15
MikamiUitOpen 0:6748e3332e85 16 using namespace Mikami;
MikamiUitOpen 0:6748e3332e85 17
MikamiUitOpen 0:6748e3332e85 18 int main()
MikamiUitOpen 0:6748e3332e85 19 {
MikamiUitOpen 0:6748e3332e85 20 Label myLabel(80, 4, "SD Card Audio Player", Label::LEFT, Font16);
MikamiUitOpen 0:6748e3332e85 21
MikamiUitOpen 0:6748e3332e85 22 const int FS = I2S_AUDIOFREQ_16K; // 標本化周波数: 16 kHz
MikamiUitOpen 0:6748e3332e85 23 SaiIO_O mySai(1024, FS);
MikamiUitOpen 0:6748e3332e85 24
MikamiUitOpen 0:6748e3332e85 25 SD_BinaryReader sdReader; // SD カード読み込み用オブジェクト
MikamiUitOpen 0:6748e3332e85 26 const int MAX_FILES = 7;
MikamiUitOpen 0:6748e3332e85 27 FileSelector selector(4, 28, MAX_FILES, 32, sdReader);
MikamiUitOpen 0:6748e3332e85 28 if (!selector.CreateTable())
MikamiUitOpen 0:6748e3332e85 29 BlinkLabel errLabel(240, 100, "SD CARD ERROR", Label::CENTER);
MikamiUitOpen 0:6748e3332e85 30
MikamiUitOpen 0:6748e3332e85 31 // ボタン用の定数
MikamiUitOpen 0:6748e3332e85 32 const uint16_t BG_LEFT = 390;
MikamiUitOpen 0:6748e3332e85 33 const uint16_t BG_WIDTH = 80;
MikamiUitOpen 0:6748e3332e85 34 const uint16_t BG_HEIGHT = 36;
MikamiUitOpen 0:6748e3332e85 35
MikamiUitOpen 0:6748e3332e85 36 // ButtonGroup: "OPEN", "PLAY", "PAUSE", "RESUME", "STOP"
MikamiUitOpen 0:6748e3332e85 37 const string MENU[5] = {"OPEN", "PLAY", "PAUSE", "RESUME", "STOP"};
MikamiUitOpen 0:6748e3332e85 38 ButtonGroup menu(BG_LEFT, 2, BG_WIDTH, BG_HEIGHT,
MikamiUitOpen 0:6748e3332e85 39 5, MENU, 0, 2, 1);
MikamiUitOpen 0:6748e3332e85 40 // OPEN のみアクティブ
MikamiUitOpen 0:6748e3332e85 41 menu.Activate(0);
MikamiUitOpen 0:6748e3332e85 42 for (int n=1; n<5; n++) menu.Inactivate(n);
MikamiUitOpen 0:6748e3332e85 43
MikamiUitOpen 0:6748e3332e85 44 // ButtonGroup: "LPF", "HPF"
MikamiUitOpen 0:6748e3332e85 45 const string LP_HP[2] = {"LPF", "HPF"};
MikamiUitOpen 0:6748e3332e85 46 ButtonGroup lpHp(BG_LEFT, 197, BG_WIDTH/2, BG_HEIGHT,
MikamiUitOpen 0:6748e3332e85 47 2, LP_HP, 0, 0, 2, 0);
MikamiUitOpen 0:6748e3332e85 48
MikamiUitOpen 0:6748e3332e85 49 // ButtonGroup: "ON", "OFF"
MikamiUitOpen 0:6748e3332e85 50 const string ON_OFF[2] = {"ON", "OFF"};
MikamiUitOpen 0:6748e3332e85 51 ButtonGroup onOff(BG_LEFT, 235, BG_WIDTH/2, BG_HEIGHT,
MikamiUitOpen 0:6748e3332e85 52 2, ON_OFF, 0, 0, 2, 1);
MikamiUitOpen 0:6748e3332e85 53
MikamiUitOpen 0:6748e3332e85 54 // フィルタの設計と周波数特性描画用
MikamiUitOpen 0:6748e3332e85 55 const int ORDER = 6; // フィルタの次数
MikamiUitOpen 0:6748e3332e85 56 DesignerDrawer drawerObj(
MikamiUitOpen 0:6748e3332e85 57 60, // グラフの左端の位置
MikamiUitOpen 0:6748e3332e85 58 230, // グラフの下端の位置
MikamiUitOpen 0:6748e3332e85 59 30, // 10 dB 当たりのピクセル数
MikamiUitOpen 0:6748e3332e85 60 FS, // 標本化周波数
MikamiUitOpen 0:6748e3332e85 61 ORDER, // フィルタの次数
MikamiUitOpen 0:6748e3332e85 62 400, // 最初に与える遮断周波数
MikamiUitOpen 0:6748e3332e85 63 200, // 遮断周波数の最小値
MikamiUitOpen 0:6748e3332e85 64 5000, // 遮断周波数の最大値
MikamiUitOpen 0:6748e3332e85 65 BilinearDesign::LPF); // 低域通過フィルタ
MikamiUitOpen 0:6748e3332e85 66
MikamiUitOpen 0:6748e3332e85 67 // フィルタの準備
MikamiUitOpen 0:6748e3332e85 68 Biquad::Coefs ck[ORDER/2];
MikamiUitOpen 0:6748e3332e85 69 float g0;
MikamiUitOpen 0:6748e3332e85 70 drawerObj.GetCoefficients(ck, g0);
MikamiUitOpen 0:6748e3332e85 71 Biquad hn[ORDER/2];
MikamiUitOpen 0:6748e3332e85 72 for (int k=0; k<ORDER/2; k++) hn[k] = Biquad(ck[k]);
MikamiUitOpen 0:6748e3332e85 73
MikamiUitOpen 0:6748e3332e85 74 int32_t frameSize = mySai.GetLength();
MikamiUitOpen 0:6748e3332e85 75 int16_t *sn = new int16_t[frameSize+1]; // フレームバッファ
MikamiUitOpen 0:6748e3332e85 76 bool playOk = false;
MikamiUitOpen 0:6748e3332e85 77 bool filterOn = false;
MikamiUitOpen 0:6748e3332e85 78 bool whileFirst = true;
MikamiUitOpen 0:6748e3332e85 79 string fileName;
MikamiUitOpen 0:6748e3332e85 80 int32_t loopCount;
MikamiUitOpen 0:6748e3332e85 81
MikamiUitOpen 0:6748e3332e85 82 while (true)
MikamiUitOpen 0:6748e3332e85 83 {
MikamiUitOpen 0:6748e3332e85 84 if (!playOk)
MikamiUitOpen 0:6748e3332e85 85 {
MikamiUitOpen 0:6748e3332e85 86 if (whileFirst)
MikamiUitOpen 0:6748e3332e85 87 {
MikamiUitOpen 0:6748e3332e85 88 whileFirst = false;
MikamiUitOpen 0:6748e3332e85 89 while (!menu.Touched(0)) // OPEN がタッチされるまで待つ
MikamiUitOpen 0:6748e3332e85 90 ModifyFilter(drawerObj, lpHp, onOff,
MikamiUitOpen 0:6748e3332e85 91 hn, ck, g0, filterOn);
MikamiUitOpen 0:6748e3332e85 92 SelectFile(menu, selector, myLabel, fileName);
MikamiUitOpen 0:6748e3332e85 93 }
MikamiUitOpen 0:6748e3332e85 94 else
MikamiUitOpen 0:6748e3332e85 95 {
MikamiUitOpen 0:6748e3332e85 96 menu.Activate(1); // PLAY 有効
MikamiUitOpen 0:6748e3332e85 97 int touch10;
MikamiUitOpen 0:6748e3332e85 98 while (!menu.GetTouchedNumber(touch10))
MikamiUitOpen 0:6748e3332e85 99 ModifyFilter(drawerObj, lpHp, onOff,
MikamiUitOpen 0:6748e3332e85 100 hn, ck, g0, filterOn);
MikamiUitOpen 0:6748e3332e85 101 if (touch10 == 0)
MikamiUitOpen 0:6748e3332e85 102 SelectFile(menu, selector, myLabel, fileName);
MikamiUitOpen 0:6748e3332e85 103 }
MikamiUitOpen 0:6748e3332e85 104
MikamiUitOpen 0:6748e3332e85 105 loopCount = SD_Open(sdReader, fileName, frameSize);
MikamiUitOpen 0:6748e3332e85 106 while (!menu.Touched(1)) // PLAY がタッチされるまで待つ
MikamiUitOpen 0:6748e3332e85 107 ModifyFilter(drawerObj, lpHp, onOff,
MikamiUitOpen 0:6748e3332e85 108 hn, ck, g0, filterOn);
MikamiUitOpen 0:6748e3332e85 109 }
MikamiUitOpen 0:6748e3332e85 110 else
MikamiUitOpen 0:6748e3332e85 111 loopCount = SD_Open(sdReader, fileName, frameSize);
MikamiUitOpen 0:6748e3332e85 112
MikamiUitOpen 0:6748e3332e85 113 selector.Erase(BG_LEFT-4, 244);
MikamiUitOpen 0:6748e3332e85 114 myLabel.Draw("IIR Butterworth filter");
MikamiUitOpen 0:6748e3332e85 115 drawerObj.DrawResponse();
MikamiUitOpen 0:6748e3332e85 116 menu.Inactivate(0); // OPEN 無効
MikamiUitOpen 0:6748e3332e85 117 menu.Activate(2); // PAUSE 有効
MikamiUitOpen 0:6748e3332e85 118 menu.Activate(4); // STOP 有効
MikamiUitOpen 0:6748e3332e85 119
MikamiUitOpen 0:6748e3332e85 120 playOk = false;
MikamiUitOpen 0:6748e3332e85 121 bool stopOk = false;
MikamiUitOpen 0:6748e3332e85 122 mySai.InitCodecOut(); // SAI の初期化
MikamiUitOpen 0:6748e3332e85 123
MikamiUitOpen 0:6748e3332e85 124 // IIR フィルタの内部の遅延器のクリア
MikamiUitOpen 0:6748e3332e85 125 for (int k=0; k<ORDER/2; k++) hn[k].Clear();
MikamiUitOpen 0:6748e3332e85 126
MikamiUitOpen 0:6748e3332e85 127 for (int k=0; k<loopCount; k++)
MikamiUitOpen 0:6748e3332e85 128 {
MikamiUitOpen 0:6748e3332e85 129 int touch42 = -1;
MikamiUitOpen 0:6748e3332e85 130 menu.GetTouchedNumber(touch42);
MikamiUitOpen 0:6748e3332e85 131 if (touch42 == 4) break; // STOP
MikamiUitOpen 0:6748e3332e85 132 if (touch42 == 2) // PAUSE
MikamiUitOpen 0:6748e3332e85 133 {
MikamiUitOpen 0:6748e3332e85 134 menu.Inactivate(2); // PAUSE 無効
MikamiUitOpen 0:6748e3332e85 135 menu.Activate(3); // RESUME 有効
MikamiUitOpen 0:6748e3332e85 136 mySai.Pause();
MikamiUitOpen 0:6748e3332e85 137
MikamiUitOpen 0:6748e3332e85 138 // PLAY か RESUME か STOP がタッチされるまで待つ
MikamiUitOpen 0:6748e3332e85 139 int touch134 = -1;
MikamiUitOpen 0:6748e3332e85 140 while (!menu.GetTouchedNumber(touch134))
MikamiUitOpen 0:6748e3332e85 141 ModifyFilter(drawerObj, lpHp, onOff,
MikamiUitOpen 0:6748e3332e85 142 hn, ck, g0, filterOn);
MikamiUitOpen 0:6748e3332e85 143 switch (touch134)
MikamiUitOpen 0:6748e3332e85 144 {
MikamiUitOpen 0:6748e3332e85 145 case 1: playOk = true; // 最初から PLAY
MikamiUitOpen 0:6748e3332e85 146 break;
MikamiUitOpen 0:6748e3332e85 147 case 3: mySai.Resume(); // PAUSE したところから PLAY 再開
MikamiUitOpen 0:6748e3332e85 148 menu.Activate(2);
MikamiUitOpen 0:6748e3332e85 149 menu.Inactivate(3);
MikamiUitOpen 0:6748e3332e85 150 menu.TouchedColor(1);
MikamiUitOpen 0:6748e3332e85 151 break;
MikamiUitOpen 0:6748e3332e85 152 case 4: stopOk = true; // STOP
MikamiUitOpen 0:6748e3332e85 153 break;
MikamiUitOpen 0:6748e3332e85 154 }
MikamiUitOpen 0:6748e3332e85 155 }
MikamiUitOpen 0:6748e3332e85 156 if (playOk || stopOk) break;
MikamiUitOpen 0:6748e3332e85 157
MikamiUitOpen 0:6748e3332e85 158 ModifyFilter(drawerObj, lpHp, onOff, hn, ck, g0, filterOn);
MikamiUitOpen 0:6748e3332e85 159 // 1フレーム分の信号処理 (IIR フィルタ) の実行
MikamiUitOpen 0:6748e3332e85 160 ProcessSignal(sdReader, mySai, sn, g0, hn, ORDER, filterOn);
MikamiUitOpen 0:6748e3332e85 161 }
MikamiUitOpen 0:6748e3332e85 162 mySai.Stop();
MikamiUitOpen 0:6748e3332e85 163 menu.Activate(0); // OPEN 有効
MikamiUitOpen 0:6748e3332e85 164 if (!playOk) menu.Activate(1); // PLAY 有効
MikamiUitOpen 0:6748e3332e85 165 for (int n=2; n<5; n++) // その他は無効
MikamiUitOpen 0:6748e3332e85 166 menu.Inactivate(n);
MikamiUitOpen 0:6748e3332e85 167 sdReader.Close(); // SD のファイルのクローズ
MikamiUitOpen 0:6748e3332e85 168 }
MikamiUitOpen 0:6748e3332e85 169 }