revised version of F746_SD_GraphicEqualizer

Dependencies:   BSP_DISCO_F746NG F746_GUI F746_SAI_IO FrequencyResponseDrawer LCD_DISCO_F746NG SDFileSystem_Warning_Fixed TS_DISCO_F746NG mbed

Fork of F746_SD_GraphicEqualizer by 不韋 呂

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 //--------------------------------------------------------------
00002 //  グラフィックイコライザ付き SD オーディオプレーヤー
00003 //      SD のファイル: *.wav
00004 //                   PCM,16 ビットステレオ,標本化周波数 44.1 kHz
00005 //                   上記以外の形式は扱わない
00006 //      出力:モノラル
00007 //
00008 //  2016/05/09, Copyright (c) 2016 MIKAMI, Naoki
00009 //--------------------------------------------------------------
00010 
00011 #include "MyFunctions.hpp"
00012 #include "BlinkLabel.hpp"
00013 
00014 using namespace Mikami;
00015 enum ts_State {
00016     IDLE_NOPALY, SELECTED_PREPARE_PALY, PALYING, PAUSED, STOPPED, RESUMED
00017 };
00018 
00019 int main()
00020 {
00021     Label myLabel1(212, 2, "SD Card Audio Player", Label::CENTER, Font16);
00022     Label myLabel2(212, 16, "---- Graphic equalizer ----", Label::CENTER, Font12);
00023 
00024     const int FS = AUDIO_FREQUENCY_44K;         // 標本化周波数: 44.1 kHz
00025     SaiIO mySai(SaiIO::OUTPUT, 2048, FS);
00026 
00027     SD_WavReader sdReader(mySai.GetLength());   // SD カード読み込み用オブジェクト
00028     const int MAX_FILES = 7;
00029     string PlayList[MAX_FILES];
00030     int list_id = -9;   // if <0 then doesn't highlight any track in the list 
00031     FileSelector selector(4, 26, MAX_FILES, 37, sdReader);
00032     if (!selector.CreateTable())
00033         BlinkLabel errLabel(240, 100, "SD CARD ERROR", Label::CENTER);
00034 
00035     // ボタン用の定数
00036     const uint16_t BG_LEFT = 414;
00037     const uint16_t BG_WIDTH = 66;
00038     const uint16_t BG_HEIGHT = 36;
00039 
00040     // ButtonGroup: "OPEN", "PLAY", "PAUSE", "RESUME", "STOP"
00041     const string MENU[5] = {"OPEN", "PLAY", "PAUSE", "RESUME", "STOP"};
00042     ButtonGroup menu(BG_LEFT, 2, BG_WIDTH, BG_HEIGHT,
00043                      5, MENU, 0, 2, 1);
00044     // OPEN のみアクティブ
00045     menu.Activate(0);
00046     for (int n=1; n<5; n++) menu.Inactivate(n);
00047 //    printf("Button flat with 0 expanded detection Area\n");
00048     Button flat(BG_LEFT, 197, BG_WIDTH, BG_HEIGHT, 0, "FLAT");
00049 
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, 0);
00053 
00054     // フィルタの設計と周波数特性描画用
00055     const int STAGES = 9;       // バンド数
00056     DesignerDrawer drawerObj(
00057         28,        // グラフの左端の位置
00058         130,       // グラフの下端の位置
00059         STAGES,    // バンド数
00060         62.5f,     // 最低域バンドの中心周波数
00061         FS,        // 標本化周波数
00062         2.5f);     // 1 dB 当たりのピクセル数
00063 
00064     // 周波数特性変更用スライダ
00065     SeekbarGroup myBars(drawerObj.GetX0(), 178, 82, STAGES,
00066                         drawerObj.GetSpaceX(), -8.0f, 8.0f, 0,
00067                         SeekBar::Vertical);
00068 
00069     // フィルタの準備
00070     BiquadGrEq::Coefs ck[STAGES];
00071     drawerObj.GetCoefficients(ck);
00072     BiquadGrEq hn[STAGES];
00073     for (int k=0; k<STAGES; k++) hn[k] = BiquadGrEq(ck[k]);
00074 
00075     int32_t frameSize = mySai.GetLength();
00076     int16_t *sn = new int16_t[frameSize+1]; // フレームバッファ
00077     bool on = true;
00078     string fileName;
00079     int32_t loopCount;
00080     ts_State ui_mode = IDLE_NOPALY;
00081     int k;
00082     while (true) {
00083         switch(ui_mode) {
00084             case IDLE_NOPALY:
00085                 while (!menu.Touched(0))    // OPEN がタッチされるまで待つ
00086                     ModifyFilter(drawerObj, myBars, hn, flat, onOff, on);
00087                 for(int m=0; m<MAX_FILES; m++)  PlayList[m]="";      // clear playlist
00088                 SelectFile(menu, selector, myLabel1, PlayList, &list_id);   // returned playlist and selected ID
00089                 ui_mode = SELECTED_PREPARE_PALY ;
00090             case SELECTED_PREPARE_PALY:
00091             printf(" current track is %s  ******\n", PlayList[list_id].c_str());
00092                 loopCount = SD_Open(sdReader, PlayList[list_id], frameSize);
00093                 // while (!menu.Touched(1))   // PLAY がタッチされるまで待つ
00094                 //     ModifyFilter(drawerObj, myBars, hn, flat, onOff, on);
00095                 selector.Erase(0, 0, BG_LEFT-4, 288);
00096                 myLabel1.Draw("9-band Graphic Equalizer");
00097                 myBars.RedrawAll();
00098                 drawerObj.DrawResponse();
00099                 menu.Inactivate(0); // OPEN 無効
00100                 menu.Activate(2);   // PAUSE 有効
00101                 menu.Activate(4);   // STOP 有効
00102                 // IIR フィルタの内部の遅延器のクリア
00103                 for (int j=0; j<STAGES; j++) hn[j].Clear();
00104                 mySai.PlayOut();    // Play 開始
00105                 ui_mode = PALYING ;
00106                 k=0;
00107             case PALYING:
00108                 for (; k<loopCount && ui_mode==PALYING; k++) {
00109                     int touch42 = -1;
00110                     menu.GetTouchedNumber(touch42);
00111                     if (touch42 == 4)     ui_mode = STOPPED;      // STOP
00112                     else if (touch42 == 2)   ui_mode = PAUSED;    // PAUSE
00113                     ModifyFilter(drawerObj, myBars, hn, flat, onOff, on);
00114                     // 1フレーム分の信号処理 (イコライザ) の実行
00115                     SignalProcessing(sdReader, mySai, sn, hn, STAGES, on);
00116                 }
00117                 if(ui_mode == PAUSED)   break;   // Paused 
00118                 mySai.StopOut();    // current track play ended
00119                 sdReader.Close();   // SD のファイルのクローズ
00120                 if(ui_mode == STOPPED)   break;   // Stopped 
00121                 
00122                 if (list_id < MAX_FILES-1) {  // goto next track
00123                     if (PlayList[list_id+1].empty())   list_id=0;
00124                     else  list_id++;
00125                 } else list_id=0;
00126                 ui_mode = SELECTED_PREPARE_PALY;
00127                 break;
00128             case PAUSED: {
00129                 menu.Inactivate(2); // PAUSE 無効
00130                 menu.Activate(3);   // RESUME 有効
00131                 mySai.PauseOut();
00132                 // PLAY か RESUME か STOP がタッチされるまで待つ
00133                 int touch134 = -1;
00134                 while (!menu.GetTouchedNumber(touch134))
00135                     ModifyFilter(drawerObj, myBars, hn, flat, onOff, on);
00136                 if(touch134 == 3) {
00137                     ui_mode = RESUMED;
00138                     break;  // PAUSE したところから PLAY 再開
00139                 }
00140                 mySai.ResumeOut();  // PAUSE したところから PLAY 再開 またはSTOPの後処理
00141                 mySai.StopOut();
00142                 sdReader.Close();   // SD のファイルのクローズ
00143 
00144                 if(touch134 == 4) {
00145                     ui_mode = STOPPED;      break;    // STOP
00146                 }
00147                 if(touch134 == 1) {
00148                     ui_mode = SELECTED_PREPARE_PALY;      // 最初から PLAY
00149                     menu.Inactivate(3);      // RESUME disable to start play
00150                     break;
00151                 }
00152                 printf("a very bad wrong point\n");
00153                 break;
00154             }
00155             case STOPPED:
00156                 menu.Activate(0);               // OPEN 有効
00157                 menu.Activate(1);               // PLAY 有効
00158                 for (int n=2; n<5; n++)         // その他は無効
00159                     menu.Inactivate(n);
00160                 int touch10;
00161                 while (!menu.GetTouchedNumber(touch10))
00162                     ModifyFilter(drawerObj, myBars, hn, flat, onOff, on);
00163                 if (touch10 == 0)        //  OPEN タッチしたら
00164                     SelectFile(menu, selector, myLabel1, PlayList, &list_id);
00165                 ui_mode = SELECTED_PREPARE_PALY;
00166                 break;
00167             case RESUMED:
00168                 mySai.ResumeOut();  // PAUSE したところから PLAY 再開
00169                 menu.Activate(2);
00170                 menu.Inactivate(3);
00171                 menu.TouchedColor(1);
00172                 ui_mode = PALYING;
00173                 break;
00174         }
00175     }
00176 }