FrqRespDrawer class to draw frequency response for digital filter. ディジタルフィルタの周波数特性を,周波数軸をログスケールで描画するための FrqRespDrawer クラス. このライブラリを登録した際のプログラム:「F746_FrequencyResponseDrawer_Demo」
Dependents: F746_SD_WavPlayer F746_SD_GraphicEqualizer_ren0620 F746_FrequencyResponseDrawer_Demo F746_SD_VarableFilter ... more
FrquencyResponseDrawer.cpp@4:47c6cbdd8d77, 2017-03-16 (annotated)
- Committer:
- MikamiUitOpen
- Date:
- Thu Mar 16 08:47:52 2017 +0000
- Revision:
- 4:47c6cbdd8d77
- Parent:
- 2:8bccc97de938
5
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
MikamiUitOpen | 0:0bc63b49e2a3 | 1 | //------------------------------------------------------------------------ |
MikamiUitOpen | 0:0bc63b49e2a3 | 2 | // ディジタルフィルタの周波数特性を,周波数軸が対数スケールで描画するクラス |
MikamiUitOpen | 0:0bc63b49e2a3 | 3 | // FrqRespDrawer class |
MikamiUitOpen | 0:0bc63b49e2a3 | 4 | // |
MikamiUitOpen | 4:47c6cbdd8d77 | 5 | // 2017/03/16, Copyright (c) 2017 MIKAMI, Naoki |
MikamiUitOpen | 0:0bc63b49e2a3 | 6 | //------------------------------------------------------------------------ |
MikamiUitOpen | 0:0bc63b49e2a3 | 7 | |
MikamiUitOpen | 0:0bc63b49e2a3 | 8 | #include "FrquencyResponseDrawer.hpp" |
MikamiUitOpen | 0:0bc63b49e2a3 | 9 | |
MikamiUitOpen | 0:0bc63b49e2a3 | 10 | namespace Mikami |
MikamiUitOpen | 0:0bc63b49e2a3 | 11 | { |
MikamiUitOpen | 0:0bc63b49e2a3 | 12 | // 目盛線の描画 |
MikamiUitOpen | 0:0bc63b49e2a3 | 13 | void FrqRespDrawer::DrawAxis() |
MikamiUitOpen | 0:0bc63b49e2a3 | 14 | { |
MikamiUitOpen | 0:0bc63b49e2a3 | 15 | uint16_t height = DB1_*(MAX_DB_ - MIN_DB_); |
MikamiUitOpen | 0:0bc63b49e2a3 | 16 | int logMin = (int)floorf(log10f(MIN_)); |
MikamiUitOpen | 0:0bc63b49e2a3 | 17 | int loop = (int)floorf(log10f(MAX_)) - logMin; |
MikamiUitOpen | 0:0bc63b49e2a3 | 18 | |
MikamiUitOpen | 4:47c6cbdd8d77 | 19 | lcd_.SetTextColor(AXIS_COLOR_); |
MikamiUitOpen | 0:0bc63b49e2a3 | 20 | uint16_t y0 = ORGY_ - height; |
MikamiUitOpen | 4:47c6cbdd8d77 | 21 | lcd_.DrawVLine(X(MIN_), y0, height); // 最小値に対応する線 |
MikamiUitOpen | 0:0bc63b49e2a3 | 22 | |
MikamiUitOpen | 0:0bc63b49e2a3 | 23 | float du = powf(10.0, logMin); // 座標値の増分 |
MikamiUitOpen | 0:0bc63b49e2a3 | 24 | float u1 = (floorf(MIN_/du) + 1.0f)*du; // 最小値に対応する線の次の座標値 |
MikamiUitOpen | 0:0bc63b49e2a3 | 25 | |
MikamiUitOpen | 0:0bc63b49e2a3 | 26 | for (int n=0; n<=loop; n++) |
MikamiUitOpen | 0:0bc63b49e2a3 | 27 | { |
MikamiUitOpen | 0:0bc63b49e2a3 | 28 | float uMax = (10.0f*du < MAX_) ? 10.0f*du : MAX_; |
MikamiUitOpen | 0:0bc63b49e2a3 | 29 | for (float u=u1; u<uMax*0.99f; u+=du) |
MikamiUitOpen | 4:47c6cbdd8d77 | 30 | lcd_.DrawVLine(X(u), y0, height); |
MikamiUitOpen | 0:0bc63b49e2a3 | 31 | |
MikamiUitOpen | 0:0bc63b49e2a3 | 32 | du = uMax; // 値の増分を 10 倍する |
MikamiUitOpen | 0:0bc63b49e2a3 | 33 | u1 = du; // 次の for ループ の最初の値 |
MikamiUitOpen | 0:0bc63b49e2a3 | 34 | } |
MikamiUitOpen | 0:0bc63b49e2a3 | 35 | |
MikamiUitOpen | 4:47c6cbdd8d77 | 36 | lcd_.DrawVLine(X(MAX_), y0, height); // 最大値に対応する線 |
MikamiUitOpen | 0:0bc63b49e2a3 | 37 | |
MikamiUitOpen | 0:0bc63b49e2a3 | 38 | uint16_t width = X(MAX_) - X(MIN_); |
MikamiUitOpen | 0:0bc63b49e2a3 | 39 | int count = Round((MAX_DB_ - MIN_DB_)/(Y_SPACE_/DB1_)); |
MikamiUitOpen | 0:0bc63b49e2a3 | 40 | for (int n=0; n<= count; n++) |
MikamiUitOpen | 4:47c6cbdd8d77 | 41 | lcd_.DrawHLine(X(MIN_), Round(ORGY_-Y_SPACE_*n), width); |
MikamiUitOpen | 0:0bc63b49e2a3 | 42 | } |
MikamiUitOpen | 0:0bc63b49e2a3 | 43 | |
MikamiUitOpen | 0:0bc63b49e2a3 | 44 | // 横軸の目盛値の表示 |
MikamiUitOpen | 0:0bc63b49e2a3 | 45 | void FrqRespDrawer::DrawNumericX(AxisX_Char xChar[], int nDisp, int offsetY, |
MikamiUitOpen | 0:0bc63b49e2a3 | 46 | string str, sFONT &fonts, uint32_t textColor) |
MikamiUitOpen | 0:0bc63b49e2a3 | 47 | { |
MikamiUitOpen | 0:0bc63b49e2a3 | 48 | for (int n=0; n<nDisp; n++) |
MikamiUitOpen | 0:0bc63b49e2a3 | 49 | Label frq(X(xChar[n].frq), ORGY_+offsetY, |
MikamiUitOpen | 0:0bc63b49e2a3 | 50 | xChar[n].str, Label::CENTER); |
MikamiUitOpen | 0:0bc63b49e2a3 | 51 | uint16_t x0 = ORGX_ + (uint16_t)(DEC_*log10f(MAX_/MIN_))/2; |
MikamiUitOpen | 0:0bc63b49e2a3 | 52 | Label l_frq(x0, ORGY_+20, str, Label::CENTER); |
MikamiUitOpen | 0:0bc63b49e2a3 | 53 | } |
MikamiUitOpen | 0:0bc63b49e2a3 | 54 | |
MikamiUitOpen | 0:0bc63b49e2a3 | 55 | // 縦軸の目盛値の表示 |
MikamiUitOpen | 0:0bc63b49e2a3 | 56 | void FrqRespDrawer::DrawNumericY(int offsetX, int offsetY, uint16_t d_dB, |
MikamiUitOpen | 0:0bc63b49e2a3 | 57 | const char fmt[], sFONT &fonts, |
MikamiUitOpen | 0:0bc63b49e2a3 | 58 | uint32_t textColor, string str) |
MikamiUitOpen | 0:0bc63b49e2a3 | 59 | { |
MikamiUitOpen | 0:0bc63b49e2a3 | 60 | uint16_t x0 = ORGX_ + offsetX; |
MikamiUitOpen | 0:0bc63b49e2a3 | 61 | uint16_t y0 = ORGY_ + offsetY; |
MikamiUitOpen | 0:0bc63b49e2a3 | 62 | int count = Round((MAX_DB_ - MIN_DB_)/d_dB); |
MikamiUitOpen | 0:0bc63b49e2a3 | 63 | |
MikamiUitOpen | 0:0bc63b49e2a3 | 64 | for (int n=0; n<=count; n++) |
MikamiUitOpen | 0:0bc63b49e2a3 | 65 | NumericLabel<int> num(x0, y0-n*d_dB*DB1_, |
MikamiUitOpen | 0:0bc63b49e2a3 | 66 | fmt, (int)(MIN_DB_+d_dB*n)); |
MikamiUitOpen | 1:19a32f6279e6 | 67 | Label l_dB(x0-2, y0-count*d_dB*DB1_-12, str); |
MikamiUitOpen | 0:0bc63b49e2a3 | 68 | } |
MikamiUitOpen | 0:0bc63b49e2a3 | 69 | |
MikamiUitOpen | 0:0bc63b49e2a3 | 70 | // 周波数特性のグラフの描画 |
MikamiUitOpen | 2:8bccc97de938 | 71 | void FrqRespDrawer::DrawGraph(FrequencyResponse &frqResp, uint32_t color) |
MikamiUitOpen | 0:0bc63b49e2a3 | 72 | { |
MikamiUitOpen | 4:47c6cbdd8d77 | 73 | lcd_.SetTextColor(color); |
MikamiUitOpen | 0:0bc63b49e2a3 | 74 | uint16_t width = X(MAX_) - X(MIN_); |
MikamiUitOpen | 0:0bc63b49e2a3 | 75 | uint16_t x1 = 0; |
MikamiUitOpen | 0:0bc63b49e2a3 | 76 | uint16_t y1 = 0; |
MikamiUitOpen | 0:0bc63b49e2a3 | 77 | float pi2FsM = -6.283185f/FS_; // -2*PI*Ts |
MikamiUitOpen | 0:0bc63b49e2a3 | 78 | for (int n=0; n<=width; n++) |
MikamiUitOpen | 0:0bc63b49e2a3 | 79 | { |
MikamiUitOpen | 0:0bc63b49e2a3 | 80 | float frq = PosToFrq(n+ORGX_); |
MikamiUitOpen | 0:0bc63b49e2a3 | 81 | uint16_t x2 = X(frq); |
MikamiUitOpen | 2:8bccc97de938 | 82 | float absHz = frqResp.AbsH_z(exp(Complex(0, pi2FsM*frq))); |
MikamiUitOpen | 0:0bc63b49e2a3 | 83 | float dB = (absHz > 0.001f) ? 20.0f*log10f(absHz) : MIN_DB_; |
MikamiUitOpen | 0:0bc63b49e2a3 | 84 | uint16_t y2 = ORGY_ - Round((dB - MIN_DB_)*DB1_); |
MikamiUitOpen | 0:0bc63b49e2a3 | 85 | if (y2 > ORGY_) y2 = ORGY_; |
MikamiUitOpen | 0:0bc63b49e2a3 | 86 | |
MikamiUitOpen | 4:47c6cbdd8d77 | 87 | if (n != 0) lcd_.DrawLine(x1, y1, x2, y2); |
MikamiUitOpen | 0:0bc63b49e2a3 | 88 | |
MikamiUitOpen | 0:0bc63b49e2a3 | 89 | x1 = x2; |
MikamiUitOpen | 0:0bc63b49e2a3 | 90 | y1 = y2; |
MikamiUitOpen | 0:0bc63b49e2a3 | 91 | } |
MikamiUitOpen | 4:47c6cbdd8d77 | 92 | lcd_.SetTextColor(AXIS_COLOR_); |
MikamiUitOpen | 4:47c6cbdd8d77 | 93 | lcd_.DrawHLine(X(MIN_), ORGY_, width+1); |
MikamiUitOpen | 0:0bc63b49e2a3 | 94 | } |
MikamiUitOpen | 0:0bc63b49e2a3 | 95 | |
MikamiUitOpen | 0:0bc63b49e2a3 | 96 | // 消去 |
MikamiUitOpen | 0:0bc63b49e2a3 | 97 | void FrqRespDrawer::Erase(float upDb) |
MikamiUitOpen | 0:0bc63b49e2a3 | 98 | { |
MikamiUitOpen | 4:47c6cbdd8d77 | 99 | lcd_.SetTextColor(BACK_COLOR_); |
MikamiUitOpen | 0:0bc63b49e2a3 | 100 | uint16_t height = DB1_*(MAX_DB_+upDb - MIN_DB_); |
MikamiUitOpen | 4:47c6cbdd8d77 | 101 | lcd_.FillRect(ORGX_, ORGY_- height, X(MAX_)-X(MIN_)+1, height+1); |
MikamiUitOpen | 0:0bc63b49e2a3 | 102 | } |
MikamiUitOpen | 0:0bc63b49e2a3 | 103 | } |