STM32F446 内蔵の DAC から出力する際に,補間フィルタを利用し,標本化周波数を入力の際の4倍の標本化周波数で出力するためのライブラリ.このライブラリを登録した際のプログラム: Demo_DSP_ADDA_Multirate. Library for outputting from built-in DAC in STM32F446 using interpolation filter at sampling frequency of 4 times in case of input.

Dependencies:   Array_Matrix DSP_ADDA

Dependents:   Demo_DSP_ADDA_Multirate DSP_AD_DA_Multirate DSP_GraphicEqualizerB DSP_VariableLHpfB ... more

Files at this revision

API Documentation at this revision

Comitter:
MikamiUitOpen
Date:
Sat Nov 28 02:27:00 2020 +0000
Parent:
7:51726b376b75
Child:
9:9f391b2d51be
Commit message:
9

Changed in this revision

MultirateLiPh.cpp Show annotated file Show diff for this revision Revisions of this file
MultirateLiPh.hpp Show annotated file Show diff for this revision Revisions of this file
MultirateLiPhCoefs.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/MultirateLiPh.cpp	Sat Nov 07 02:17:52 2020 +0000
+++ b/MultirateLiPh.cpp	Sat Nov 28 02:27:00 2020 +0000
@@ -1,8 +1,8 @@
 //-----------------------------------------------------------
 //  出力を 4 倍にアップサンプリングするクラス
-//  補間処理で使うフィルタとして,直線位相 FIR フィルタを使用
+//  補間処理で使うフィルタ:直線位相 FIR フィルタ
 //  
-//  2020/06/18, Copyright (c) 2020 MIKAMI, Naoki
+//  2020/11/28, Copyright (c) 2020 MIKAMI, Naoki
 //-----------------------------------------------------------
 
 #include "MultirateLiPh.hpp"
@@ -12,20 +12,26 @@
     // コンストラクタ(デフォルトの補間フィルタの係数を使う場合)
     MultirateLiPh::MultirateLiPh(float fSampling,
                                  PinName pin, ADC_TypeDef* const adc)
-        : indexW_(0), FIR_LOOP_(ORDER_/4), CENTER_(ORDER_/(FACTOR_*2)),
-          un_(ORDER_/4, 0.0f),
-          h1_(ORDER_/4, HK1_), h2_(ORDER_/4, HK2_), h3_(ORDER_/4, HK3_)
-    {   Init(fSampling, pin, adc); }
+        : indexW_(0), FIR_LOOP_((ORDER_+2)/UR_), CENTER_((ORDER_+2)/(UR_*2)),
+          vn_((ORDER_+2)/UR_, 0.0f), h1_((ORDER_+2)/UR_, HK1_),
+          h2_((ORDER_+2)/UR_, HK2_), h3_((ORDER_+2)/UR_, HK3_)
+    {
+        MBED_ASSERT((ORDER_ % UR_) == 2);
+        Init(fSampling, pin, adc);
+    }
 
     // コンストラクタ(デフォルト以外の補間フィルタの係数を使う場合)
     MultirateLiPh::MultirateLiPh(float fSampling, int order,
                                  const float hk1[], const float hk2[],
                                  const float hk3[],
                                  PinName pin, ADC_TypeDef* const adc)
-        : indexW_(0), FIR_LOOP_(order/4), CENTER_(order/(FACTOR_*2)),
-          un_(order/4, 0.0f),
-          h1_(order/4, hk1), h2_(order/4, hk2), h3_(order/4, hk3)
-    {   Init(fSampling, pin, adc); }
+        : indexW_(0), FIR_LOOP_((order+2)/UR_), CENTER_((order+2)/(UR_*2)),
+          vn_((order+2)/UR_, 0.0f), h1_((order+2)/UR_, hk1),
+          h2_((order+2)/UR_, hk2), h3_((order+2)/UR_, hk3)
+    {
+        MBED_ASSERT((order % UR_) == 2);
+        Init(fSampling, pin, adc);
+    }
 
     // 標本化の実行開始
     void MultirateLiPh::Start(void (*Func)())
@@ -42,14 +48,14 @@
     // 補間用フィルタを実行し,処理結果を出力用バッファへ書き込む
     void MultirateLiPh::Output(float yn)
     {
-        un_[0] = yn;    // 補間フィルタ用バッファの先頭に書き込む
+        vn_[0] = yn;    // 補間フィルタ用バッファの先頭に書き込む
 
-        buf_[ModIndex(indexW_)] = un_[CENTER_];
-        buf_[ModIndex(indexW_)] = Interpolator(h1_);
-        buf_[ModIndex(indexW_)] = Interpolator(h2_);
-        buf_[ModIndex(indexW_)] = Interpolator(h3_);
+        buf_[ModIndex(indexW_)] = vn_[CENTER_];
+        buf_[ModIndex(indexW_)] = Interpolate(h1_);
+        buf_[ModIndex(indexW_)] = Interpolate(h2_);
+        buf_[ModIndex(indexW_)] = Interpolate(h3_);
 
-        for (int k=FIR_LOOP_-1; k>0; k--) un_[k] = un_[k-1];
+        for (int k=FIR_LOOP_-1; k>0; k--) vn_[k] = vn_[k-1];
     }
 
     // ADC 変換終了割り込みに対する割り込みサービス・ルーチン
@@ -62,14 +68,14 @@
 
         if (count == 0)                 // AD変換器からの入力信号は4回に1回使う
             NVIC->STIR = CAN2_TX_IRQn;  // ソフトウェア割込み発生,信号処理を起動
-        count = ++count & MASK_FACTOR_; // 入力を4回に1回行うための処理
+        count = ++count & MASK_UR_; // 入力を4回に1回行うための処理
     }
 
     // 補間用 FIR フィルタ
-    float MultirateLiPh::Interpolator(const float hk[]) const
+    float MultirateLiPh::Interpolate(const float hk[]) const
     {
         float y = 0;
-        for (int n=0; n<FIR_LOOP_; n++) y += un_[n]*hk[n];
+        for (int n=0; n<FIR_LOOP_; n++) y += vn_[n]*hk[n];
         return y;
     }
 
@@ -79,13 +85,13 @@
         NVIC_SetPriority(ADC_IRQn, 0);      // ADC 終了割り込み:最優先
         NVIC_SetPriority(CAN2_TX_IRQn, 1);  // ソフトウェア割り込みで使用:2番目に優先
 
-        adc_ = new DspAdc_Intr(fSampling*FACTOR_, pin, adc);
+        adc_ = new DspAdc_Intr(fSampling*UR_, pin, adc);
     }
 
     // static メンバの実体の宣言/初期化
     DspAdc_Intr *MultirateLiPh::adc_;    // AD変換器のオブジェクトのポインタ
     DspDac MultirateLiPh::dac_;          // DA変換器のオブジェクト
-    Array<float> MultirateLiPh::buf_(2*FACTOR_, 0.0f);
-    int MultirateLiPh::indexR_ = FACTOR_;
+    Array<float> MultirateLiPh::buf_(2*UR_, 0.0f);
+    int MultirateLiPh::indexR_ = UR_;
     float MultirateLiPh::xn_;
 }
\ No newline at end of file
--- a/MultirateLiPh.hpp	Sat Nov 07 02:17:52 2020 +0000
+++ b/MultirateLiPh.hpp	Sat Nov 28 02:27:00 2020 +0000
@@ -1,10 +1,10 @@
 //-----------------------------------------------------------
 //  出力を 4 倍にアップサンプリングするクラス(ヘッダ)
-//  補間処理で使うフィルタとして,直線位相 FIR フィルタを使用
+//  補間処理で使うフィルタ:直線位相 FIR フィルタ
 //
 //      出力端子: A2 (PA_4) 
 //
-//  2020/09/13, Copyright (c) 2020 MIKAMI, Naoki
+//  2020/11/28, Copyright (c) 2020 MIKAMI, Naoki
 //-----------------------------------------------------------
 
 #include "DSP_AdcIntr.hpp"
@@ -45,10 +45,10 @@
         void Output(float yn);
 
     private:
-        static const int FACTOR_ = 4;   // アップサンプリング倍率:4 倍
-                                        // この倍率は 2 のべき乗にすること
-        static const int MASK_FACTOR_ = FACTOR_ - 1;
-        static const int MASK_BUF_ = 2*FACTOR_ - 1;
+        static const int UR_ = 4;   // アップサンプリング倍率:4 倍
+                                    // この倍率は 2 のべき乗にすること
+        static const int MASK_UR_ = UR_ - 1;
+        static const int MASK_BUF_ = 2*UR_ - 1;
 
         static DspAdc_Intr *adc_;   // AD変換器のオブジェクトのポインタ
         static DspDac dac_;         // DA変換器のオブジェクト
@@ -61,7 +61,7 @@
         // 補間用フィルタ用
         const int FIR_LOOP_;        // FIR フィルタのループの数
         const int CENTER_;          // 補間処理をしない信号の位置
-        Array<float> un_;           // FIR フィルタの遅延器に対応するバッファ
+        Array<float> vn_;           // FIR フィルタの遅延器に対応するバッファ
         Array<float> h1_, h2_, h3_; // FIR フィルタの係数
 
         // 補間用フィルタ用の係数(デフォルト)
@@ -76,7 +76,7 @@
         static void AdcIsr();
 
         // 補間用 FIR フィルタ
-        float Interpolator(const float hk[]) const;
+        float Interpolate(const float hk[]) const;
 
         // ADC の初期化と割込み優先順位の設定
         void Init(float fSampling, PinName pin, ADC_TypeDef* const adc);
--- a/MultirateLiPhCoefs.cpp	Sat Nov 07 02:17:52 2020 +0000
+++ b/MultirateLiPhCoefs.cpp	Sat Nov 28 02:27:00 2020 +0000
@@ -1,9 +1,9 @@
 //-------------------------------------------------------------------
 // デフォルトの補間用フィルタの係数
-//      このの係数は,入力の標本化周波数を 10 kHz,出力の標本化周波数を
-//      40 kHz として設計したもの
+//      この係数は,入力の標本化周波数を 10 kHz,
+//      出力の標本化周波数を 40 kHz として設計した
 //
-//  2020/09/12, Copyright (c) 2020 MIKAMI, Naoki
+//  2020/11/28, Copyright (c) 2020 MIKAMI, Naoki
 //-------------------------------------------------------------------
 
 #include "MultirateLiPh.hpp"
@@ -12,27 +12,27 @@
 {
     // 使用窓関数   Kaiser 窓
     // 標本化周波数 (kHz)      40.000000
-    // 次数                    72
+    // 次数                    70
     // 種類         LPF
     // 遮断周波数 (kHz)         5.000000
-    // 減衰量 (dB)             40.00
-    const int MultirateLiPh::ORDER_ = 72; 
+    // 減衰量 (dB)             40.00 
+    const int MultirateLiPh::ORDER_ = 70;
     const float MultirateLiPh::HK1_[] = {
-         4.431256E-03f, -8.146596E-03f,  1.341366E-02f, -2.077330E-02f,
-         3.116614E-02f, -4.650688E-02f,  7.151836E-02f, -1.218529E-01f,
-         2.971602E-01f,  8.993316E-01f, -1.751857E-01f,  9.144896E-02f,
-        -5.727932E-02f,  3.802786E-02f, -2.550498E-02f,  1.678651E-02f,
-        -1.055827E-02f,  6.120216E-03f};
+         3.806160E-03f, -7.410556E-03f,  1.260559E-02f, -1.994242E-02f,
+         3.036776E-02f, -4.579744E-02f,  7.095016E-02f, -1.214690E-01f,
+         2.969901E-01f,  8.992744E-01f, -1.749060E-01f,  9.096828E-02f,
+        -5.663444E-02f,  3.726704E-02f, -2.468324E-02f,  1.596038E-02f,
+        -9.780624E-03f,  5.435560E-03f};
     const float MultirateLiPh::HK2_[] = {
-         7.405152E-03f, -1.315348E-02f,  2.125564E-02f, -3.257789E-02f,
-         4.868468E-02f, -7.290120E-02f,  1.139337E-01f, -2.039652E-01f,
-         6.338376E-01f,  6.338376E-01f, -2.039652E-01f,  1.139337E-01f,
-        -7.290120E-02f,  4.868468E-02f, -3.257789E-02f,  2.125564E-02f,
-        -1.315348E-02f,  7.405152E-03f};
+         6.477720E-03f, -1.208128E-02f,  2.009782E-02f, -3.140681E-02f,
+         4.757964E-02f, -7.194132E-02f,  1.131902E-01f, -2.034948E-01f,
+         6.336764E-01f,  6.336764E-01f, -2.034948E-01f,  1.131902E-01f,
+        -7.194132E-02f,  4.757964E-02f, -3.140681E-02f,  2.009782E-02f,
+        -1.208128E-02f,  6.477720E-03f};
     const float MultirateLiPh::HK3_[] = {
-         6.120216E-03f, -1.055827E-02f,  1.678651E-02f, -2.550498E-02f,
-         3.802786E-02f, -5.727932E-02f,  9.144896E-02f, -1.751857E-01f,
-         8.993316E-01f,  2.971602E-01f, -1.218529E-01f,  7.151836E-02f,
-        -4.650688E-02f,  3.116614E-02f, -2.077330E-02f,  1.341366E-02f,
-        -8.146596E-03f,  4.431256E-03f};
+         5.435560E-03f, -9.780624E-03f,  1.596038E-02f, -2.468324E-02f,
+         3.726704E-02f, -5.663444E-02f,  9.096828E-02f, -1.749060E-01f,
+         8.992744E-01f,  2.969901E-01f, -1.214690E-01f,  7.095016E-02f,
+        -4.579744E-02f,  3.036776E-02f, -1.994242E-02f,  1.260559E-02f,
+        -7.410556E-03f,  3.806160E-03f};
 }
\ No newline at end of file