Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: BSP_DISCO_F746NG F746_GUI LCD_DISCO_F746NG SDFileSystem_Warning_Fixed TS_DISCO_F746NG mbed FrequencyResponseDrawer F746_SAI_IO Array_Matrix
MyClasses_Functions/DesignerDrawer.cpp
- Committer:
- MikamiUitOpen
- Date:
- 2016-04-25
- Revision:
- 3:cda40218256c
- Parent:
- 2:2478e7a8e8d5
- Child:
- 5:3e8ca1ed31a1
File content as of revision 3:cda40218256c:
//------------------------------------------------------------------------------
// IIR フィルタを双一次 z 変換で設計し,その周波数特性を描画するためのクラス
//
// 2016/04/25, Copyright (c) 2016 MIKAMI, Naoki
//------------------------------------------------------------------------------
#include "DesignerDrawer.hpp"
namespace Mikami
{
// Constructor
DesignerDrawer::DesignerDrawer(uint16_t x0, uint16_t y0,
uint16_t db1, int fs, int order,
float fc, uint16_t fL, uint16_t fH,
BilinearDesign::Type lpHp)
: lcd_(GuiBase::GetLcdPtr()), ts_(GuiBase::GetTsPtr()),
X0_(x0), Y0_(y0), DB1_(db1), ORDER_(order),
CURSOR_Y0_(y0+1-db1*60), CURSOR_LENGTH_(db1*60-1),
LOWER_F_(fL), HIGHER_F_(fH),
CURSOR_COLOR_(0xFFE000D0), CURSOR_TOUCHED_COLOR_(0xFFFF80FF)
{
drawerObj_ = new FrqRespDrawer(x0, 100.0f, 20000.0f, 140,
y0, -60, 0, db1, 10, fs);
// 双一次 z 変換による IIR フィルタの設計
designObj_ = new BilinearDesign(order, fs);
coefs_ = new BilinearDesign::Coefs[order/2];
ck_ = (Biquad::Coefs *)coefs_;
fC_ = fc; // 最初に与える遮断周波数
designObj_->Execute(fC_, lpHp, coefs_, g0_);
frqResp_ = new IIR_CascadeFrqResp();
frqResp_->SetParams(ORDER_, g0_, ck_);
// 周波数特性の描画
lblFrq_ = new NumericLabel<int>(110, 30);
DrawResponse();
tp_ = new TouchPanelDetectorX(
drawerObj_->X(LOWER_F_), drawerObj_->X(HIGHER_F_),
CURSOR_Y0_, y0);
lp_ = lpHp;
cursorRedraw_ = false;
}
DesignerDrawer::~DesignerDrawer()
{
delete tp_;
delete lblFrq_;
delete coefs_;
delete designObj_;
delete drawerObj_;
}
// フィルタの再設計と周波数特性の再描画
bool DesignerDrawer::ReDesignAndDraw(Biquad::Coefs *ck, float &g0,
BilinearDesign::Type lpHp)
{
bool changed = (lpHp != lp_) ? true : false;
bool tch = tp_->IsTouched(cursorX_, cursorX_);
if (tch || changed)
{
int newFc = Frq10(drawerObj_->PosToFrq(cursorX_));
newFc = (newFc > HIGHER_F_) ? HIGHER_F_ : newFc;
if ((abs(newFc - fC_) >= 10) || changed)
{
fC_ = newFc;
lblFrq_->Draw("Cutoff frequency = %4d Hz", newFc);
designObj_->Execute(newFc, lpHp, coefs_, g0_);
GetCoefficients(ck, g0);
frqResp_->SetParams(ORDER_, g0_, ck_);
drawerObj_->Erase();
drawerObj_->DrawAxis(); // 目盛線の描画
drawerObj_->DrawGraph(frqResp_); // 周波数特性のグラフのカーブを描画する
if (tch) // カーソルの移動
{
lcd_->SetTextColor(CURSOR_TOUCHED_COLOR_);
lcd_->DrawVLine(cursorX_, CURSOR_Y0_, CURSOR_LENGTH_);
}
cursorRedraw_ = true;
oldCursorX_ = cursorX_;
lp_ = lpHp;
return true;
}
}
if (!tch && cursorRedraw_) // カーソルを元の色に戻す
{
lcd_->SetTextColor(CURSOR_COLOR_);
lcd_->DrawVLine(oldCursorX_, CURSOR_Y0_, CURSOR_LENGTH_);
cursorRedraw_ = false;
}
return false;
}
// 周波数特性の描画
void DesignerDrawer::DrawResponse()
{
lblFrq_->Draw("Cutoff frequency = %4d Hz", fC_);
drawerObj_->DrawAxis(); // 目盛線の描画
FrqRespDrawer::AxisX_Char numX[] = // 横軸の目盛値を描画する際に使う構造体の配列
{{ 100, "0.1"}, { 200, "0.2"}, { 500, "0.5"}, { 1000, "1"},
{ 2000, "2"}, { 5000, "5"}, {10000, "10"}, {20000, "20"}};
drawerObj_->DrawNumericX(numX, 8, 6, "Frequency [kHz]"); // 横軸の目盛
drawerObj_->DrawNumericY(-24, -6, 20, "%3d"); // 縦軸の目盛は 20 dB 間隔
drawerObj_->DrawGraph(frqResp_); // 周波数特性のカーブの描画
cursorX_ = drawerObj_->X(fC_);
lcd_->SetTextColor(CURSOR_COLOR_);
lcd_->DrawVLine(cursorX_, CURSOR_Y0_, CURSOR_LENGTH_);
}
// フィルタ係数の取得
void DesignerDrawer::GetCoefficients(Biquad::Coefs *c, float &g0)
{
for (int k=0; k<ORDER_/2; k++) c[k] = ck_[k];
g0 = g0_;
}
// 周波数を 10, 20, 50, 100 Hz の倍数にする
int DesignerDrawer::Frq10(float f)
{
if (f < 1000)
return ((int)(f/10.0f + 0.5f))*10;
if (f < 2000)
return ((int)(f/20.0f + 0.5f))*20;
if (f < 3000)
return ((int)(f/50.0f + 0.5f))*50;
else
return ((int)(f/100.0f + 0.5f))*100;
}
}