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
MyClasses_Functions/DesignerDrawer.cpp
- Committer:
- MikamiUitOpen
- Date:
- 2016-05-01
- Revision:
- 5:3e8ca1ed31a1
- Parent:
- 3:cda40218256c
File content as of revision 5:3e8ca1ed31a1:
//------------------------------------------------------------------------------ // IIR フィルタを双一次 z 変換で設計し,その周波数特性を描画するためのクラス // // 2016/05/01, Copyright (c) 2016 MIKAMI, Naoki //------------------------------------------------------------------------------ #include "DesignerDrawer.hpp" namespace Mikami { // Constructor DesignerDrawer::DesignerDrawer(uint16_t x0, uint16_t y0, float 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), 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, 38); 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; } }