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
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
Generated on Wed Jul 27 2022 22:49:01 by 1.7.2