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/LinearPrediction.cpp@0:c35b8a23a863, 2015-10-26 (annotated)
- Committer:
- MikamiUitOpen
- Date:
- Mon Oct 26 08:06:57 2015 +0000
- Revision:
- 0:c35b8a23a863
1
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
MikamiUitOpen | 0:c35b8a23a863 | 1 | //----------------------------------------------------- |
MikamiUitOpen | 0:c35b8a23a863 | 2 | // Class for linear prediction |
MikamiUitOpen | 0:c35b8a23a863 | 3 | // Copyright (c) 2014 MIKAMI, Naoki, 2014/12/30 |
MikamiUitOpen | 0:c35b8a23a863 | 4 | //----------------------------------------------------- |
MikamiUitOpen | 0:c35b8a23a863 | 5 | |
MikamiUitOpen | 0:c35b8a23a863 | 6 | #include "LinearPrediction.hpp" |
MikamiUitOpen | 0:c35b8a23a863 | 7 | |
MikamiUitOpen | 0:c35b8a23a863 | 8 | namespace Mikami |
MikamiUitOpen | 0:c35b8a23a863 | 9 | { |
MikamiUitOpen | 0:c35b8a23a863 | 10 | LinearPred::LinearPred(int nData, int order) |
MikamiUitOpen | 0:c35b8a23a863 | 11 | : N_DATA_(nData), ORDER_(order) |
MikamiUitOpen | 0:c35b8a23a863 | 12 | { |
MikamiUitOpen | 0:c35b8a23a863 | 13 | r_ = new float[order+1]; // for auto-correlation |
MikamiUitOpen | 0:c35b8a23a863 | 14 | k_ = new float[order]; // for PARCOR coefficients |
MikamiUitOpen | 0:c35b8a23a863 | 15 | am_ = new float[order]; // working area |
MikamiUitOpen | 0:c35b8a23a863 | 16 | } |
MikamiUitOpen | 0:c35b8a23a863 | 17 | |
MikamiUitOpen | 0:c35b8a23a863 | 18 | LinearPred::~LinearPred() |
MikamiUitOpen | 0:c35b8a23a863 | 19 | { |
MikamiUitOpen | 0:c35b8a23a863 | 20 | delete[] r_; |
MikamiUitOpen | 0:c35b8a23a863 | 21 | delete[] k_; |
MikamiUitOpen | 0:c35b8a23a863 | 22 | delete[] am_; |
MikamiUitOpen | 0:c35b8a23a863 | 23 | } |
MikamiUitOpen | 0:c35b8a23a863 | 24 | |
MikamiUitOpen | 0:c35b8a23a863 | 25 | // Calculate linear-predictive coefficients |
MikamiUitOpen | 0:c35b8a23a863 | 26 | bool LinearPred::Execute(const float x[], float a[], |
MikamiUitOpen | 0:c35b8a23a863 | 27 | float &em) |
MikamiUitOpen | 0:c35b8a23a863 | 28 | { |
MikamiUitOpen | 0:c35b8a23a863 | 29 | AutoCorr(x); |
MikamiUitOpen | 0:c35b8a23a863 | 30 | return Durbin(a, em); |
MikamiUitOpen | 0:c35b8a23a863 | 31 | } |
MikamiUitOpen | 0:c35b8a23a863 | 32 | |
MikamiUitOpen | 0:c35b8a23a863 | 33 | // Calculate auto-correlation |
MikamiUitOpen | 0:c35b8a23a863 | 34 | void LinearPred::AutoCorr(const float x[]) |
MikamiUitOpen | 0:c35b8a23a863 | 35 | { |
MikamiUitOpen | 0:c35b8a23a863 | 36 | for (int j=0; j<=ORDER_; j++) |
MikamiUitOpen | 0:c35b8a23a863 | 37 | { |
MikamiUitOpen | 0:c35b8a23a863 | 38 | r_[j] = 0.0; |
MikamiUitOpen | 0:c35b8a23a863 | 39 | for (int n=0; n<N_DATA_-j; n++) |
MikamiUitOpen | 0:c35b8a23a863 | 40 | r_[j] = r_[j] + x[n]*x[n+j]; |
MikamiUitOpen | 0:c35b8a23a863 | 41 | } |
MikamiUitOpen | 0:c35b8a23a863 | 42 | } |
MikamiUitOpen | 0:c35b8a23a863 | 43 | |
MikamiUitOpen | 0:c35b8a23a863 | 44 | // Levinson-Durbin algorithm |
MikamiUitOpen | 0:c35b8a23a863 | 45 | bool LinearPred::Durbin(float a[], float &em) |
MikamiUitOpen | 0:c35b8a23a863 | 46 | { |
MikamiUitOpen | 0:c35b8a23a863 | 47 | // Initialization |
MikamiUitOpen | 0:c35b8a23a863 | 48 | em = r_[0]; |
MikamiUitOpen | 0:c35b8a23a863 | 49 | |
MikamiUitOpen | 0:c35b8a23a863 | 50 | // Repeat |
MikamiUitOpen | 0:c35b8a23a863 | 51 | for (int m=0; m<ORDER_; m++) |
MikamiUitOpen | 0:c35b8a23a863 | 52 | { |
MikamiUitOpen | 0:c35b8a23a863 | 53 | float w = r_[m+1]; |
MikamiUitOpen | 0:c35b8a23a863 | 54 | for (int j=0; j<=m-1; j++) |
MikamiUitOpen | 0:c35b8a23a863 | 55 | w = w - r_[m-j]*a[j]; |
MikamiUitOpen | 0:c35b8a23a863 | 56 | |
MikamiUitOpen | 0:c35b8a23a863 | 57 | k_[m] = w/em; |
MikamiUitOpen | 0:c35b8a23a863 | 58 | em = em*(1 - k_[m]*k_[m]); |
MikamiUitOpen | 0:c35b8a23a863 | 59 | |
MikamiUitOpen | 0:c35b8a23a863 | 60 | if (em < 0) break; // Error for negative squared sum of residual |
MikamiUitOpen | 0:c35b8a23a863 | 61 | |
MikamiUitOpen | 0:c35b8a23a863 | 62 | a[m] = k_[m]; |
MikamiUitOpen | 0:c35b8a23a863 | 63 | for (int j=0; j<=m-1; j++) |
MikamiUitOpen | 0:c35b8a23a863 | 64 | am_[j] = a[j]; |
MikamiUitOpen | 0:c35b8a23a863 | 65 | for (int j=0; j<=m-1; j++) |
MikamiUitOpen | 0:c35b8a23a863 | 66 | a[j] = am_[j] - k_[m]*am_[m-j-1]; |
MikamiUitOpen | 0:c35b8a23a863 | 67 | } |
MikamiUitOpen | 0:c35b8a23a863 | 68 | |
MikamiUitOpen | 0:c35b8a23a863 | 69 | if (em < 0) return false; |
MikamiUitOpen | 0:c35b8a23a863 | 70 | else return true; |
MikamiUitOpen | 0:c35b8a23a863 | 71 | } |
MikamiUitOpen | 0:c35b8a23a863 | 72 | } |