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