Real-time spectrum analyzer for ST Nucleo F401RE using Seeed Studio 2.8'' TFT Touch Shield V2.0.
Dependencies: SeeedStudioTFTv2 UITDSP_ADDA UIT_FFT_Real mbed
Revision 0:c5b026c2d07e, committed 2015-07-26
- Comitter:
- MikamiUitOpen
- Date:
- Sun Jul 26 02:48:23 2015 +0000
- Commit message:
- 1
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SeeedStudioTFTv2.lib Sun Jul 26 02:48:23 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/teams/components/code/SeeedStudioTFTv2/#362765fdf287
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SpactrumAnalysisClasses/FFT_Analysis.cpp Sun Jul 26 02:48:23 2015 +0000
@@ -0,0 +1,51 @@
+//-------------------------------------------------------
+// Class for spectrum analysis using FFT
+// Copyright (c) 2014 MIKAMI, Naoki, 2014/12/30
+//-------------------------------------------------------
+
+#include "FFT_Analysis.hpp"
+
+namespace Mikami
+{
+ FftAnalyzer::FftAnalyzer(int nData, int nFft)
+ : N_DATA_(nData), N_FFT_(nFft),
+ hm_(nData-1, nFft), fft_(nFft)
+ {
+ pkHolder_ = new PeakHolder[nFft/2+1];
+ for (int n=0; n<=nFft/2; n++)
+ pkHolder_[n].SetCoefs(0.2f);
+
+ xData = new float[nData]; // Data to be analyzed
+ xFft = new float[nFft]; // Input for FFT
+ yFft = new Complex[nFft/2+1]; // Output of FFT
+ normY = new float[nFft/2+1]; // Powerspectrum
+ }
+
+ FftAnalyzer::~FftAnalyzer()
+ {
+ delete[] pkHolder_;
+ delete[] xData;
+ delete[] xFft;
+ delete[] yFft;
+ delete[] normY;
+ }
+
+ void FftAnalyzer::Execute(float xn[], float db[])
+ {
+ // Differencing
+ for (int n=0; n<N_DATA_-1; n++)
+ xData[n] = xn[n+1] - xn[n];
+
+ hm_.Execute(xData, xFft); // Windowing and zero-padding
+ fft_.Execute(xFft, yFft); // Execute FFT
+
+ // Smoothing
+ for (int n=0; n<=N_FFT_/2; n++)
+ normY[n] = pkHolder_[n].Execute(Sqr(yFft[n].real())
+ + Sqr(yFft[n].imag()));
+
+ // Translate to dB
+ for (int n=0; n<=N_FFT_/2; n++)
+ db[n] = 10.0f*log10f(normY[n]);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SpactrumAnalysisClasses/FFT_Analysis.hpp Sun Jul 26 02:48:23 2015 +0000
@@ -0,0 +1,39 @@
+//-------------------------------------------------------
+// Class for spectrum analysis using FFT (Header)
+// Copyright (c) 2014 MIKAMI, Naoki, 2014/12/30
+//-------------------------------------------------------
+
+#ifndef FFT_ANALYZER_HPP
+#define FFT_ANALYZER_HPP
+
+#include "fftReal.hpp"
+#include "Hamming.hpp"
+#include "PeakHolder.hpp"
+
+namespace Mikami
+{
+ class FftAnalyzer
+ {
+ public:
+ FftAnalyzer(int nData, int nFft);
+ ~FftAnalyzer();
+ void Execute(float xn[], float db[]);
+
+ private:
+ const int N_DATA_;
+ const int N_FFT_;
+
+ HammingWindow hm_;
+ FftReal fft_;
+ PeakHolder* pkHolder_;
+
+ float* xData; // Data to be analyzed
+ float* xFft; // Input for FFT
+ Complex* yFft; // Output of FFT
+ float* normY; // Powerspectrum
+
+ float Sqr(float x) { return x*x; }
+ };
+}
+
+#endif // FFT_ANALYZER_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SpactrumAnalysisClasses/Hamming.hpp Sun Jul 26 02:48:23 2015 +0000
@@ -0,0 +1,44 @@
+//-------------------------------------------------------------------
+// Hamming windowing with zero-padding
+// Copyright (c) 2014 MIKAMI, Naoki, 2014/12/21
+//-------------------------------------------------------------------
+
+#ifndef HAMMING_WINDOW_HPP
+#define HAMMING_WINDOW_HPP
+
+#include "mbed.h"
+
+namespace Mikami
+{
+ class HammingWindow
+ {
+ private:
+ const int N_;
+ const int NFFT_;
+
+ float* w_;
+
+ public:
+ // Constructor
+ HammingWindow(uint16_t nData, uint16_t nFft)
+ : N_(nData), NFFT_(nFft)
+ {
+ w_ = new float[nData];
+ float pi2L = 6.283185f/(float)nData;
+ for (int k=0; k<nData; k++)
+ w_[k] = 0.54f - 0.46f*cosf(k*pi2L);
+ }
+
+ // Destructor
+ ~HammingWindow() {delete[] w_;}
+
+ // Windowing
+ void Execute(const float x[], float y[])
+ {
+ for (int n=0; n<N_; n++) y[n] = x[n]*w_[n];
+ for (int n=N_; n<NFFT_; n++) y[n] = 0;
+ }
+ };
+}
+#endif // HAMMING_WINDOW_HPP
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SpactrumAnalysisClasses/LPC_Analysis.cpp Sun Jul 26 02:48:23 2015 +0000
@@ -0,0 +1,62 @@
+//-------------------------------------------------------
+// Class for spectrum analysis using linear prediction
+// Copyright (c) 2014 MIKAMI, Naoki, 2014/12/30
+//-------------------------------------------------------
+
+#include "LPC_Analysis.hpp"
+
+namespace Mikami
+{
+ LpcAnalyzer::LpcAnalyzer(int nData, int order, int nFft)
+ : N_DATA_(nData), ORDER_(order), N_FFT_(nFft),
+ hm_(nData-1, nData-1), lp_(nData-1, order),
+ fft_(nFft)
+ {
+ pkHolder_ = new PeakHolder[nFft/2+1];
+ for (int n=0; n<=nFft/2; n++)
+ pkHolder_[n].SetCoefs(0.2f);
+
+ xData_ = new float[nData]; // Data to be analyzed
+ an_ = new float[order]; // Linear-predictive coefficients
+ xFft_ = new float[nFft]; // Input for FFT
+ yFft_ = new Complex[nFft/2+1]; // Output of FFT
+ normY_ = new float[nFft/2+1]; // Powerspectrum
+ }
+
+ LpcAnalyzer::~LpcAnalyzer()
+ {
+ delete[] pkHolder_;
+ delete[] xData_;
+ delete[] an_;
+ delete[] xFft_;
+ delete[] yFft_;
+ delete[] normY_;
+ }
+
+ void LpcAnalyzer::Execute(float xn[], float db[])
+ {
+ // Differencing
+ for (int n=0; n<N_DATA_-1; n++)
+ xData_[n] = xn[n+1] - xn[n];
+
+ hm_.Execute(xData_, xData_); // Windowing
+ float em;
+ lp_.Execute(xData_, an_, em);
+
+ // To spectrum
+ xFft_[0] = 1.0f;
+ for (int n=0; n<ORDER_; n++) xFft_[n+1] = -an_[n];
+ for (int n=ORDER_+1; n<N_FFT_; n++) xFft_[n] = 0.0f;
+ fft_.Execute(xFft_, yFft_); // Execute FFT
+
+ // Smoothing
+ for (int n=0; n<=N_FFT_/2; n++)
+ normY_[n] = pkHolder_[n].Execute(Sqr(yFft_[n].real())
+ + Sqr(yFft_[n].imag()));
+
+ // Translate to dB
+ float b0Db = 20.0f*log10f(em); // b0 to dB
+ for (int n=0; n<=N_FFT_/2; n++)
+ db[n] = -10.0f*log10f(normY_[n]) + b0Db + 30;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SpactrumAnalysisClasses/LPC_Analysis.hpp Sun Jul 26 02:48:23 2015 +0000
@@ -0,0 +1,42 @@
+//---------------------------------------------------------------
+// Class for spectrum analysis using linear prediction (Header)
+// Copyright (c) 2014 MIKAMI, Naoki, 2014/12/30
+//---------------------------------------------------------------
+
+#ifndef LPC_ANALYZER_HPP
+#define LPC_ANALYZER_HPP
+
+#include "fftReal.hpp"
+#include "Hamming.hpp"
+#include "PeakHolder.hpp"
+#include "LinearPrediction.hpp"
+
+namespace Mikami
+{
+ class LpcAnalyzer
+ {
+ public:
+ LpcAnalyzer(int nData, int order, int nFft);
+ ~LpcAnalyzer();
+ void Execute(float xn[], float db[]);
+ private:
+ const int N_DATA_;
+ const int ORDER_;
+ const int N_FFT_;
+
+ HammingWindow hm_;
+ LinearPred lp_;
+ FftReal fft_;
+ PeakHolder* pkHolder_;
+
+ float* xData_; // Data to be analyzed
+ float* an_;
+ float* xFft_; // Input for FFT
+ Complex* yFft_; // Output of FFT
+ float* normY_; // Powerspectrum
+
+ float Sqr(float x) { return x*x; }
+ };
+}
+#endif // LPC_ANALYZER_HPP
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SpactrumAnalysisClasses/LinearPrediction.cpp Sun Jul 26 02:48:23 2015 +0000
@@ -0,0 +1,72 @@
+//-----------------------------------------------------
+// Class for linear prediction
+// Copyright (c) 2014 MIKAMI, Naoki, 2014/12/30
+//-----------------------------------------------------
+
+#include "LinearPrediction.hpp"
+
+namespace Mikami
+{
+ LinearPred::LinearPred(int nData, int order)
+ : N_DATA_(nData), ORDER_(order)
+ {
+ r_ = new float[order+1]; // for auto-correlation
+ k_ = new float[order]; // for PARCOR coefficients
+ am_ = new float[order]; // working area
+ }
+
+ LinearPred::~LinearPred()
+ {
+ delete[] r_;
+ delete[] k_;
+ delete[] am_;
+ }
+
+ // Calculate linear-predictive coefficients
+ bool LinearPred::Execute(const float x[], float a[],
+ float &em)
+ {
+ AutoCorr(x);
+ return Durbin(a, em);
+ }
+
+ // Calculate auto-correlation
+ void LinearPred::AutoCorr(const float x[])
+ {
+ for (int j=0; j<=ORDER_; j++)
+ {
+ r_[j] = 0.0;
+ for (int n=0; n<N_DATA_-j; n++)
+ r_[j] = r_[j] + x[n]*x[n+j];
+ }
+ }
+
+ // Levinson-Durbin algorithm
+ bool LinearPred::Durbin(float a[], float &em)
+ {
+ // Initialization
+ em = r_[0];
+
+ // Repeat
+ for (int m=0; m<ORDER_; m++)
+ {
+ float w = r_[m+1];
+ for (int j=0; j<=m-1; j++)
+ w = w - r_[m-j]*a[j];
+
+ k_[m] = w/em;
+ em = em*(1 - k_[m]*k_[m]);
+
+ if (em < 0) break; // Error for negative squared sum of residual
+
+ a[m] = k_[m];
+ for (int j=0; j<=m-1; j++)
+ am_[j] = a[j];
+ for (int j=0; j<=m-1; j++)
+ a[j] = am_[j] - k_[m]*am_[m-j-1];
+ }
+
+ if (em < 0) return false;
+ else return true;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SpactrumAnalysisClasses/LinearPrediction.hpp Sun Jul 26 02:48:23 2015 +0000
@@ -0,0 +1,31 @@
+//-----------------------------------------------------
+// Class for linear prediction (Header)
+// Copyright (c) 2014 MIKAMI, Naoki, 2014/12/30
+//-----------------------------------------------------
+
+#ifndef LINEAR_PREDICTION_HPP
+#define LINEAR_PREDICTION_HPP
+
+#include "mbed.h"
+
+namespace Mikami
+{
+ class LinearPred
+ {
+ public:
+ LinearPred(int nData, int order);
+ ~LinearPred();
+ bool Execute(const float x[], float a[], float &em);
+ public:
+ const uint16_t N_DATA_;
+ const uint16_t ORDER_;
+
+ float* r_;
+ float* k_;
+ float* am_;
+
+ void AutoCorr(const float x[]);
+ bool Durbin(float a[], float &em);
+ };
+}
+#endif // LINEAR_PREDICTION_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SpactrumAnalysisClasses/PeakHolder.hpp Sun Jul 26 02:48:23 2015 +0000
@@ -0,0 +1,45 @@
+//-------------------------------------------------------------------
+// Peak holder
+// Copyright (c) 2014 MIKAMI, Naoki, 2014/12/20
+//-------------------------------------------------------------------
+
+#ifndef PEAK_HOLDER_HPP
+#define PEAK_HOLDER_HPP
+
+#include "mbed.h"
+
+namespace Mikami
+{
+ class PeakHolder
+ {
+ private:
+ float a1_, b0_;
+ float ynM1_;
+
+ public:
+ // Constructor
+ explicit PeakHolder(float a1 = 0)
+ {
+ SetCoefs(a1);
+ ynM1_ = 0;
+ }
+
+ // Argument a1 must be as follows: 0 < a1 < 1
+ void SetCoefs(float a1)
+ {
+ a1_ = a1;
+ b0_ =1.0f - a1;
+ }
+
+ float Execute(float xn)
+ {
+ float yn = xn;
+ if (xn < ynM1_) yn = a1_*ynM1_ + b0_*xn;
+ ynM1_ = yn;
+
+ return yn;
+ }
+ };
+}
+#endif // PEAK_HOLDER_HPP
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SpactrumAnalysisClasses/SpectrumDisplay.cpp Sun Jul 26 02:48:23 2015 +0000
@@ -0,0 +1,110 @@
+//-------------------------------------------------------
+// Class for display spectrum
+// Copyright (c) 2014 MIKAMI, Naoki, 2014/12/28
+//-------------------------------------------------------
+
+#include "SpectrumDisplay.hpp"
+
+namespace Mikami
+{
+ SpectrumDisplay::SpectrumDisplay(
+ SeeedStudioTFTv2* lcd,
+ int nFft, int x0, int y0,
+ float db1, int bin, float maxDb, int fs)
+ : N_FFT_(nFft), X0_(x0), Y0_(y0),
+ DB1_(db1), BIN_(bin), MAX_DB_(maxDb), FS_(fs),
+ lcd_(lcd)
+ {
+ lcd_->background(Navy);
+ lcd_->foreground(White);
+ lcd_->cls();
+ lcd_->set_orientation(1);
+ lcd_->set_font((uint8_t*) Arial12x12);
+ lcd_->locate(86,3);
+ lcd_->printf("Spectrum Analyzer");
+
+ AxisX();
+ AxisY();
+ }
+
+ void SpectrumDisplay::BarChart(float db[], float offset)
+ {
+ for (int n=1; n<=N_FFT_/2; n++)
+ {
+ float h = ((db[n] + offset) >= 0)? db[n] + offset : 0;
+ if (h > MAX_DB_) h = MAX_DB_;
+ int y = Y0_ - (int)(h*DB1_);
+ lcd_->line(X0_+n, Y0_-1, X0_+n, y, Cyan);
+ lcd_->line(X0_+n, y-1, X0_+n, Y0_-(int)(MAX_DB_*DB1_), Navy);
+ }
+ lcd_->line(X0_, Y0_, X0_+BIN_*N_FFT_/2, Y0_, Yellow);
+ }
+
+ void SpectrumDisplay::LineChart(float db[], float offset)
+ {
+ lcd_->fillrect(X0_+1, Y0_-(int)(MAX_DB_*DB1_),
+ X0_+N_FFT_*BIN_/2, Y0_-1, Navy);
+
+ float db1 = ((db[1] + offset) > 0)? db[1] + offset : 0;
+ int y1 = Y0_ - (int)(db1*DB1_);
+ for (int n=1; n<N_FFT_/2; n++)
+ {
+ float db2 = ((db[n+1] + offset) > 0)? db[n+1] + offset : 0;
+ if (db2 > MAX_DB_) db2 = MAX_DB_;
+ int y2 = Y0_ - (int)(db2*DB1_);
+ lcd_->line(X0_+n, y1, X0_+n+1, y2, Cyan);
+ y1 = y2;
+ }
+ lcd_->line(X0_, Y0_, X0_+BIN_*N_FFT_/2, Y0_, Yellow);
+ }
+
+ void SpectrumDisplay::DisplayVolume(float volume)
+ {
+ const int X_POS = 305;
+ const float TH = 0.85f;
+ if (volume < TH) // volume < 85 %
+ {
+ lcd_->fillrect(X_POS, Y0_-DB1_*MAX_DB_, X_POS+5, Y0_, Navy);
+ lcd_->fillrect(X_POS, Y0_-DB1_*MAX_DB_*volume,
+ X_POS+5, Y0_, Cyan);
+ }
+ else // volume >= 85 %
+ {
+ lcd_->fillrect(X_POS, Y0_-DB1_*MAX_DB_, X_POS+5, Y0_, Navy);
+ lcd_->fillrect(X_POS, Y0_-DB1_*MAX_DB_*volume,
+ X_POS+5, Y0_-DB1_*MAX_DB_*TH, Red);
+ lcd_->fillrect(X_POS, Y0_-DB1_*MAX_DB_*TH, X_POS+5, Y0_, Cyan);
+ }
+ }
+
+ // x-axis
+ void SpectrumDisplay::AxisX()
+ {
+ lcd_->line(X0_, Y0_, X0_+BIN_*N_FFT_/2, Y0_, Yellow);
+ float dx = BIN_*(N_FFT_*1000.0f)/(float)FS_;
+ for (int n=0; n<=5; n++)
+ {
+ int xTick = X0_ + (int)(dx*n + 0.5f);
+ lcd_->locate(xTick-4, Y0_+10);
+ lcd_->printf("%d", n);
+ lcd_->line(xTick, Y0_, xTick, Y0_+5, Yellow);
+ }
+ lcd_->locate(110, Y0_+24);
+ lcd_->printf("Frequency [kHz]");
+ }
+
+ // y-axis
+ void SpectrumDisplay::AxisY()
+ {
+ lcd_->line(X0_, Y0_+5, X0_, Y0_-(int)(MAX_DB_*DB1_), Yellow);
+ for (int n=0; n<=(int)MAX_DB_; n+=20)
+ {
+ int yTick = Y0_-(int)(DB1_*n);
+ lcd_->locate(X0_-22, yTick-5);
+ lcd_->printf("%2d", n);
+ lcd_->line(X0_-5, yTick, X0_, yTick, Yellow);
+ }
+ lcd_->locate(X0_-27, Y0_-(int)(DB1_*MAX_DB_)-18);
+ lcd_->printf("[dB]");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SpactrumAnalysisClasses/SpectrumDisplay.hpp Sun Jul 26 02:48:23 2015 +0000
@@ -0,0 +1,42 @@
+//-------------------------------------------------------
+// Class for display spectrum
+// Copyright (c) 2014 MIKAMI, Naoki, 2014/12/28
+//-------------------------------------------------------
+
+#ifndef SPECTRUM_DISPLAY_HPP
+#define SPECTRUM_DISPLAY_HPP
+
+// Following two files were imported from
+// http://developer.mbed.org/teams/shields/code/
+// Seeed_TFT_Touch_Shield/
+#include "SeeedStudioTFTv2.h" // imported
+#include "Arial12x12.h" // imported
+
+namespace Mikami
+{
+ class SpectrumDisplay
+ {
+ public:
+ SpectrumDisplay(SeeedStudioTFTv2* lcd,
+ int nFft, int x0, int y0,
+ float db1, int bin, float maxDb, int fs);
+ void BarChart(float db[], float offset);
+ void LineChart(float db[], float offset);
+ void DisplayVolume(float volume);
+
+ private:
+ const int N_FFT_; // number of date for FFT
+ const int X0_; // Origin for x axis
+ const int Y0_; // Origin for y axis
+ const float DB1_; // Pixels for 1 dB
+ const int BIN_; // Pixels per bin
+ const float MAX_DB_; // Maximum dB
+ const int FS_; // Sampling frequency: 10 kHz
+
+ SeeedStudioTFTv2* lcd_;
+
+ void AxisX(); // x-axis
+ void AxisY(); // y-axis
+ };
+}
+#endif // SPECTRUM_DISPLAY_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/UITDSP_ADDA.lib Sun Jul 26 02:48:23 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/MikamiUitOpen/code/UITDSP_ADDA/#543daa087bd5
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/UIT_FFT_Real.lib Sun Jul 26 02:48:23 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/MikamiUitOpen/code/UIT_FFT_Real/#982a9acf3a07
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/fonts/Arial12x12.h Sun Jul 26 02:48:23 2015 +0000
@@ -0,0 +1,111 @@
+//--------------------------------------------------------------
+// This file (Arial12x12.h) is imported from the following URL
+//
+// https://developer.mbed.org/users/dreschpe/code/TFT_fonts/
+//--------------------------------------------------------------
+
+//GLCD FontName : Arial12x12
+//GLCD FontSize : 12 x 12
+
+/** Arial Font with 12*12 matrix to use with SPI_TFT lib
+ */
+__align(2)
+const unsigned char Arial12x12[] = {
+ 25,12,12,2, // Length,horz,vert,byte/vert
+ 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char
+ 0x02, 0x00, 0x00, 0x7F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char !
+ 0x03, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char "
+ 0x07, 0x24, 0x00, 0xA4, 0x01, 0x7C, 0x00, 0xA7, 0x01, 0x7C, 0x00, 0x27, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char #
+ 0x06, 0x00, 0x00, 0xCE, 0x00, 0x11, 0x01, 0xFF, 0x03, 0x11, 0x01, 0xE2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char $
+ 0x0A, 0x00, 0x00, 0x0E, 0x00, 0x11, 0x00, 0x11, 0x01, 0xCE, 0x00, 0x38, 0x00, 0xE6, 0x00, 0x11, 0x01, 0x10, 0x01, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char %
+ 0x08, 0x00, 0x00, 0xE0, 0x00, 0x1E, 0x01, 0x11, 0x01, 0x29, 0x01, 0xC6, 0x00, 0xA0, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char &
+ 0x02, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char '
+ 0x04, 0x00, 0x00, 0xF8, 0x00, 0x06, 0x03, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char (
+ 0x03, 0x01, 0x04, 0x06, 0x03, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char )
+ 0x05, 0x02, 0x00, 0x0A, 0x00, 0x07, 0x00, 0x0A, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char *
+ 0x06, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x7C, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char +
+ 0x02, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ,
+ 0x03, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char -
+ 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char .
+ 0x03, 0x80, 0x01, 0x7C, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char /
+ 0x06, 0x00, 0x00, 0xFE, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 0
+ 0x06, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 1
+ 0x06, 0x00, 0x00, 0x02, 0x01, 0x81, 0x01, 0x41, 0x01, 0x31, 0x01, 0x0E, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 2
+ 0x06, 0x00, 0x00, 0x82, 0x00, 0x01, 0x01, 0x11, 0x01, 0x11, 0x01, 0xEE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 3
+ 0x06, 0x00, 0x00, 0x60, 0x00, 0x58, 0x00, 0x46, 0x00, 0xFF, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 4
+ 0x06, 0x00, 0x00, 0x9C, 0x00, 0x0B, 0x01, 0x09, 0x01, 0x09, 0x01, 0xF1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 5
+ 0x06, 0x00, 0x00, 0xFE, 0x00, 0x11, 0x01, 0x09, 0x01, 0x09, 0x01, 0xF2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 6
+ 0x06, 0x00, 0x00, 0x01, 0x00, 0xC1, 0x01, 0x39, 0x00, 0x07, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 7
+ 0x06, 0x00, 0x00, 0xEE, 0x00, 0x11, 0x01, 0x11, 0x01, 0x11, 0x01, 0xEE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 8
+ 0x06, 0x00, 0x00, 0x9E, 0x00, 0x21, 0x01, 0x21, 0x01, 0x11, 0x01, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 9
+ 0x02, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char :
+ 0x02, 0x00, 0x00, 0x40, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ;
+ 0x06, 0x00, 0x00, 0x10, 0x00, 0x28, 0x00, 0x28, 0x00, 0x44, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char <
+ 0x06, 0x48, 0x00, 0x48, 0x00, 0x48, 0x00, 0x48, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char =
+ 0x06, 0x00, 0x00, 0x44, 0x00, 0x44, 0x00, 0x28, 0x00, 0x28, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char >
+ 0x06, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x61, 0x01, 0x11, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ?
+ 0x0C, 0x00, 0x00, 0xF0, 0x01, 0x0C, 0x02, 0xE2, 0x04, 0x12, 0x09, 0x09, 0x09, 0x09, 0x09, 0xF1, 0x09, 0x19, 0x09, 0x02, 0x05, 0x86, 0x04, 0x78, 0x02, // Code for char @
+ 0x07, 0x80, 0x01, 0x70, 0x00, 0x2E, 0x00, 0x21, 0x00, 0x2E, 0x00, 0x70, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char A
+ 0x07, 0x00, 0x00, 0xFF, 0x01, 0x11, 0x01, 0x11, 0x01, 0x11, 0x01, 0x11, 0x01, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char B
+ 0x08, 0x00, 0x00, 0x7C, 0x00, 0x82, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x82, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char C
+ 0x08, 0x00, 0x00, 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x82, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char D
+ 0x07, 0x00, 0x00, 0xFF, 0x01, 0x11, 0x01, 0x11, 0x01, 0x11, 0x01, 0x11, 0x01, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char E
+ 0x06, 0x00, 0x00, 0xFF, 0x01, 0x11, 0x00, 0x11, 0x00, 0x11, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char F
+ 0x08, 0x00, 0x00, 0x7C, 0x00, 0x82, 0x00, 0x01, 0x01, 0x01, 0x01, 0x11, 0x01, 0x92, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char G
+ 0x08, 0x00, 0x00, 0xFF, 0x01, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char H
+ 0x02, 0x00, 0x00, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char I
+ 0x05, 0xC0, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char J
+ 0x08, 0x00, 0x00, 0xFF, 0x01, 0x20, 0x00, 0x10, 0x00, 0x28, 0x00, 0x44, 0x00, 0x82, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char K
+ 0x07, 0x00, 0x00, 0xFF, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char L
+ 0x08, 0x00, 0x00, 0xFF, 0x01, 0x06, 0x00, 0x78, 0x00, 0x80, 0x01, 0x78, 0x00, 0x06, 0x00, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char M
+ 0x08, 0x00, 0x00, 0xFF, 0x01, 0x02, 0x00, 0x0C, 0x00, 0x10, 0x00, 0x60, 0x00, 0x80, 0x00, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char N
+ 0x08, 0x00, 0x00, 0x7C, 0x00, 0x82, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x82, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char O
+ 0x07, 0x00, 0x00, 0xFF, 0x01, 0x11, 0x00, 0x11, 0x00, 0x11, 0x00, 0x11, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char P
+ 0x08, 0x00, 0x00, 0x7C, 0x00, 0x82, 0x00, 0x01, 0x01, 0x41, 0x01, 0x41, 0x01, 0x82, 0x00, 0x7C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Q
+ 0x08, 0x00, 0x00, 0xFF, 0x01, 0x11, 0x00, 0x11, 0x00, 0x11, 0x00, 0x31, 0x00, 0xD1, 0x00, 0x0E, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char R
+ 0x07, 0x00, 0x00, 0xCE, 0x00, 0x11, 0x01, 0x11, 0x01, 0x11, 0x01, 0x11, 0x01, 0xE6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char S
+ 0x07, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0xFF, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char T
+ 0x08, 0x00, 0x00, 0x7F, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x80, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char U
+ 0x07, 0x03, 0x00, 0x1C, 0x00, 0x60, 0x00, 0x80, 0x01, 0x60, 0x00, 0x1C, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char V
+ 0x0B, 0x07, 0x00, 0x78, 0x00, 0x80, 0x01, 0x70, 0x00, 0x0E, 0x00, 0x01, 0x00, 0x0E, 0x00, 0x70, 0x00, 0x80, 0x01, 0x7C, 0x00, 0x03, 0x00, 0x00, 0x00, // Code for char W
+ 0x07, 0x01, 0x01, 0xC6, 0x00, 0x28, 0x00, 0x10, 0x00, 0x28, 0x00, 0xC6, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char X
+ 0x07, 0x01, 0x00, 0x06, 0x00, 0x08, 0x00, 0xF0, 0x01, 0x08, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Y
+ 0x07, 0x00, 0x01, 0x81, 0x01, 0x61, 0x01, 0x11, 0x01, 0x0D, 0x01, 0x03, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Z
+ 0x03, 0x00, 0x00, 0xFF, 0x07, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char [
+ 0x03, 0x03, 0x00, 0x7C, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char BackSlash
+ 0x02, 0x01, 0x04, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ]
+ 0x05, 0x18, 0x00, 0x06, 0x00, 0x01, 0x00, 0x06, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ^
+ 0x07, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char _
+ 0x03, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char `
+ 0x06, 0x00, 0x00, 0xC8, 0x00, 0x24, 0x01, 0x24, 0x01, 0xA4, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char a
+ 0x06, 0x00, 0x00, 0xFF, 0x01, 0x88, 0x00, 0x04, 0x01, 0x04, 0x01, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char b
+ 0x05, 0x00, 0x00, 0xF8, 0x00, 0x04, 0x01, 0x04, 0x01, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char c
+ 0x06, 0x00, 0x00, 0xF8, 0x00, 0x04, 0x01, 0x04, 0x01, 0x08, 0x01, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char d
+ 0x06, 0x00, 0x00, 0xF8, 0x00, 0x24, 0x01, 0x24, 0x01, 0x24, 0x01, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char e
+ 0x04, 0x04, 0x00, 0xFE, 0x01, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char f
+ 0x06, 0x00, 0x00, 0xF8, 0x04, 0x04, 0x05, 0x04, 0x05, 0x88, 0x04, 0xFC, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char g
+ 0x06, 0x00, 0x00, 0xFF, 0x01, 0x08, 0x00, 0x04, 0x00, 0x04, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char h
+ 0x02, 0x00, 0x00, 0xFD, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char i
+ 0x02, 0x00, 0x04, 0xFD, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char j
+ 0x06, 0x00, 0x00, 0xFF, 0x01, 0x20, 0x00, 0x30, 0x00, 0xC8, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char k
+ 0x02, 0x00, 0x00, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char l
+ 0x0A, 0x00, 0x00, 0xFC, 0x01, 0x08, 0x00, 0x04, 0x00, 0x04, 0x00, 0xF8, 0x01, 0x08, 0x00, 0x04, 0x00, 0x04, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x00, // Code for char m
+ 0x06, 0x00, 0x00, 0xFC, 0x01, 0x08, 0x00, 0x04, 0x00, 0x04, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char n
+ 0x06, 0x00, 0x00, 0xF8, 0x00, 0x04, 0x01, 0x04, 0x01, 0x04, 0x01, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char o
+ 0x06, 0x00, 0x00, 0xFC, 0x07, 0x88, 0x00, 0x04, 0x01, 0x04, 0x01, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char p
+ 0x06, 0x00, 0x00, 0xF8, 0x00, 0x04, 0x01, 0x04, 0x01, 0x88, 0x00, 0xFC, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char q
+ 0x04, 0x00, 0x00, 0xFC, 0x01, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char r
+ 0x06, 0x00, 0x00, 0x98, 0x00, 0x24, 0x01, 0x24, 0x01, 0x24, 0x01, 0xC8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char s
+ 0x03, 0x04, 0x00, 0xFF, 0x01, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char t
+ 0x06, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0xFC, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char u
+ 0x05, 0x0C, 0x00, 0x70, 0x00, 0x80, 0x01, 0x70, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char v
+ 0x09, 0x0C, 0x00, 0x70, 0x00, 0x80, 0x01, 0x70, 0x00, 0x0C, 0x00, 0x70, 0x00, 0x80, 0x01, 0x70, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char w
+ 0x05, 0x04, 0x01, 0xD8, 0x00, 0x20, 0x00, 0xD8, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char x
+ 0x05, 0x0C, 0x00, 0x70, 0x04, 0x80, 0x03, 0x70, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char y
+ 0x05, 0x04, 0x01, 0xC4, 0x01, 0x24, 0x01, 0x1C, 0x01, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char z
+ 0x03, 0x20, 0x00, 0xDE, 0x03, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char {
+ 0x02, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char |
+ 0x04, 0x00, 0x00, 0x01, 0x04, 0xDE, 0x03, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char }
+ 0x07, 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0x10, 0x00, 0x20, 0x00, 0x20, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ~
+ 0x08, 0x00, 0x00, 0xFE, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0xFE, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Code for char
+ };
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Sun Jul 26 02:48:23 2015 +0000
@@ -0,0 +1,160 @@
+//--------------------------------------------------------------
+// Spectrum analyzer
+// input PC_3
+// sampling frquency 10 kHz
+// window Hamming window
+// number of data 240 points
+// number of FFT 512 points
+// preemphasis 1st-order difference
+//
+// Touch pannel
+// upper ---- left: update display
+// right: freeze display
+// lower ---- left: bar chart of FFT
+// center: line chart of FFT
+// right: line chart of linear prediction
+// When you touch the touch pannel, PZT speaker connected PB_1
+// sounds "pi" generated using PWM object.
+//
+// 2015/07/25, Copyright (c) 2015 MIKAMI, Naoki
+//--------------------------------------------------------------
+
+#include "ADC_Interrupt.hpp" // for ADC using interrupt
+#include "FFT_Analysis.hpp"
+#include "SpectrumDisplay.hpp"
+#include "LPC_Analysis.hpp"
+
+using namespace Mikami;
+
+const int N_FFT_ = 512; // number of date for FFT
+const int N_DATA_ = 240; // number of data to be analyzed
+
+const int X0_ = 36; // Origin for x axis
+const int Y0_ = 200; // Origin for y axis
+const float DB1_ = 2.8f; // Pixels for 1 dB
+const int BIN_ = 1; // Pixels per bin
+const int MAX_DB_ = 60; // Maximum dB
+
+const int FS_ = 10000; // Sampling frequency: 10 kHz
+
+// Pointer of object for using Seeed Studio 2.8" TFT Touch Shield V2.0
+SeeedStudioTFTv2* lcd_;
+
+ADC_Intr adc_(PC_3, FS_); // for external mic connected with PC3
+PeakHolder mag_(0.9998f); // for input volume
+FftAnalyzer fft_(N_DATA_, N_FFT_);
+LpcAnalyzer lpc_(N_DATA_, 16, N_FFT_);
+
+float volume_ = 0;
+float bufIn_[N_DATA_]; // Buffer for input signal
+volatile bool analysisOk_;
+
+PwmOut sound_(PB_1);
+Timeout off_;
+
+void IsrTimeout() { sound_.write(0); }
+
+// Interrupt service routine for ADC
+void AdcIsr()
+{
+ static int count = 0; // counter of input buffer
+
+ bufIn_[count] = adc_.Read(); // Read from PC_3
+ volume_ = mag_.Execute(fabs(bufIn_[count]));
+
+ if (++count >= N_DATA_)
+ {
+ count = 0;
+ analysisOk_ = true; // This permits to FFT analysis
+ }
+}
+
+int main()
+{
+ lcd_ = new SeeedStudioTFTv2 (A3, A1, A2, A0, // X+, X-, Y+, Y-
+ D11, D12, D13, // MOSI, MISO, SCLK
+ D5, D6, D7, D4); // CS_TFT, DC_TFT, BL_TFT, CS_SD
+
+ SpectrumDisplay disp(lcd_, N_FFT_, X0_, Y0_,
+ DB1_, BIN_, MAX_DB_, FS_);
+
+ analysisOk_ = false;
+ adc_.SetIntrVec(AdcIsr); // Assign ISR for ADC interrupt
+ sound_.period_us((int)(1.0e6f/4000.0f));
+
+
+ int touchBefore = 0;
+ int touchNow = 0;
+// bool runBefore = true;
+ bool update = true;
+ float xn[N_DATA_]; // data to be analyzed
+ float db[N_FFT_/2+1]; // Log powerspectrum
+
+// Timer tim;
+ while (true)
+ if (analysisOk_)
+ {
+ // Sampled signals to working area
+ for (int n=0; n<N_DATA_; n++)
+ xn[n] = bufIn_[n];
+
+// tim.reset();
+ // Read touched Position
+ NVIC_DisableIRQ(ADC_IRQn);
+ point pos; // Touched position
+
+// tim.start();
+ lcd_->getPixel(pos);
+// tim.stop();
+
+ adc_.Select1stChannel();
+ NVIC_ClearPendingIRQ(ADC_IRQn);
+ NVIC_EnableIRQ(ADC_IRQn);
+// printf("Execution time: %d micro seconds\r\n", tim.read_us());
+
+ // Display log spectrum
+ float offset = 30;
+
+ // Sound "pi" 0.1 seconds
+ if ( (pos.x != 320) && (pos.y !=0) )
+ {
+ sound_.write(0.5f);
+ off_.attach(&IsrTimeout, 0.1f);
+ }
+
+ // If touched upper, update: left, freeze: right
+ if (pos.y > 120)
+ {
+ if (pos.x <160) update = false;
+ else update = true;
+ }
+
+ if (update)
+ {
+ printf("\r\n%d, %d", pos.x, pos.y);
+ if ( (pos.x != 320) && (pos.y != 0)
+ && (pos.y < 120) ) // Touched lower?
+ {
+ if (pos.x < 107) touchNow = 2;
+ else if (pos.x < 213) touchNow = 1;
+ else touchNow = 0;
+
+ if (touchNow != touchBefore) touchBefore = touchNow;
+ }
+
+ // Spectrum analysis
+ if (touchNow < 2) fft_.Execute(xn, db);
+ else lpc_.Execute(xn, db);
+
+ if (touchNow == 0) disp.BarChart(db, offset);
+ else disp.LineChart(db, offset);
+
+ disp.DisplayVolume(volume_); // Display volume of input
+ }
+
+ wait(0.1f);
+ analysisOk_ = false;
+ }
+}
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Sun Jul 26 02:48:23 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/4fc01daae5a5 \ No newline at end of file