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
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 }
Generated on Thu Jul 21 2022 23:30:51 by 1.7.2