Output the audio signal with filtering by IIR filter in the *.wav file on the SD card using onboard CODEC. SD カードの *.wav ファイルのオーディオ信号を遮断周波数可変の IIR フィルタを通して,ボードに搭載されているCODEC で出力する.

Dependencies:   BSP_DISCO_F746NG F746_GUI LCD_DISCO_F746NG SDFileSystem_Warning_Fixed TS_DISCO_F746NG mbed FrequencyResponseDrawer F746_SAI_IO Array_Matrix

Committer:
MikamiUitOpen
Date:
Mon Jul 04 05:59:44 2016 +0000
Revision:
11:769d986c10fa
Parent:
9:fe097e4c9024
12

Who changed what in which revision?

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