Adaptive line enhancer using normalized leaky LMS algorithm. 学習同定法を用いる線スペクトル強調器.係数の更新は leaky LMS 法を使用.

Dependencies:   Array_Matrix F446_AD_DA UIT_AQM1602 mbed

Committer:
MikamiUitOpen
Date:
Tue Feb 21 13:42:22 2017 +0000
Revision:
0:db50a6a3e574
1

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MikamiUitOpen 0:db50a6a3e574 1 //---------------------------------------------------------------------------
MikamiUitOpen 0:db50a6a3e574 2 // 学習同定法による線スペクトル強調器(ALE)
MikamiUitOpen 0:db50a6a3e574 3 // 係数更新で Leaky LMS 法を使用
MikamiUitOpen 0:db50a6a3e574 4 // 次数:100 次,遅延器数:5 個
MikamiUitOpen 0:db50a6a3e574 5 // 作成者,著作権者: 三上直樹 2017/02/21
MikamiUitOpen 0:db50a6a3e574 6 //---------------------------------------------------------------------------
MikamiUitOpen 0:db50a6a3e574 7
MikamiUitOpen 0:db50a6a3e574 8 #include "F446_ADC_Interrupt.hpp" // AD, DA
MikamiUitOpen 0:db50a6a3e574 9 #include "AQM1602.hpp" // LCD 表示器
MikamiUitOpen 0:db50a6a3e574 10 using namespace Mikami;
MikamiUitOpen 0:db50a6a3e574 11
MikamiUitOpen 0:db50a6a3e574 12 const int FS_ = 24000; // 標本化周波数: 24 kHz
MikamiUitOpen 0:db50a6a3e574 13
MikamiUitOpen 0:db50a6a3e574 14 const int ORDER_ = 200; // 次数
MikamiUitOpen 0:db50a6a3e574 15 const int DELAY_ = 5; // 相関除去用の遅延器数
MikamiUitOpen 0:db50a6a3e574 16 const int N_ALL_ = ORDER_ + DELAY_; // 全体で必要な遅延器数
MikamiUitOpen 0:db50a6a3e574 17
MikamiUitOpen 0:db50a6a3e574 18 const float GM_ = 0.996; // γ
MikamiUitOpen 0:db50a6a3e574 19 const float S0_ = 0.1; // 分母が 0 になるのを防止
MikamiUitOpen 0:db50a6a3e574 20 float alpha_ = 0.2; // α
MikamiUitOpen 0:db50a6a3e574 21
MikamiUitOpen 0:db50a6a3e574 22 float x_[N_ALL_+1], h_[ORDER_+1];
MikamiUitOpen 0:db50a6a3e574 23
MikamiUitOpen 0:db50a6a3e574 24 AdcDual_Intr myAdc_(FS_); // 参照:"F446_ADC_Interrupt.hpp"
MikamiUitOpen 0:db50a6a3e574 25 DacDual myDac_; // 参照:"F446_DAC.hpp"
MikamiUitOpen 0:db50a6a3e574 26 DigitalOut ledG_(D10, 1); // LED 緑色
MikamiUitOpen 0:db50a6a3e574 27
MikamiUitOpen 0:db50a6a3e574 28 // ADC 変換終了割り込みに対する割り込みサービス・ルーチン
MikamiUitOpen 0:db50a6a3e574 29 void AdcIsr()
MikamiUitOpen 0:db50a6a3e574 30 {
MikamiUitOpen 0:db50a6a3e574 31 static float mu, err_mu;
MikamiUitOpen 0:db50a6a3e574 32 static float ss = 0.0f;
MikamiUitOpen 0:db50a6a3e574 33
MikamiUitOpen 0:db50a6a3e574 34 float xn1, xn2, yn1, yn2;
MikamiUitOpen 0:db50a6a3e574 35 myAdc_.Read(xn1, xn2); // 入力(xn2 は使わない)
MikamiUitOpen 0:db50a6a3e574 36
MikamiUitOpen 0:db50a6a3e574 37 // 左チャンネルの処理(FIR フィルタの計算)
MikamiUitOpen 0:db50a6a3e574 38 x_[0] = xn1;
MikamiUitOpen 0:db50a6a3e574 39 yn1 = 0.0;
MikamiUitOpen 0:db50a6a3e574 40 for(int k=0; k<=ORDER_; k++) yn1 = yn1 + x_[k+DELAY_]*h_[k];
MikamiUitOpen 0:db50a6a3e574 41
MikamiUitOpen 0:db50a6a3e574 42 // ステップ・サイズ・パラメータの計算
MikamiUitOpen 0:db50a6a3e574 43 ss = GM_*ss + xn1*xn1; // パワに比例する値の推定値
MikamiUitOpen 0:db50a6a3e574 44 mu = alpha_/(ss + S0_); // ステップ・サイズ・パラメータの計算
MikamiUitOpen 0:db50a6a3e574 45 // 係数の更新
MikamiUitOpen 0:db50a6a3e574 46 err_mu = (xn1 - yn1)*mu; // 誤差*μ
MikamiUitOpen 0:db50a6a3e574 47 for(int k=0; k<=ORDER_; k++)
MikamiUitOpen 0:db50a6a3e574 48 h_[k] = GM_*h_[k] + err_mu*x_[k+DELAY_];
MikamiUitOpen 0:db50a6a3e574 49
MikamiUitOpen 0:db50a6a3e574 50 // 遅延器内のデータの移動
MikamiUitOpen 0:db50a6a3e574 51 for (int k=N_ALL_; k>0; k--) x_[k] = x_[k-1];
MikamiUitOpen 0:db50a6a3e574 52
MikamiUitOpen 0:db50a6a3e574 53 // 右チャンネル出力は入力をそのまま出力する
MikamiUitOpen 0:db50a6a3e574 54 yn2 = xn1;
MikamiUitOpen 0:db50a6a3e574 55
MikamiUitOpen 0:db50a6a3e574 56 myDac_.Write(yn1, yn2); // 出力
MikamiUitOpen 0:db50a6a3e574 57 }
MikamiUitOpen 0:db50a6a3e574 58
MikamiUitOpen 0:db50a6a3e574 59 int main()
MikamiUitOpen 0:db50a6a3e574 60 {
MikamiUitOpen 0:db50a6a3e574 61 printf("\r\nALE using normalized LMS algorithm\r\n");
MikamiUitOpen 0:db50a6a3e574 62 AnalogIn a3In(A3); // VR からの電圧読み取り用
MikamiUitOpen 0:db50a6a3e574 63 Aqm1602 lcd; // LCD 表示器
MikamiUitOpen 0:db50a6a3e574 64 lcd.WriteStringXY("ALE", 0, 0);
MikamiUitOpen 0:db50a6a3e574 65
MikamiUitOpen 0:db50a6a3e574 66 // 出力の LPF の遮断周波数を 10 kHz に設定
MikamiUitOpen 0:db50a6a3e574 67 myDac_.ScfClock(10000*100);
MikamiUitOpen 0:db50a6a3e574 68
MikamiUitOpen 0:db50a6a3e574 69 // ALE のバッファのクリア
MikamiUitOpen 0:db50a6a3e574 70 for (int k=0; k<=N_ALL_; k++) x_[k] = 0.0f;
MikamiUitOpen 0:db50a6a3e574 71 for (int k=0; k<=ORDER_; k++) h_[k] = 0.0f;
MikamiUitOpen 0:db50a6a3e574 72
MikamiUitOpen 0:db50a6a3e574 73 // ADC 変換終了割り込みに対する割り込みサービス・ルーチン割り当て
MikamiUitOpen 0:db50a6a3e574 74 myAdc_.SetIntrVec(&AdcIsr);
MikamiUitOpen 0:db50a6a3e574 75
MikamiUitOpen 0:db50a6a3e574 76 float vrOld = -1;
MikamiUitOpen 0:db50a6a3e574 77 while(1)
MikamiUitOpen 0:db50a6a3e574 78 {
MikamiUitOpen 0:db50a6a3e574 79 float vrNow = a3In.read();
MikamiUitOpen 0:db50a6a3e574 80 if (fabsf(vrOld - vrNow) > 0.02f)
MikamiUitOpen 0:db50a6a3e574 81 {
MikamiUitOpen 0:db50a6a3e574 82 alpha_ = powf(10.0f, (vrNow-1)*2);
MikamiUitOpen 0:db50a6a3e574 83 vrOld = vrNow;
MikamiUitOpen 0:db50a6a3e574 84
MikamiUitOpen 0:db50a6a3e574 85 printf("a0 = %5.3f\r\n", alpha_);
MikamiUitOpen 0:db50a6a3e574 86 lcd.ClearLine(1);
MikamiUitOpen 0:db50a6a3e574 87 lcd.WriteStringXY("alpha: ", 0, 1);
MikamiUitOpen 0:db50a6a3e574 88 lcd.WriteValue("%6.3f", alpha_);
MikamiUitOpen 0:db50a6a3e574 89 }
MikamiUitOpen 0:db50a6a3e574 90 wait(0.2f);
MikamiUitOpen 0:db50a6a3e574 91 }
MikamiUitOpen 0:db50a6a3e574 92 }