Spectrum analyzer using DISCO-F746NG. Spectrum is calculated by FFT or linear prediction. The vowel data is in "vowel_data.hpp"

Dependencies:   BSP_DISCO_F746NG LCD_DISCO_F746NG TS_DISCO_F746NG UIT_FFT_Real mbed BUTTON_GROUP

Committer:
MikamiUitOpen
Date:
Mon Oct 26 13:25:03 2015 +0000
Revision:
1:2ef356b500f2
Parent:
0:c35b8a23a863
2

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MikamiUitOpen 0:c35b8a23a863 1 //-------------------------------------------------------
MikamiUitOpen 0:c35b8a23a863 2 // Class for spectrum analysis using linear prediction
MikamiUitOpen 0:c35b8a23a863 3 // Copyright (c) 2015 MIKAMI, Naoki, 2015/10/26
MikamiUitOpen 0:c35b8a23a863 4 //-------------------------------------------------------
MikamiUitOpen 0:c35b8a23a863 5
MikamiUitOpen 0:c35b8a23a863 6 #include "LPC_Analysis.hpp"
MikamiUitOpen 0:c35b8a23a863 7
MikamiUitOpen 0:c35b8a23a863 8 namespace Mikami
MikamiUitOpen 0:c35b8a23a863 9 {
MikamiUitOpen 0:c35b8a23a863 10 LpcAnalyzer::LpcAnalyzer(int nData, int order, int nFft)
MikamiUitOpen 0:c35b8a23a863 11 : N_DATA_(nData), ORDER_(order), N_FFT_(nFft),
MikamiUitOpen 0:c35b8a23a863 12 hm_(nData-1, nData-1), lp_(nData-1, order),
MikamiUitOpen 0:c35b8a23a863 13 fft_(nFft)
MikamiUitOpen 0:c35b8a23a863 14 {
MikamiUitOpen 0:c35b8a23a863 15 xData_ = new float[nData]; // Data to be analyzed
MikamiUitOpen 0:c35b8a23a863 16 an_ = new float[order]; // Linear-predictive coefficients
MikamiUitOpen 0:c35b8a23a863 17 xFft_ = new float[nFft]; // Input for FFT
MikamiUitOpen 0:c35b8a23a863 18 yFft_ = new Complex[nFft/2+1]; // Output of FFT
MikamiUitOpen 0:c35b8a23a863 19 normY_ = new float[nFft/2+1]; // Powerspectrum
MikamiUitOpen 0:c35b8a23a863 20 }
MikamiUitOpen 0:c35b8a23a863 21
MikamiUitOpen 0:c35b8a23a863 22 LpcAnalyzer::~LpcAnalyzer()
MikamiUitOpen 0:c35b8a23a863 23 {
MikamiUitOpen 0:c35b8a23a863 24 delete[] xData_;
MikamiUitOpen 0:c35b8a23a863 25 delete[] an_;
MikamiUitOpen 0:c35b8a23a863 26 delete[] xFft_;
MikamiUitOpen 0:c35b8a23a863 27 delete[] yFft_;
MikamiUitOpen 0:c35b8a23a863 28 delete[] normY_;
MikamiUitOpen 0:c35b8a23a863 29 }
MikamiUitOpen 0:c35b8a23a863 30
MikamiUitOpen 0:c35b8a23a863 31 void LpcAnalyzer::Execute(float xn[], float db[])
MikamiUitOpen 0:c35b8a23a863 32 {
MikamiUitOpen 0:c35b8a23a863 33 // Differencing
MikamiUitOpen 0:c35b8a23a863 34 for (int n=0; n<N_DATA_-1; n++)
MikamiUitOpen 0:c35b8a23a863 35 xData_[n] = xn[n+1] - xn[n];
MikamiUitOpen 0:c35b8a23a863 36
MikamiUitOpen 0:c35b8a23a863 37 hm_.Execute(xData_, xData_); // Windowing
MikamiUitOpen 0:c35b8a23a863 38 float em;
MikamiUitOpen 0:c35b8a23a863 39 lp_.Execute(xData_, an_, em);
MikamiUitOpen 0:c35b8a23a863 40
MikamiUitOpen 0:c35b8a23a863 41 // To spectrum
MikamiUitOpen 0:c35b8a23a863 42 xFft_[0] = 1.0f;
MikamiUitOpen 0:c35b8a23a863 43 for (int n=0; n<ORDER_; n++) xFft_[n+1] = -an_[n];
MikamiUitOpen 0:c35b8a23a863 44 for (int n=ORDER_+1; n<N_FFT_; n++) xFft_[n] = 0.0f;
MikamiUitOpen 0:c35b8a23a863 45 fft_.Execute(xFft_, yFft_); // Execute FFT
MikamiUitOpen 0:c35b8a23a863 46
MikamiUitOpen 0:c35b8a23a863 47 // Squared magnitude
MikamiUitOpen 0:c35b8a23a863 48 for (int n=0; n<=N_FFT_/2; n++)
MikamiUitOpen 0:c35b8a23a863 49 normY_[n] = 1.0f/(Sqr(yFft_[n].real()) + Sqr(yFft_[n].imag()));
MikamiUitOpen 0:c35b8a23a863 50
MikamiUitOpen 1:2ef356b500f2 51 // Search maximum
MikamiUitOpen 0:c35b8a23a863 52 float max = 0;
MikamiUitOpen 0:c35b8a23a863 53 for (int n=0; n<=N_FFT_/2; n++)
MikamiUitOpen 0:c35b8a23a863 54 max = (max > normY_[n]) ? max : normY_[n];
MikamiUitOpen 0:c35b8a23a863 55 float invMax = 1.0f/max;
MikamiUitOpen 0:c35b8a23a863 56
MikamiUitOpen 0:c35b8a23a863 57 // Translate to dB
MikamiUitOpen 0:c35b8a23a863 58 for (int n=0; n<=N_FFT_/2; n++)
MikamiUitOpen 0:c35b8a23a863 59 db[n] = 10.0f*log10f(invMax*normY_[n]);
MikamiUitOpen 0:c35b8a23a863 60 }
MikamiUitOpen 0:c35b8a23a863 61 }
MikamiUitOpen 0:c35b8a23a863 62