Output the audio signal (*.bin) with filtering by IIR filter in the SD card using onboard CODEC. For *.wav file, F746_SD_WavPlayer and F746_SD_GraphicEqualiser are published on mbed. SD カードのオーディオ信号 (*.bin) を遮断周波数可変の IIR フィルタを通して,ボードに搭載されているCODEC で出力する.*.wav 形式のファイル用には,F746_SD_WavPlayer と F746_SD_GraphicEqualiser を mbed で公開している.
Dependencies: BSP_DISCO_F746NG_patch_fixed F746_GUI LCD_DISCO_F746NG SDFileSystem_Warning_Fixed TS_DISCO_F746NG mbed
MyClasses_Functions/DesignerDrawer.cpp@5:4a99dabc9180, 2016-04-17 (annotated)
- Committer:
- MikamiUitOpen
- Date:
- Sun Apr 17 08:44:43 2016 +0000
- Revision:
- 5:4a99dabc9180
- Parent:
- 4:76aa20fb326a
6
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
MikamiUitOpen | 4:76aa20fb326a | 1 | //------------------------------------------------------------------------------ |
MikamiUitOpen | 4:76aa20fb326a | 2 | // IIR フィルタを双一次 z 変換で設計し,その周波数特性を描画するためのクラス |
MikamiUitOpen | 4:76aa20fb326a | 3 | // |
MikamiUitOpen | 5:4a99dabc9180 | 4 | // 2016/04/17, Copyright (c) 2016 MIKAMI, Naoki |
MikamiUitOpen | 4:76aa20fb326a | 5 | //------------------------------------------------------------------------------ |
MikamiUitOpen | 4:76aa20fb326a | 6 | |
MikamiUitOpen | 4:76aa20fb326a | 7 | #include "DesignerDrawer.hpp" |
MikamiUitOpen | 4:76aa20fb326a | 8 | |
MikamiUitOpen | 4:76aa20fb326a | 9 | namespace Mikami |
MikamiUitOpen | 4:76aa20fb326a | 10 | { |
MikamiUitOpen | 4:76aa20fb326a | 11 | // Constructor |
MikamiUitOpen | 4:76aa20fb326a | 12 | DesignerDrawer::DesignerDrawer(uint16_t x0, uint16_t y0, |
MikamiUitOpen | 4:76aa20fb326a | 13 | uint16_t db10, int fs, int order, |
MikamiUitOpen | 4:76aa20fb326a | 14 | float fc, uint16_t fL, uint16_t fH, |
MikamiUitOpen | 4:76aa20fb326a | 15 | BilinearDesign::Type lpHp) |
MikamiUitOpen | 4:76aa20fb326a | 16 | : lcd_(GuiBase::GetLcdPtr()), ts_(GuiBase::GetTsPtr()), |
MikamiUitOpen | 4:76aa20fb326a | 17 | X0_(x0), Y0_(y0), DB10_(db10), ORDER_(order), |
MikamiUitOpen | 4:76aa20fb326a | 18 | CURSOR_Y0_(y0+1-db10*6), CURSOR_LENGTH_(db10*6-1), |
MikamiUitOpen | 4:76aa20fb326a | 19 | LOWER_F_(fL), HIGHER_F_(fH), |
MikamiUitOpen | 4:76aa20fb326a | 20 | CURSOR_COLOR_(0xFFE000D0), CURSOR_TOUCHED_COLOR_(0xFFFF80FF) |
MikamiUitOpen | 4:76aa20fb326a | 21 | { |
MikamiUitOpen | 4:76aa20fb326a | 22 | drawerObj_ = new FrqRespDrawer(x0, 100.0f, 8000.0f, 150, |
MikamiUitOpen | 4:76aa20fb326a | 23 | y0, -60, 0, db10, fs); |
MikamiUitOpen | 4:76aa20fb326a | 24 | |
MikamiUitOpen | 4:76aa20fb326a | 25 | // 双一次 z 変換による IIR フィルタの設計 |
MikamiUitOpen | 4:76aa20fb326a | 26 | designObj_ = new BilinearDesign(order, fs); |
MikamiUitOpen | 4:76aa20fb326a | 27 | coefs_ = new BilinearDesign::Coefs[order/2]; |
MikamiUitOpen | 4:76aa20fb326a | 28 | ck_ = (Biquad::Coefs *)coefs_; |
MikamiUitOpen | 4:76aa20fb326a | 29 | |
MikamiUitOpen | 4:76aa20fb326a | 30 | fC_ = fc; // 最初に与える遮断周波数 |
MikamiUitOpen | 4:76aa20fb326a | 31 | designObj_->Execute(fC_, lpHp, coefs_, g0_); |
MikamiUitOpen | 5:4a99dabc9180 | 32 | frqResp_.SetParams(ORDER_, g0_, ck_); |
MikamiUitOpen | 4:76aa20fb326a | 33 | |
MikamiUitOpen | 4:76aa20fb326a | 34 | // 周波数特性の描画 |
MikamiUitOpen | 4:76aa20fb326a | 35 | lblFrq_ = new NumericLabel<int>(110, 30); |
MikamiUitOpen | 4:76aa20fb326a | 36 | DrawResponse(); |
MikamiUitOpen | 4:76aa20fb326a | 37 | tp_ = new TouchPanelDetectorX( |
MikamiUitOpen | 4:76aa20fb326a | 38 | drawerObj_->X(LOWER_F_), drawerObj_->X(HIGHER_F_), |
MikamiUitOpen | 4:76aa20fb326a | 39 | CURSOR_Y0_, y0); |
MikamiUitOpen | 4:76aa20fb326a | 40 | lp_ = lpHp; |
MikamiUitOpen | 4:76aa20fb326a | 41 | cursorRedraw_ = false; |
MikamiUitOpen | 4:76aa20fb326a | 42 | } |
MikamiUitOpen | 4:76aa20fb326a | 43 | |
MikamiUitOpen | 4:76aa20fb326a | 44 | DesignerDrawer::~DesignerDrawer() |
MikamiUitOpen | 4:76aa20fb326a | 45 | { |
MikamiUitOpen | 4:76aa20fb326a | 46 | delete tp_; |
MikamiUitOpen | 4:76aa20fb326a | 47 | delete lblFrq_; |
MikamiUitOpen | 4:76aa20fb326a | 48 | delete coefs_; |
MikamiUitOpen | 4:76aa20fb326a | 49 | delete designObj_; |
MikamiUitOpen | 4:76aa20fb326a | 50 | delete drawerObj_; |
MikamiUitOpen | 4:76aa20fb326a | 51 | } |
MikamiUitOpen | 4:76aa20fb326a | 52 | |
MikamiUitOpen | 4:76aa20fb326a | 53 | // フィルタの再設計と周波数特性の再描画 |
MikamiUitOpen | 4:76aa20fb326a | 54 | bool DesignerDrawer::ReDesignAndDraw(Biquad::Coefs *ck, float &g0, |
MikamiUitOpen | 4:76aa20fb326a | 55 | BilinearDesign::Type lpHp) |
MikamiUitOpen | 4:76aa20fb326a | 56 | { |
MikamiUitOpen | 4:76aa20fb326a | 57 | bool changed = (lpHp != lp_) ? true : false; |
MikamiUitOpen | 4:76aa20fb326a | 58 | bool tch = tp_->IsTouched(cursorX_, cursorX_); |
MikamiUitOpen | 4:76aa20fb326a | 59 | if (tch || changed) |
MikamiUitOpen | 4:76aa20fb326a | 60 | { |
MikamiUitOpen | 4:76aa20fb326a | 61 | int newFc = Frq10(drawerObj_->PosToFrq(cursorX_)); |
MikamiUitOpen | 4:76aa20fb326a | 62 | newFc = (newFc > HIGHER_F_) ? HIGHER_F_ : newFc; |
MikamiUitOpen | 4:76aa20fb326a | 63 | if ((abs(newFc - fC_) >= 10) || changed) |
MikamiUitOpen | 4:76aa20fb326a | 64 | { |
MikamiUitOpen | 4:76aa20fb326a | 65 | fC_ = newFc; |
MikamiUitOpen | 4:76aa20fb326a | 66 | lblFrq_->Draw("Cutoff frequency = %4d Hz", newFc); |
MikamiUitOpen | 4:76aa20fb326a | 67 | designObj_->Execute(newFc, lpHp, coefs_, g0_); |
MikamiUitOpen | 4:76aa20fb326a | 68 | GetCoefficients(ck, g0); |
MikamiUitOpen | 4:76aa20fb326a | 69 | |
MikamiUitOpen | 5:4a99dabc9180 | 70 | frqResp_.SetParams(ORDER_, g0_, ck_); |
MikamiUitOpen | 4:76aa20fb326a | 71 | drawerObj_->Erase(); |
MikamiUitOpen | 5:4a99dabc9180 | 72 | drawerObj_->DrawAxis(); // 目盛線の描画 |
MikamiUitOpen | 5:4a99dabc9180 | 73 | drawerObj_->DrawGraph(frqResp_); // 周波数特性のグラフのカーブを描画する |
MikamiUitOpen | 4:76aa20fb326a | 74 | |
MikamiUitOpen | 4:76aa20fb326a | 75 | if (tch) // カーソルの移動 |
MikamiUitOpen | 4:76aa20fb326a | 76 | { |
MikamiUitOpen | 4:76aa20fb326a | 77 | lcd_->SetTextColor(CURSOR_TOUCHED_COLOR_); |
MikamiUitOpen | 4:76aa20fb326a | 78 | lcd_->DrawVLine(cursorX_, CURSOR_Y0_, CURSOR_LENGTH_); |
MikamiUitOpen | 4:76aa20fb326a | 79 | } |
MikamiUitOpen | 4:76aa20fb326a | 80 | cursorRedraw_ = true; |
MikamiUitOpen | 4:76aa20fb326a | 81 | oldCursorX_ = cursorX_; |
MikamiUitOpen | 4:76aa20fb326a | 82 | lp_ = lpHp; |
MikamiUitOpen | 4:76aa20fb326a | 83 | return true; |
MikamiUitOpen | 4:76aa20fb326a | 84 | } |
MikamiUitOpen | 4:76aa20fb326a | 85 | } |
MikamiUitOpen | 4:76aa20fb326a | 86 | |
MikamiUitOpen | 4:76aa20fb326a | 87 | if (!tch && cursorRedraw_) // カーソルを元の色に戻す |
MikamiUitOpen | 4:76aa20fb326a | 88 | { |
MikamiUitOpen | 4:76aa20fb326a | 89 | lcd_->SetTextColor(CURSOR_COLOR_); |
MikamiUitOpen | 4:76aa20fb326a | 90 | lcd_->DrawVLine(oldCursorX_, CURSOR_Y0_, CURSOR_LENGTH_); |
MikamiUitOpen | 4:76aa20fb326a | 91 | cursorRedraw_ = false; |
MikamiUitOpen | 4:76aa20fb326a | 92 | } |
MikamiUitOpen | 4:76aa20fb326a | 93 | return false; |
MikamiUitOpen | 4:76aa20fb326a | 94 | } |
MikamiUitOpen | 4:76aa20fb326a | 95 | |
MikamiUitOpen | 4:76aa20fb326a | 96 | // 周波数特性の描画 |
MikamiUitOpen | 4:76aa20fb326a | 97 | void DesignerDrawer::DrawResponse() |
MikamiUitOpen | 4:76aa20fb326a | 98 | { |
MikamiUitOpen | 4:76aa20fb326a | 99 | lblFrq_->Draw("Cutoff frequency = %4d Hz", fC_); |
MikamiUitOpen | 5:4a99dabc9180 | 100 | DrawAxisNum(); // 目盛値の描画 |
MikamiUitOpen | 5:4a99dabc9180 | 101 | drawerObj_->DrawAxis(); // 目盛線の描画 |
MikamiUitOpen | 5:4a99dabc9180 | 102 | drawerObj_->DrawGraph(frqResp_); // 周波数特性のカーブの描画 |
MikamiUitOpen | 4:76aa20fb326a | 103 | |
MikamiUitOpen | 4:76aa20fb326a | 104 | cursorX_ = drawerObj_->X(fC_); |
MikamiUitOpen | 4:76aa20fb326a | 105 | lcd_->SetTextColor(CURSOR_COLOR_); |
MikamiUitOpen | 4:76aa20fb326a | 106 | lcd_->DrawVLine(cursorX_, CURSOR_Y0_, CURSOR_LENGTH_); |
MikamiUitOpen | 4:76aa20fb326a | 107 | } |
MikamiUitOpen | 4:76aa20fb326a | 108 | |
MikamiUitOpen | 4:76aa20fb326a | 109 | // フィルタ係数の取得 |
MikamiUitOpen | 4:76aa20fb326a | 110 | void DesignerDrawer::GetCoefficients(Biquad::Coefs *c, float &g0) |
MikamiUitOpen | 4:76aa20fb326a | 111 | { |
MikamiUitOpen | 4:76aa20fb326a | 112 | for (int k=0; k<ORDER_/2; k++) c[k] = ck_[k]; |
MikamiUitOpen | 4:76aa20fb326a | 113 | g0 = g0_; |
MikamiUitOpen | 4:76aa20fb326a | 114 | } |
MikamiUitOpen | 4:76aa20fb326a | 115 | |
MikamiUitOpen | 4:76aa20fb326a | 116 | // 周波数を 10, 20, 50, 100 Hz の倍数にする |
MikamiUitOpen | 4:76aa20fb326a | 117 | int DesignerDrawer::Frq10(float f) |
MikamiUitOpen | 4:76aa20fb326a | 118 | { |
MikamiUitOpen | 4:76aa20fb326a | 119 | if (f < 1000) |
MikamiUitOpen | 4:76aa20fb326a | 120 | return ((int)(f/10.0f + 0.5f))*10; |
MikamiUitOpen | 4:76aa20fb326a | 121 | if (f < 2000) |
MikamiUitOpen | 4:76aa20fb326a | 122 | return ((int)(f/20.0f + 0.5f))*20; |
MikamiUitOpen | 4:76aa20fb326a | 123 | if (f < 3000) |
MikamiUitOpen | 4:76aa20fb326a | 124 | return ((int)(f/50.0f + 0.5f))*50; |
MikamiUitOpen | 4:76aa20fb326a | 125 | else |
MikamiUitOpen | 4:76aa20fb326a | 126 | return ((int)(f/100.0f + 0.5f))*100; |
MikamiUitOpen | 4:76aa20fb326a | 127 | } |
MikamiUitOpen | 4:76aa20fb326a | 128 | |
MikamiUitOpen | 5:4a99dabc9180 | 129 | // 周波数特性の目盛値の描画 |
MikamiUitOpen | 4:76aa20fb326a | 130 | void DesignerDrawer::DrawAxisNum() |
MikamiUitOpen | 4:76aa20fb326a | 131 | { |
MikamiUitOpen | 4:76aa20fb326a | 132 | const int16_t OFS = 6; |
MikamiUitOpen | 4:76aa20fb326a | 133 | drawerObj_->DrawCharX(100, OFS, "0.1"); |
MikamiUitOpen | 4:76aa20fb326a | 134 | drawerObj_->DrawCharX(300, OFS, "0.3"); |
MikamiUitOpen | 4:76aa20fb326a | 135 | drawerObj_->DrawCharX(1000, OFS, "1.0"); |
MikamiUitOpen | 4:76aa20fb326a | 136 | drawerObj_->DrawCharX(3000, OFS, "3.0"); |
MikamiUitOpen | 4:76aa20fb326a | 137 | drawerObj_->DrawCharX(8000, OFS, "8.0"); |
MikamiUitOpen | 4:76aa20fb326a | 138 | |
MikamiUitOpen | 4:76aa20fb326a | 139 | Label l_frq(drawerObj_->X(900), Y0_+20, "Frequency [kHz]", |
MikamiUitOpen | 4:76aa20fb326a | 140 | Label::CENTER); |
MikamiUitOpen | 4:76aa20fb326a | 141 | drawerObj_->DrawNumericY(-24, -6, 4, 20, "%3d"); // 縦軸の目盛は 20 dB 間隔 |
MikamiUitOpen | 4:76aa20fb326a | 142 | Label l_dB(X0_-24, Y0_-DB10_*6-20, "[dB]"); |
MikamiUitOpen | 4:76aa20fb326a | 143 | } |
MikamiUitOpen | 4:76aa20fb326a | 144 | } |
MikamiUitOpen | 5:4a99dabc9180 | 145 |