Kryentech ロゴ 電気工学の記事

2次デジタルローパスフィルタの導出

アナログ伝達関数から離散時間実装へ

デジタルフィルタは現代の信号処理の中核である。オーディオから制御まで、特に効率的で広く使われているのが2次IIRフィルタ(バイクアッド)である。

本記事では、アナログ伝達関数からデジタルフィルタがどう得られ、それがどのようにコードに直接対応するかを段階的に示す。

実践: デジタルフィルタの設計 – カットオフとサンプリング周波数からバイクアッド係数(計算機付き)

2次デジタルローパスフィルタ導出のブロック図
アナログの基礎から差分方程式まで、2次デジタルローパスの導出。

IIRフィルタとは(簡潔に)

IIR(無限インパルス応答)フィルタは、過去の出力サンプルを用いて現在の出力を計算する。計算量が少なくても強いフィルタ特性が得られる。

1. アナログの出発点

正規化された2次ローパスは次で与えられる。

\[ G(s) = \frac{1}{a s^2 + b s + 1} \]

ここで\(a\)は主にカットオフ周波数、\(b\)は減衰すなわちQに関係する。

2. 双一次変換

離散化には双一次変換を用いる。

\[ s = \frac{2}{T_s}\cdot\frac{1-z^{-1}}{1+z^{-1}} \]

\(c = \frac{2}{T_s}\)とすると、z領域では

\[ H(z) = \frac{z^{-2} + 2z^{-1} + 1}{(a c^2 - b c + 1) z^{-2} + (2 - 2a c^2) z^{-1} + (b c + a c^2 + 1)} \]

3. 差分方程式(IIR、2次)

入力\(U_E[k]\)、出力\(U_A[k]\)として

\[ U_A[k] = U_E[k] + 2U_E[k-1] + U_E[k-2] - vU_A[k-1] - uU_A[k-2] \]

ただし

\[ u = a c^2 - b c + 1,\quad v = 2 - 2a c^2,\quad w = b c + a c^2 + 1 \]

これは古典的なバイクアッドIIRである。正規化すれば標準的な\(b_0, b_1, b_2\)および\(a_1, a_2\)表記にも書き換えられる(下記)。

モデルから実装へ:デジタルフィルタ計算の概要
係数からコード上の再帰計算へ(バイクアッド計算機と係数も参照)。

数式モデルからコードへ

入力\(x[k]\)、出力\(y[k]\)とした差分方程式の一般形:

\[ y[k] = b_0 x[k] + b_1 x[k-1] + b_2 x[k-2] - a_1 y[k-1] - a_2 y[k-2] \]

これは数学的な記述である。実行可能なコードにするにはメモリ処理順に落とし込む。

1. 各項の意味

  • \(x[k]\) – 現在の入力サンプル
  • \(x[k-1]\), \(x[k-2]\) – 過去の入力
  • \(y[k-1]\), \(y[k-2]\) – 過去の出力

重要:CPUは自動的に「過去」を覚えない。変数に保存する必要がある。

2. 状態(メモリ)の定義

過去の値には通常次を用いる。

x1 = x[k-1]
x2 = x[k-2]
y1 = y[k-1]
y2 = y[k-2]

これがフィルタの状態である。

3. 式をそのままコードへ

式はほぼそのまま写せる。

y = b0 * x
  + b1 * x1
  + b2 * x2
  - a1 * y1
  - a2 * y2;

同じ差分方程式をコード形で書いただけである。

4. 状態の更新

出力計算後、次サンプル用にシフトする。

x2 = x1;
x1 = x;

y2 = y1;
y1 = y;

これにより今回の値が次回の「過去」になる。

5. サンプルごとの流れ

各入力サンプルで同じサイクルを繰り返す。

  1. 新しい入力\(x[k]\)を読む
  2. 出力\(y[k]\)を計算
  3. 状態を更新

通常はbiquad_process()のような関数がこれを担う。

6. 直感

フィルタは直近の値を覚え、係数で重み付けする。フィードフォワードは現在・過去入力(\(b_0, b_1, b_2\))、フィードバックは過去出力(\(a_1, a_2\))。これが典型的なフィルタ挙動(例:ローパス)を生む。

7. よくある誤り

  • 出力後に状態を更新しない → 誤動作や不安定
  • 状態シフトの順序が間違っている
  • 実装で\(a_1, a_2\)の符号を忘れる(標準形では減算として現れる)
  • 再帰が正規形を期待しているのに非正規化係数を使う

式→コードの要点:式を書く → 状態を保持 → 各サンプル計算 → 状態シフト。直接形IIのIIRバイクアッドの基本である。

コード実装(2次IIR)

導出した差分方程式はそのままソフトウェアに落とせる。2次IIR(バイクアッド)は状態変数が少なく効率的である。

一般形と係数

\[ y[k] = b_0 x[k] + b_1 x[k-1] + b_2 x[k-2] - a_1 y[k-1] - a_2 y[k-2] \]

  • \(b_0, b_1, b_2\) – フィードフォワード(分子/入力経路)
  • \(a_1, a_2\) – フィードバック(分母/再帰。正規化後は\(a_0=1\)が一般的)

Cの例(組み込み/MCU)

typedef struct {
    float b0, b1, b2;
    float a1, a2;
    float x1, x2;
    float y1, y2;
} Biquad;

float biquad_process(Biquad *f, float x) {
    float y = f->b0 * x
            + f->b1 * f->x1
            + f->b2 * f->x2
            - f->a1 * f->y1
            - f->a2 * f->y2;

    /* 状態更新 */
    f->x2 = f->x1;
    f->x1 = x;
    f->y2 = f->y1;
    f->y1 = y;

    return y;
}

利点:サンプルあたり演算が少なく、実行時間が予測しやすい。リアルタイムDSPやMCUに適する。

Pythonの例(解析/シミュレーション)

class Biquad:
    def __init__(self, b0, b1, b2, a1, a2):
        self.b0, self.b1, self.b2 = b0, b1, b2
        self.a1, self.a2 = a1, a2
        self.x1 = self.x2 = 0.0
        self.y1 = self.y2 = 0.0

    def process(self, x):
        y = (self.b0 * x +
             self.b1 * self.x1 +
             self.b2 * self.x2 -
             self.a1 * self.y1 -
             self.a2 * self.y2)

        self.x2 = self.x1
        self.x1 = x
        self.y2 = self.y1
        self.y1 = y

        return y

導出との対応

導出ではアナログの\(a\)、\(b\)、\(c=2/T_s\)、離散係数\(u,v,w\)が現れる。そこから\(H(z)\)を作り、実装では標準バイクアッド形の\(b_0,b_1,b_2,a_1,a_2\)へ写す。通常は分母の先頭係数で正規化(\(a_0=1\))する。

重要:リアルタイムの再帰は常にこの正規化係数で動く。

実務上の注意

  • 数値:高周波や低減衰では丸め誤差の影響が大きくなる。
  • 固定小数点と浮動小数点:FPUのないMCUはスケーリングした固定小数が多い。
  • 初期値:\(x_1,x_2,y_1,y_2\)は通常0から(静止開始)。
  • オーバーフロー:高ゲインや整数演算では飽和に注意。

実装のまとめ

2次IIRの実装は構造が単純で効率的である。難しいのは係数の正しい計算と正規化である。バイクアッドはオーディオ制御リアルタイムDSPの標準である。

パラメータ選択とツール

アナログ\(G(s)\)の連続パラメータ\(a,b\)はカットオフと減衰から選び、\(T_s\)はサンプリング周波数から決まる。設計・検証にはPython/NumPy、MATLAB/Simulink、DSPツールなどが使われる。

まとめ

本導出は、アナログ記述からデジタルローパスが系統的に得られることを示す。 バイクアッド構造により、組み込み、オーディオ、制御にそのまま使える効率的な実装が得られる。

係数の正しい計算と正規化が重要であり、実際の周波数応答を決める。

詳しくは次の記事も参照: カットオフ周波数からバイクアッド係数を求める

著者: Ruedi von Kryentech

作成: 2026年4月6日 · 最終更新: 2026年4月6日

最終更新時点の技術的内容。