Realtime spectrum analyzer. Using FFT, linear prediction, or cepstrum smoothing. Version using MEMS microphone and CODEC, named "F746_RealtimeSpectrumAnalyzer_MEMS_Mic" is registered. リアルタイム スペクトル解析器.解析の手法:FFT,線形予測法,ケプストラムによる平滑化の3種類.このプログラムの説明は,CQ出版社のインターフェース誌,2016年4月号に掲載.外付けのマイクまたは他の信号源等を A0 に接続する.線形予測法,ケプストラムは,スペクトル解析の対象を音声信号に想定してパラメータを設定している.MEMS マイクと CODEC を使ったバージョンを "F746_RealtimeSpectrumAnalyzer_MEMS_Mic" として登録.
Dependencies: BSP_DISCO_F746NG BUTTON_GROUP LCD_DISCO_F746NG TS_DISCO_F746NG UIT_FFT_Real mbed
MyClasses/LinearPrediction.cpp@0:5c237fdcba23, 2015-12-09 (annotated)
- Committer:
- MikamiUitOpen
- Date:
- Wed Dec 09 05:05:00 2015 +0000
- Revision:
- 0:5c237fdcba23
- Child:
- 4:99d4d5ea06a2
1
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
MikamiUitOpen | 0:5c237fdcba23 | 1 | //----------------------------------------------------- |
MikamiUitOpen | 0:5c237fdcba23 | 2 | // Class for linear prediction |
MikamiUitOpen | 0:5c237fdcba23 | 3 | // |
MikamiUitOpen | 0:5c237fdcba23 | 4 | // 2015/12/08, Copyright (c) 2015 MIKAMI, Naoki |
MikamiUitOpen | 0:5c237fdcba23 | 5 | //----------------------------------------------------- |
MikamiUitOpen | 0:5c237fdcba23 | 6 | |
MikamiUitOpen | 0:5c237fdcba23 | 7 | #include "LinearPrediction.hpp" |
MikamiUitOpen | 0:5c237fdcba23 | 8 | |
MikamiUitOpen | 0:5c237fdcba23 | 9 | namespace Mikami |
MikamiUitOpen | 0:5c237fdcba23 | 10 | { |
MikamiUitOpen | 0:5c237fdcba23 | 11 | LinearPred::LinearPred(int nData, int order) |
MikamiUitOpen | 0:5c237fdcba23 | 12 | : N_DATA_(nData), ORDER_(order), |
MikamiUitOpen | 0:5c237fdcba23 | 13 | r_(new float[order+1]), k_(new float[order]), |
MikamiUitOpen | 0:5c237fdcba23 | 14 | am_(new float[order]) {} |
MikamiUitOpen | 0:5c237fdcba23 | 15 | |
MikamiUitOpen | 0:5c237fdcba23 | 16 | LinearPred::~LinearPred() |
MikamiUitOpen | 0:5c237fdcba23 | 17 | { |
MikamiUitOpen | 0:5c237fdcba23 | 18 | delete[] r_; |
MikamiUitOpen | 0:5c237fdcba23 | 19 | delete[] k_; |
MikamiUitOpen | 0:5c237fdcba23 | 20 | delete[] am_; |
MikamiUitOpen | 0:5c237fdcba23 | 21 | } |
MikamiUitOpen | 0:5c237fdcba23 | 22 | |
MikamiUitOpen | 0:5c237fdcba23 | 23 | // Calculate linear-predictive coefficients |
MikamiUitOpen | 0:5c237fdcba23 | 24 | bool LinearPred::Execute(const float x[], float a[], |
MikamiUitOpen | 0:5c237fdcba23 | 25 | float &em) |
MikamiUitOpen | 0:5c237fdcba23 | 26 | { |
MikamiUitOpen | 0:5c237fdcba23 | 27 | AutoCorr(x); |
MikamiUitOpen | 0:5c237fdcba23 | 28 | return Durbin(a, em); |
MikamiUitOpen | 0:5c237fdcba23 | 29 | } |
MikamiUitOpen | 0:5c237fdcba23 | 30 | |
MikamiUitOpen | 0:5c237fdcba23 | 31 | // Calculate auto-correlation |
MikamiUitOpen | 0:5c237fdcba23 | 32 | void LinearPred::AutoCorr(const float x[]) |
MikamiUitOpen | 0:5c237fdcba23 | 33 | { |
MikamiUitOpen | 0:5c237fdcba23 | 34 | for (int j=0; j<=ORDER_; j++) |
MikamiUitOpen | 0:5c237fdcba23 | 35 | { |
MikamiUitOpen | 0:5c237fdcba23 | 36 | r_[j] = 0.0; |
MikamiUitOpen | 0:5c237fdcba23 | 37 | for (int n=0; n<N_DATA_-j; n++) |
MikamiUitOpen | 0:5c237fdcba23 | 38 | r_[j] = r_[j] + x[n]*x[n+j]; |
MikamiUitOpen | 0:5c237fdcba23 | 39 | } |
MikamiUitOpen | 0:5c237fdcba23 | 40 | } |
MikamiUitOpen | 0:5c237fdcba23 | 41 | |
MikamiUitOpen | 0:5c237fdcba23 | 42 | // Levinson-Durbin algorithm |
MikamiUitOpen | 0:5c237fdcba23 | 43 | bool LinearPred::Durbin(float a[], float &em) |
MikamiUitOpen | 0:5c237fdcba23 | 44 | { |
MikamiUitOpen | 0:5c237fdcba23 | 45 | // Initialization |
MikamiUitOpen | 0:5c237fdcba23 | 46 | em = r_[0]; |
MikamiUitOpen | 0:5c237fdcba23 | 47 | |
MikamiUitOpen | 0:5c237fdcba23 | 48 | // Repeat |
MikamiUitOpen | 0:5c237fdcba23 | 49 | for (int m=0; m<ORDER_; m++) |
MikamiUitOpen | 0:5c237fdcba23 | 50 | { |
MikamiUitOpen | 0:5c237fdcba23 | 51 | float w = r_[m+1]; |
MikamiUitOpen | 0:5c237fdcba23 | 52 | for (int j=0; j<=m-1; j++) |
MikamiUitOpen | 0:5c237fdcba23 | 53 | w = w - r_[m-j]*a[j]; |
MikamiUitOpen | 0:5c237fdcba23 | 54 | |
MikamiUitOpen | 0:5c237fdcba23 | 55 | k_[m] = w/em; |
MikamiUitOpen | 0:5c237fdcba23 | 56 | em = em*(1 - k_[m]*k_[m]); |
MikamiUitOpen | 0:5c237fdcba23 | 57 | |
MikamiUitOpen | 0:5c237fdcba23 | 58 | if (em < 0) break; // Error for negative squared sum of residual |
MikamiUitOpen | 0:5c237fdcba23 | 59 | |
MikamiUitOpen | 0:5c237fdcba23 | 60 | a[m] = k_[m]; |
MikamiUitOpen | 0:5c237fdcba23 | 61 | for (int j=0; j<=m-1; j++) |
MikamiUitOpen | 0:5c237fdcba23 | 62 | am_[j] = a[j]; |
MikamiUitOpen | 0:5c237fdcba23 | 63 | for (int j=0; j<=m-1; j++) |
MikamiUitOpen | 0:5c237fdcba23 | 64 | a[j] = am_[j] - k_[m]*am_[m-j-1]; |
MikamiUitOpen | 0:5c237fdcba23 | 65 | } |
MikamiUitOpen | 0:5c237fdcba23 | 66 | |
MikamiUitOpen | 0:5c237fdcba23 | 67 | if (em < 0) return false; |
MikamiUitOpen | 0:5c237fdcba23 | 68 | else return true; |
MikamiUitOpen | 0:5c237fdcba23 | 69 | } |
MikamiUitOpen | 0:5c237fdcba23 | 70 | } |
MikamiUitOpen | 0:5c237fdcba23 | 71 |