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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers FrquencyResponseDrawer.cpp Source File

FrquencyResponseDrawer.cpp

00001 //------------------------------------------------------------------------
00002 //  ディジタルフィルタの周波数特性を,周波数軸が対数スケールで描画するクラス
00003 //  FrqRespDrawer class
00004 //
00005 //  2017/03/16, Copyright (c) 2017 MIKAMI, Naoki
00006 //------------------------------------------------------------------------
00007 
00008 #include "FrquencyResponseDrawer.hpp"
00009 
00010 namespace Mikami
00011 {
00012     // 目盛線の描画
00013     void FrqRespDrawer::DrawAxis()
00014     {
00015         uint16_t height = DB1_*(MAX_DB_ - MIN_DB_);
00016         int logMin = (int)floorf(log10f(MIN_));
00017         int loop = (int)floorf(log10f(MAX_)) - logMin;
00018 
00019         lcd_.SetTextColor(AXIS_COLOR_);
00020         uint16_t y0 = ORGY_ - height;
00021         lcd_.DrawVLine(X(MIN_), y0, height);   // 最小値に対応する線
00022 
00023         float du = powf(10.0, logMin);          // 座標値の増分
00024         float u1 = (floorf(MIN_/du) + 1.0f)*du; // 最小値に対応する線の次の座標値
00025 
00026         for (int n=0; n<=loop; n++)
00027         {
00028             float uMax = (10.0f*du < MAX_) ? 10.0f*du : MAX_;
00029             for (float u=u1; u<uMax*0.99f; u+=du)
00030                 lcd_.DrawVLine(X(u), y0, height);
00031 
00032             du = uMax;          // 値の増分を 10 倍する
00033             u1 = du;            // 次の for ループ の最初の値
00034         }
00035 
00036         lcd_.DrawVLine(X(MAX_), y0, height);   // 最大値に対応する線
00037         
00038         uint16_t width = X(MAX_) - X(MIN_);
00039         int count = Round((MAX_DB_ - MIN_DB_)/(Y_SPACE_/DB1_));
00040         for (int n=0; n<= count; n++)
00041             lcd_.DrawHLine(X(MIN_), Round(ORGY_-Y_SPACE_*n), width);
00042     }
00043 
00044     // 横軸の目盛値の表示
00045     void FrqRespDrawer::DrawNumericX(AxisX_Char xChar[], int nDisp, int offsetY,
00046                                      string str, sFONT &fonts, uint32_t textColor)
00047     {
00048         for (int n=0; n<nDisp; n++)
00049             Label frq(X(xChar[n].frq), ORGY_+offsetY,
00050                         xChar[n].str, Label::CENTER);
00051         uint16_t x0 = ORGX_ + (uint16_t)(DEC_*log10f(MAX_/MIN_))/2;
00052         Label l_frq(x0, ORGY_+20, str, Label::CENTER);
00053     }
00054 
00055     // 縦軸の目盛値の表示
00056     void FrqRespDrawer::DrawNumericY(int offsetX, int offsetY, uint16_t d_dB,
00057                                      const char fmt[], sFONT &fonts,
00058                                      uint32_t textColor, string str)
00059     {
00060         uint16_t x0 = ORGX_ + offsetX;
00061         uint16_t y0 = ORGY_ + offsetY;
00062         int count = Round((MAX_DB_ - MIN_DB_)/d_dB);
00063 
00064         for (int n=0; n<=count; n++)
00065             NumericLabel<int> num(x0, y0-n*d_dB*DB1_,
00066                                   fmt, (int)(MIN_DB_+d_dB*n));
00067         Label l_dB(x0-2, y0-count*d_dB*DB1_-12, str);
00068     }
00069 
00070     // 周波数特性のグラフの描画
00071     void FrqRespDrawer::DrawGraph(FrequencyResponse &frqResp, uint32_t color)
00072     {
00073         lcd_.SetTextColor(color);
00074         uint16_t width = X(MAX_) - X(MIN_);   
00075         uint16_t x1 = 0;
00076         uint16_t y1 = 0;
00077         float pi2FsM = -6.283185f/FS_;  // -2*PI*Ts
00078         for (int n=0; n<=width; n++)
00079         {
00080             float frq = PosToFrq(n+ORGX_);
00081             uint16_t x2 = X(frq);
00082             float absHz = frqResp.AbsH_z(exp(Complex(0, pi2FsM*frq)));
00083             float dB = (absHz > 0.001f) ? 20.0f*log10f(absHz) : MIN_DB_;
00084             uint16_t y2 = ORGY_ - Round((dB - MIN_DB_)*DB1_);
00085             if (y2 > ORGY_) y2 = ORGY_;
00086 
00087             if (n != 0) lcd_.DrawLine(x1, y1, x2, y2);
00088 
00089             x1 = x2;
00090             y1 = y2;
00091         }
00092         lcd_.SetTextColor(AXIS_COLOR_);
00093         lcd_.DrawHLine(X(MIN_), ORGY_, width+1);
00094     }
00095 
00096     // 消去
00097     void FrqRespDrawer::Erase(float upDb)
00098     {
00099         lcd_.SetTextColor(BACK_COLOR_);
00100         uint16_t height = DB1_*(MAX_DB_+upDb - MIN_DB_);
00101         lcd_.FillRect(ORGX_, ORGY_- height, X(MAX_)-X(MIN_)+1, height+1);
00102     }
00103 }