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
- Committer:
- MikamiUitOpen
- Date:
- 2015-07-26
- Revision:
- 0:c5b026c2d07e
File content as of revision 0:c5b026c2d07e:
//-----------------------------------------------------
// 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;
}
}