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
Diff: SpactrumAnalysisClasses/LinearPrediction.cpp
- Revision:
- 0:c35b8a23a863
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SpactrumAnalysisClasses/LinearPrediction.cpp Mon Oct 26 08:06:57 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; + } +}