Output the audio signal with filtering by IIR filter in the Quad-SPI flash memory using onboard CODEC. QSPI フラッシュメモリのオーディオデータを遮断周波数可変の IIR フィルタを通してボードに搭載されているCODEC で出力するプログラム.

Dependencies:   BSP_DISCO_F746NG_patch_fixed F746_GUI LCD_DISCO_F746NG QSPI_DISCO_F746NG TS_DISCO_F746NG mbed

Committer:
MikamiUitOpen
Date:
Fri Apr 01 05:03:20 2016 +0000
Revision:
0:2eb96a7cf9b9
1

Who changed what in which revision?

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