1. RBJ フィルターアルゴリズム
1.1 概略
「RBJ フィルターアルゴリズム」と書きましたが、実際には Robert Bristow-Johnson氏がWeb上で公開した、
デジタルフィルターの設計式をまとめた有名なテキスト『Audio EQ Cookbook』について簡単に紹介したいと思います。
この『Audio EQ Cookbook』は、オーディオ信号処理で最も広く使われているデジタルフィルター(双二次フィルター:Biquad Filter)の係数を計算するための計算レシピ集(アルゴリズム)です。
Web Audio APIの標準仕様や、数多くの音楽制作プラグイン(VSTなど)の内部でそのまま採用されています。
この『Audio EQ Cookbook』は、オーディオ信号処理で最も広く使われているデジタルフィルター(双二次フィルター:Biquad Filter)の係数を計算するための計算レシピ集(アルゴリズム)です。
Web Audio APIの標準仕様や、数多くの音楽制作プラグイン(VSTなど)の内部でそのまま採用されています。
1.2 特徴
(1) 一発で計算できる:
サンプリング周波数(Fs)、遮断・中心周波数(f₀)、クオリティファクタ(Q または帯域幅)、ゲイン(dB)を入れるだけで、
複雑な行列計算などをせずに四則演算と三角関数(sin, cos)だけで一瞬で係数が求まります。
(2) あらゆるフィルターに対応:
同じ仕組み(双二次フィルター)を使いながら、計算式(レシピ)を少し変えるだけで、以下の8種類以上の定番フィルターをすべて作ることができます。
| フィルター種類 | 簡単な役割 |
| ①ローパス (LPF) | 指定した周波数より低い音だけを通す(モコモコした音にする) |
| ②ハイパス (HPF) | 指定した周波数より高い音だけを通す(低音のゴソゴソ音をカット) |
| ③バンドパス (BPF) | 特定の周波数周辺の狭い範囲だけを通す |
| ④ノッチ (Notch) | 特定の周波数ピンポイントだけを完全に消し去る(ハウリング対策など) |
| ⑤ピーキング EQ | 一般的なイコライザ。特定の周波数周辺を山型にブースト/カットする |
| ⑥ローシェルフ / ハイシェルフ | 指定した周波数より低域、または高域を全体的に棚型に上げ下げする |
| ⑦オールパス (APF) | 音量は変えずに、位相(音のタイミング)だけを変化させる |
1.3 アルゴリズムの3つの核
このアルゴリズムを簡単に説明すると、以下の3つのステップで成り立っています。
(1) アナログ回路をベースにする(アナログプロトタイプ)
(1) アナログ回路をベースにする(アナログプロトタイプ)
まずは、昔ながらのアナログオーディオ回路(理想的な電気回路)のフィルター特性を基準(モデル)とします。
(2) デジタル世界へ変換する(双一次変換 / BLT)
アナログの数式をデジタルの数式に変換するために、双一次変換(Bilinear Transform)という数学的な手法を使います。
このとき、デジタル化による周波数の歪み(周波数ワーピング)が発生するため、あらかじめ計算を補正(プレワーピング)しておく処理も組み込まれています。
(3) 5つの係数を導き出すこのとき、デジタル化による周波数の歪み(周波数ワーピング)が発生するため、あらかじめ計算を補正(プレワーピング)しておく処理も組み込まれています。
変換した結果、デジタルフィルターを動かすために必要な5つの係数(b₀, b₁, b₂ と a₁, a₂ ※a₀=1 に正規化)を直接求めるための一発の計算式が導き出されます。
1.4 アナログから一般式へ
アナログ回路をベースにする(アナログプロトタイプ)
インダクタ(L)とキャパシタ(C)という2つのエネルギー蓄積要素を持つLCR回路の入力と出力の関係を、ラプラス変換を用いて代数式の一般式を作成します。
\(\begin{aligned}H(s)&=\frac{b_{2}s^{2}+b_{1}s+b_{0}}{a_{2}s^{2}+a_{1}s+a_{0}}\end{aligned}\)
インダクタ(L)とキャパシタ(C)という2つのエネルギー蓄積要素を持つLCR回路の入力と出力の関係を、ラプラス変換を用いて代数式の一般式を作成します。
\(\begin{aligned}H(s)&=\frac{b_{2}s^{2}+b_{1}s+b_{0}}{a_{2}s^{2}+a_{1}s+a_{0}}\end{aligned}\)
1.4.1 各LCR素子の「s領域」での特性
時間領域の微分・積分方程式をラプラス変換(時間を変数 \(s\) に変換)すると、各素子の電圧 \(V(s)\) と電流 \(I(s)\) の関係(インピーダンス \(Z\))は以下のように単純な掛け算で表せます。
• 抵抗 (R): \(Z_R = R\) (電圧は電流に比例)
• インダクタ (L): \(Z_L = sL\) (電圧は電流の微分に比例:\(v = L \frac{di}{dt}\))
• キャパシタ (C): \(Z_C = \frac{1}{sC}\) (電圧は電流の積分に比例:\(v = \frac{1}{C} \int i dt\))
• 抵抗 (R): \(Z_R = R\) (電圧は電流に比例)
• インダクタ (L): \(Z_L = sL\) (電圧は電流の微分に比例:\(v = L \frac{di}{dt}\))
• キャパシタ (C): \(Z_C = \frac{1}{sC}\) (電圧は電流の積分に比例:\(v = \frac{1}{C} \int i dt\))
1.4.2 脱線「ラプラス変換」
ラプラス変換の世界では、微分を表す記号「\(\frac{d}{dt}\)」そのものが「\(s\)」という1つの文字に変身し、積分を表す記号「\(\int \cdots dt\)」そのものが「\(\frac{1}{s}\)」に変身します。
(1)微分(インダクタ)の場合の変身
(2)積分(キャパシタ)の場合の変身
(3)なぜそんな都合よく変身できるのか?
(1)微分(インダクタ)の場合の変身
現実世界のインダクタの式をパーツ分解してみます。
\(v=L\times \underbrace{\frac{d}{dt}}_{\text{①「時間を細かく区切る」という微分の命令}}\quad \underbrace{i}_{\text{②電流}}\)
この式の中の ①「\(\frac{d}{dt}\)」という部分が、ラプラス変換によって丸ごと「\(s\)」という文字に変身します。
• 電圧 \(v\) ➔ 大文字の \(V(s)\) に変身
• 電流 \(i\) ➔ 大文字の \(I(s)\) に変身
• 微分の命令 \(\frac{d}{dt}\) ➔ \(s\) に変身(インダクタの \(L\) は定数なのでそのまま)
パーツをそのまま置き換えて合体させると、こうなります。
\(V(s)=L\times \mathbfit{s}\times I(s)\)
並び替えると:
\(V(s)=(sL)\times I(s)\)
つまり、「微分しなさい」というややこしい命令(\(\frac{d}{dt}\))が、ただの「\(s\) を掛け算しなさい」という文字(パーツ)にすり替わったことになります。
\(v=L\times \underbrace{\frac{d}{dt}}_{\text{①「時間を細かく区切る」という微分の命令}}\quad \underbrace{i}_{\text{②電流}}\)
この式の中の ①「\(\frac{d}{dt}\)」という部分が、ラプラス変換によって丸ごと「\(s\)」という文字に変身します。
• 電圧 \(v\) ➔ 大文字の \(V(s)\) に変身
• 電流 \(i\) ➔ 大文字の \(I(s)\) に変身
• 微分の命令 \(\frac{d}{dt}\) ➔ \(s\) に変身(インダクタの \(L\) は定数なのでそのまま)
パーツをそのまま置き換えて合体させると、こうなります。
\(V(s)=L\times \mathbfit{s}\times I(s)\)
並び替えると:
\(V(s)=(sL)\times I(s)\)
つまり、「微分しなさい」というややこしい命令(\(\frac{d}{dt}\))が、ただの「\(s\) を掛け算しなさい」という文字(パーツ)にすり替わったことになります。
(2)積分(キャパシタ)の場合の変身
今度は積分の式をパーツ分解してみます。
\(v=\frac{1}{C}\times \underbrace{\int \cdots dt}_{\text{①「コツコツ積み上げる」という積分の命令}}\quad \underbrace{i}_{\text{②電流}}\)
積分は微分のちょうど「真逆」の操作です。
数学の世界では、逆の操作をするときは「分母と分子をひっくり返す(逆数にする)」というルールがありますよね。(例えば、2倍の逆は \(\frac{1}{2}\) 倍にするのと同じです)。
そのため、微分が「\(s\)」になるなら、その真逆である積分の命令「\(\int \cdots dt\)」は、ひっくり返って「\(\frac{1}{s}\)」という文字に変身します。
• 電圧 \(v\) ➔ 大文字の \(V(s)\) に変身
• 電流 \(i\) ➔ 大文字の \(I(s)\) に変身
• 積分の命令 \(\int \cdots dt\) ➔ \(\frac{\mathbfit{1}}{\mathbfit{s}}\) に変身(\(C\) はそのまま分母にいます)
パーツを置き換えて合体させます。
\(V(s)=\frac{1}{C}\times \frac{\mathbfit{1}}{\mathbfit{s}}\times I(s)\)
まとめると:
\(V(s)=\left(\frac{1}{sC}\right)\times I(s)\)
こちらも、「積分しなさい」という命令が、丸ごと「分母に \(s\) を入れなさい(\(s\) で割り算しなさい)」というパーツにすり替わりました。
\(v=\frac{1}{C}\times \underbrace{\int \cdots dt}_{\text{①「コツコツ積み上げる」という積分の命令}}\quad \underbrace{i}_{\text{②電流}}\)
積分は微分のちょうど「真逆」の操作です。
数学の世界では、逆の操作をするときは「分母と分子をひっくり返す(逆数にする)」というルールがありますよね。(例えば、2倍の逆は \(\frac{1}{2}\) 倍にするのと同じです)。
そのため、微分が「\(s\)」になるなら、その真逆である積分の命令「\(\int \cdots dt\)」は、ひっくり返って「\(\frac{1}{s}\)」という文字に変身します。
• 電圧 \(v\) ➔ 大文字の \(V(s)\) に変身
• 電流 \(i\) ➔ 大文字の \(I(s)\) に変身
• 積分の命令 \(\int \cdots dt\) ➔ \(\frac{\mathbfit{1}}{\mathbfit{s}}\) に変身(\(C\) はそのまま分母にいます)
パーツを置き換えて合体させます。
\(V(s)=\frac{1}{C}\times \frac{\mathbfit{1}}{\mathbfit{s}}\times I(s)\)
まとめると:
\(V(s)=\left(\frac{1}{sC}\right)\times I(s)\)
こちらも、「積分しなさい」という命令が、丸ごと「分母に \(s\) を入れなさい(\(s\) で割り算しなさい)」というパーツにすり替わりました。
(3)なぜそんな都合よく変身できるのか?
「命令の記号が文字に変わるなんて、そんな手品みたいなことが許されるの?」と思われるかもしれません。
実は、ラプラス変換という翻訳の裏側では、すべての関数を \(e^{st}\)(指数関数) という特殊な数式をベースにして計算するという数学的な仕掛けがあります。
この \(e^{st}\) という関数は、「1回微分すると、勝手に前に \(s\) がポロンと飛び出してくる」という不思議な性質を持っています。
この数学の性質を上手に利用しているため、私たちが使うときには、難しい計算をすっ飛ばして「微分の記号を見つけたら \(s\) に書き換える」「積分の記号を見つけたら \(\frac{1}{s}\) に書き換える」という、 パズルのような作業だけで済むようになっているのです。
実は、ラプラス変換という翻訳の裏側では、すべての関数を \(e^{st}\)(指数関数) という特殊な数式をベースにして計算するという数学的な仕掛けがあります。
この \(e^{st}\) という関数は、「1回微分すると、勝手に前に \(s\) がポロンと飛び出してくる」という不思議な性質を持っています。
この数学の性質を上手に利用しているため、私たちが使うときには、難しい計算をすっ飛ばして「微分の記号を見つけたら \(s\) に書き換える」「積分の記号を見つけたら \(\frac{1}{s}\) に書き換える」という、 パズルのような作業だけで済むようになっているのです。
1.4.3 具体的な回路例と方程式
回路図


分子・分母がともに2次式になる代表的な例として、以下の分圧回路を考えます。
• 回路構成: 入力電圧 \(V_{in}\) に対して、抵抗 \(R_{1}\) と、「抵抗 \(R_{2}\) + インダクタ \(L\) + キャパシタ \(C\)」の直列部分が直列に接続されている回路。
• 出力電圧: 「\(R_2, L, C\) の直列部分」の両端の電圧を \(V_{out}\) とします。
この回路の合成インピーダンスは以下のようになります。
• 出力側のインピーダンス: \(Z_{out} = sL + R_2 + \frac{1}{sC}\)
• 回路全体のインピーダンス: \(Z_{all} = R_1 + Z_{out} = sL + (R_1 + R_2) + \frac{1}{sC}\)
• 回路構成: 入力電圧 \(V_{in}\) に対して、抵抗 \(R_{1}\) と、「抵抗 \(R_{2}\) + インダクタ \(L\) + キャパシタ \(C\)」の直列部分が直列に接続されている回路。
• 出力電圧: 「\(R_2, L, C\) の直列部分」の両端の電圧を \(V_{out}\) とします。
この回路の合成インピーダンスは以下のようになります。
• 出力側のインピーダンス: \(Z_{out} = sL + R_2 + \frac{1}{sC}\)
• 回路全体のインピーダンス: \(Z_{all} = R_1 + Z_{out} = sL + (R_1 + R_2) + \frac{1}{sC}\)
1.4.4 伝達関数 \(H(s)\) の導出計算
ステップ1:出力電圧 \(V_{out}(s)\) を式にする
ステップ2:入力電圧 \(V_{in}(s)\) を式にする
ステップ3:伝達関数 \(H(s)\) の形に合体させる
出力電圧は、縦に並んだ3つの部品(\(R_2, L_1, C_1\))の全体に掛かる電圧です。
オームの法則「電圧 = 抵抗(インピーダンス)× 電流」に当てはめると、次のように表せます。
\(V_{out}(s)=\left(R_{2}+sL+\frac{1}{sC}\right)\times I(s)\quad \text{--- ①}\)
オームの法則「電圧 = 抵抗(インピーダンス)× 電流」に当てはめると、次のように表せます。
\(V_{out}(s)=\left(R_{2}+sL+\frac{1}{sC}\right)\times I(s)\quad \text{--- ①}\)
ステップ2:入力電圧 \(V_{in}(s)\) を式にする
入力電圧は、回路全体のスタートからゴールまでに掛かる電圧です。
つまり、\(R_{1}\) と、その先にある縦の3つの部品すべてを合わせた電圧になります。
同じように電流 \(I(s)\) を使って表すと、こうなります。
\(V_{in}(s)=\left(R_{1}+R_{2}+sL+\frac{1}{sC}\right)\times I(s)\quad \text{--- ②}\)
つまり、\(R_{1}\) と、その先にある縦の3つの部品すべてを合わせた電圧になります。
同じように電流 \(I(s)\) を使って表すと、こうなります。
\(V_{in}(s)=\left(R_{1}+R_{2}+sL+\frac{1}{sC}\right)\times I(s)\quad \text{--- ②}\)
ステップ3:伝達関数 \(H(s)\) の形に合体させる
伝達関数 \(H(s)\) の定義は、「入力に対する出力の比(\(\frac{V_{out}}{V_{in}}\))」でしたね。
①と②の式をそのまま分数にはめ込んでみます。
\(H(s)=\frac{V_{out}(s)}{V_{in}(s)}=\frac{\left(R_{2}+sL+\frac{1}{sC}\right)\times I(s)}{\left(R_{1}+R_{2}+sL+\frac{1}{sC}\right)\times I(s)}\)
分母、分子にある Is を削除し
\(H(s)=\frac{V_{out}(s)}{V_{in}(s)}=\frac{Z_{out}}{Z_{all}}=\frac{sL+R_{2}+\frac{1}{sC}}{sL+(R_{1}+R_{2})+\frac{1}{sC}}\)
この繁分数の形を解消するために、分子と分母に \(sC\) を掛けます。
\(H(s)=\frac{(sL+R_{2}+\frac{1}{sC})\cdot sC}{(sL+R_{1}+R_{2}+\frac{1}{sC})\cdot sC}\)
それぞれ展開して \(s\) の次数(高い順)に整理します。
\(H(s)=\frac{LCs^{2}+R_{2}Cs+1}{LCs^{2}+(R_{1}+R_{2})Cs+1}\)
①と②の式をそのまま分数にはめ込んでみます。
\(H(s)=\frac{V_{out}(s)}{V_{in}(s)}=\frac{\left(R_{2}+sL+\frac{1}{sC}\right)\times I(s)}{\left(R_{1}+R_{2}+sL+\frac{1}{sC}\right)\times I(s)}\)
分母、分子にある Is を削除し
\(H(s)=\frac{V_{out}(s)}{V_{in}(s)}=\frac{Z_{out}}{Z_{all}}=\frac{sL+R_{2}+\frac{1}{sC}}{sL+(R_{1}+R_{2})+\frac{1}{sC}}\)
この繁分数の形を解消するために、分子と分母に \(sC\) を掛けます。
\(H(s)=\frac{(sL+R_{2}+\frac{1}{sC})\cdot sC}{(sL+R_{1}+R_{2}+\frac{1}{sC})\cdot sC}\)
それぞれ展開して \(s\) の次数(高い順)に整理します。
\(H(s)=\frac{LCs^{2}+R_{2}Cs+1}{LCs^{2}+(R_{1}+R_{2})Cs+1}\)
1.4.5 一般式へ
\(LC\)」や「\((R_1+R_2)C\)」といった複雑な塊を、それぞれ \(b_2, b_1, b_0, a_2, a_1, a_0\) というシンプルな1つの係数に置き換えます。
\(\begin{aligned}H(s)&=\frac{LCs^{2}+R_{2}Cs+1}{LCs^{2}+(R_{1}+R_{2})Cs+1}\end{aligned}\)
• \(LC = b_2\), \(R_2C = b_1\), \(1 = b_0\) (分子:出力側の素子で決定)
• \(LC = a_2\), \((R_1 + R_2)C = a_1\), \(1 = a_0\) (分母:回路全体の素子で決定)
\(\begin{aligned}H(s)&=\frac{b_{2}s^{2}+b_{1}s+b_{0}}{a_{2}s^{2}+a_{1}s+a_{0}}\end{aligned}\)
\(\begin{aligned}H(s)&=\frac{LCs^{2}+R_{2}Cs+1}{LCs^{2}+(R_{1}+R_{2})Cs+1}\end{aligned}\)
• \(LC = b_2\), \(R_2C = b_1\), \(1 = b_0\) (分子:出力側の素子で決定)
• \(LC = a_2\), \((R_1 + R_2)C = a_1\), \(1 = a_0\) (分母:回路全体の素子で決定)
\(\begin{aligned}H(s)&=\frac{b_{2}s^{2}+b_{1}s+b_{0}}{a_{2}s^{2}+a_{1}s+a_{0}}\end{aligned}\)
1.5 一般式からLPFへ
低域通過フィルタ(LPF)は「高周波を遮断し、低周波を通す」特性を持ちます。
1.5.1 LPFの条件を適用する
LPFは「低周波を通し、高周波を遮断する」特性を持ちます。周波数が無限大(\(s \to \infty\))のときにゲインが0になる必要があるため、分子の \(s\) の次数は分母の次数よりも低くなければなりません。
したがって、分子の \(s^{2}\) と \(s\) の係数を \(b_2 = 0\)、\(b_1 = 0\) とします。
\(\begin{aligned}H(s)=\frac{b_{0}}{a_{2}s^{2}+a_{1}s+a_{0}}\end{aligned}\)
したがって、分子の \(s^{2}\) と \(s\) の係数を \(b_2 = 0\)、\(b_1 = 0\) とします。
\(\begin{aligned}H(s)=\frac{b_{0}}{a_{2}s^{2}+a_{1}s+a_{0}}\end{aligned}\)
1.5.2 \(s^{2}\)を 1 にする
数式を扱いやすくするため、分母と分子を \(a_{2}\) で割ることで、\(s^{2}\) の係数を 1 に整えます。
\(\begin{aligned}H(s)=\frac{\frac{b_{0}}{a_{2}}}{s^{2}+\frac{a_{1}}{a_{2}}s+\frac{a_{0}}{a_{2}}}\end{aligned}\)
\(\begin{aligned}H(s)=\frac{\frac{b_{0}}{a_{2}}}{s^{2}+\frac{a_{1}}{a_{2}}s+\frac{a_{0}}{a_{2}}}\end{aligned}\)
1.5.3 パラメータと対応付ける
回路設計や制御工学において、2次システムの分母は通常、カットオフ角周波数 \(\omega _{0}\) と クオリティファクタ \(Q\)(または減衰係数 \(\zeta = \frac{1}{2Q}\))を用いて以下のように定義されます。
• 分母の定数項: \(\omega_0^2 = \frac{a_0}{a_2}\)
• 分母の \(s\) の係数: \(\frac{\omega_0}{Q} = \frac{a_1}{a_2}\)
これらを代入すると、伝達関数は次のようになります。
\(\begin{aligned}H(s)=\frac{\frac{b_{0}}{a_{2}}}{s^{2}+\frac{\omega _{0}}{Q}s+\omega _{0}^{2}}\end{aligned}\)
• 分母の定数項: \(\omega_0^2 = \frac{a_0}{a_2}\)
• 分母の \(s\) の係数: \(\frac{\omega_0}{Q} = \frac{a_1}{a_2}\)
これらを代入すると、伝達関数は次のようになります。
\(\begin{aligned}H(s)=\frac{\frac{b_{0}}{a_{2}}}{s^{2}+\frac{\omega _{0}}{Q}s+\omega _{0}^{2}}\end{aligned}\)
1.5.4 正規化する
提示された目的の式 \(H(s) = \frac{1}{s^2 + \frac{s}{Q} + 1}\) に仕上げるために、2つの基準(正規化)を設けます。
(1)カットオフ角周波数を 1 にする(周波数正規化)
(2)直流ゲイン(\(s=0\) のときの増幅率)を 1 にする
ここまでの条件(\(\omega_0 = 1\)、分子 = 1)をステップ3の式に代入します。
\(\begin{aligned}H(s)=\frac{1}{s^{2}+\frac{1}{Q}s+1}=\frac{1}{s^{2}+\frac{s}{Q}+1}\end{aligned}\)
これで、目的の2次LPFの標準形が導き出されました。
(1)カットオフ角周波数を 1 にする(周波数正規化)
\(\omega_0 = 1\) とします。これにより \(\omega_0^2 = 1\) となり、分母の定数項が 1 になります。
(2)直流ゲイン(\(s=0\) のときの増幅率)を 1 にする
\(s=0\) を代入したときに \(H(0) = 1\) となるよう、分子の定数項を調整します。
\(\omega_0 = 1\) のとき分母の定数項は 1 なので、分子の \(\frac{b_{0}}{a_{2}}\) も 1 に設定します(つまり \(b_0 = a_2\))。
\(\omega_0 = 1\) のとき分母の定数項は 1 なので、分子の \(\frac{b_{0}}{a_{2}}\) も 1 に設定します(つまり \(b_0 = a_2\))。
ここまでの条件(\(\omega_0 = 1\)、分子 = 1)をステップ3の式に代入します。
\(\begin{aligned}H(s)=\frac{1}{s^{2}+\frac{1}{Q}s+1}=\frac{1}{s^{2}+\frac{s}{Q}+1}\end{aligned}\)
これで、目的の2次LPFの標準形が導き出されました。
1.6 一般式からHPFへ
高域通過フィルタ(HPF)は「低周波を遮断し、高周波を通す」特性を持ちます。
1.6.1 HPFの条件を適用する
直流(\(s \to 0\))のときにゲインが0になり、無限大(\(s \to \infty\))のときに一定のゲインを持つ必要があります。
\(s \to 0\) で分子が0になるためには、分子の定数項と \(s\) の一次の項を消去しなければなりません。
したがって、分子の係数を \(b_1 = 0, b_0 = 0\) とします。
\(\begin{aligned}H(s)=\frac{b_{2}s^{2}}{a_{2}s^{2}+a_{1}s+a_{0}}\end{aligned}\)
\(s \to 0\) で分子が0になるためには、分子の定数項と \(s\) の一次の項を消去しなければなりません。
したがって、分子の係数を \(b_1 = 0, b_0 = 0\) とします。
\(\begin{aligned}H(s)=\frac{b_{2}s^{2}}{a_{2}s^{2}+a_{1}s+a_{0}}\end{aligned}\)
1.6.2 \(s^{2}\)を 1 にする
分母の最高次(\(s^{2}\))の係数を 1 に整えるため、分母と分子を \(a_{2}\) で割ります。
\(\begin{aligned}H(s)=\frac{\frac{b_{2}}{a_{2}}s^{2}}{s^{2}+\frac{a_{1}}{a_{2}}s+\frac{a_{0}}{a_{2}}}\end{aligned}\)
\(\begin{aligned}H(s)=\frac{\frac{b_{2}}{a_{2}}s^{2}}{s^{2}+\frac{a_{1}}{a_{2}}s+\frac{a_{0}}{a_{2}}}\end{aligned}\)
1.6.3 パラメータと対応付ける
2次システムの共通パラメータであるカットオフ角周波数 \(\omega _{0}\) とクオリティファクタ \(Q\) の関係式(\(\omega_0^2 = \frac{a_0}{a_2}\)、\(\frac{\omega_0}{Q} = \frac{a_1}{a_2}\))を分母に代入します。
\(\begin{aligned}H(s)=\frac{\frac{b_{2}}{a_{2}}s^{2}}{s^{2}+\frac{\omega _{0}}{Q}s+\omega _{0}^{2}}\end{aligned}\)
\(\begin{aligned}H(s)=\frac{\frac{b_{2}}{a_{2}}s^{2}}{s^{2}+\frac{\omega _{0}}{Q}s+\omega _{0}^{2}}\end{aligned}\)
1.6.4 正規化する
目標の式へ展開するために、周波数と高域ゲインを正規化します。
(1) 周波数の正規化:
\(\begin{aligned}H(s)=\frac{s^{2}}{s^{2}+\frac{1}{Q}s+1}=\frac{s^{2}}{s^{2}+\frac{s}{Q}+1}\end{aligned}\)
(1) 周波数の正規化:
カットオフ角周波数を \(\omega_0 = 1\) とします。
(2) 通過域ゲインの正規化:
高周波(\(s \to \infty\))でのゲインが 1 になるように、分子の係数 \(\frac{b_{2}}{a_{2}}\) を 1 とします(つまり \(b_2 = a_2\))。
これらを代入することで、目標のHPFの標準形が導かれます。\(\begin{aligned}H(s)=\frac{s^{2}}{s^{2}+\frac{1}{Q}s+1}=\frac{s^{2}}{s^{2}+\frac{s}{Q}+1}\end{aligned}\)
1.7 一般式からBPFへ
帯域通過フィルタ(BPF)は「特定の周波数帯域だけを通し、低周波も高周波も遮断する」特性を持ちます。
1.7.1 BPFの条件を適用する
直流(\(s \to 0\))と無限大(\(s \to \infty\))の両方でゲインが0になる必要があります。
分子に定数項があると \(s \to 0\) で0にならず、分子に \(s^{2}\) の項があると \(s \to \infty\) で0になりません。
したがって、分子の係数を \(b_2 = 0, b_0 = 0\) とします。
\(\begin{aligned}H(s)=\frac{b_{1}s}{a_{2}s^{2}+a_{1}s+a_{0}}\end{aligned}\)
分子に定数項があると \(s \to 0\) で0にならず、分子に \(s^{2}\) の項があると \(s \to \infty\) で0になりません。
したがって、分子の係数を \(b_2 = 0, b_0 = 0\) とします。
\(\begin{aligned}H(s)=\frac{b_{1}s}{a_{2}s^{2}+a_{1}s+a_{0}}\end{aligned}\)
1.7.2 \(s^{2}\)を 1 にする
同様に、分母の最高次の係数を 1 にするため、分母と分子を \(a_{2}\) で割ります。
\(\begin{aligned}H(s)=\frac{\frac{b_{1}}{a_{2}}s}{s^{2}+\frac{a_{1}}{a_{2}}s+\frac{a_{0}}{a_{2}}}\end{aligned}\)
\(\begin{aligned}H(s)=\frac{\frac{b_{1}}{a_{2}}s}{s^{2}+\frac{a_{1}}{a_{2}}s+\frac{a_{0}}{a_{2}}}\end{aligned}\)
1.7.3 パラメータと対応付ける
分母に特性パラメータ \(\omega _{0}\) と \(Q\) の関係式を代入します。
\(\begin{aligned}H(s)=\frac{\frac{b_{1}}{a_{2}}s}{s^{2}+\frac{\omega _{0}}{Q}s+\omega _{0}^{2}}\end{aligned}\)
\(\begin{aligned}H(s)=\frac{\frac{b_{1}}{a_{2}}s}{s^{2}+\frac{\omega _{0}}{Q}s+\omega _{0}^{2}}\end{aligned}\)
1.7.4 正規化する
目標の式へ展開するために、周波数と中心周波数でのゲインを正規化します。
(1) 周波数の正規化:
\(\begin{aligned}H(s)=\frac{\frac{1}{Q}s}{s^{2}+\frac{1}{Q}s+1}=\frac{\frac{s}{Q}}{s^{2}+\frac{s}{Q}+1}\end{aligned}\)
(1) 周波数の正規化:
中心角周波数を \(\omega_0 = 1\) とします。分母の \(s\) の係数は \(\frac{1}{Q}\) になります。
(2) 中心周波数ゲインの正規化:
中心周波数(\(s = j\omega_0 = j1\))のときにゲインが 1 になるようにします。
\(s = j\) を分母に代入すると \(s^2 + \frac{s}{Q} + 1 = -1 + \frac{j}{Q} + 1 = \frac{j}{Q}\) となります。
分子もこれと同じ \(\frac{j}{Q}\) になれば \(H(j) = 1\) となるため、分子の係数 \(\frac{b_{1}}{a_{2}}\) を \(\frac{1}{Q}\) と設定します(つまり \(b_1 = \frac{a_2}{Q}\))。
これらを代入することで、目標のBPFの標準形が導かれます。\(s = j\) を分母に代入すると \(s^2 + \frac{s}{Q} + 1 = -1 + \frac{j}{Q} + 1 = \frac{j}{Q}\) となります。
分子もこれと同じ \(\frac{j}{Q}\) になれば \(H(j) = 1\) となるため、分子の係数 \(\frac{b_{1}}{a_{2}}\) を \(\frac{1}{Q}\) と設定します(つまり \(b_1 = \frac{a_2}{Q}\))。
\(\begin{aligned}H(s)=\frac{\frac{1}{Q}s}{s^{2}+\frac{1}{Q}s+1}=\frac{\frac{s}{Q}}{s^{2}+\frac{s}{Q}+1}\end{aligned}\)
1.8 一般式から各フィルータへ
抵抗(R)、コンデンサ(C)、コイル(L)やオペアンプで構成される伝統的なアナログ回路(アクティブ・フィルターなど)の特性を
入力X(s)→H(S)→出力Y(s)という伝達関数で表すと
\(Q\) はフィルターの鋭さ(Quality Factor)、\(A\) はブースト/カットの量をリニア倍率に換算した値(\(A = 10^{\text{dBgain}/40}\))です。
このアナログモデルにおける重要なポイント
(1) 2次システム(Biquad)としての美しさ
(2) Qの挙動
入力X(s)→H(S)→出力Y(s)という伝達関数で表すと
| フィルタータイプ | アナログ伝達関数 \(H(s)\) (プロトタイプモデル) | 特性の説明 |
|---|---|---|
| ①LPF (ローパス) | \(\begin{aligned}H(s)=\frac{1}{s^{2}+\frac{s}{Q}+1}\end{aligned}\) | 低域を通過させ、高域を-12dB/octで減衰。\(Q=1/\sqrt{2}\)でバターワース特性(最平坦)になる。 |
| ②HPF (ハイパス) | \(\begin{aligned}H(s)=\frac{s^{2}}{s^{2}+\frac{s}{Q}+1}\end{aligned}\) | 高域を通過させ、低域を-12dB/octで減衰。 |
| ③BPF (バンドパス) (定数ピーク型) | \(\begin{aligned}H(s)=\frac{\frac{s}{Q}}{s^{2}+\frac{s}{Q}+1}\end{aligned}\) | 中心周波数でのピークゲインが常に0dB(1倍)に固定されるバンドパス。 |
| ④Notch (ノッチ/帯域除去) | \(\begin{aligned}H(s)=\frac{s^{2}+1}{s^{2}+\frac{s}{Q}+1}\end{aligned}\) | 特定の中心周波数(\(\omega=1\))の成分を完全にゼロ(無限大の減衰)にする。 |
| ⑤Peaking EQ (ピークEQ) | \(\begin{aligned}H(s)=\frac{s^{2}+\frac{A}{Q}s+1}{s^{2}+\frac{1}{AQ}s+1}\end{aligned}\) | 音楽制作で最も使われるベル型のEQ。\(A\) はゲイン(ブースト/カット)を表す変数。 |
| ⑥Low Shelf (ローシェルフ) | \(\begin{aligned}H(s)=A\cdot \frac{s^{2}+\frac{\sqrt{A}}{Q}s+A}{As^{2}+\frac{\sqrt{A}}{Q}s+1}\end{aligned}\) | 低域を指定したゲイン \(A\) に持ち上げ、または下げ、高域は元のままにする。 |
| ⑦APF (オールパス) | \(\begin{aligned}H(s)=\frac{s^{2}-\frac{s}{Q}+1}{s^{2}+\frac{s}{Q}+1}\end{aligned}\) | 振幅特性は全周波数で0dB(平坦)のまま、位相だけを反転・変化させる。 |
| ⑧High Shelf (ハイシェルフ) | \(\begin{aligned}H(s)=A\cdot \frac{As^{2}+\frac{\sqrt{A}}{Q}s+1}{s^{2}+\frac{\sqrt{A}}{Q}s+A}\end{aligned}\) | 高域を指定したゲイン \(A\) に持ち上げ、または下げ、低域は元のままにする。 |
このアナログモデルにおける重要なポイント
(1) 2次システム(Biquad)としての美しさ
分母がすべて \(s^2 + \frac{s}{Q} + 1\) という共通の形をベースにしていることがわかります。
これは、アナログ回路でいうと「Sallen-Key回路」や「ステート・バリアブル(状態変数)回路」などで実現できる、最も基本的かつ応用が利く回路モデルです。
これは、アナログ回路でいうと「Sallen-Key回路」や「ステート・バリアブル(状態変数)回路」などで実現できる、最も基本的かつ応用が利く回路モデルです。
(2) Qの挙動
アナログ回路における \(Q\)(クオリティファクター)は、カットオフ・中心周波数付近の「エネルギーの集中の度合い(共振の強さ)」を示します。
\(Q\) が大きくなるほど回路は激しく共振し、デジタル化した際にも鋭いピークが生まれます。
RBJ Cookbookの次のステップ(2)では、この美しいアナログの特性方程式に対して「双一次変換(Bilinear Transform: BLT)」という数学的な手法を適用し、サンプリング周波数 \(F_{s}\) で動作するデジタルのコードへと変換していきます。
\(Q\) が大きくなるほど回路は激しく共振し、デジタル化した際にも鋭いピークが生まれます。
RBJ Cookbookの次のステップ(2)では、この美しいアナログの特性方程式に対して「双一次変換(Bilinear Transform: BLT)」という数学的な手法を適用し、サンプリング周波数 \(F_{s}\) で動作するデジタルのコードへと変換していきます。
2. 使用例
入力電圧 \(V_{in}\) に対して、インダクタ(\(L\))、キャパシタ(\(C\))、抵抗(\(R\))を1列に直列接続した1.4.3で説明した回路を想像してください。この回路は、「出力をどこから取り出すか」を変えるだけで、すべての2次フィルタに変身します。
2.1 素子値の後仕込み
どのフィルタであっても、回路全体のインピーダンスは共通(\(sL + \frac{1}{sC} + R\))であるため、分母の式はすべて同じになります。
分母を標準形(\(s^2 + \frac{\omega_0}{Q}s + \omega_0^2\))と比較することで、以下の共通の落とし込み公式が導かれます。
• カットオフ(中心)角周波数: \(\omega_0 = \frac{1}{\sqrt{LC}}\)
• クオリティファクタ(鋭さ): \(Q = \frac{1}{R}\sqrt{\frac{L}{C}}\)
各フィルタの構成(出力の取り出し方)
具体的な設計手順(落とし込みの例)
仕様として、カットオフ周波数 \(\omega _{0}\) と 鋭さ \(Q\) が決まっている場合、以下の手順で具体的な \(R, L, C\) の値を決定します。
(1) 最初に入手しやすいキャパシタ \(C\) の値を任意に仮定します。
(2) \(\omega_0 = \frac{1}{\sqrt{LC}}\) より、インダクタの値を計算します: \(\begin{aligned}L = \frac{1}{\omega_0^2 C}\end{aligned}\)
(3) \(Q = \frac{1}{R}\sqrt{\frac{L}{C}}\) より、抵抗の値を計算します: \(\begin{aligned}R = \frac{1}{\omega_0 C Q}\end{aligned}\)
分母を標準形(\(s^2 + \frac{\omega_0}{Q}s + \omega_0^2\))と比較することで、以下の共通の落とし込み公式が導かれます。
• カットオフ(中心)角周波数: \(\omega_0 = \frac{1}{\sqrt{LC}}\)
• クオリティファクタ(鋭さ): \(Q = \frac{1}{R}\sqrt{\frac{L}{C}}\)
各フィルタの構成(出力の取り出し方)
| フィルタ種類 | 出力を取り出す場所 | 回路素子を考慮した伝達関数 \(H(s)\) |
|---|---|---|
| 2次LPF | キャパシタ(\(C\))の両端 | \(\begin{aligned}H(s) = \frac{\frac{1}{LC}}{s^2 + \frac{R}{L}s + \frac{1}{LC}}\end{aligned}\) |
| 2次HPF | インダクタ(\(L\))の両端 | \(\begin{aligned}H(s) = \frac{s^2}{s^2 + \frac{R}{L}s + \frac{1}{LC}}\end{aligned}\) |
| 2次BPF | 抵抗(\(R\))の両端 | \(\begin{aligned}H(s) = \frac{\frac{R}{L}s}{s^2 + \frac{R}{L}s + \frac{1}{LC}}\end{aligned}\) |
仕様として、カットオフ周波数 \(\omega _{0}\) と 鋭さ \(Q\) が決まっている場合、以下の手順で具体的な \(R, L, C\) の値を決定します。
(1) 最初に入手しやすいキャパシタ \(C\) の値を任意に仮定します。
(2) \(\omega_0 = \frac{1}{\sqrt{LC}}\) より、インダクタの値を計算します: \(\begin{aligned}L = \frac{1}{\omega_0^2 C}\end{aligned}\)
(3) \(Q = \frac{1}{R}\sqrt{\frac{L}{C}}\) より、抵抗の値を計算します: \(\begin{aligned}R = \frac{1}{\omega_0 C Q}\end{aligned}\)
2.2 特性グラフの作成
周波数特性(数式)を得るために、それぞれの正規化伝達関数に \(s = j\omega\) を代入します。
2.2.1 振幅特性の導き方
複素数に変形した式の絶対値 \(\vert{}H(j\omega)\vert{}\) を計算します。デシベルにする場合は \(20\log_{10}\vert{}H(j\omega)\vert{}\) をとります。
• LPF: \(\begin{aligned}\vert{}H(j\omega)\vert{} = \frac{1}{\sqrt{(1 - \omega^2)^2 + \left(\frac{\omega}{Q}\right)^2}}\end{aligned}\)
• \(\omega \to 0\) でゲインは \(1\) (\(0\text{ dB}\))、\(\omega \to \infty\) で \(-40\text{ dB/dec}\) で急激に減衰します。
• HPF: \(\begin{aligned}\vert{}H(j\omega)\vert{} = \frac{\omega^2}{\sqrt{(1 - \omega^2)^2 + \left(\frac{\omega}{Q}\right)^2}}\end{aligned}\)
• \(\omega \to 0\) で完全に遮断され、\(\omega \to \infty\) でゲインは \(1\) (\(0\text{ dB}\)) に収束します。
• BPF: \(\begin{aligned}\vert{}H(j\omega)\vert{} = \frac{\frac{\omega}{Q}}{\sqrt{(1 - \omega^2)^2 + \left(\frac{\omega}{Q}\right)^2}}\end{aligned}\)
• 低域も高域も遮断し、中心周波数 \(\omega = 1\) のときに分母が最小となり、ゲインは最大値 \(1\) (\(0\text{ dB}\)) になります。
• LPF: \(\begin{aligned}\vert{}H(j\omega)\vert{} = \frac{1}{\sqrt{(1 - \omega^2)^2 + \left(\frac{\omega}{Q}\right)^2}}\end{aligned}\)
• \(\omega \to 0\) でゲインは \(1\) (\(0\text{ dB}\))、\(\omega \to \infty\) で \(-40\text{ dB/dec}\) で急激に減衰します。
• HPF: \(\begin{aligned}\vert{}H(j\omega)\vert{} = \frac{\omega^2}{\sqrt{(1 - \omega^2)^2 + \left(\frac{\omega}{Q}\right)^2}}\end{aligned}\)
• \(\omega \to 0\) で完全に遮断され、\(\omega \to \infty\) でゲインは \(1\) (\(0\text{ dB}\)) に収束します。
• BPF: \(\begin{aligned}\vert{}H(j\omega)\vert{} = \frac{\frac{\omega}{Q}}{\sqrt{(1 - \omega^2)^2 + \left(\frac{\omega}{Q}\right)^2}}\end{aligned}\)
• 低域も高域も遮断し、中心周波数 \(\omega = 1\) のときに分母が最小となり、ゲインは最大値 \(1\) (\(0\text{ dB}\)) になります。
2.2.2 位相特性の導き方
分子の偏角(角度)から分母の偏角 \(\begin{aligned}\phi = \tan^{-1}\left(\frac{\omega/Q}{1-\omega^2}\right)\end{aligned}\) を引くことで導きます。
• LPF: \(\theta(\omega) = -\phi\)
• 開始は \(0^{\circ }\)、カットオフ(\(\omega=1\))で \(-90^{\circ }\)、最終的に \(-180^{\circ }\) まで遅れます。
• HPF: \(\theta(\omega) = 180^\circ - \phi\)
• 開始は \(+180^{\circ }\)(進み)、カットオフで \(+90^{\circ }\)、最終的に \(0^{\circ }\)(位相ズレなし)に収束します。
• BPF: \(\theta(\omega) = 90^\circ - \phi\)
• 開始は \(+90^{\circ }\)、中心周波数で \(0^{\circ }\)(同位相)、最終的に \(-90^{\circ }\) まで遅れます。
• LPF: \(\theta(\omega) = -\phi\)
• 開始は \(0^{\circ }\)、カットオフ(\(\omega=1\))で \(-90^{\circ }\)、最終的に \(-180^{\circ }\) まで遅れます。
• HPF: \(\theta(\omega) = 180^\circ - \phi\)
• 開始は \(+180^{\circ }\)(進み)、カットオフで \(+90^{\circ }\)、最終的に \(0^{\circ }\)(位相ズレなし)に収束します。
• BPF: \(\theta(\omega) = 90^\circ - \phi\)
• 開始は \(+90^{\circ }\)、中心周波数で \(0^{\circ }\)(同位相)、最終的に \(-90^{\circ }\) まで遅れます。
2.2.3 周波数特性の比較
すべて \(Q = 1.0\) に統一したときの、LPF、HPF、BPFの振幅特性と位相特性のグラフです。
同じ分母(同じ \(R, L, C\) の組み合わせ)から、取り出し方を変えるだけでこれほど特性が変わる様子が視覚的に分かります。

同じ分母(同じ \(R, L, C\) の組み合わせ)から、取り出し方を変えるだけでこれほど特性が変わる様子が視覚的に分かります。

2.2.4 周波数特性の確認
RBJ Cookbook フィルター特性シミュレーター
1000 Hz
0.7
6.0 dB
3. 双二次フィルター(ブロック図前説)
3.1 双二次(Biquad)ってなに?
これまで扱ってきた一般式を思い出してください。
\(\begin{aligned}\vert{}H(s)=\frac{b_{2}s^{2}+b_{1}s+b_{0}}{a_{2}s^{2}+a_{1}s+a_{0}}\end{aligned}\)
このように、「分子も2次式(Quadratic)」で「分母も2次式(Quadratic)」になっている、つまり2次式が2つ(Bi-)並んでいるから「双二次(Biquad)」と呼びます。
今までの項でやったLPFやHPFは、分子の \(s^{2}\) や \(s\) をゼロ(0次)にして機能を限定していましたが、双二次フィルターは分子の係数(\(b_2, b_1, b_0\))もすべてフル活用します。
これにより、これまでのLPF、HPF、BPFだけでなく、
デジタル信号処理の世界では、この「共通化できる」という特徴がめちゃくちゃ重宝されます。
\(\begin{aligned}\vert{}H(s)=\frac{b_{2}s^{2}+b_{1}s+b_{0}}{a_{2}s^{2}+a_{1}s+a_{0}}\end{aligned}\)
このように、「分子も2次式(Quadratic)」で「分母も2次式(Quadratic)」になっている、つまり2次式が2つ(Bi-)並んでいるから「双二次(Biquad)」と呼びます。
今までの項でやったLPFやHPFは、分子の \(s^{2}\) や \(s\) をゼロ(0次)にして機能を限定していましたが、双二次フィルターは分子の係数(\(b_2, b_1, b_0\))もすべてフル活用します。
これにより、これまでのLPF、HPF、BPFだけでなく、
• 特定の周波数だけをピンポイントで消し去る ノッチ(Notch)フィルター
• 特定の周波数だけをブースト/カットする ピーキング(Peaking)EQ
• 振幅を変えずに位相だ
など、あらゆる特性の2次フィルターを「ひとつの共通の計算式(プログラム)」だけで着せ替えるように作り出せるのが最大のメリットです。• 特定の周波数だけをブースト/カットする ピーキング(Peaking)EQ
• 振幅を変えずに位相だ
デジタル信号処理の世界では、この「共通化できる」という特徴がめちゃくちゃ重宝されます。
3.2 双二次(Biquad)の概要
分子と分母がそれぞれ2次の多項式で表されるIIR(無限インパルス応答)フィルターです。
ローパスやハイパス、バンドパスなどの特性をシンプルな計算で実現でき、オーディオ処理やモーター制御などで広く使われています。
ローパスやハイパス、バンドパスなどの特性をシンプルな計算で実現でき、オーディオ処理やモーター制御などで広く使われています。
3.2.1 基本の仕組み
• 伝達関数:
入力と出力の関係を、2つの2次式の比率(分母・分子)で表します。
• 双一次変換:
アナログフィルターの設計(H(s))を、周波数プリワーピングをかけてデジタル用(z変換)に変換します。
• 主な種類:
• ローパス(LPF)・ハイパス(HPF)
• バンドパス(BPF)・バンドストップ(BEF)
• オールパス、ピーキング、ロー/ハイシェルフ
• バンドパス(BPF)・バンドストップ(BEF)
• オールパス、ピーキング、ロー/ハイシェルフ
3.2.2 特徴とメリット
• 実装が簡単:
掛け算と足し算の組み合わせだけで構成でき、DSPやマイコンでの演算処理が非常に高速です。
• 安定性:
2次(2ステップ遅延)単位でカスケード接続(多段接続)することで、高次フィルターでも数値誤差や発振を抑えて安定動作させます。
• 設計の定番:
ロバート・ブリסטウ・ジョンソン(RBJ)氏による「Audio-EQ-Cookbook」の係数計算式が、オーディオ分野で広く標準的に利用されています。
3.3 各変数の概要
ユーザーが指定する「基本パラメータ」から、プログラムの内部で「中間変数(ωo,α)」を計算します。
双二次(バイカッド)フィルターのブロック図(Direct Form I や II など)には、入力 \(x[n]\) や出力 \(y[n]\) だけでなく、 遅延素子から出てくる変数や、計算をシンプルにするための一時的な変数が多く登場します。 ブロック図を説明する前にこの変数、基本変数と中間変数を説明します。 • 基本変数:
双二次(バイカッド)フィルターのブロック図(Direct Form I や II など)には、入力 \(x[n]\) や出力 \(y[n]\) だけでなく、 遅延素子から出てくる変数や、計算をシンプルにするための一時的な変数が多く登場します。 ブロック図を説明する前にこの変数、基本変数と中間変数を説明します。 • 基本変数:
入力・出力や、フィルターの特性を決める固定の「係数(\(a_n, b_n\))」のこと。
• 中間変数:
計算の途中で生まれる一時的なデータ(Direct Form II で使われる \(w[n]\) など)のこと。この2つの役割を分けることで、頭の中が整理されます。
3.3.1 基本変数
基本変数は、基本パラメータでユーザーが指定するもの
a. Fs (Sampling Frequency) :
サンプリング周波数(例: 44100 Hz や 48000 Hz)
b. fo (Center / Cutoff Frequency) :
中心周波数 または 遮断(カットオフ)周波数(Hz)
c. Q (Quality Factor) :
クオリティファクタ。フィルターの「鋭さ」や「帯域幅(Bandwidth)」を表します。
値が大きいほどピンポイントに鋭く効き、小さいほど緩やかに広く効きます。
d.dBgain:
ゲイン(dB)。ピーキングEQやシェルフフィルターで、音量を何dB上げ下げするかを指定します(ローパス等では使いません)。
サンプリング周波数(例: 44100 Hz や 48000 Hz)
b. fo (Center / Cutoff Frequency) :
中心周波数 または 遮断(カットオフ)周波数(Hz)
c. Q (Quality Factor) :
クオリティファクタ。フィルターの「鋭さ」や「帯域幅(Bandwidth)」を表します。
値が大きいほどピンポイントに鋭く効き、小さいほど緩やかに広く効きます。
d.dBgain:
ゲイン(dB)。ピーキングEQやシェルフフィルターで、音量を何dB上げ下げするかを指定します(ローパス等では使いません)。
3.3.2 中間変数
a. ω0 (オメガ・ゼロ)
• 意味:
デジタル世界における角周波数(ラジアン)です。
• 計算式:
ω0=2πfo/Fs
• 補足:
アナログの周波数を、デジタルの円周上の角度(0 〜 π)にマッピングしたものです。
これを使って、プログラム内で sin や cos を計算します。
b. α (アルファ)デジタル世界における角周波数(ラジアン)です。
• 計算式:
ω0=2πfo/Fs
• 補足:
アナログの周波数を、デジタルの円周上の角度(0 〜 π)にマッピングしたものです。
これを使って、プログラム内で sin や cos を計算します。
• 意味:
フィルターの帯域幅(Q値)を実際の計算に組み込むための共通係数です。
• 計算式(Q基準の場合):
α = sin(ω0) / 2Q
• 補足:
RBJ Cookbookでは、Qの代わりに「オクターブ幅(BW)」や「シェルフの傾き(S)」から α を計算するバリエーションも用意されていますが、この Q を使った式が最も一般的です。
c. A (エー)フィルターの帯域幅(Q値)を実際の計算に組み込むための共通係数です。
• 計算式(Q基準の場合):
α = sin(ω0) / 2Q
• 補足:
RBJ Cookbookでは、Qの代わりに「オクターブ幅(BW)」や「シェルフの傾き(S)」から α を計算するバリエーションも用意されていますが、この Q を使った式が最も一般的です。
• 意味:
ゲインの倍率(リニア値)の平方根です。(※ピーキングとシェルフでのみ使用)
• 計算式:
\(A = 10^{\frac{\text{dBgain}}{40}} = \sqrt{10^{\frac{\text{dBgain}}{20}}}\)
ゲインの倍率(リニア値)の平方根です。(※ピーキングとシェルフでのみ使用)
• 計算式:
\(A = 10^{\frac{\text{dBgain}}{40}} = \sqrt{10^{\frac{\text{dBgain}}{20}}}\)
3.3.3 フィルターの計算式
(1)双二次フィルター(Biquad Filter)の基本形は、以下のデジタル信号処理の式です。
\(y[n]=\frac{b_{0}}{a_{0}}x[n]+\frac{b_{1}}{a_{0}}x[n-1]+\frac{b_{2}}{a_{0}}x[n-2]-\frac{a_{1}}{a_{0}}y[n-1]-\frac{a_{2}}{a_{0}}y[n-2]\)
RBJ Cookbookのレシピは、この b0, b1, b2, a0, a1, a2 の6つの係数を決めるためのものです。
実際の実装では、あらかじめ全体を a0 で割って、a0 = 1 として処理します
(2)以下に、主要な7種類のフィルターの計算レシピをまとめました。RBJ Cookbookのレシピは、この b0, b1, b2, a0, a1, a2 の6つの係数を決めるためのものです。
実際の実装では、あらかじめ全体を a0 で割って、a0 = 1 として処理します
共通で使用する値:cos(ω0), sin(ω0),α,A
⑦ ローシェルフ (Low-Shelf) ※少し複雑になります
(3)式の共通点
| フィルター種類 | b0 | b1 | b2 | a0 | a1 | a2 |
|---|---|---|---|---|---|---|
| ① ローパス (LPF) | (1-cosω0)/2 | 1-cosω0 | (1-cosω0)/2 | 1+α | -2cosω0 | 1-α |
| ② ハイパス (HPF) | (1+cosω0)/2 | -(1+cosω0) | (1+cosω0)/2 | 1+α | -2cosω0 | 1-α |
| ③ バンドパス (BPF) (ピークゲイン0dB版) | α | 0 | -α | 1+α | -2cosω0 | 1-α |
| ④ ノッチ (Notch) | 1 | -2cosω0 | 1 | 1+α | -2cosω0 | 1-α |
| ⑤ オールパス (APF) | 1-α | -2cosω0 | 1+α | 1+α | -2cosω0 | 1-α |
| ⑥ ピーキング EQ | 1+ α×A | -2cosω0 | 1- α×A | 1+ α/A | -2cosω0 | 1- α/A |
・β = 2 sqrt(A) × α (※Qから導出する場合の簡略形)
b0=A[(A+1)-(A-1)cosω0+β]
b1=2A[(A-1)-(A+1)cosω0]
b2=A[(A+1)-(A-1)cosω0-β]
a0=(A+1)+(A-1)cosω0+β
a1=-2[(A-1)+(A+1)cosω0]
a2=(A+1)-(A-1)cosω0-β
b1=2A[(A-1)-(A+1)cosω0]
b2=A[(A+1)-(A-1)cosω0-β]
a0=(A+1)+(A-1)cosω0+β
a1=-2[(A-1)+(A+1)cosω0]
a2=(A+1)-(A-1)cosω0-β
このアルゴリズムの素晴らしいところは、分母の係数(特に a1 と a2 に注目すると分かります。
• LPF、HPF、BPF、Notch、APF は、すべて分母 a0,a1,a2 の形が全く同じ 1+α, -2cosω0, 1-α です。
• 分子の b 系列を入れ替えるだけで、ローパスになったりハイパスになったりします。
この共通性があるため、プログラムを作る際は「基本のBiquadフィルター構造」を1つ用意しておき、スイッチを切り替えるように分子・分母の係数を代入するだけで、あらゆるイコライザーやフィルターを実装することができます。
• LPF、HPF、BPF、Notch、APF は、すべて分母 a0,a1,a2 の形が全く同じ 1+α, -2cosω0, 1-α です。
• 分子の b 系列を入れ替えるだけで、ローパスになったりハイパスになったりします。
この共通性があるため、プログラムを作る際は「基本のBiquadフィルター構造」を1つ用意しておき、スイッチを切り替えるように分子・分母の係数を代入するだけで、あらゆるイコライザーやフィルターを実装することができます。
4. 双二次フィルター(ブロック図)
4.1概要
RBJ Cookbookの各フィルター(ローパスやピーキングEQなど)は、物理的な「抵抗やコンデンサを組み合わせたアナログ回路」ではなく、「共通の1つのデジタル構造(ブロック図)」のなかの「係数の値(数字)」だけを書き換えて実現します。
そのため、ローパス専用の回路図、ハイパス専用の回路図が個別に存在するわけではなく、すべてのフィルターで全く同じ以下の「信号流路図(ブロック図)」を共有します。
デジタル信号処理(DSP)では、この構造を「Direct Form I(直接型I)」または「Direct Form II(直接型II)」と呼びます。
ブロック図の説明

デジタルフィルター(Biquad 4大構造)の比較表
表を読み解くポイント
• メモリの節約:
そのため、ローパス専用の回路図、ハイパス専用の回路図が個別に存在するわけではなく、すべてのフィルターで全く同じ以下の「信号流路図(ブロック図)」を共有します。
デジタル信号処理(DSP)では、この構造を「Direct Form I(直接型I)」または「Direct Form II(直接型II)」と呼びます。
ブロック図の説明

デジタルフィルター(Biquad 4大構造)の比較表
| 構造(フォーム) | 必要最小限の遅延器 | 演算ノイズ | 特徴と主な用途 |
|---|---|---|---|
| Direct Form I | 4個 | 普通 | ・数式から直感的に実装可能 |
| Direct Form I 転置型 | 4個 | 少ない | ・通常のI型よりノイズが減少 |
| Direct Form II | 2個 | 普通 | ・メモリ消費を削減 |
| Direct Form II 転置型 | 2個 | 極めて少ない | ・省メモリと低ノイズを両立 |
Direct Form II 系列では遅延器の数を半減できます。
• 実用上のベストプラクティス:
多くのシステムで採用されているのは 「Direct Form II 転置型」 です。
4.2 Direct Form I
4.2.1 概要
Direct Form I(直接型I)は、デジタルフィルターの基本式を最も素直にそのまま表した構造です。
ブロック図:

特徴:
ブロック図:

特徴:
中央の加算器を境に、左側に入力信号 x[n] の過去ログ用遅延器 (Z^-1) が2つ、右側に出力信号 y[n] の過去ログ用遅延器 (Z^-1) が2つ、計4つの遅延器が完全に独立して配置されています。
4.2.2 1つで7つ
なぜ1つの図で「7種類のフィルター」に化けるのか?
アナログ回路であれば、ローパスフィルターを作るには「抵抗とコンデンサ」を繋ぎ、ハイパスにするにはその配置を物理的に組み替える必要があります。
しかし、RBJ Cookbookのレシピで計算した5つの係数 (b0, b1, b2, a1, a2) の数値を書き換えるだけで、フィルターの性質が全く別物に変化します。
• ローパス (LPF) にしたいとき:
アナログ回路であれば、ローパスフィルターを作るには「抵抗とコンデンサ」を繋ぎ、ハイパスにするにはその配置を物理的に組み替える必要があります。
しかし、RBJ Cookbookのレシピで計算した5つの係数 (b0, b1, b2, a1, a2) の数値を書き換えるだけで、フィルターの性質が全く別物に変化します。
• ローパス (LPF) にしたいとき:
高音をカットする数値を設定します。過去の入力と出力の波が互いに打ち消し合い、滑らかな低音だけが残るように係数が調整されます。
• ノッチ(特定の音を消す)にしたいとき:
特定の周波数を消し去る数値を設定します。狙った周波数の波だけがちょうど逆位相(プラスマイナス逆)になって足し合わされ、完全に消滅します。
4.2.3 実装はどうなるか
1枚目の図の通り、左右の遅延器にそれぞれ過去のデータを蓄えて計算するプログラムです。
// 過去の記憶(遅延器 Z⁻¹)の変数(初期値はすべて 0.0)
double x1 = 0.0, x2 = 0.0; // 入力の過去ログ(図の左側)
double y1 = 0.0, y2 = 0.0; // 出力の過去ログ(図の右側)
// 毎サンプルごとの処理関数
double processDF1(double x, double b0, double b1, double b2, double a1, double a2) {
// 図の通りに掛け算と足し算を行う(a0=1に正規化済み)
double y = b0 * x + b1 * x1 + b2 * x2 - a1 * y1 - a2 * y2;
// 遅延器(Z⁻¹)の記憶を更新して次に備える
x2 = x1; x1 = x; // 左側のシフト
y2 = y1; y1 = y; // 右側のシフト
return y;
}
double x1 = 0.0, x2 = 0.0; // 入力の過去ログ(図の左側)
double y1 = 0.0, y2 = 0.0; // 出力の過去ログ(図の右側)
// 毎サンプルごとの処理関数
double processDF1(double x, double b0, double b1, double b2, double a1, double a2) {
// 図の通りに掛け算と足し算を行う(a0=1に正規化済み)
double y = b0 * x + b1 * x1 + b2 * x2 - a1 * y1 - a2 * y2;
// 遅延器(Z⁻¹)の記憶を更新して次に備える
x2 = x1; x1 = x; // 左側のシフト
y2 = y1; y1 = y; // 右側のシフト
return y;
}
4.2.4 強みと注意点
強み:
入力と出力の過去ログが完全に独立しているため、数式からの置き換えが直感的です。
数値的な限界(オーバーフロー)が起きにくく、初心者にも非常に扱いやすい安定した構造です。
注意点:
左右で別々に過去ログを記憶するため、遅延器(メモリ変数)が合計4つ必要になり、メモリの消費量が後述の Direct Form II より多くなります。
4.3 Direct Form I 転置型
4.3.1 概要
Direct Form I 転置型(直接型I 転置構成)は、Direct Form I の「入力の過去」と「出力の過去」を独立して処理する特性をそのままに、掛け算と遅延の順序を反転(転置)させた構造です。
ブロック図:

特徴:
ブロック図:

特徴:
遅延器 (Z^-1) が左側に2つ、右側に2つ、計4つに分かれている点は通常の Direct Form I と同じです。
しかし、中央の共通ラインから信号が四方に分岐して、先に係数 (b0, b1, b2, -a1, -a2) と掛け算され、その後に遅延器と加算器 を通りながら「下から上へ」と足し上げられていくのが大きな違いです。
しかし、中央の共通ラインから信号が四方に分岐して、先に係数 (b0, b1, b2, -a1, -a2) と掛け算され、その後に遅延器と加算器 を通りながら「下から上へ」と足し上げられていくのが大きな違いです。
4.3.2 1つで7つ
なぜ1つの図で「7種類のフィルター」に化けるのか?
他の構造と同じく、図の流路(配線)は一切変えず、流し込む5つの係数の数値を書き換えるだけで変化します。
• ローパス (LPF) にしたいとき:
他の構造と同じく、図の流路(配線)は一切変えず、流し込む5つの係数の数値を書き換えるだけで変化します。
• ローパス (LPF) にしたいとき:
入力・出力された信号がそれぞれのルートで一斉に掛け算され、下から上へ遅延しながら合流していく段階で、高音の波だけが綺麗に打ち消し合うように係数が作用します。
• ノッチ(特定の音を消す)にしたいとき:
狙った特定の周波数の成分だけが、上へ昇りながら加算器で合流した瞬間に、ちょうどプラスマイナスゼロ(逆位相)になって完全に消滅するような数値を流し込みます。
4.3.3 実装はどうなるか
左側のフィードバック用の遅延器(内部状態)を dl1, dl2、右側のフィードフォワード用の遅延器を dr1, dr2 と置き、図を下から上へ読み解くように計算するプログラムです。
// 4つの遅延器(図の左側2つ、右側2つの Z⁻¹ 内部状態。初期値はすべて 0.0)
double dl1 = 0.0, dl2 = 0.0; // 左側の遅延器(上、下)
double dr1 = 0.0, dr2 = 0.0; // 右側の遅延器(上、下)
// 毎サンプルごとの処理関数
double processDF1T(double x, double b0, double b1, double b2, double a1, double a2) {
// 1. 図の左上:入力 x と、左側ルートから上がってきた dl1 が合流して中央のラインが決まる
double center = x + dl1;
// 2. 図の右上:中央ラインに b0 を掛けたものと、右側ルートから上がってきた dr1 が合流して出力 y になる
double y = b0 * center + dr1;
// 3. 次のサンプルのために、左側(フィードバック側)の遅延器を更新
// ※掛ける相手は出力「y」です
dl1 = -a1 * y + dl2; // 左側中央の加算器
dl2 = -a2 * y; // 左側一番下の遅延器へ
// 4. 次のサンプルのために、右側(フィードフォワード側)の遅延器を更新
// ※掛ける相手は入力「x」です
dr1 = b1 * x + dr2; // 右側中央の加算器
dr2 = b2 * x; // 右側一番下の遅延器へ
return y;
}
double dl1 = 0.0, dl2 = 0.0; // 左側の遅延器(上、下)
double dr1 = 0.0, dr2 = 0.0; // 右側の遅延器(上、下)
// 毎サンプルごとの処理関数
double processDF1T(double x, double b0, double b1, double b2, double a1, double a2) {
// 1. 図の左上:入力 x と、左側ルートから上がってきた dl1 が合流して中央のラインが決まる
double center = x + dl1;
// 2. 図の右上:中央ラインに b0 を掛けたものと、右側ルートから上がってきた dr1 が合流して出力 y になる
double y = b0 * center + dr1;
// 3. 次のサンプルのために、左側(フィードバック側)の遅延器を更新
// ※掛ける相手は出力「y」です
dl1 = -a1 * y + dl2; // 左側中央の加算器
dl2 = -a2 * y; // 左側一番下の遅延器へ
// 4. 次のサンプルのために、右側(フィードフォワード側)の遅延器を更新
// ※掛ける相手は入力「x」です
dr1 = b1 * x + dr2; // 右側中央の加算器
dr2 = b2 * x; // 右側一番下の遅延器へ
return y;
}
4.3.4 強みと注意点
• 強み(低ノイズ・高精度):
先にすべての掛け算を行ってから遅延・加算する特性上、3.3で解説した通常の Direct Form I よりも浮動小数点の計算で発生するノイズ(丸め誤差)が少なくなります。
また、Direct Form I 由来の「オーバーフロー(数値のパンク)への強さ」も維持しています。
• 注意点(数値のバースト):
また、Direct Form I 由来の「オーバーフロー(数値のパンク)への強さ」も維持しています。
3.5の「Direct Form II 転置型」がメモリを2つに節約でき、なおかつノイズも少なくて優秀であるため、実用上のオーディオプラグインなどではあえてメモリを4つ使うこの「Direct Form I 転置型」が選ばれるケースはやや稀です。
しかし、理論的な美しさと演算の並列化のしやすさから、DSPの設計書や教科書には必ず登場する重要な構造です。
しかし、理論的な美しさと演算の並列化のしやすさから、DSPの設計書や教科書には必ず登場する重要な構造です。
4.4 Direct Form II
4.4.1 概要
Direct Form II(直接型II)は、Direct Form I の無駄を省き、メモリの効率を極限まで高めた構造です。
ブロック図:

特徴:
ブロック図:

特徴:
入出力の順序を数学的に入れ替えることで、中央の縦1列にある2つの遅延器 (Z^-1) を、入力と出力の両方で「共通のメモリ」としてシェアしています。
4.4.2 1つで7つ
なぜ1つの図で「7種類のフィルター」に化けるのか?
Direct Form I と同様に、図の構造(流路)はそのままで、係数(b, a 系列の数値) を切り替えるだけで変化します。 • ローパス (LPF) にしたいとき:
Direct Form I と同様に、図の構造(流路)はそのままで、係数(b, a 系列の数値) を切り替えるだけで変化します。 • ローパス (LPF) にしたいとき:
左側のフィードバックで「低音が強調されやすい中央ライン(中間状態)」を作り、それを右側の (b0, b1, b2) で整えて低音だけを出力します。
• ノッチ(特定の音を消す)にしたいとき:
特定の周波数のときに、中央ラインから右側へ進む合流ポイントで波が綺麗に相殺されるような係数セットを流し込みます。
4.4.3 実装はどうなるか
ブロック図の通り、中央の縦一列(中間状態の過去ログ)を基準に計算するプログラムです。
// 共通の遅延器(図の中央にある Z⁻¹ 2つ。初期値は 0.0)
double w1 = 0.0; // 上側の Z⁻¹
double w2 = 0.0; // 下側の Z⁻¹
// 毎サンプルごとの処理関数
double processDF2(double x, double b0, double b1, double b2, double a1, double a2) {
// 1. 図の左側:中央最上段のポイント(中間状態 w)を計算
double w = x - a1 * w1 - a2 * w2;
// 2. 図の右側:右端の最終出力 y を計算
double y = b0 * w + b1 * w1 + b2 * w2;
// 3. 中央の遅延器を上から下へシフトして更新
w2 = w1;
w1 = w;
return y;
}
double w1 = 0.0; // 上側の Z⁻¹
double w2 = 0.0; // 下側の Z⁻¹
// 毎サンプルごとの処理関数
double processDF2(double x, double b0, double b1, double b2, double a1, double a2) {
// 1. 図の左側:中央最上段のポイント(中間状態 w)を計算
double w = x - a1 * w1 - a2 * w2;
// 2. 図の右側:右端の最終出力 y を計算
double y = b0 * w + b1 * w1 + b2 * w2;
// 3. 中央の遅延器を上から下へシフトして更新
w2 = w1;
w1 = w;
return y;
}
4.4.4 強みと注意点
• 強み(省メモリ):
必要な遅延器(メモリ)が2つだけで済むため、Direct Form I に比べてメモリ消費量を50%カットできます。
大量のフィルターを同時に動かすハードウェアやプラグインで非常に有利です。
• 注意点(数値のバースト):
大量のフィルターを同時に動かすハードウェアやプラグインで非常に有利です。
計算の途中で、中央の変数(w)の値が一時的に非常に大きくなる性質があります。
現代のパソコン(浮動小数点)なら問題ありませんが、古い機器などの整数計算環境では音が歪んだりバースト(オーバーフロー)しやすいため注意が必要です。
現代のパソコン(浮動小数点)なら問題ありませんが、古い機器などの整数計算環境では音が歪んだりバースト(オーバーフロー)しやすいため注意が必要です。
4.5 Direct Form II 転置型
4.5.1 概要
Direct Form II 転置型(直接型II 転置構成)は、Direct Form II の「メモリが少なくて済む」というメリットを維持したまま、さらに構造をひっくり返すことで欠点を克服した、実用上最も完成度の高い構造です
ブロック図:

特徴:
ブロック図:

特徴:
Direct Form II と同様に、遅延器 (Z^-1) は中央の2つだけです。
4.5.2 1つで7つ
なぜ1つの図で「7種類のフィルター」に化けるのか?
他の構造と同じく、図の流路(配線)は固定したまま、係数の数値だけを入れ替えることで機能が化けます。 • ローパス (LPF) にしたいとき:
他の構造と同じく、図の流路(配線)は固定したまま、係数の数値だけを入れ替えることで機能が化けます。 • ローパス (LPF) にしたいとき:
入力された音に一斉に (b0, b1, b2) が掛けられ、同時に出力された音からも (-a1, -a2) が掛けられます。
これらが中央の遅延器を通って合流する際、高域の成分だけが打ち消し合うような数値セットになります。
• ノッチ(特定の音を消す)にしたいとき:
狙った特定の周波数の成分だけが、中央の加算器で合流したときにちょうどプラスマイナスゼロ(逆位相)になって綺麗に相殺されるような数値を流し込みます。
4.5.3 実装はどうなるか
中央の縦に並んだ遅延器(内部状態)の場所を、上から順に d1、d2 という2つの変数として保持し、図を下から上へ読み解くように計算するプログラムです。
// 2つの遅延器(中央にある Z⁻¹ の内部状態。初期値は 0.0)
double d1 = 0.0; // 上側の Z⁻¹
double d2 = 0.0; // 下側の Z⁻¹
// 毎サンプルごとの処理関数
double processDF2T(double x, double b0, double b1, double b2, double a1, double a2) {
// 1. 最上段の合流ポイントで、現在の出力 y が決まる
double y = b0 * x + d1;
// 2. 次のサンプルのために、上側の遅延器 (d1) を更新
//(中央の加算器の場所:左からの b1*x、右からの -a1*y、下からの d2 が合流)
d1 = b1 * x - a1 * y + d2;
// 3. 一番下の遅延器 (d2) を更新
//(最下段の加算器の場所:左からの b2*x、右からの -a2*y が合流)
d2 = b2 * x - a2 * y;
return y;
}
double d1 = 0.0; // 上側の Z⁻¹
double d2 = 0.0; // 下側の Z⁻¹
// 毎サンプルごとの処理関数
double processDF2T(double x, double b0, double b1, double b2, double a1, double a2) {
// 1. 最上段の合流ポイントで、現在の出力 y が決まる
double y = b0 * x + d1;
// 2. 次のサンプルのために、上側の遅延器 (d1) を更新
//(中央の加算器の場所:左からの b1*x、右からの -a1*y、下からの d2 が合流)
d1 = b1 * x - a1 * y + d2;
// 3. 一番下の遅延器 (d2) を更新
//(最下段の加算器の場所:左からの b2*x、右からの -a2*y が合流)
d2 = b2 * x - a2 * y;
return y;
}
4.5.4 強みと注意点
• 強み(省メモリ):
通常の Direct Form II の弱点だった「途中の数値が大きくなりすぎる(オーバーフロー)」という問題が構造上発生しません。
また、浮動小数点の計算で発生する微小なノイズ(丸め誤差)も非常に少なく、「省メモリ」「高音質」「数値的な安定性」のすべてを兼ね備えています。
そのため、MATLABの標準フィルターや、各種オーディオプラグイン(DSP)の内部実装では、この「転置型」が業界の標準(デファクトスタンダード)として最も広く使われています。
• 注意点(数値のバースト):
また、浮動小数点の計算で発生する微小なノイズ(丸め誤差)も非常に少なく、「省メモリ」「高音質」「数値的な安定性」のすべてを兼ね備えています。
そのため、MATLABの標準フィルターや、各種オーディオプラグイン(DSP)の内部実装では、この「転置型」が業界の標準(デファクトスタンダード)として最も広く使われています。
信号が四方八方に分岐して同時に掛け算されるため、ブロック図をパッと見たときの直感的な信号の流れ(数式との一致度)が、
Direct Form I ほど分かりやすくないという点だけが唯一のデメリットです(プログラムの性能面でのデメリットはありません)。
