Final version.
Dependencies: F746_GUI F746_SAI_IO UIT_FFT_Real
Fork of F746_Spectrogram by
MySpectrogram/MethodCollection.hpp@9:444e58089d09, 2017-08-30 (annotated)
- Committer:
- mladjo1993
- Date:
- Wed Aug 30 07:47:58 2017 +0000
- Revision:
- 9:444e58089d09
- Parent:
- 8:99d57d6e0ea1
Final version.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mladjo1993 | 7:23b60827582d | 1 | /******************************************************** |
mladjo1993 | 7:23b60827582d | 2 | * Global function used in spectrogram |
mladjo1993 | 7:23b60827582d | 3 | * |
mladjo1993 | 7:23b60827582d | 4 | * Mladen Adamovic, 3326/2016 |
mladjo1993 | 7:23b60827582d | 5 | *******************************************************/ |
MikamiUitOpen | 0:9470a174c910 | 6 | |
MikamiUitOpen | 0:9470a174c910 | 7 | #ifndef METHOD_COLLECTION_HPP |
MikamiUitOpen | 0:9470a174c910 | 8 | #define METHOD_COLLECTION_HPP |
MikamiUitOpen | 0:9470a174c910 | 9 | |
MikamiUitOpen | 0:9470a174c910 | 10 | #include "mbed.h" |
MikamiUitOpen | 0:9470a174c910 | 11 | #include "NumericLabel.hpp" |
MikamiUitOpen | 0:9470a174c910 | 12 | #include "Matrix.hpp" |
MikamiUitOpen | 0:9470a174c910 | 13 | #include "FFT_Analysis.hpp" |
MikamiUitOpen | 0:9470a174c910 | 14 | |
mladjo1993 | 8:99d57d6e0ea1 | 15 | namespace etf |
MikamiUitOpen | 0:9470a174c910 | 16 | { |
mladjo1993 | 7:23b60827582d | 17 | // Convert intensity to hue difference |
MikamiUitOpen | 0:9470a174c910 | 18 | // 0.0 <= x <= 1.0 |
MikamiUitOpen | 0:9470a174c910 | 19 | uint32_t HueScale(float x) |
MikamiUitOpen | 0:9470a174c910 | 20 | { |
MikamiUitOpen | 6:b3885567877c | 21 | if (x > 1) return LCD_COLOR_WHITE; |
MikamiUitOpen | 0:9470a174c910 | 22 | int r = 0; |
MikamiUitOpen | 0:9470a174c910 | 23 | int b = 0; |
MikamiUitOpen | 0:9470a174c910 | 24 | |
MikamiUitOpen | 0:9470a174c910 | 25 | if (x<0.5f) b = (x<0.33f) ? 255 : -(int)(1500.0f*x) + 750; |
MikamiUitOpen | 0:9470a174c910 | 26 | else r = (0.67f<x) ? 255 : (int)(1500.0f*x) - 750; |
MikamiUitOpen | 0:9470a174c910 | 27 | int g = 255 - (int)(1020.0f*(x - 0.5f)*(x - 0.5f)); |
MikamiUitOpen | 0:9470a174c910 | 28 | |
MikamiUitOpen | 0:9470a174c910 | 29 | return 0xFF000000 | (((r << 8) | g) << 8) | b; |
MikamiUitOpen | 0:9470a174c910 | 30 | } |
mladjo1993 | 8:99d57d6e0ea1 | 31 | |
mladjo1993 | 8:99d57d6e0ea1 | 32 | // Clear axis |
mladjo1993 | 8:99d57d6e0ea1 | 33 | void ClearAxis(int x0, int y0, LCD_DISCO_F746NG &lcd) |
mladjo1993 | 8:99d57d6e0ea1 | 34 | { |
mladjo1993 | 8:99d57d6e0ea1 | 35 | lcd.SetTextColor(GuiBase::ENUM_BACK); |
mladjo1993 | 8:99d57d6e0ea1 | 36 | lcd.FillRect(x0-30,y0-180, 430, 215); |
mladjo1993 | 8:99d57d6e0ea1 | 37 | } |
MikamiUitOpen | 0:9470a174c910 | 38 | |
mladjo1993 | 8:99d57d6e0ea1 | 39 | // Coordinate axis for 2D view |
mladjo1993 | 8:99d57d6e0ea1 | 40 | void DrawAxis2D(int x0, int y0, int w0, int h0, uint32_t axisColor, |
mladjo1993 | 8:99d57d6e0ea1 | 41 | float hz100, uint16_t px20dB, LCD_DISCO_F746NG &lcd) |
mladjo1993 | 8:99d57d6e0ea1 | 42 | { |
mladjo1993 | 8:99d57d6e0ea1 | 43 | |
mladjo1993 | 8:99d57d6e0ea1 | 44 | |
mladjo1993 | 8:99d57d6e0ea1 | 45 | const uint16_t TICK = 5; // Length of graduation line |
mladjo1993 | 8:99d57d6e0ea1 | 46 | |
mladjo1993 | 8:99d57d6e0ea1 | 47 | ClearAxis(x0, y0, lcd); |
mladjo1993 | 8:99d57d6e0ea1 | 48 | lcd.SetTextColor(axisColor); |
mladjo1993 | 8:99d57d6e0ea1 | 49 | |
mladjo1993 | 8:99d57d6e0ea1 | 50 | // Transverse axis |
mladjo1993 | 8:99d57d6e0ea1 | 51 | lcd.DrawHLine(x0, y0+TICK, w0); |
mladjo1993 | 8:99d57d6e0ea1 | 52 | for (int n=0; n<=60; n++) |
mladjo1993 | 8:99d57d6e0ea1 | 53 | if ((n % 10)== 0) lcd.DrawVLine(x0+n*hz100, y0, 5); |
mladjo1993 | 8:99d57d6e0ea1 | 54 | else lcd.DrawVLine(x0+n*hz100, y0+3, 2); |
mladjo1993 | 8:99d57d6e0ea1 | 55 | for (int n=0; n<=60; n+=10) |
mladjo1993 | 8:99d57d6e0ea1 | 56 | NumericLabel<int> num(x0+n*hz100, y0+TICK+3, |
mladjo1993 | 8:99d57d6e0ea1 | 57 | "%1d", (int)(n*0.1f), Label::CENTER); |
mladjo1993 | 8:99d57d6e0ea1 | 58 | Label frequency(x0+w0/2, y0+22, "FREQUENCY [kHz]", Label::CENTER); |
mladjo1993 | 8:99d57d6e0ea1 | 59 | |
mladjo1993 | 8:99d57d6e0ea1 | 60 | // Vertical axis |
mladjo1993 | 8:99d57d6e0ea1 | 61 | lcd.DrawVLine(x0-TICK, y0-h0, h0); |
mladjo1993 | 8:99d57d6e0ea1 | 62 | for (int n=0; n<=h0/px20dB; n++) |
mladjo1993 | 8:99d57d6e0ea1 | 63 | lcd.DrawHLine(x0-TICK, y0-n*px20dB, TICK); |
mladjo1993 | 8:99d57d6e0ea1 | 64 | for (int n=0; n<=h0/px20dB; n++) |
mladjo1993 | 8:99d57d6e0ea1 | 65 | if (n == 0) |
mladjo1993 | 8:99d57d6e0ea1 | 66 | NumericLabel<int> num(x0-TICK-12, y0-n*px20dB-5, "%1d", n*20); |
mladjo1993 | 8:99d57d6e0ea1 | 67 | else if( n > 0 && n < 5) |
mladjo1993 | 8:99d57d6e0ea1 | 68 | NumericLabel<int> num(x0-TICK-19, y0-n*px20dB-5, "%1d", n*20); |
mladjo1993 | 8:99d57d6e0ea1 | 69 | else |
mladjo1993 | 8:99d57d6e0ea1 | 70 | NumericLabel<int> num(x0-TICK-26, y0-n*px20dB-5, "%1d", n*20); |
mladjo1993 | 8:99d57d6e0ea1 | 71 | Label db(x0-27, y0-8*px20dB-20, "[dB]"); |
mladjo1993 | 8:99d57d6e0ea1 | 72 | } |
mladjo1993 | 8:99d57d6e0ea1 | 73 | |
mladjo1993 | 8:99d57d6e0ea1 | 74 | // Coordinate axis for 3D view |
mladjo1993 | 8:99d57d6e0ea1 | 75 | void DrawAxis3D(int x0, int y0, int w0, int h0, uint32_t axisColor, |
MikamiUitOpen | 5:c0877670b0ac | 76 | uint16_t ms100, uint16_t px1kHz, LCD_DISCO_F746NG &lcd) |
MikamiUitOpen | 0:9470a174c910 | 77 | { |
mladjo1993 | 8:99d57d6e0ea1 | 78 | |
mladjo1993 | 8:99d57d6e0ea1 | 79 | |
mladjo1993 | 7:23b60827582d | 80 | const uint16_t TICK = 5; // Length of graduation line |
mladjo1993 | 8:99d57d6e0ea1 | 81 | |
mladjo1993 | 8:99d57d6e0ea1 | 82 | ClearAxis(x0, y0, lcd); |
MikamiUitOpen | 6:b3885567877c | 83 | lcd.SetTextColor(axisColor); |
MikamiUitOpen | 6:b3885567877c | 84 | |
mladjo1993 | 7:23b60827582d | 85 | // Transverse axis |
MikamiUitOpen | 5:c0877670b0ac | 86 | lcd.DrawHLine(x0, y0+TICK, w0); |
MikamiUitOpen | 0:9470a174c910 | 87 | for (int n=0; n<=w0/ms100; n++) |
MikamiUitOpen | 5:c0877670b0ac | 88 | if ((n % 10)== 0) lcd.DrawVLine(x0+n*ms100, y0, 5); |
MikamiUitOpen | 5:c0877670b0ac | 89 | else lcd.DrawVLine(x0+n*ms100, y0+3, 2); |
MikamiUitOpen | 0:9470a174c910 | 90 | for (int n=0; n<=w0/ms100; n+=10) |
MikamiUitOpen | 0:9470a174c910 | 91 | NumericLabel<int> num(x0+n*ms100, y0+TICK+3, |
MikamiUitOpen | 0:9470a174c910 | 92 | "%1d", (int)(n*0.1f), Label::CENTER); |
MikamiUitOpen | 0:9470a174c910 | 93 | Label time(x0+w0/2, y0+22, "TIME [s]", Label::CENTER); |
MikamiUitOpen | 6:b3885567877c | 94 | |
mladjo1993 | 7:23b60827582d | 95 | // Vertical axis |
MikamiUitOpen | 5:c0877670b0ac | 96 | lcd.DrawVLine(x0-TICK, y0-h0, h0); |
MikamiUitOpen | 0:9470a174c910 | 97 | for (int n=0; n<=h0/px1kHz; n++) |
MikamiUitOpen | 5:c0877670b0ac | 98 | lcd.DrawHLine(x0-TICK, y0-n*px1kHz, TICK); |
MikamiUitOpen | 0:9470a174c910 | 99 | for (int n=0; n<=h0/px1kHz; n++) |
MikamiUitOpen | 0:9470a174c910 | 100 | NumericLabel<int> num(x0-TICK-12, y0-n*px1kHz-5, "%1d", n); |
MikamiUitOpen | 0:9470a174c910 | 101 | Label hz(x0-32, y0-5*px1kHz-20, "[kHz]"); |
MikamiUitOpen | 0:9470a174c910 | 102 | } |
MikamiUitOpen | 0:9470a174c910 | 103 | |
mladjo1993 | 7:23b60827582d | 104 | // Display of relationship between color and dB |
mladjo1993 | 8:99d57d6e0ea1 | 105 | void DrawColorDb(int y0, uint32_t axisColor, LCD_DISCO_F746NG &lcd) |
MikamiUitOpen | 0:9470a174c910 | 106 | { |
MikamiUitOpen | 5:c0877670b0ac | 107 | lcd.SetTextColor(axisColor); |
MikamiUitOpen | 5:c0877670b0ac | 108 | lcd.DrawVLine(455, y0-100, 100); |
MikamiUitOpen | 0:9470a174c910 | 109 | for (int n=0; n<=8; n++) |
MikamiUitOpen | 5:c0877670b0ac | 110 | lcd.DrawHLine(455, y0-(n*100)/8, 4); |
MikamiUitOpen | 0:9470a174c910 | 111 | for (int n=0; n<=4; n++) |
MikamiUitOpen | 0:9470a174c910 | 112 | NumericLabel<int> num(440, y0-(n*100)/4-5, "%2d", n*20); |
MikamiUitOpen | 0:9470a174c910 | 113 | Label dB(432, y0-120, "[dB]"); |
MikamiUitOpen | 0:9470a174c910 | 114 | |
MikamiUitOpen | 6:b3885567877c | 115 | for (int n=0; n<=101; n++) |
MikamiUitOpen | 0:9470a174c910 | 116 | { |
MikamiUitOpen | 5:c0877670b0ac | 117 | lcd.SetTextColor(HueScale(n/100.0f)); |
MikamiUitOpen | 5:c0877670b0ac | 118 | lcd.DrawHLine(460, y0-n, 16); |
MikamiUitOpen | 0:9470a174c910 | 119 | } |
MikamiUitOpen | 0:9470a174c910 | 120 | } |
mladjo1993 | 8:99d57d6e0ea1 | 121 | |
mladjo1993 | 8:99d57d6e0ea1 | 122 | // Clear relationship between color and dB |
mladjo1993 | 8:99d57d6e0ea1 | 123 | void ClearColorDb(int y0, uint32_t axisColor, LCD_DISCO_F746NG &lcd) |
mladjo1993 | 8:99d57d6e0ea1 | 124 | { |
mladjo1993 | 8:99d57d6e0ea1 | 125 | lcd.SetTextColor(GuiBase::ENUM_BACK); |
mladjo1993 | 8:99d57d6e0ea1 | 126 | lcd.FillRect(432,y0-120, 45, 125); |
mladjo1993 | 8:99d57d6e0ea1 | 127 | } |
MikamiUitOpen | 0:9470a174c910 | 128 | |
mladjo1993 | 7:23b60827582d | 129 | // Spectrum update |
MikamiUitOpen | 0:9470a174c910 | 130 | void SpectrumUpdate(Matrix<uint32_t> &x, FftAnalyzer &analyzer, |
MikamiUitOpen | 0:9470a174c910 | 131 | const Array<float> &sn, const Array<float> &db) |
MikamiUitOpen | 0:9470a174c910 | 132 | { |
mladjo1993 | 7:23b60827582d | 133 | // One past spectra are shifted |
MikamiUitOpen | 0:9470a174c910 | 134 | for (int n=0; n<x.Rows()-1; n++) |
MikamiUitOpen | 0:9470a174c910 | 135 | for (int k=0; k<x.Cols(); k++) |
MikamiUitOpen | 0:9470a174c910 | 136 | x[n][k] = x[n+1][k]; |
MikamiUitOpen | 0:9470a174c910 | 137 | |
mladjo1993 | 7:23b60827582d | 138 | // New spectrum |
MikamiUitOpen | 0:9470a174c910 | 139 | analyzer.Execute(sn, db); |
mladjo1993 | 7:23b60827582d | 140 | const float FACTOR = 1.0f/80.0f; // Display range: 0 to 80 dB |
MikamiUitOpen | 0:9470a174c910 | 141 | for (int k=0; k<=x.Cols(); k++) |
MikamiUitOpen | 0:9470a174c910 | 142 | x[x.Rows()-1][k] = HueScale(FACTOR*((db[k] > 20) ? db[k]-20 : 0)); |
MikamiUitOpen | 0:9470a174c910 | 143 | } |
MikamiUitOpen | 0:9470a174c910 | 144 | |
mladjo1993 | 8:99d57d6e0ea1 | 145 | // Display 3D spectrum |
mladjo1993 | 8:99d57d6e0ea1 | 146 | void DisplaySpectrum3D(const Matrix<uint32_t> &x, int x0, int y0, |
MikamiUitOpen | 5:c0877670b0ac | 147 | int hBar, LCD_DISCO_F746NG &lcd) |
MikamiUitOpen | 0:9470a174c910 | 148 | { |
MikamiUitOpen | 0:9470a174c910 | 149 | for (int n=0; n<x.Rows(); n++) |
MikamiUitOpen | 0:9470a174c910 | 150 | for (int k=0; k<x.Cols(); k++) |
MikamiUitOpen | 0:9470a174c910 | 151 | { |
MikamiUitOpen | 5:c0877670b0ac | 152 | lcd.SetTextColor(x[n][k]); |
MikamiUitOpen | 5:c0877670b0ac | 153 | lcd.DrawHLine(x0+n*hBar, y0-k, hBar); |
MikamiUitOpen | 0:9470a174c910 | 154 | } |
MikamiUitOpen | 0:9470a174c910 | 155 | } |
mladjo1993 | 8:99d57d6e0ea1 | 156 | |
mladjo1993 | 8:99d57d6e0ea1 | 157 | // Display 2D spectrum |
mladjo1993 | 8:99d57d6e0ea1 | 158 | void DisplaySpectrum2D(const Array<float> &x, int x0, int y0, int w0, |
mladjo1993 | 8:99d57d6e0ea1 | 159 | int hBar, LCD_DISCO_F746NG &lcd) |
mladjo1993 | 8:99d57d6e0ea1 | 160 | { |
mladjo1993 | 8:99d57d6e0ea1 | 161 | for (int k=0; k<w0; k++) |
mladjo1993 | 8:99d57d6e0ea1 | 162 | { |
mladjo1993 | 8:99d57d6e0ea1 | 163 | lcd.SetTextColor(GuiBase::ENUM_BACK); |
mladjo1993 | 8:99d57d6e0ea1 | 164 | lcd.FillRect(x0+k*hBar, y0-160, hBar, 161); |
mladjo1993 | 8:99d57d6e0ea1 | 165 | lcd.SetTextColor(LCD_COLOR_WHITE); |
mladjo1993 | 8:99d57d6e0ea1 | 166 | lcd.DrawHLine(x0+k*hBar, y0-(unsigned int)(x[k]), hBar); |
mladjo1993 | 8:99d57d6e0ea1 | 167 | } |
mladjo1993 | 8:99d57d6e0ea1 | 168 | } |
mladjo1993 | 8:99d57d6e0ea1 | 169 | |
mladjo1993 | 8:99d57d6e0ea1 | 170 | // Clear display |
mladjo1993 | 8:99d57d6e0ea1 | 171 | void ClearDisplay(int x0, int y0, int width, int height, LCD_DISCO_F746NG &lcd) |
mladjo1993 | 8:99d57d6e0ea1 | 172 | { |
mladjo1993 | 8:99d57d6e0ea1 | 173 | lcd.SetTextColor(GuiBase::ENUM_BACK); |
mladjo1993 | 8:99d57d6e0ea1 | 174 | lcd.FillRect(x0, y0-height, width, height); |
mladjo1993 | 8:99d57d6e0ea1 | 175 | } |
MikamiUitOpen | 0:9470a174c910 | 176 | } |
MikamiUitOpen | 0:9470a174c910 | 177 | #endif // METHOD_COLLECTION_HPP |