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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DesignerDrawer.cpp Source File

DesignerDrawer.cpp

00001 //------------------------------------------------------------------------------
00002 //  IIR フィルタを双一次 z 変換で設計し,その周波数特性を描画するためのクラス
00003 //  
00004 //  2016/05/01, Copyright (c) 2016 MIKAMI, Naoki
00005 //------------------------------------------------------------------------------
00006 
00007 #include "DesignerDrawer.hpp"
00008 
00009 namespace Mikami
00010 {
00011     // Constructor
00012     DesignerDrawer::DesignerDrawer(uint16_t x0, uint16_t y0,
00013                                    float db1, int fs, int order,
00014                                    float fc, uint16_t fL, uint16_t fH,
00015                                    BilinearDesign::Type lpHp)
00016         : lcd_(GuiBase::GetLcdPtr()), ts_(GuiBase::GetTsPtr()),
00017           X0_(x0), Y0_(y0), ORDER_(order),
00018           CURSOR_Y0_(y0+1-db1*60), CURSOR_LENGTH_(db1*60-1),
00019           LOWER_F_(fL), HIGHER_F_(fH),
00020           CURSOR_COLOR_(0xFFE000D0), CURSOR_TOUCHED_COLOR_(0xFFFF80FF)
00021     {
00022         drawerObj_ = new FrqRespDrawer(x0, 100.0f, 20000.0f, 140,
00023                                        y0, -60, 0, db1, 10, fs);
00024 
00025         // 双一次 z 変換による IIR フィルタの設計
00026         designObj_ = new BilinearDesign(order, fs);
00027         coefs_ = new BilinearDesign::Coefs[order/2];
00028         ck_ = (Biquad::Coefs *)coefs_;
00029        
00030         fC_ = fc;               // 最初に与える遮断周波数
00031         designObj_->Execute(fC_, lpHp, coefs_, g0_);
00032         frqResp_ = new IIR_CascadeFrqResp();
00033         frqResp_->SetParams(ORDER_, g0_, ck_);
00034 
00035         // 周波数特性の描画
00036         lblFrq_ = new NumericLabel<int>(110, 38);
00037         DrawResponse();
00038         tp_ = new TouchPanelDetectorX(
00039                 drawerObj_->X(LOWER_F_), drawerObj_->X(HIGHER_F_),
00040                 CURSOR_Y0_, y0);
00041         lp_ = lpHp;
00042         cursorRedraw_ = false;
00043     }
00044 
00045     DesignerDrawer::~DesignerDrawer()
00046     {
00047         delete tp_;
00048         delete lblFrq_;
00049         delete coefs_;
00050         delete designObj_;
00051         delete drawerObj_;
00052     }
00053 
00054     // フィルタの再設計と周波数特性の再描画
00055     bool DesignerDrawer::ReDesignAndDraw(Biquad::Coefs *ck, float &g0,
00056                                          BilinearDesign::Type lpHp)
00057     {
00058         bool changed = (lpHp != lp_) ? true : false;
00059         bool tch = tp_->IsTouched(cursorX_, cursorX_);
00060         if (tch || changed)
00061         {
00062             int newFc = Frq10(drawerObj_->PosToFrq(cursorX_));
00063             newFc = (newFc > HIGHER_F_) ? HIGHER_F_ : newFc;
00064             if ((abs(newFc - fC_) >= 10) || changed)
00065             {
00066                 fC_ = newFc;
00067                 lblFrq_->Draw("Cutoff frequency = %4d Hz", newFc);
00068                 designObj_->Execute(newFc, lpHp, coefs_, g0_);
00069                 GetCoefficients(ck, g0);
00070 
00071                 frqResp_->SetParams(ORDER_, g0_, ck_);
00072                 drawerObj_->Erase();
00073                 drawerObj_->DrawAxis();             // 目盛線の描画
00074                 drawerObj_->DrawGraph(frqResp_);    // 周波数特性のグラフのカーブを描画する
00075 
00076                 if (tch)    // カーソルの移動
00077                 {
00078                     lcd_->SetTextColor(CURSOR_TOUCHED_COLOR_);
00079                     lcd_->DrawVLine(cursorX_, CURSOR_Y0_, CURSOR_LENGTH_);
00080                 }
00081                 cursorRedraw_ = true;
00082                 oldCursorX_ = cursorX_;
00083                 lp_ = lpHp;
00084                 return true;
00085             }
00086         }
00087         
00088         if (!tch && cursorRedraw_)   // カーソルを元の色に戻す
00089         {
00090             lcd_->SetTextColor(CURSOR_COLOR_);
00091             lcd_->DrawVLine(oldCursorX_, CURSOR_Y0_, CURSOR_LENGTH_);
00092             cursorRedraw_ = false;
00093         }
00094         return false;
00095     }
00096 
00097     // 周波数特性の描画
00098     void DesignerDrawer::DrawResponse()
00099     {
00100         lblFrq_->Draw("Cutoff frequency = %4d Hz", fC_);
00101         drawerObj_->DrawAxis();             // 目盛線の描画
00102         FrqRespDrawer::AxisX_Char numX[] =  // 横軸の目盛値を描画する際に使う構造体の配列
00103             {{  100, "0.1"}, {  200, "0.2"}, {  500, "0.5"}, { 1000,  "1"},
00104              { 2000,   "2"}, { 5000,   "5"}, {10000,  "10"}, {20000, "20"}};
00105         drawerObj_->DrawNumericX(numX, 8, 6, "Frequency [kHz]");    // 横軸の目盛
00106         drawerObj_->DrawNumericY(-24, -6, 20, "%3d");               // 縦軸の目盛は 20 dB 間隔
00107         drawerObj_->DrawGraph(frqResp_);    // 周波数特性のカーブの描画
00108 
00109         cursorX_ = drawerObj_->X(fC_);
00110         lcd_->SetTextColor(CURSOR_COLOR_);
00111         lcd_->DrawVLine(cursorX_, CURSOR_Y0_, CURSOR_LENGTH_);
00112     }
00113 
00114     // フィルタ係数の取得
00115     void DesignerDrawer::GetCoefficients(Biquad::Coefs *c, float &g0)
00116     {
00117         for (int k=0; k<ORDER_/2; k++) c[k] = ck_[k];
00118         g0 = g0_;
00119     }
00120     
00121     // 周波数を 10, 20, 50, 100 Hz の倍数にする
00122     int DesignerDrawer::Frq10(float f)
00123     {
00124         if (f < 1000)
00125             return ((int)(f/10.0f + 0.5f))*10;
00126         if (f < 2000)
00127             return ((int)(f/20.0f + 0.5f))*20;
00128         if (f < 3000)
00129             return ((int)(f/50.0f + 0.5f))*50;           
00130         else
00131             return ((int)(f/100.0f + 0.5f))*100;
00132     }
00133 }
00134