Output the audio signal with filtering by graphic equalizer in the *.wav file on the SD card using onboard CODEC. SD カードの *.wav ファイルのオーディオ信号をグラフィック・イコライザを通して,ボードに搭載されているCODEC で出力する.
Dependencies: F746_GUI F746_SAI_IO SD_PlayerSkeleton FrequencyResponseDrawer
main.cpp@11:f4929315bc9f, 2016-07-03 (annotated)
- Committer:
- MikamiUitOpen
- Date:
- Sun Jul 03 05:29:38 2016 +0000
- Revision:
- 11:f4929315bc9f
- Parent:
- 10:160fcbe4dee8
- Child:
- 13:728576fffe65
12
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
MikamiUitOpen | 0:e953eb392151 | 1 | //-------------------------------------------------------------- |
MikamiUitOpen | 0:e953eb392151 | 2 | // グラフィックイコライザ付き SD オーディオプレーヤー |
MikamiUitOpen | 0:e953eb392151 | 3 | // SD のファイル: *.wav |
MikamiUitOpen | 0:e953eb392151 | 4 | // PCM,16 ビットステレオ,標本化周波数 44.1 kHz |
MikamiUitOpen | 0:e953eb392151 | 5 | // 上記以外の形式は扱わない |
MikamiUitOpen | 11:f4929315bc9f | 6 | // 出力:モノラル(L+R,左チャンネルのみ,右チャンネルには出力しない) |
MikamiUitOpen | 0:e953eb392151 | 7 | // |
MikamiUitOpen | 11:f4929315bc9f | 8 | // 2016/07/03, Copyright (c) 2016 MIKAMI, Naoki |
MikamiUitOpen | 0:e953eb392151 | 9 | //-------------------------------------------------------------- |
MikamiUitOpen | 0:e953eb392151 | 10 | |
MikamiUitOpen | 0:e953eb392151 | 11 | #include "MyFunctions.hpp" |
MikamiUitOpen | 0:e953eb392151 | 12 | #include "BlinkLabel.hpp" |
MikamiUitOpen | 0:e953eb392151 | 13 | |
MikamiUitOpen | 0:e953eb392151 | 14 | using namespace Mikami; |
MikamiUitOpen | 0:e953eb392151 | 15 | |
MikamiUitOpen | 0:e953eb392151 | 16 | int main() |
MikamiUitOpen | 0:e953eb392151 | 17 | { |
MikamiUitOpen | 11:f4929315bc9f | 18 | const uint16_t X_CENTER = 214; |
MikamiUitOpen | 11:f4929315bc9f | 19 | Label myLabel1(X_CENTER, 4, "9-band Graphic Equalizer", Label::CENTER, Font16); |
MikamiUitOpen | 11:f4929315bc9f | 20 | Label myLabel2(X_CENTER, 20, "---- Source: microSD card ----", Label::CENTER); |
MikamiUitOpen | 0:e953eb392151 | 21 | |
MikamiUitOpen | 0:e953eb392151 | 22 | const int FS = AUDIO_FREQUENCY_44K; // 標本化周波数: 44.1 kHz |
MikamiUitOpen | 5:a5a4f9d7b26c | 23 | SaiIO mySai(SaiIO::OUTPUT, 2048, FS); |
MikamiUitOpen | 0:e953eb392151 | 24 | |
MikamiUitOpen | 0:e953eb392151 | 25 | SD_WavReader sdReader(mySai.GetLength()); // SD カード読み込み用オブジェクト |
MikamiUitOpen | 0:e953eb392151 | 26 | const int MAX_FILES = 7; |
MikamiUitOpen | 11:f4929315bc9f | 27 | FileSelector selector(4, 22, MAX_FILES, 37, sdReader); |
MikamiUitOpen | 0:e953eb392151 | 28 | if (!selector.CreateTable()) |
MikamiUitOpen | 0:e953eb392151 | 29 | BlinkLabel errLabel(240, 100, "SD CARD ERROR", Label::CENTER); |
MikamiUitOpen | 0:e953eb392151 | 30 | |
MikamiUitOpen | 0:e953eb392151 | 31 | // ボタン用の定数 |
MikamiUitOpen | 2:2a5c93bf729a | 32 | const uint16_t BG_LEFT = 414; |
MikamiUitOpen | 2:2a5c93bf729a | 33 | const uint16_t BG_WIDTH = 66; |
MikamiUitOpen | 7:be29ba9c83b2 | 34 | const uint16_t BG_HEIGHT = 36; |
MikamiUitOpen | 11:f4929315bc9f | 35 | |
MikamiUitOpen | 0:e953eb392151 | 36 | // ButtonGroup: "OPEN", "PLAY", "PAUSE", "RESUME", "STOP" |
MikamiUitOpen | 0:e953eb392151 | 37 | const string MENU[5] = {"OPEN", "PLAY", "PAUSE", "RESUME", "STOP"}; |
MikamiUitOpen | 0:e953eb392151 | 38 | ButtonGroup menu(BG_LEFT, 2, BG_WIDTH, BG_HEIGHT, |
MikamiUitOpen | 0:e953eb392151 | 39 | 5, MENU, 0, 2, 1); |
MikamiUitOpen | 11:f4929315bc9f | 40 | menu.InactivateAll(); |
MikamiUitOpen | 11:f4929315bc9f | 41 | |
MikamiUitOpen | 0:e953eb392151 | 42 | menu.Activate(0); |
MikamiUitOpen | 7:be29ba9c83b2 | 43 | Button flat(BG_LEFT, 197, BG_WIDTH, BG_HEIGHT, "FLAT"); |
MikamiUitOpen | 7:be29ba9c83b2 | 44 | |
MikamiUitOpen | 2:2a5c93bf729a | 45 | const string ON_OFF[2] = {"ON", "OFF"}; |
MikamiUitOpen | 7:be29ba9c83b2 | 46 | ButtonGroup onOff(BG_LEFT, 235, BG_WIDTH/2, BG_HEIGHT, |
MikamiUitOpen | 2:2a5c93bf729a | 47 | 2, ON_OFF, 0, 0, 2, 0); |
MikamiUitOpen | 0:e953eb392151 | 48 | |
MikamiUitOpen | 0:e953eb392151 | 49 | // フィルタの設計と周波数特性描画用 |
MikamiUitOpen | 11:f4929315bc9f | 50 | const int BANDS = 9; // バンド数 |
MikamiUitOpen | 0:e953eb392151 | 51 | DesignerDrawer drawerObj( |
MikamiUitOpen | 2:2a5c93bf729a | 52 | 28, // グラフの左端の位置 |
MikamiUitOpen | 0:e953eb392151 | 53 | 130, // グラフの下端の位置 |
MikamiUitOpen | 11:f4929315bc9f | 54 | BANDS, // バンド数 |
MikamiUitOpen | 0:e953eb392151 | 55 | 62.5f, // 最低域バンドの中心周波数 |
MikamiUitOpen | 0:e953eb392151 | 56 | FS, // 標本化周波数 |
MikamiUitOpen | 2:2a5c93bf729a | 57 | 2.5f); // 1 dB 当たりのピクセル数 |
MikamiUitOpen | 0:e953eb392151 | 58 | |
MikamiUitOpen | 0:e953eb392151 | 59 | // 周波数特性変更用スライダ |
MikamiUitOpen | 11:f4929315bc9f | 60 | SeekbarGroup myBars(drawerObj.GetX0(), 178, 82, BANDS, |
MikamiUitOpen | 7:be29ba9c83b2 | 61 | drawerObj.GetSpaceX(), -8.0f, 8.0f, 0, |
MikamiUitOpen | 0:e953eb392151 | 62 | SeekBar::Vertical); |
MikamiUitOpen | 0:e953eb392151 | 63 | |
MikamiUitOpen | 0:e953eb392151 | 64 | // フィルタの準備 |
MikamiUitOpen | 11:f4929315bc9f | 65 | BiquadGrEq::Coefs ck[BANDS]; |
MikamiUitOpen | 0:e953eb392151 | 66 | drawerObj.GetCoefficients(ck); |
MikamiUitOpen | 11:f4929315bc9f | 67 | BiquadGrEq hn[BANDS]; |
MikamiUitOpen | 11:f4929315bc9f | 68 | for (int k=0; k<BANDS; k++) hn[k] = BiquadGrEq(ck[k]); |
MikamiUitOpen | 0:e953eb392151 | 69 | |
MikamiUitOpen | 0:e953eb392151 | 70 | int32_t frameSize = mySai.GetLength(); |
MikamiUitOpen | 0:e953eb392151 | 71 | bool playOk = false; |
MikamiUitOpen | 2:2a5c93bf729a | 72 | bool on = true; |
MikamiUitOpen | 0:e953eb392151 | 73 | bool whileFirst = true; |
MikamiUitOpen | 0:e953eb392151 | 74 | string fileName; |
MikamiUitOpen | 0:e953eb392151 | 75 | int32_t loopCount; |
MikamiUitOpen | 0:e953eb392151 | 76 | |
MikamiUitOpen | 0:e953eb392151 | 77 | while (true) |
MikamiUitOpen | 0:e953eb392151 | 78 | { |
MikamiUitOpen | 0:e953eb392151 | 79 | if (!playOk) |
MikamiUitOpen | 0:e953eb392151 | 80 | { |
MikamiUitOpen | 0:e953eb392151 | 81 | if (whileFirst) |
MikamiUitOpen | 0:e953eb392151 | 82 | { |
MikamiUitOpen | 0:e953eb392151 | 83 | whileFirst = false; |
MikamiUitOpen | 0:e953eb392151 | 84 | while (!menu.Touched(0)) // OPEN がタッチされるまで待つ |
MikamiUitOpen | 7:be29ba9c83b2 | 85 | ModifyFilter(drawerObj, myBars, hn, flat, onOff, on); |
MikamiUitOpen | 2:2a5c93bf729a | 86 | SelectFile(menu, selector, myLabel1, fileName); |
MikamiUitOpen | 0:e953eb392151 | 87 | } |
MikamiUitOpen | 0:e953eb392151 | 88 | else |
MikamiUitOpen | 0:e953eb392151 | 89 | { |
MikamiUitOpen | 0:e953eb392151 | 90 | menu.Activate(1); // PLAY 有効 |
MikamiUitOpen | 0:e953eb392151 | 91 | int touch10; |
MikamiUitOpen | 0:e953eb392151 | 92 | while (!menu.GetTouchedNumber(touch10)) |
MikamiUitOpen | 7:be29ba9c83b2 | 93 | ModifyFilter(drawerObj, myBars, hn, flat, onOff, on); |
MikamiUitOpen | 0:e953eb392151 | 94 | if (touch10 == 0) |
MikamiUitOpen | 2:2a5c93bf729a | 95 | SelectFile(menu, selector, myLabel1, fileName); |
MikamiUitOpen | 0:e953eb392151 | 96 | } |
MikamiUitOpen | 0:e953eb392151 | 97 | |
MikamiUitOpen | 0:e953eb392151 | 98 | loopCount = SD_Open(sdReader, fileName, frameSize); |
MikamiUitOpen | 0:e953eb392151 | 99 | while (!menu.Touched(1)) // PLAY がタッチされるまで待つ |
MikamiUitOpen | 7:be29ba9c83b2 | 100 | ModifyFilter(drawerObj, myBars, hn, flat, onOff, on); |
MikamiUitOpen | 0:e953eb392151 | 101 | } |
MikamiUitOpen | 0:e953eb392151 | 102 | else |
MikamiUitOpen | 0:e953eb392151 | 103 | loopCount = SD_Open(sdReader, fileName, frameSize); |
MikamiUitOpen | 0:e953eb392151 | 104 | |
MikamiUitOpen | 2:2a5c93bf729a | 105 | selector.Erase(0, 0, BG_LEFT-4, 288); |
MikamiUitOpen | 11:f4929315bc9f | 106 | myLabel1.Draw(); |
MikamiUitOpen | 0:e953eb392151 | 107 | myBars.RedrawAll(); |
MikamiUitOpen | 0:e953eb392151 | 108 | drawerObj.DrawResponse(); |
MikamiUitOpen | 0:e953eb392151 | 109 | menu.Inactivate(0); // OPEN 無効 |
MikamiUitOpen | 0:e953eb392151 | 110 | menu.Activate(2); // PAUSE 有効 |
MikamiUitOpen | 0:e953eb392151 | 111 | menu.Activate(4); // STOP 有効 |
MikamiUitOpen | 0:e953eb392151 | 112 | |
MikamiUitOpen | 0:e953eb392151 | 113 | playOk = false; |
MikamiUitOpen | 0:e953eb392151 | 114 | bool stopOk = false; |
MikamiUitOpen | 0:e953eb392151 | 115 | |
MikamiUitOpen | 0:e953eb392151 | 116 | // IIR フィルタの内部の遅延器のクリア |
MikamiUitOpen | 11:f4929315bc9f | 117 | for (int k=0; k<BANDS; k++) hn[k].Clear(); |
MikamiUitOpen | 7:be29ba9c83b2 | 118 | mySai.PlayOut(); // Play 開始 |
MikamiUitOpen | 0:e953eb392151 | 119 | |
MikamiUitOpen | 0:e953eb392151 | 120 | for (int k=0; k<loopCount; k++) |
MikamiUitOpen | 0:e953eb392151 | 121 | { |
MikamiUitOpen | 0:e953eb392151 | 122 | int touch42 = -1; |
MikamiUitOpen | 0:e953eb392151 | 123 | menu.GetTouchedNumber(touch42); |
MikamiUitOpen | 0:e953eb392151 | 124 | if (touch42 == 4) break; // STOP |
MikamiUitOpen | 0:e953eb392151 | 125 | if (touch42 == 2) // PAUSE |
MikamiUitOpen | 0:e953eb392151 | 126 | { |
MikamiUitOpen | 0:e953eb392151 | 127 | menu.Inactivate(2); // PAUSE 無効 |
MikamiUitOpen | 0:e953eb392151 | 128 | menu.Activate(3); // RESUME 有効 |
MikamiUitOpen | 9:0d5bd1539291 | 129 | mySai.PauseOut(); |
MikamiUitOpen | 0:e953eb392151 | 130 | |
MikamiUitOpen | 0:e953eb392151 | 131 | // PLAY か RESUME か STOP がタッチされるまで待つ |
MikamiUitOpen | 0:e953eb392151 | 132 | int touch134 = -1; |
MikamiUitOpen | 0:e953eb392151 | 133 | while (!menu.GetTouchedNumber(touch134)) |
MikamiUitOpen | 7:be29ba9c83b2 | 134 | ModifyFilter(drawerObj, myBars, hn, flat, onOff, on); |
MikamiUitOpen | 0:e953eb392151 | 135 | switch (touch134) |
MikamiUitOpen | 0:e953eb392151 | 136 | { |
MikamiUitOpen | 9:0d5bd1539291 | 137 | case 1: playOk = true; // 最初から PLAY |
MikamiUitOpen | 0:e953eb392151 | 138 | break; |
MikamiUitOpen | 9:0d5bd1539291 | 139 | case 3: mySai.ResumeOut(); // PAUSE したところから PLAY 再開 |
MikamiUitOpen | 0:e953eb392151 | 140 | menu.Activate(2); |
MikamiUitOpen | 0:e953eb392151 | 141 | menu.Inactivate(3); |
MikamiUitOpen | 0:e953eb392151 | 142 | menu.TouchedColor(1); |
MikamiUitOpen | 0:e953eb392151 | 143 | break; |
MikamiUitOpen | 9:0d5bd1539291 | 144 | case 4: stopOk = true; // STOP |
MikamiUitOpen | 0:e953eb392151 | 145 | break; |
MikamiUitOpen | 0:e953eb392151 | 146 | } |
MikamiUitOpen | 0:e953eb392151 | 147 | } |
MikamiUitOpen | 0:e953eb392151 | 148 | if (playOk || stopOk) break; |
MikamiUitOpen | 0:e953eb392151 | 149 | |
MikamiUitOpen | 7:be29ba9c83b2 | 150 | ModifyFilter(drawerObj, myBars, hn, flat, onOff, on); |
MikamiUitOpen | 0:e953eb392151 | 151 | // 1フレーム分の信号処理 (イコライザ) の実行 |
MikamiUitOpen | 11:f4929315bc9f | 152 | SignalProcessing(sdReader, mySai, hn, BANDS, on); |
MikamiUitOpen | 0:e953eb392151 | 153 | } |
MikamiUitOpen | 9:0d5bd1539291 | 154 | mySai.StopOut(); |
MikamiUitOpen | 0:e953eb392151 | 155 | menu.Activate(0); // OPEN 有効 |
MikamiUitOpen | 0:e953eb392151 | 156 | if (!playOk) menu.Activate(1); // PLAY 有効 |
MikamiUitOpen | 0:e953eb392151 | 157 | for (int n=2; n<5; n++) // その他は無効 |
MikamiUitOpen | 0:e953eb392151 | 158 | menu.Inactivate(n); |
MikamiUitOpen | 0:e953eb392151 | 159 | sdReader.Close(); // SD のファイルのクローズ |
MikamiUitOpen | 0:e953eb392151 | 160 | } |
MikamiUitOpen | 0:e953eb392151 | 161 | } |