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
SpactrumAnalysisClasses/FFT_Analysis.cpp@1:2ef356b500f2, 2015-10-26 (annotated)
- Committer:
- MikamiUitOpen
- Date:
- Mon Oct 26 13:25:03 2015 +0000
- Revision:
- 1:2ef356b500f2
- Parent:
- 0:c35b8a23a863
2
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
MikamiUitOpen | 0:c35b8a23a863 | 1 | //------------------------------------------------------- |
MikamiUitOpen | 0:c35b8a23a863 | 2 | // Class for spectrum analysis using FFT |
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 "FFT_Analysis.hpp" |
MikamiUitOpen | 0:c35b8a23a863 | 7 | |
MikamiUitOpen | 0:c35b8a23a863 | 8 | namespace Mikami |
MikamiUitOpen | 0:c35b8a23a863 | 9 | { |
MikamiUitOpen | 0:c35b8a23a863 | 10 | FftAnalyzer::FftAnalyzer(int nData, int nFft) |
MikamiUitOpen | 0:c35b8a23a863 | 11 | : N_DATA_(nData), N_FFT_(nFft), |
MikamiUitOpen | 0:c35b8a23a863 | 12 | hm_(nData-1, nFft), fft_(nFft) |
MikamiUitOpen | 0:c35b8a23a863 | 13 | { |
MikamiUitOpen | 0:c35b8a23a863 | 14 | xData = new float[nData]; // Data to be analyzed |
MikamiUitOpen | 0:c35b8a23a863 | 15 | xFft = new float[nFft]; // Input for FFT |
MikamiUitOpen | 0:c35b8a23a863 | 16 | yFft = new Complex[nFft/2+1]; // Output of FFT |
MikamiUitOpen | 0:c35b8a23a863 | 17 | normY = new float[nFft/2+1]; // Powerspectrum |
MikamiUitOpen | 0:c35b8a23a863 | 18 | } |
MikamiUitOpen | 0:c35b8a23a863 | 19 | |
MikamiUitOpen | 0:c35b8a23a863 | 20 | FftAnalyzer::~FftAnalyzer() |
MikamiUitOpen | 0:c35b8a23a863 | 21 | { |
MikamiUitOpen | 0:c35b8a23a863 | 22 | delete[] xData; |
MikamiUitOpen | 0:c35b8a23a863 | 23 | delete[] xFft; |
MikamiUitOpen | 0:c35b8a23a863 | 24 | delete[] yFft; |
MikamiUitOpen | 0:c35b8a23a863 | 25 | delete[] normY; |
MikamiUitOpen | 0:c35b8a23a863 | 26 | } |
MikamiUitOpen | 0:c35b8a23a863 | 27 | |
MikamiUitOpen | 0:c35b8a23a863 | 28 | void FftAnalyzer::Execute(float xn[], float db[]) |
MikamiUitOpen | 0:c35b8a23a863 | 29 | { |
MikamiUitOpen | 0:c35b8a23a863 | 30 | // Differencing |
MikamiUitOpen | 0:c35b8a23a863 | 31 | for (int n=0; n<N_DATA_-1; n++) |
MikamiUitOpen | 0:c35b8a23a863 | 32 | xData[n] = xn[n+1] - xn[n]; |
MikamiUitOpen | 0:c35b8a23a863 | 33 | |
MikamiUitOpen | 0:c35b8a23a863 | 34 | hm_.Execute(xData, xFft); // Windowing and zero-padding |
MikamiUitOpen | 0:c35b8a23a863 | 35 | fft_.Execute(xFft, yFft); // Execute FFT |
MikamiUitOpen | 0:c35b8a23a863 | 36 | |
MikamiUitOpen | 0:c35b8a23a863 | 37 | // Squared magnitude |
MikamiUitOpen | 0:c35b8a23a863 | 38 | for (int n=0; n<=N_FFT_/2; n++) |
MikamiUitOpen | 0:c35b8a23a863 | 39 | normY[n] = Sqr(yFft[n].real()) + Sqr(yFft[n].imag()); |
MikamiUitOpen | 0:c35b8a23a863 | 40 | |
MikamiUitOpen | 1:2ef356b500f2 | 41 | // Search maximum |
MikamiUitOpen | 0:c35b8a23a863 | 42 | float max = 0; |
MikamiUitOpen | 0:c35b8a23a863 | 43 | for (int n=0; n<=N_FFT_/2; n++) |
MikamiUitOpen | 0:c35b8a23a863 | 44 | max = (max > normY[n]) ? max : normY[n]; |
MikamiUitOpen | 0:c35b8a23a863 | 45 | float invMax = 1.0f/max; |
MikamiUitOpen | 0:c35b8a23a863 | 46 | |
MikamiUitOpen | 0:c35b8a23a863 | 47 | // Translate to dB |
MikamiUitOpen | 0:c35b8a23a863 | 48 | for (int n=0; n<=N_FFT_/2; n++) |
MikamiUitOpen | 0:c35b8a23a863 | 49 | db[n] = 10.0f*log10f(invMax*normY[n]); |
MikamiUitOpen | 0:c35b8a23a863 | 50 | } |
MikamiUitOpen | 0:c35b8a23a863 | 51 | } |
MikamiUitOpen | 0:c35b8a23a863 | 52 | |
MikamiUitOpen | 1:2ef356b500f2 | 53 |