不韋 呂 / F746_MySoundMachine

Dependencies:   F746_GUI F746_SAI_IO FrequencyResponseDrawer SD_PlayerSkeleton UIT_FFT_Real

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers BtwthDesignerDrawer.cpp Source File

BtwthDesignerDrawer.cpp

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