?

Committer:
phungductung
Date:
Tue Jun 04 21:58:08 2019 +0000
Revision:
0:cacfc9e25452
?;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
phungductung 0:cacfc9e25452 1 //------------------------------------------------------------------------------
phungductung 0:cacfc9e25452 2 // IIR フィルタを双一次 z 変換で設計し,その周波数特性を描画するためのクラス
phungductung 0:cacfc9e25452 3 //
phungductung 0:cacfc9e25452 4 // 2016/05/01, Copyright (c) 2016 MIKAMI, Naoki
phungductung 0:cacfc9e25452 5 //------------------------------------------------------------------------------
phungductung 0:cacfc9e25452 6
phungductung 0:cacfc9e25452 7 #include "DesignerDrawer.hpp"
phungductung 0:cacfc9e25452 8
phungductung 0:cacfc9e25452 9 namespace Mikami
phungductung 0:cacfc9e25452 10 {
phungductung 0:cacfc9e25452 11 // Constructor
phungductung 0:cacfc9e25452 12 DesignerDrawer::DesignerDrawer(uint16_t x0, uint16_t y0,
phungductung 0:cacfc9e25452 13 float db1, int fs, int order,
phungductung 0:cacfc9e25452 14 float fc, uint16_t fL, uint16_t fH,
phungductung 0:cacfc9e25452 15 BilinearDesign::Type lpHp)
phungductung 0:cacfc9e25452 16 : lcd_(GuiBase::GetLcdPtr()), ts_(GuiBase::GetTsPtr()),
phungductung 0:cacfc9e25452 17 X0_(x0), Y0_(y0), ORDER_(order),
phungductung 0:cacfc9e25452 18 CURSOR_Y0_(y0+1-db1*60), CURSOR_LENGTH_(db1*60-1),
phungductung 0:cacfc9e25452 19 LOWER_F_(fL), HIGHER_F_(fH),
phungductung 0:cacfc9e25452 20 CURSOR_COLOR_(0xFFE000D0), CURSOR_TOUCHED_COLOR_(0xFFFF80FF)
phungductung 0:cacfc9e25452 21 {
phungductung 0:cacfc9e25452 22 drawerObj_ = new FrqRespDrawer(x0, 100.0f, 20000.0f, 140,
phungductung 0:cacfc9e25452 23 y0, -60, 0, db1, 10, fs);
phungductung 0:cacfc9e25452 24
phungductung 0:cacfc9e25452 25 // 双一次 z 変換による IIR フィルタの設計
phungductung 0:cacfc9e25452 26 designObj_ = new BilinearDesign(order, fs);
phungductung 0:cacfc9e25452 27 coefs_ = new BilinearDesign::Coefs[order/2];
phungductung 0:cacfc9e25452 28 ck_ = (Biquad::Coefs *)coefs_;
phungductung 0:cacfc9e25452 29
phungductung 0:cacfc9e25452 30 fC_ = fc; // 最初に与える遮断周波数
phungductung 0:cacfc9e25452 31 designObj_->Execute(fC_, lpHp, coefs_, g0_);
phungductung 0:cacfc9e25452 32 frqResp_ = new IIR_CascadeFrqResp();
phungductung 0:cacfc9e25452 33 frqResp_->SetParams(ORDER_, g0_, ck_);
phungductung 0:cacfc9e25452 34
phungductung 0:cacfc9e25452 35 // 周波数特性の描画
phungductung 0:cacfc9e25452 36 lblFrq_ = new NumericLabel<int>(110, 38);
phungductung 0:cacfc9e25452 37 DrawResponse();
phungductung 0:cacfc9e25452 38 tp_ = new TouchPanelDetectorX(
phungductung 0:cacfc9e25452 39 drawerObj_->X(LOWER_F_), drawerObj_->X(HIGHER_F_),
phungductung 0:cacfc9e25452 40 CURSOR_Y0_, y0);
phungductung 0:cacfc9e25452 41 lp_ = lpHp;
phungductung 0:cacfc9e25452 42 cursorRedraw_ = false;
phungductung 0:cacfc9e25452 43 }
phungductung 0:cacfc9e25452 44
phungductung 0:cacfc9e25452 45 DesignerDrawer::~DesignerDrawer()
phungductung 0:cacfc9e25452 46 {
phungductung 0:cacfc9e25452 47 delete tp_;
phungductung 0:cacfc9e25452 48 delete lblFrq_;
phungductung 0:cacfc9e25452 49 delete coefs_;
phungductung 0:cacfc9e25452 50 delete designObj_;
phungductung 0:cacfc9e25452 51 delete drawerObj_;
phungductung 0:cacfc9e25452 52 }
phungductung 0:cacfc9e25452 53
phungductung 0:cacfc9e25452 54 // フィルタの再設計と周波数特性の再描画
phungductung 0:cacfc9e25452 55 bool DesignerDrawer::ReDesignAndDraw(Biquad::Coefs *ck, float &g0,
phungductung 0:cacfc9e25452 56 BilinearDesign::Type lpHp)
phungductung 0:cacfc9e25452 57 {
phungductung 0:cacfc9e25452 58 bool changed = (lpHp != lp_) ? true : false;
phungductung 0:cacfc9e25452 59 bool tch = tp_->IsTouched(cursorX_, cursorX_);
phungductung 0:cacfc9e25452 60 if (tch || changed)
phungductung 0:cacfc9e25452 61 {
phungductung 0:cacfc9e25452 62 int newFc = Frq10(drawerObj_->PosToFrq(cursorX_));
phungductung 0:cacfc9e25452 63 newFc = (newFc > HIGHER_F_) ? HIGHER_F_ : newFc;
phungductung 0:cacfc9e25452 64 if ((abs(newFc - fC_) >= 10) || changed)
phungductung 0:cacfc9e25452 65 {
phungductung 0:cacfc9e25452 66 fC_ = newFc;
phungductung 0:cacfc9e25452 67 lblFrq_->Draw("Tan So Cat = %4d Hz", newFc);
phungductung 0:cacfc9e25452 68 designObj_->Execute(newFc, lpHp, coefs_, g0_);
phungductung 0:cacfc9e25452 69 GetCoefficients(ck, g0);
phungductung 0:cacfc9e25452 70
phungductung 0:cacfc9e25452 71 frqResp_->SetParams(ORDER_, g0_, ck_);
phungductung 0:cacfc9e25452 72 drawerObj_->Erase();
phungductung 0:cacfc9e25452 73 drawerObj_->DrawAxis(); // 目盛線の描画
phungductung 0:cacfc9e25452 74 drawerObj_->DrawGraph(frqResp_); // 周波数特性のグラフのカーブを描画する
phungductung 0:cacfc9e25452 75
phungductung 0:cacfc9e25452 76 if (tch) // カーソルの移動
phungductung 0:cacfc9e25452 77 {
phungductung 0:cacfc9e25452 78 lcd_->SetTextColor(CURSOR_TOUCHED_COLOR_);
phungductung 0:cacfc9e25452 79 lcd_->DrawVLine(cursorX_, CURSOR_Y0_, CURSOR_LENGTH_);
phungductung 0:cacfc9e25452 80 }
phungductung 0:cacfc9e25452 81 cursorRedraw_ = true;
phungductung 0:cacfc9e25452 82 oldCursorX_ = cursorX_;
phungductung 0:cacfc9e25452 83 lp_ = lpHp;
phungductung 0:cacfc9e25452 84 return true;
phungductung 0:cacfc9e25452 85 }
phungductung 0:cacfc9e25452 86 }
phungductung 0:cacfc9e25452 87
phungductung 0:cacfc9e25452 88 if (!tch && cursorRedraw_) // カーソルを元の色に戻す
phungductung 0:cacfc9e25452 89 {
phungductung 0:cacfc9e25452 90 lcd_->SetTextColor(CURSOR_COLOR_);
phungductung 0:cacfc9e25452 91 lcd_->DrawVLine(oldCursorX_, CURSOR_Y0_, CURSOR_LENGTH_);
phungductung 0:cacfc9e25452 92 cursorRedraw_ = false;
phungductung 0:cacfc9e25452 93 }
phungductung 0:cacfc9e25452 94 return false;
phungductung 0:cacfc9e25452 95 }
phungductung 0:cacfc9e25452 96
phungductung 0:cacfc9e25452 97 // 周波数特性の描画
phungductung 0:cacfc9e25452 98 void DesignerDrawer::DrawResponse()
phungductung 0:cacfc9e25452 99 {
phungductung 0:cacfc9e25452 100 lblFrq_->Draw("Tan So Cat = %4d Hz", fC_);
phungductung 0:cacfc9e25452 101 drawerObj_->DrawAxis(); // 目盛線の描画
phungductung 0:cacfc9e25452 102 FrqRespDrawer::AxisX_Char numX[] = // 横軸の目盛値を描画する際に使う構造体の配列
phungductung 0:cacfc9e25452 103 {{ 100, "0.1"}, { 200, "0.2"}, { 500, "0.5"}, { 1000, "1"},
phungductung 0:cacfc9e25452 104 { 2000, "2"}, { 5000, "5"}, {10000, "10"}, {20000, "20"}};
phungductung 0:cacfc9e25452 105 drawerObj_->DrawNumericX(numX, 8, 6, "Tan So [kHz]"); // 横軸の目盛
phungductung 0:cacfc9e25452 106 drawerObj_->DrawNumericY(-24, -6, 20, "%3d"); // 縦軸の目盛は 20 dB 間隔
phungductung 0:cacfc9e25452 107 drawerObj_->DrawGraph(frqResp_); // 周波数特性のカーブの描画
phungductung 0:cacfc9e25452 108
phungductung 0:cacfc9e25452 109 cursorX_ = drawerObj_->X(fC_);
phungductung 0:cacfc9e25452 110 lcd_->SetTextColor(CURSOR_COLOR_);
phungductung 0:cacfc9e25452 111 lcd_->DrawVLine(cursorX_, CURSOR_Y0_, CURSOR_LENGTH_);
phungductung 0:cacfc9e25452 112 }
phungductung 0:cacfc9e25452 113
phungductung 0:cacfc9e25452 114 // フィルタ係数の取得
phungductung 0:cacfc9e25452 115 void DesignerDrawer::GetCoefficients(Biquad::Coefs *c, float &g0)
phungductung 0:cacfc9e25452 116 {
phungductung 0:cacfc9e25452 117 for (int k=0; k<ORDER_/2; k++) c[k] = ck_[k];
phungductung 0:cacfc9e25452 118 g0 = g0_;
phungductung 0:cacfc9e25452 119 }
phungductung 0:cacfc9e25452 120
phungductung 0:cacfc9e25452 121 // 周波数を 10, 20, 50, 100 Hz の倍数にする
phungductung 0:cacfc9e25452 122 int DesignerDrawer::Frq10(float f)
phungductung 0:cacfc9e25452 123 {
phungductung 0:cacfc9e25452 124 if (f < 1000)
phungductung 0:cacfc9e25452 125 return ((int)(f/10.0f + 0.5f))*10;
phungductung 0:cacfc9e25452 126 if (f < 2000)
phungductung 0:cacfc9e25452 127 return ((int)(f/20.0f + 0.5f))*20;
phungductung 0:cacfc9e25452 128 if (f < 3000)
phungductung 0:cacfc9e25452 129 return ((int)(f/50.0f + 0.5f))*50;
phungductung 0:cacfc9e25452 130 else
phungductung 0:cacfc9e25452 131 return ((int)(f/100.0f + 0.5f))*100;
phungductung 0:cacfc9e25452 132 }
phungductung 0:cacfc9e25452 133 }
phungductung 0:cacfc9e25452 134