Orchestra

Epic

Soundtrack

Orchestra

Epic

Soundtrack

Fantasy

Japanese

Style

Ethnic

Fantasy

Japanese

Style

Ethnic

Kashiwade

Music

Composer

Kashiwade

Music

Composer

Mystical

Adventure

Melody

Mystical

Adventure

Melody

DTMerのためのデジタル信号処理 ~IIRなEQを作ろう~

DTMerのためのデジタル信号処理 ~IIRなEQを作ろう~

Published: 2025-03-16

はじめに

こんにちは!Kashiwadeです。普段はオーケストラ系の曲を作っています。

最近円安で辛いですね…。全然プラグイン買えてないです。プラグインを買えないなら…自作してしまいましょう!!というわけで過去何回かプラグイン自作記事を書いてきました。JUCEを使うと簡単にプラグインを作ることができます。

もちろんEQも簡単に作れます。JUCEにはめっちゃ便利なクラスがあるので、これにサンプルを渡すだけでEQをかけれます。

でも、折角プラグインを自作するならこだわりたいですよね…?肝心要の信号処理部分は自分で1から練り上げたものを使いたいですよね…?

というわけでこの記事では、デジタル信号処理の基礎と、IIR型のEQの原理と実装方法を説明します!ライブラリに頼らずIIRなEQを自作プラグインに組み込めるようになりましょう!

元々は自分の勉強用に書いていたメモを、外部公開用にアップデートした感じの記事です。なので、以降の本文は文体が固くなります。

この記事には間違いがあるかもしれません!もし間違いがあったら教えてください!!!

目次

Chapter 1. 前提知識

本文を理解するうえで必要な前提知識を浚う。

よく使う文字の定義

  • jj: 虚数単位。j2=1j^2=-1であるようなjj
    • 普通はiiを使うが、電気回路の分野では電流を意味するIIと文字が衝突するため、jjを使うことが多い。
  • kk, nn: 整数
  • ω\omega: 角周波数。単位はrad/s。文章中で単に周波数と表現したとしても、数式がω\omegaを使用している場合、それは角周波数のことを指している。

オイラーの公式

信号解析で頻出の「複素数乗」とは一体なんなのかを理解する必要がある。

ejx=cosx+jsinxe^{jx} = \cos x + j \sin x

直感的な証明

exe^xをマクローリン展開すると、

ex=n=0xnn!e^x = \sum_{n=0}^{\infty} \frac{x^n}{n!}

実はxxに複素数を代入することができるので、

ejx=n=0(jx)nn!=n=0jnn!xn=k=0j2k(2k)!x2k+k=0j2k+1(2k+1)!x2k+1=k=0(1)k(2k)!x2k+jk=0(1)k(2k+1)!x2k+1\begin{aligned} e^{jx} &= \sum_{n=0}^{\infty} \frac{(jx)^n}{n!} = \sum_{n=0}^{\infty} \frac{j^n}{n!}x^n \\ &= \sum_{k=0}^{\infty} \frac{j^{2k}}{(2k)!}x^{2k} + \sum_{k=0}^{\infty} \frac{j^{2k+1}}{(2k+1)!}x^{2k+1} \\ &= \sum_{k=0}^{\infty} \frac{(-1)^{k}}{(2k)!}x^{2k} + j \sum_{k=0}^{\infty} \frac{(-1)^{k}}{(2k+1)!}x^{2k+1} \\ \end{aligned}

ちなみに、

cosx=n=0(1)n(2n)!x2nsinx=n=0(1)n(2n+1)!x2n+1\begin{aligned} \cos x &= \sum_{n=0}^{\infty} \frac{(-1)^{n}}{(2n)!}x^{2n} \\ \sin x &= \sum_{n=0}^{\infty} \frac{(-1)^{n}}{(2n+1)!}x^{2n+1} \end{aligned}

なので、

ejx=cosx+jsinxe^{jx} = \cos x + j \sin x

を得る。

オイラーの公式の嬉しさ

オイラーの公式の嬉しさを説明する為に、複素数平面の嬉しさを説明する。 複素数平面とは、横軸に実軸(Reと書くことが多い)、縦軸に虚軸(Imと書くことが多い)をとった平面である。通常の二次元平面では点Aの座標を(1,2)(1, 2)と表現するが、複素数平面ではこの点を1+2j1+2jと表現する。ここでjjとは虚数単位であり、j2=1j^2=-1であるようなjjのことを指す。

従来であれば1つの点の位置を表現するのに2つの値が必要だったが、複素数平面を用いることで、1つの点の位置を表現するのに1つの値で十分になる。

続いて、オイラーの公式の両辺にAAを掛けたAejx=Acosx+jAsinxAe^{jx} = A \cos x + j A \sin xを複素数平面上に描画するとこうなる。

複素数平面なら1つの点の位置を表現するのに1つの値で十分になるという意味が明白になったと思う。

フーリエ変換

下記の動画が分かりやすい。信号を単位円上に巻きつけて、それの重心を考えるというアイデアである。

https://www.youtube.com/watch?v=fGos3wrKeHY

この結果、連続的な信号f(t)f(t)に対して、下記のようなフーリエ変換の式を得る。

F[f(t)](ω)=f(t)ejωtdt\mathcal{F}[f(t)](\omega) = \int_{-\infty}^{\infty} f(t) e^{-j\omega t} dt

また、関数f(t)f(t)をフーリエ変換した物をF[f(t)]\mathcal{F}[f(t)]F[f(t)](ω)\mathcal{F}[f(t)](\omega)F(ω)F(\omega)と書くこともある。

ω\omegaは角周波数であり、1秒間に何ラジアン進むかを意味する。1回転は2π[rad]2 \pi \, [\mathit{\mathrm{rad}}]なので、周期T=2πωT=\frac{2 \pi}{\omega}であり、周波数f=1T=ω2π[Hz]f = \frac{1}{T} = \frac{\omega}{2 \pi}\, [\mathrm{Hz}]である。

性質数式説明
線形性F[af(t)+bg(t)]=aF(ω)+bG(ω)\mathcal{F}[a f(t) + b g(t)] = a F(\omega) + b G(\omega) フーリエ変換は線形演算を保つ
時間シフトF[f(tt0)]=ejωt0F(ω)\mathcal{F}[f(t - t_0)] = e^{-j\omega t_0} F(\omega)関数の遅延は周波数領域で位相変化を引き起こす
周波数シフトF[ejω0tf(t)]=F(ωω0)\mathcal{F}[e^{j \omega_0 t} f(t)] = F(\omega - \omega_0)時間領域での指数関数の乗算は周波数領域での平行移動に対応
時間スケーリングF[f(at)]=1aF(ωa)\mathcal{F}[f(a t)] = \frac{1}{\lvert a \rvert} F ( \frac{\omega}{a} )時間領域でのスケーリングは周波数領域で逆スケーリングと振幅の変化を引き起こす
時間反転F[f(t)]=F(ω)\mathcal{F}[f(-t)] = F(-\omega)時間反転は周波数領域での反転に対応する
畳み込みF[f(t)g(t)]=F(ω)G(ω)\mathcal{F}[f(t) * g(t)] = F(\omega) G(\omega)時間領域での畳み込みは周波数領域での積に対応する
時間領域での積F[f(t)g(t)]=12π(FG)(ω)\mathcal{F}[f(t) g(t)] = \frac{1}{2\pi} (F * G)(\omega)時間領域での積は周波数領域での畳み込みに対応する
積分定理F[tf(τ)dτ]=1jωF(ω)+πF(0)δ(ω)\mathcal{F} \left[ \int_{-\infty}^{t} f(\tau) d\tau \right] = \frac{1}{j\omega}F(\omega) + \pi F(0) \delta(\omega) 時間領域での積分は周波数領域での分数形式に変換される
微分定理F[f(t)]=jωF(ω)\mathcal{F}[f'(t)] = j\omega F(\omega)時間領域の微分は周波数領域での乗算に対応する
フーリエ変換のフーリエ変換F[F[f(t)]]=2πf(t)\mathcal{F}[\mathcal{F}[f(t)]] = 2\pi f(-t)時間反転と振幅の変化を伴う

フーリエ級数

前述のフーリエ変換を得るために、本来はフーリエ級数→フーリエ積分→フーリエ変換と導出していくのが普通だが、本記事ではフーリエ変換は道具の1つなので、天下り的にフーリエ変換と級数を紹介する。フーリエ級数は、周期信号を三角関数の和に展開する。

区間T2tT2-\frac{T}{2} \leq t \leq \frac{T}{2}で定義された信号f(t)f(t)が区間外で周期TTの周期信号であるなら、その信号は、

f(t)=n=Cnejn2πTtCn=1TT2T2f(t)ejn2πTt\begin{aligned} f(t) &= \sum_{n=-\infty}^{\infty} C_n e^{jn\frac{2 \pi}{T}t} \\ C_n&=\frac{1}{T}\int_{-\frac{T}{2}}^{\frac{T}{2}} f(t) e^{-jn\frac{2 \pi}{T}t} \end{aligned}

というフーリエ級数に展開できる。

離散フーリエ変換

前に示した動画のように、フーリエ変換のことを、ある信号を単位円上に巻きつけたその重心と考えるなら、離散的な信号を単位円上に巻きつけた時の重心は

n=f(nT)ejωnT\sum_{n=-\infty}^{\infty} f(nT)e^{-j \omega nT}

と書ける。これが離散フーリエ変換の式である。

ラプラス変換

フーリエ変換には便利な性質がある。例えば、微分記号を外すことができる。

F[f(n)](ω)=(jω)nF[f](ω)\mathcal{F}[f^{(n)}](\omega) = (j \omega)^{n} \mathcal{F}[f](\omega)

現実世界の解析では微分方程式を解くことが多く、微分を外せるというフーリエ変換の性質は非常に便利である。

しかし、フーリエ変換の値が存在するためには、f(t)f(t)(,)(- \infty, \infty)で絶対可積分であること。つまり

f(t)dt<\int_{-\infty}^{\infty} |f(t)| dt < \infty

であることが必要である。これだとf(t)f(t)の制約が強く、少し使い勝手が悪い。

そこでf(t)f(t)tt \rightarrow \inftyで有界にすべく、tt(0,)(0, \infty)とし、新たなパラメータσ (σ>0)\sigma \ (\sigma > 0)を用いて、eσtf(t)e^{-\sigma t}f(t)と考える。これでフーリエ変換の式を書き直すと、

F[eσtf(t)](ω)=0eσtf(t)ejωtdt=0f(t)e(σ+jω)tdt\begin{aligned} \mathcal{F}[e^{-\sigma t}f(t)](\omega) &= \int_{0}^{\infty} e^{-\sigma t}f(t) e^{-j\omega t} dt \\ &= \int_{0}^{\infty} f(t) e^{- (\sigma + j\omega) t} dt \end{aligned}

ここで、σ+jω\sigma + j\omegaは単なる複素数であるからssと置くことで、ラプラス変換の式

L[f(t)](s)=0f(t)estdt\mathcal{L}[f(t)](s) = \int_{0}^{\infty} f(t) e^{- st} dt

を得る。 関数f(t)f(t)をラプラス変換した物をL[f(t)]\mathcal{L}[f(t)]L[f(t)](s)\mathcal{L}[f(t)](s)F(s)F(s)と書くこともある。

s=jωs=j \omegaとすることで、ラプラス変換の結果からフーリエ変換の結果を得ることができる。実際、

L[f(t)](jω)=0f(t)ejωtdt\begin{aligned} \mathcal{L}[f(t)](j \omega) = \int_{0}^{\infty} f(t) e^{- j \omega t} dt \end{aligned}

は、

F[f(t)](ω)=f(t)ejωtdt\mathcal{F}[f(t)](\omega) = \int_{-\infty}^{\infty} f(t) e^{-j \omega t} dt

と似ている。フーリエ変換がf(t)f(t)を時間(,)(-\infty, \infty)で切り取って単位円上に巻きつけた時の重心の位置を示すことを考えると、切り取った時間が(0,)(0, \infty)としても些細な物。

性質数式説明
線形性L[af(t)+bg(t)]=aF(s)+bG(s)\mathcal{L}[a f(t) + b g(t)] = a F(s) + b G(s)ラプラス変換は線形演算を保つ
時間シフトL[f(tt0)u(tt0)]=est0F(s)\mathcal{L}[f(t - t_0) u(t - t_0)] = e^{-st_0} F(s)関数の遅延が指数関数の乗算に変換
指数関数乗算の性質L[es0tf(t)]=F(ss0)\mathcal{L}[e^{s_0t} f(t)] = F(s - s_0)時間領域での指数関数の乗算は変数の平行移動に対応
畳み込みのラプラス変換L[f(t)g(t)]=F(s)G(s)\mathcal{L}[f(t) * g(t)]= F(s) G(s)畳み込みはラプラス変換での積に対応
時間領域での積L[f(t)g(t)]=12πjcjc+jF(σ)G(sσ)dσ\mathcal{L}[f(t) g(t)] = \frac{1}{2\pi j} \int_{c - j\infty}^{c + j\infty} F(\sigma) G(s - \sigma) d\sigma積はラプラス変換での複素畳み込みに対応
積分のラプラス変換L[0tf(τ)dτ]=F(s)s\mathcal{L} [\int_0^t f(\tau) d\tau] = \frac{F(s)}{s} 時間領域での積分はラプラス変換での除算に対応
微分のラプラス変換L[f(t)]=sF(s)f(0)\mathcal{L} [f'(t)] = s F(s) - f(0)関数の微分がラプラス変換では乗算と初期値に対応
2階微分のラプラス変換L[f(t)]=s2F(s)sf(0)f(0)\mathcal{L}[f''(t)] = s^2 F(s) - s f(0) - f'(0)高階微分も同様に変換できる

Z変換

離散版のラプラス変換のような物である。離散フーリエ変換の式に対して、ラプラス変換の導出と同じように求める。zzは複素数である。

n=0eσnTf(nT)ejωnT=k=0f(nT)e(σ+jω)nT=n=0f(nT)zn\begin{aligned} \sum_{n=0}^{\infty} e^{-\sigma nT}f(nT)e^{-j \omega nT} &= \sum_{k=0}^{\infty} f(nT)e^{- (\sigma + j \omega) nT} \\ &= \sum_{n=0}^{\infty} f(nT)z^{-n} \end{aligned}

関数f(t)f(t)をZ変換した物をZ[f(t)]\mathcal{Z}[f(t)]Z[f(t)](z)\mathcal{Z}[f(t)](z)F(z)F(z)と書くこともある。

z=ejωTz=e^{j \omega T}とすることで、Z変換の結果から離散フーリエ変換の結果を得ることができる。実際、

Z[f(t)](ejωT)=n=0f(nT)(ejωT)n=n=0f(nT)ejωnT\begin{aligned} \mathcal{Z}[f(t)](e^{j \omega T}) &= \sum_{n=0}^{\infty} f(nT)(e^{j \omega T})^{-n} \\ &= \sum_{n=0}^{\infty} f(nT)e^{-j \omega nT} \end{aligned}

は、

F[f(n)](ω)=n=f(nT)ejωnT\mathcal{F}[f(n)](\omega) = \sum_{n=-\infty}^{\infty} f(nT)e^{-j \omega nT}

と似ている。離散フーリエ変換がf(t)f(t)を時間(,)(-\infty, \infty)で切り取って単位円上に巻きつけた時の重心の位置を示すことを考えると、切り取った時間が(0,)(0, \infty)としても些細な物。

性質数式説明
線形性Z[af(t)+bg(t)]=aF(z)+bG(z)\mathcal{Z}[a f(t) + b g(t)] = a F(z) + b G(z)Z変換は線形演算を保つ
時間シフトZ[f[nk]]=zkF(z)\mathcal{Z}[f[n - k]] = z^{-k} F(z)時間領域のシフトは zz の乗算に対応
指数関数乗算の性質Z[αnf(t)]=F(z/α)\mathcal{Z}[\alpha^n f(t)] = F(z/\alpha)時間領域での指数関数の乗算は変数のスケーリングに対応
畳み込みのZ変換Z[f(t)g(t)]=F(z)G(z)\mathcal{Z}[f(t) * g(t)] = F(z) G(z)畳み込みはZ変換での積に対応
和のZ変換Z[k=0nf[k]]=F(z)1z1\mathcal{Z} \left[ \sum_{k=0}^{n} f[k] \right] = \frac{F(z)}{1 - z^{-1}}累積和はZ変換での除算に対応
微分のZ変換(離散時間)Z[Δf(t)]=(z1)F(z)\mathcal{Z} [\Delta f(t)] = (z - 1) F(z)離散差分はZ変換では乗算に対応
2階差分のZ変換Z[Δ2f(t)]=(z1)2F(z)\mathcal{Z} [\Delta^2 f(t)] = (z - 1)^2 F(z)高階差分も同様に変換できる

離散時間システムの表現

デジタルフィルタは離散時間システムである。離散時間システムへの入力信号と出力信号は整数nnとサンプリング周期TT及び連続時間信号f(t)f(t)を用いてf(nT)f(nT)と表現される。離散時間信号を、サンプリング周期を考えずに値の配列として考えて、f[n]f[n]と表現することもある。

離散時間信号とデジタル信号はほぼ同じ意味を持つが厳密には違う。離散時間信号の反対は連続時間信号であり、これは時間軸方向が離散であるかに着目した名前である。デジタル信号の反対はアナログ信号であり、これは時間軸方向と振幅方向が離散であるかに着目した名前である。

振幅方向が離散であるかどうかは、演算精度の議論でしか問題にならないため、本記事では離散時間信号とデジタル信号は同じ意味として使う。

離散時間信号を表現する重要なツールとして単位インパルス信号が挙げられる。

δ(nT)={1,n=00,n0\delta (nT)= \begin{cases} 1, & n=0 \\ 0, & n \neq 0 \end{cases}

これは次のような波形を持つ。

インパルス信号の頂点は並行移動することができ、整数kkを用いて

δ(nTkT)={1,n=k0,nk\delta (nT-kT)= \begin{cases} 1, & n=k \\ 0, & n \neq k \end{cases}

と書ける。これを用いれば任意の信号x(nT)x(nT)

x(nT)=k=x(kT)δ(nTkT)x(nT) = \sum_{k=-\infty}^{\infty} x(kT) \delta (nT - kT)

と書ける。これはかなり当たり前な式だが、離散時間システムを表現するうえで役立つ。

インパルス信号を用いて離散時間システムを表現することを考えよう。離散時間システムは、離散時間信号x(nT)x(nT)を入力して処理を行い離散時間信号y(nT)y(nT)を得ることと言えるため、離散時間システムをffという関数と見れば

y(nT)=f[x(nT)]y(nT) = f[x(nT)]

と書ける。図で表すなら下記の通りである。

システムにインパルス信号を入力したときの出力、インパルス応答をh(nT)=f[δ(nT)]h(nT)=f[\delta(nT)]とする。

前に述べたようにx(nT)=k=x(kT)δ(nTkT)x(nT) = \sum_{k=-\infty}^{\infty} x(kT) \delta (nT - kT)であるから、

y(nT)=f[x(nT)]=f[k=x(kT)δ(nTkT)]y(nT) = f[x(nT)] = f \left[ \sum_{k=-\infty}^{\infty} x(kT) \delta (nT - kT) \right]

と書ける。離散時間システムは線形性(EQ掛けてから信号を足しても、信号を足してからEQを掛けても結果は同じ)を持つから、

f[a1x1(nT)+a2x2(nT)]=a1f[x1(nT)]+a2f[x2(nT)]f[a_1x_1(nT)+a_2x_2(nT)] = a_1f[x_1(nT)]+a_2f[x_2(nT)]

が成り立つので、

y(nT)=f[x(nT)]=f[k=x(kT)δ(nTkT)]=k=f[x(kT)δ(nTkT)]=k=x(kT)f[δ(nTkT)]\begin{aligned} y(nT) = f[x(nT)] &= f \left[ \sum_{k=-\infty}^{\infty} x(kT) \delta (nT - kT) \right] \\ &= \sum_{k=-\infty}^{\infty} f \left[x(kT) \delta (nT - kT) \right] \\ &= \sum_{k=-\infty}^{\infty} x(kT) f \left[ \delta (nT - kT) \right] \end{aligned}

ここで、離散時間システムは時不変性(いつ入力しても結果は同じ)を持つので、インパルス応答の式からh(nTkT)=f[δ(nTkT)]h(nT-kT)=f[\delta(nT-kT)]であるから、

y(nT)=f[x(nT)]=k=x(kT)f[δ(nTkT)]=k=x(kT)h(nTkT)\begin{aligned} y(nT) = f[x(nT)] &= \sum_{k=-\infty}^{\infty} x(kT) f \left[ \delta (nT - kT) \right] \\ &= \sum_{k=-\infty}^{\infty} x(kT) h(nT-kT) \end{aligned}

この式の右辺の形を畳み込み和(コンボリューション)と呼ぶ。つまり、任意の入力信号に対する出力信号は、システムのインパルス応答を入力信号に畳み込むと得られるということが分かる。

また、当たり前な式だと紹介したx(nT)=k=x(kT)δ(nTkT)x(nT) = \sum_{k=-\infty}^{\infty} x(kT) \delta (nT - kT)は、実は畳み込み和の計算であり、インパルス信号δ(nT)\delta(nT)は畳み込み和における単位元ということも分かる。

システムのインパルス応答が有限長であればそのシステムはFIRシステム(Finite Impulse Response)であり、無限長であればIIRシステム(Infinite Impulse Response)である。 現実のシステムを考える際、FIRシステムであれば有限長のインパルス応答を畳み込めば良いので実現可能である。ただし、無限長のインパルス応答を畳み込むのは不可能であるためIIRシステムは実現できないように見える。しかし、差分方程式を使うことでIIRシステムは上手いこと実現可能である。

具体的に見てみる。インパルス応答が下記式で表せるようなIIRシステムを考える。

h(nT)={αn,0n0,otherwiseh(nT) = \begin{cases} \alpha ^n, & 0 \leq n \\ 0, & \text{otherwise} \end{cases}

インパルス応答h(nT)h(nT)n<0n<0では常にゼロである。もしh(nT)h(nT)n<0n<0でゼロでないなら、入力のインパルスが来る前に何等かの応答が表れていることになる。未来の入力を先取りして応答するシステムは現実では存在しない。ちなみに、インパルス応答h(nT)h(nT)n<0n<0で常にゼロであるシステムを因果的なシステムと呼ぶ。現実に存在する全てのシステムは因果的である。このインパルス応答を用いれば入力信号x(nT)x(nT)に対する出力信号y(nT)y(nT)は畳み込みを利用して

y(nT)=f[x(nT)]=k=x(kT)h(nTkT)=k=h(kT)x(nTkT)※畳み込みは可換=k=0αkx(nTkT)\begin{aligned} y(nT) = f[x(nT)] &= \sum_{k=-\infty}^{\infty} x(kT) h(nT-kT) \\ &= \sum_{k=-\infty}^{\infty} h(kT) x(nT-kT) \quad \scriptsize{※畳み込みは可換}\\ &= \sum_{k=0}^{\infty} \alpha^k x(nT-kT) \end{aligned}

具体的なnnkkを書き出してみると、

y(0×T)=k=0αkx(kT)=α0x(0)+α1x(T)+α2x(2T)+α3x(3T)+α4x(4T)+y(1×T)=k=0αkx(TkT)=α0x(T)+α1x(0)+α2x(T)+α3x(2T)+α4x(3T)+=α0x(T)+α(α0x(0)+α1x(T)+α2x(2T)+α3x(3T)+)=α0x(T)+αy(0×T)y(2×T)=k=0αkx(2TkT)=α0x(2T)+α1x(T)+α2x(0)+α3x(T)+α4x(2T)+=α0x(2T)+α(α0x(T)+α1x(0)+α2x(T)+α3x(2T)+)=α0x(2T)+αy(1×T)\begin{aligned} y(0 \times T) &= \sum_{k=0}^{\infty} \alpha^k x(-kT) \\ &= \alpha^0 x(0) + \alpha^1 x(-T) + \alpha^2 x(-2T) + \alpha^3 x(-3T) + \alpha^4 x(-4T) + \cdots \\ y(1 \times T) &= \sum_{k=0}^{\infty} \alpha^k x(T-kT) \\ &= \alpha^0 x(T) + \alpha^1 x(0) + \alpha^2 x(-T) + \alpha^3 x(-2T) + \alpha^4 x(-3T) + \cdots \\ &= \alpha^0 x(T) + \alpha ( \alpha^0 x(0) + \alpha^1 x(-T) + \alpha^2 x(-2T) + \alpha^3 x(-3T) + \cdots )\\ &= \alpha^0 x(T) + \alpha y(0 \times T) \\ y(2 \times T) &= \sum_{k=0}^{\infty} \alpha^k x(2T-kT) \\ &= \alpha^0 x(2T) + \alpha^1 x(T) + \alpha^2 x(0) + \alpha^3 x(-T) + \alpha^4 x(-2T) + \cdots \\ &= \alpha^0 x(2T) + \alpha (\alpha^0 x(T) + \alpha^1 x(0) + \alpha^2 x(-T) + \alpha^3 x(-2T) + \cdots ) \\ &= \alpha^0 x(2T) + \alpha y (1 \times T) \end{aligned}

段々法則も分かって来たので、

y(nT)=f[x(nT)]=k=0αkx(nTkT)=x(nT)+k=1αkx(nTkT)=x(nT)+k=0αk+1x(nT(k+1)T)=x(nT)+αk=0αkx((n1)TkT)=x(nT)+αy((n1)T)\begin{aligned} y(nT) = f[x(nT)] &= \sum_{k=0}^{\infty} \alpha^k x(nT-kT) \\ &= x(nT) + \sum_{k=1}^{\infty} \alpha^{k} x(nT-kT) \\ &= x(nT) + \sum_{k=0}^{\infty} \alpha^{k+1} x(nT-(k+1)T) \\ &= x(nT) + \alpha \sum_{k=0}^{\infty} \alpha^{k} x((n-1)T-kT) \\ &= x(nT) + \alpha y((n-1)T) \end{aligned}

以上より、前の結果を定数倍して現在の信号に加算すれば実現可能ということが分かった。

これを一般化すれば、離散時間システムの入出力関係の式は

y(nT)=a0x(nT)+a1x(nTT)++aMx(nTMT)(b0y(nT)+b1y(nTT)++bMy(nTNT))=k=0Makx(nTkT)k=1Nbky(nTkT)\begin{aligned} y(nT) &= a_0x(nT) + a_1x(nT-T) + \cdots + a_Mx(nT-MT) \\ & \qquad -(b_0y(nT) + b_1y(nT-T) + \cdots + b_My(nT-NT)) \\ &= \sum_{k=0}^{M} a_k x(nT-kT) - \sum_{k=1}^{N}b_ky(nT-kT) \\ \end{aligned}

となる。これを差分方程式と呼ぶ。MMNNのうち大きい方をシステムの次数と呼ぶ。

離散時間システムの解析

離散時間システムの解析にはZ変換を用いる。これは離散時間におけるラプラス変換のような物である。電気回路などの連続時間システムの解析にラプラス変換を用いることと対応づけると良い。

直前の項で、離散時間システムの入出力関係は差分方程式で表せると述べた。この差分方程式の両辺をZ変換してみる。

Y(z)=k=0MakzkX(Z)k=1NbkzkY(z)Y(z)X(z)=k=0Makzk1+k=1Nbkzk\begin{aligned} Y(z) &= \sum_{k=0}^{M} a_k z^{-k} X(Z) - \sum_{k=1}^{N} b_k z^{-k}Y(z) \\ \frac{Y(z)}{X(z)} &= \frac{\sum_{k=0}^{M} a_k z^{-k}}{1+\sum_{k=1}^{N} b_k z^{-k}} \end{aligned}

入出力の信号のZ変換の関係式Y(z)X(z)\frac{Y(z)}{X(z)}を伝達関数H(z)H(z)と言う。Z変換ではz=ejωTz=e^{j\omega T}を代入すれば離散フーリエ変換の結果を得ることができるため、この伝達関数にz=ejωTz=e^{j\omega T}を代入すればこのシステムの周波数特性H(ω)H(\omega)を得ることができる。

周波数特性H(ω)H(\omega)の振幅をとったH(ω)|H(\omega)|を周波数振幅特性、あるいは単に振幅特性と言い、偏角をとったarg(H(ω))\arg(H(\omega))を周波数位相特性、あるいは単に位相特性と言う。

プラグインでよく見るスペクトラムアナライザは振幅特性の2乗に対数をとったもの、つまり、

log10(H(ω)2)=2log10(H(ω)) [B]※単位はベル=20log10(H(ω)) [dB]※単位はデシベル\begin{aligned} \log_{10}(|H(\omega)|^2) &= 2 \log_{10}(|H(\omega)|)\ [\mathrm{B}] \quad \footnotesize{※単位はベル} \\ &= 20 \log_{10}(|H(\omega)|)\ [\mathrm{dB}] \quad \footnotesize{※単位はデシベル} \end{aligned}

の式で得られたものの内、正の周波数を表示したものである。

標本化定理(サンプリング定理)

アナログ世界の信号は連続信号であることが多い。これをデジタル世界で処理する為には、連続信号を離散信号に変換する必要がある。時間方向に離散化することを「標本化」や「サンプリング」と呼ぶ。振幅方向に離散化することを「量子化」と呼ぶ。

連続信号f(t)f(t)を周期TTでサンプリングした信号の周波数特性を考えてみる。単純に考えれば連続信号f(t)f(t)を周期TTでサンプリングした信号は

fsampled(t)={f(nT),t=nT(nは整数)0,otherwisef_{\mathit{sampled}}(t) = \begin{cases} f(nT), & t = nT\quad (n は整数) \\ 0, & \text{otherwise} \end{cases}

と書けるため、フーリエ変換の式は下記のようになりそう。

F=fsampled(t)eiωtdt\mathcal{F}=\int_{-\infty}^{\infty} f_{\mathit{sampled}}(t) e^{-i\omega t} dt

しかし、fsampled(t)f_{\mathit{sampled}}(t)は面積がゼロであるため、上式の結果はゼロになる。これは困るので、fsampled(t)f_{\mathit{sampled}}(t)の定義を考え直す必要がある。(ちなみに、これを短冊の面積と考えて計算すると、離散フーリエ変換の式が出てくる。それは今回欲しい物ではない。)

そこでディラックのデルタ関数を用意する。この関数は任意の連続な関数g(x)g(x)を用いて下記のように定義される。

g(x)δ(x)dx=g(0)\int_{-\infty}^{\infty} g(x) \delta(x) \, dx = g(0)

ディラックのデルタ関数は「関数(function)」という名前がついているが正しくは「超関数(distribution)」であり、関数ではない。なのでδ(x)=〇〇\delta(x)=〇〇という形では書けない。ただ、なんとなくのイメージとして表現はできる。例えばg(x)=1g(x)=1の時、ディラックのデルタ関数の定義式から

δ(x)dx=1\int_{-\infty}^{\infty} \delta(x) \, dx = 1

を得る。つまり、ディラックのデルタ関数の面積は1である。また定義式から、g(x)δ(x)g(x) \delta(x)の演算を通して、どんな関数に対してもx=0x=0の時の値g(0)g(0)しか拾わず、x=0x=0以外の値は打ち消している様子から

δ(x)={,x=00,x0\delta(x) = \begin{cases} \infty, & x = 0 \\ 0, & x \neq 0 \end{cases}

のようなイメージができる。なぜ11ではなく\inftyなのか。前述の通りディラックのデルタ関数の面積は1であるので、面積が1の長方形を考える。ただし、この長方形の幅は0である。そのような長方形を考えると高さを\inftyと表現するしかない。

注意しなければならないのが、これはあくまでもイメージということである。信号処理の分野では、δ(0)\delta (0)の値を便宜上11と解釈してデルタ関数を扱うと直感的に分かりやすい場面が多い。

このディラックのデルタ関数を間隔TTで並べたデルタ関数列は、

δT(t)=n=δ(tnT)\delta_T(t) = \sum_{n=-\infty}^{\infty} \delta(t-nT)

と書ける。デルタ関数列と連続信号f(t)f(t)の積を取ることで、連続信号であることを保ったままfsampled(t)f_{\mathit{sampled}}(t)を得ることができる。

fsampled(t)=f(t)δT(t)f_{\mathit{sampled}}(t)=f(t)\delta_T(t)

ディラックのデルタ関数の性質を考えると、fsampled(t)=f(t)δT(t)f_{\mathit{sampled}}(t)=f(t)\delta_T(t)は等間隔に\inftyになるくし形関数になるのでは?と思える。

δ(x)={,x=00,x0\delta(x) = \begin{cases} \infty, & x = 0 \\ 0, & x \neq 0 \end{cases}

ただ、上述の性質はあくまでもイメージであることと、この後fsampled(t)f_{\mathit{sampled}}(t)をフーリエ変換(積分)するのが前提の処理であるため、ここでは深く考える必要はない。ディラックのデルタ関数は、積分すれば、あたかも高さが1のインパルスを元の連続信号に掛けたように扱えるという理解で十分である。

ちなみに。ディラックのデルタ関数と一般の関数f(t)f(t)の畳み込みを行うと次のようになる。

f(u)δ(tu)du=δ(u)f(tu)du=f(t)\begin{aligned} \int_{-\infty}^{\infty} f(u)\delta (t-u) \, du &= \int_{-\infty}^{\infty} \delta(u) f(t-u) \, du = f(t) \end{aligned}

これをディラックのデルタ関数の定義としても良い。この式から、ディラックのデルタ関数は畳み込み演算に置ける単位元と言える。離散時間システムの表現の項で、離散時間畳み込み和の単位元はインパルス信号であると書いた。連続時間信号畳み込みの単位元がディラックのデルタ関数である事実と照らし合わせると良い。

いよいよfsampled(t)=f(t)δT(t)f_{\mathit{sampled}}(t)=f(t)\delta_T(t)をフーリエ変換する。時間領域での積は周波数領域での畳み込みに対応するため、

F[f(t)δT(t)](ω)=12πF[f(t)](u)F[δT(t)](ωu)du\begin{aligned} \mathcal{F}[f(t)\delta_T(t)](\omega) = \frac{1}{2 \pi} \int_{-\infty}^{\infty} \mathcal{F}[f(t)](u) \cdot \mathcal{F}[\delta_T(t)](\omega - u) \, du \end{aligned}

を計算すれば良い。まず、デルタ関数列のフーリエ変換から行う。 デルタ関数列は周期TTの周期関数なのでフーリエ級数展開して、

δT(t)=n=(1TT2T2δ(t)ejn2πTt)ejn2πTt=1Tn=ejn2πTt\begin{aligned} \delta_T(t) &= \sum_{n=-\infty}^{\infty} \left( \frac{1}{T}\int_{-\frac{T}{2}}^{\frac{T}{2}} \delta(t) e^{-jn\frac{2 \pi}{T}t} \right) e^{jn\frac{2 \pi}{T}t} \\ &= \frac{1}{T} \sum_{n=-\infty}^{\infty} e^{jn\frac{2 \pi}{T}t} \end{aligned}

これをフーリエ変換すると

F[δT(t)](ω)=δT(t)ejωtdt=(1Tn=ejn2πTt)ejωtdt=1Tn=ejn2πTtejωtdt\begin{aligned} \mathcal{F}[\delta_T(t)](\omega) &= \int_{-\infty}^{\infty} \delta_T(t) e^{-j \omega t} \, dt \\ &= \int_{-\infty}^{\infty} \left( \frac{1}{T} \sum_{n=-\infty}^{\infty} e^{jn\frac{2 \pi}{T}t} \right) e^{-j \omega t} \, dt \\ &= \frac{1}{T} \sum_{n=-\infty}^{\infty} \int_{-\infty}^{\infty} e^{jn\frac{2 \pi}{T}t} e^{-j \omega t} \, dt \\ \end{aligned}

ここで、ディラックのデルタ関数のフーリエ変換F[δ(t)](ω)=1\mathcal{F}[\delta(t)](\omega)=1と、フーリエ変換のフーリエ変換を用いればF[1](ω)=2πδ(ω)\mathcal{F}[1](\omega)=2 \pi \delta(\omega)であり、更に周波数シフトを考えればF[1ejω0t](ω)=2πδ(ωω0)\mathcal{F}[1 \cdot e^{j \omega_0 t}](\omega)=2 \pi \delta(\omega - \omega_0)なので、

F[δT(t)](ω)=δT(t)ejωtdt=1Tn=2πδ(ωn2πT)=2πTn=δ(ωn2πT)\begin{aligned} \mathcal{F}[\delta_T(t)](\omega) &= \int_{-\infty}^{\infty} \delta_T(t) e^{-j \omega t} \, dt \\ &= \frac{1}{T} \sum_{n=-\infty}^{\infty} 2 \pi \delta(\omega - n\frac{2 \pi}{T}) \\ &= \frac{2 \pi}{T} \sum_{n=-\infty}^{\infty} \delta(\omega - n\frac{2 \pi}{T}) \\ \end{aligned}

これを使えばfsampled(t)=f(t)δT(t)f_{\mathit{sampled}}(t)=f(t)\delta_T(t)のフーリエ変換は

F[f(t)δT(t)](ω)=12πF[f(t)](u)F[δT(t)](ωu)du=12πF[f(t)](u)2πTn=δ(ωn2πTu)du=1Tn=F[f(t)](u)δ(ωn2πTu)du\begin{aligned} \mathcal{F}[f(t)\delta_T(t)](\omega) &= \frac{1}{2 \pi} \int_{-\infty}^{\infty} \mathcal{F}[f(t)](u) \cdot \mathcal{F}[\delta_T(t)](\omega - u) \, du \\ &= \frac{1}{2 \pi} \int_{-\infty}^{\infty} \mathcal{F}[f(t)](u) \cdot \frac{2 \pi}{T} \sum_{n=-\infty}^{\infty} \delta(\omega - n\frac{2 \pi}{T} - u) \, du \\ &= \frac{1}{T} \sum_{n=-\infty}^{\infty} \int_{-\infty}^{\infty} \mathcal{F}[f(t)](u) \cdot \delta(\omega - n\frac{2 \pi}{T} - u) \, du \\ \end{aligned}

ディラックのデルタ関数は畳み込み演算に置ける単位元なので、

F[f(t)δT(t)](ω)=1Tn=F[f(t)](u)δ(ωn2πTu)du=1Tn=F[f(t)](ωn2πT)=1Tn=F(ωn2πT)\begin{aligned} \mathcal{F}[f(t)\delta_T(t)](\omega) &= \frac{1}{T} \sum_{n=-\infty}^{\infty} \int_{-\infty}^{\infty} \mathcal{F}[f(t)](u) \cdot \delta(\omega - n\frac{2 \pi}{T} - u) \, du \\ &= \frac{1}{T} \sum_{n=-\infty}^{\infty} \mathcal{F}[f(t)](\omega - n\frac{2 \pi}{T}) \\ &= \frac{1}{T} \sum_{n=-\infty}^{\infty} F(\omega - n\frac{2 \pi}{T}) \end{aligned}

この式を解釈すると、連続時間信号をサンプリングした離散信号のスペクトルは、連続時間信号のスペクトルを間隔2πT\frac{2 \pi}{T}で並べた物と言える。間隔2πT\frac{2 \pi}{T}とはサンプリング周波数である。これを図で描くと次のようになる。

連続時間信号のスペクトルの最大値がσ\sigma以下、つまり、連続時間信号がσ\sigma以下で帯域制限されている場合を図示している。これをサンプリングした信号のスペクトルは、連続時間信号のスペクトルをサンプリング周波数間隔で並べた物になる。もしσ12×2πT\sigma \geq \frac{1}{2} \times \frac{2 \pi}{T}なら、サンプリング後のスペクトルが一部重複し信号が歪んでしまう。この歪みのことをエイリアシング歪みと呼ぶ。元信号をサンプリングする際にエイリアシング歪みが起こらないサンプリング周波数の下限のことをナイキストレートと呼び、あるサンプリング周波数でサンプリングしたときに表現できる周波数の上限のことをナイキスト周波数と呼ぶ。

折角なのでサンプリングした信号から連続時間信号を復元する処理も行ってみよう。ここではエイリアシング歪みが無かった時を考える。

連続時間信号をサンプリングした離散信号のスペクトルは、連続時間信号のスペクトルを間隔2πT\frac{2 \pi}{T}で並べた物である。離散信号から連続信号を復元するには、離散信号のスペクトルのうち中心以外にあるものを打ち消すような処理を行えばいい。つまり、低域通過フィルタを適応させれば良い。

カットオフ周波数がωc\omega_cである理想低域通過フィルタの周波数特性は次のようにあらわせる。

H(ω)={1,ωωC0,ωC<ωH(\omega) = \begin{cases} 1, & |\omega| \leq \omega_C \\ 0, & \omega_C < |\omega| \end{cases}

理想低域通過フィルタを時間領域で表現するにはH(ω)H(\omega)を逆フーリエ変換すればよく、

h(t)=12πωcωcejωt=ωcπsinωctωcth(t) = \frac{1}{2 \pi} \int_{-\omega_c}^{\omega_c} e^{j \omega t} = \frac{\omega_c}{\pi} \frac{\sin \omega_ct}{\omega_ct}

である。これはsinc関数である。

周波数領域にて、サンプリングした離散信号のスペクトルにH(ω)H(\omega)を掛ければ、中心以外にあるものを打ち消すことができ、連続時間信号を復元できる。周波数領域に置ける積は時間領域に置ける畳み込みに対応する。つまり、離散信号にsinc関数を畳み込めば連続時間信号を復元できるのである。

今回はサンプリング定理の説明を数式で行ったが、もっと直感的な説明も可能である。 例えば下図左側は周波数が0.25Hzの連続信号を1Hzでサンプリングした様子を示している。赤い点だけみても、波の形を保てているのが分かる。下図中央は周波数が0.33Hzの連続信号を1Hzでサンプリングしている。こちらも波の形を保てている。しかし、下図右側のように周波数が0.5Hzの連続信号、つまりナイキスト周波数と丁度同じ周波数を持つ信号を1Hzでサンプリングすると、波の形を保てていないことが分かる。

Chapter 2. IIRデジタルフィルタの設計

いよいよIIRデジタルフィルタの設計に移る。実は、IIRデジタルフィルタを無から作り出すのは難しい。そこで、アナログフィルタの理論は昔からよく研究されていることから、アナログフィルタを何等かの形で変換してデジタルフィルタを得ることを考えよう。ここではいくつかの方法を紹介する。

電気回路からの直接設計

下記はRCローパスフィルタの回路である。これをデジタルフィルタとして設計し、プログラムで実装可能なブロックダイアグラムを得ることを目的とする。

周波数特性の確認

まずはこの回路がどのような周波数特性を持つのかを確認する。 この回路について成り立つ式は次の通り。

Vx=Vr+VcVy=VcVr=IRI=dQcdtQc=CVc\begin{aligned} V_x &= V_r + V_c \\ V_y &= V_c \\ V_r &= IR \\ I &= \frac{d Q_c}{dt} \\ Q_c &= C V_c \end{aligned}

これを整理すると次のようになる。

Vx=Vr+Vc=IR+Vy=RdQcdt+Vy=RdCVcdt+Vy=RdCVydt+Vy=RCdVydt+Vy\begin{aligned} V_x &= V_r + V_c \\ &= IR + V_y \\ &= R \frac{d Q_c}{dt} + V_y \\ &= R \frac{d C V_c}{dt} + V_y \\ &= R \frac{d C V_y}{dt} + V_y \\ &= R C \frac{d V_y}{dt} + V_y \end{aligned}

微分方程式となり少々厄介なので、両辺をラプラス変換して微分を消す。

L[Vx](s)=sRCL[Vy](s)+L[Vy](s)=(1+sRC)L[Vy](s)\begin{aligned} \mathcal{L}[V_x](s) &= s R C \mathcal{L}[V_y](s) + \mathcal{L}[V_y](s) \\ &= (1+sRC) \mathcal{L}[V_y](s) \end{aligned}

この回路の周波数特性を知るためには、入出力信号の周波数特性の比F[Vy](ω)F[Vx](ω)\frac{\mathcal{F}[V_y](\omega)}{\mathcal{F}[V_x](\omega)}を求めればよい。ラプラス変換を用いると、F[Vy](ω)=L[Vy](jω)\mathcal{F}[V_y](\omega)=\mathcal{L}[V_y](j \omega)かつF[Vx](ω)=L[Vx](jω)\mathcal{F}[V_x](\omega)=\mathcal{L}[V_x](j \omega)と書けるから、伝達関数H(s)H(s)

H(s)=L[Vy](s)L[Vx](s)=11+sRCH(s) = \frac{\mathcal{L}[V_y](s)}{\mathcal{L}[V_x](s)} = \frac{1}{1+sRC}

となり、周波数特性H(jω)H(j \omega)

H(jω)=L[Vy](jω)L[Vx](jω)=11+jωRCH(j \omega) = \frac{\mathcal{L}[V_y](j \omega)}{\mathcal{L}[V_x](j \omega)} = \frac{1}{1+j \omega RC}

となる。カットオフ周波数のパラメータをωc=1RC\omega_c = \frac{1}{RC}のように定めれば、

H(jω)=11+jω/ωcH(j \omega) = \frac{1}{1+j \omega / \omega_c}

振幅特性と位相特性はそれぞれ次のように書ける。

H(jω)=11+jω/ωcargH(jω)=arg11+jω/ωc\begin{aligned} |H(j \omega)| &= \left| \frac{1}{1+j \omega / \omega_c} \right| \\ \arg H(j \omega) &= \arg \frac{1}{1+j \omega / \omega_c} \end{aligned}

カットオフ周波数を1000Hzにするために、ωc=1RC=2π×1000\omega_c = \frac{1}{RC} = 2\pi \times 1000 とした時の振幅特性と位相特性は下記のようになる。

コンピュータ実装のためのブロックダイアグラム

この回路をデジタルフィルタとしてプログラムで実装するために、信号の処理過程を示すブロックダイアグラムを得る。 まず、実際の信号がどのように処理されるのかを知るため、微分方程式を実際に解く。 伝達関数を書き換える。

(1+sRC)L[Vy](s)=L[Vx](s)sRCL[Vy](s)=L[Vx](s)L[Vy](s)L[Vy](s)=1s1RC(L[Vx](s)L[Vy](s))\begin{aligned} (1+sRC) \mathcal{L}[V_y](s) &= \mathcal{L}[V_x](s)\\ sRC \mathcal{L}[V_y](s) &= \mathcal{L}[V_x](s) - \mathcal{L}[V_y](s) \\ \mathcal{L}[V_y](s) &= \frac{1}{s} \cdot \frac{1}{RC} \cdot (\mathcal{L}[V_x](s) - \mathcal{L}[V_y](s)) \end{aligned}

逆ラプラス変換を行う。

L[Vy](s)=1s1RC(L[Vx](s)L[Vy](s))=1RC{1sL[Vx](s)1sL[Vy](s)}Vy=1RC{0tVx(τ)dτ0tVy(τ)dτ}=1RC{0tVx(τ)Vy(τ)dτ}\begin{aligned} \mathcal{L}[V_y](s) &= \frac{1}{s} \cdot \frac{1}{RC} \cdot (\mathcal{L}[V_x](s) - \mathcal{L}[V_y](s)) \\ &= \frac{1}{RC} \cdot \left\{\frac{1}{s} \cdot \mathcal{L}[V_x](s) - \frac{1}{s} \cdot \mathcal{L}[V_y](s) \right\} \\ V_y &= \frac{1}{RC} \cdot \left\{ \int_0^{t} V_x(\tau) d\tau - \int_0^{t} V_y(\tau) d\tau \right\} \\ &= \frac{1}{RC} \cdot \left\{ \int_0^{t} V_x(\tau) - V_y(\tau) d\tau \right\} \end{aligned}

VxV_xVyV_yの式を得た。しかし、VxV_xVyV_yは連続的な値である。プログラムで実装するするためには、離散的な信号の処理を知る必要がある。 そこでVxV_xVyV_yを離散的な値として見なす。すると、0tVx(τ)Vy(τ)dτ\int_0^{t} V_x(\tau) - V_y(\tau) d\tauは幅TTの短冊の面積の合計と考えることができ、積分記号を積和記号に置き換えることができる。

Vy(kT)=1RCT{n=0kVx(nT)Vy(nT)}V_y(kT) = \frac{1}{RC} \cdot T \left\{ \sum_{n=0}^{k} V_x(nT) - V_y(nT) \right\}

これのブロックダイアグラムを考えればゴールだが、積和記号をどのようにブロックダイアグラムにすれば良いのかすぐには分からない。

問題を簡単にし、例としてVy(t)=0tVx(τ)dτV_y(t) = \int_0^{t} V_x(\tau) d\tauという連続信号を離散化してそれのダイアグラムを考えてみる。 離散化すると、

Vy(kT)=Tn=0kVx(nT)V_y(kT) = T \sum_{n=0}^{k} V_x(nT)

を得る。分かりやすいようにkkに具体的な値を入れて書き出すと、

Vy(0)=Tn=00Vx(nT)=TVx(0)Vy(T)=Tn=01Vx(nT)=TVx(0)+TVx(T)=Vy(0)+TVx(T)Vy(2T)=Tn=02Vx(nT)=TVx(0)+TVx(T)+TVx(2T)=Vy(T)+TVx(2T)Vy(3T)=Tn=03Vx(nT)=TVx(0)+TVx(T)+TVx(2T)+TVx(3T)=Vy(2T)+TVx(3T)Vy(kT)=Vy((k1)T)+TVx(kT)\begin{aligned} V_y(0) &= T \sum_{n=0}^{0} V_x(nT) = TV_x(0) \\ V_y(T) &= T \sum_{n=0}^{1} V_x(nT) = TV_x(0) + TV_x(T) = V_y(0) + TV_x(T) \\ V_y(2T) &= T \sum_{n=0}^{2} V_x(nT) = TV_x(0) + TV_x(T) + TV_x(2T)= V_y(T) + TV_x(2T) \\ V_y(3T) &= T \sum_{n=0}^{3} V_x(nT) = TV_x(0) + TV_x(T) + TV_x(2T) + TV_x(3T)= V_y(2T) + TV_x(3T) \\ \cdots \\ V_y(kT) &= V_y\left((k-1)T\right) + TV_x(kT) \end{aligned}

これからブロックダイアグラムを書くと、 である。ここでz1z^{-1}とは信号を1サンプル遅らせるという意味である。

これを使えば、先の式のダイアグラムを書くことができる。

Vy(kT)=1RCT{n=0kVx(nT)Vy(nT)}\begin{aligned} V_y(kT) &= \frac{1}{RC} \cdot T \left\{ \sum_{n=0}^{k} V_x(nT) - V_y(nT) \right\} \\ \end{aligned}

これをプログラムで実装すれば、デジタルフィルタを実現できる。 カットオフ周波数が1000Hzになるようにパラメータを設定して実装し、振幅特性と位相特性を図示すると下記のようになる。サンプリング周波数は48000Hzである。青色で示されるAnalog RC LPFがアナログフィルタの特性を示し、橙色のDigital Naive RC LPFが上記ダイアグラムを実装して作ったデジタルフィルタの特性である。ナイキスト周波数に近づくにつれてアナログフィルタの特性と乖離していることが分かる。

双一次変換法

デジタルフィルタをアナログフィルタ電気回路から直接設計する手法はあまり効率的ではない。出来れば、アナログフィルタの伝達関数を良い感じに変形すればデジタルフィルタを得られるようにしたい。その方法が双一次変換法である。

標本化定理の所で扱ったように、連続時間信号の周波数領域は -\infty \sim \infty の範囲に広がるのに対し、離散時間信号の周波数領域は πTπT-\frac{\pi}{T} \sim \frac{\pi}{T} に限られる。双一次変換法は等角写像を利用し、この -\infty \sim \infty の範囲を πTπT-\frac{\pi}{T} \sim \frac{\pi}{T} に圧縮する手法である。

アナログフィルタの伝達関数から周波数特性を得るにはs=jωs=j\omegaを代入すれば良い。このことは、ss平面の虚軸上で伝達関数の値を評価することと同じである。一方、デジタルフィルタの伝達関数から周波数特性を得るにはz=ejωz=e^{j\omega}を代入すればよい。このことは、zz平面の単位円上で伝達関数の値を評価することと同じである。つまり、ss平面上の虚軸をzz平面上の単位円に対応させる変換を見つければ良い。結論を述べると、そのような変換はs=1z11+z1s=\frac{1-z^{-1}}{1+z^{-1}}で実現できる。

双一次変換法は、アナログフィルタの解析の結果得た伝達関数H(s)H(s)s=1z11+z1s=\frac{1-z^{-1}}{1+z^{-1}}を代入することで、デジタルフィルタの伝達関数を得る方法である。双一次変換法はこのように、非常に簡単な処理でデジタルフィルタを得ることができる。しかし、問題がある。 アナログフィルタの周波数特性は s=jΩs = j\Omega の代入により得られ、デジタルフィルタの周波数特性は z=ejωTz = e^{j\omega T} の代入により得られる。双一次変換を通して得たデジタルフィルタの周波数特性は、元のアナログフィルタの伝達関数H(s)H(s)を用いて表すと、H(1ejωT1+ejωT)H\left( \frac{1-e^{-j \omega T}}{1+e^{-j \omega T}} \right)となる。元のアナログフィルタの周波数特性H(jΩ)H(j\Omega)と、双一次変換後の周波数特性H(1ejωT1+ejωT)H\left( \frac{1-e^{-j \omega T}}{1+e^{-j \omega T}} \right)について、アナログ領域のΩ\Omegaとデジタル領域のω\omegaの関係式は、

jΩ=1ejωT1+ejωT=tanh(jωT2)=jtanωT2Ω=tanωT2\begin{aligned} j \Omega &= \frac{1-e^{-j \omega T}}{1+e^{-j \omega T}} = \tanh \left( j\frac{\omega T}{2} \right) = j \tan \frac{\omega T}{2} \\ \Omega &= \tan \frac{\omega T}{2} \end{aligned}

となる。つまり対応関係が非線形であり、周波数尺度が変わってしまう。この対応関係を多少まともにする方法として、双一次変換の際にアナログフィルタの伝達関数H(s)H(s)s=2T1z11+z1s=\frac{2}{T}\frac{1-z^{-1}}{1+z^{-1}}を代入する方法が挙げられる。

これにより、アナログ領域のΩ\Omegaとデジタル領域のω\omegaの関係式は

Ω=2TtanωT2\begin{aligned} \Omega &= \frac{2}{T} \tan \frac{\omega T}{2} \end{aligned}

となる。この関係を、角周波数を周波数に変更して対数軸にプロットした物が下図である。サンプリング周波数は48000Hzとしている。このグラフから、Ω\Omegaω\omegaは低周波数領域では理想的な関係Ω=ω\Omega=\omegaに沿って遷移するが、ナイキスト周波数に近づくにつれて段々ずれていくことが分かる。

実際に双一次変換法を用いて、先に説明したRC低域通過フィルタの伝達関数からデジタルフィルタを得てみよう。 RC低域通過フィルタの伝達関数は次の通り。

H(s)=11+sRCH(s) = \frac{1}{1+sRC}

s=2T1z11+z1s=\frac{2}{T}\frac{1-z^{-1}}{1+z^{-1}}を代入して、

H(z)=11+RC2T1z11+z1=T+Tz1T+Tz1+2RC2RCz1=T+Tz1(T+2RC)+(T2RC)z1=TT+2RC+TT+2RCz11+T2RCT+2RCz1\begin{aligned} H(z) &= \frac{1}{1+RC \frac{2}{T}\frac{1-z^{-1}}{1+z^{-1}}} \\ &= \frac{T + Tz^{-1}}{T + Tz^{-1} + 2RC- 2RCz^{-1}} \\ &= \frac{T + Tz^{-1}}{(T + 2RC) + (T - 2RC)z^{-1}} \\ &= \frac{\frac{T}{T + 2RC} + \frac{T}{T + 2RC}z^{-1}}{1 + \frac{T - 2RC}{T + 2RC}z^{-1}} \\ \end{aligned}

離散時間信号の差分方程式が

y(nT)=k=0Makx(nTkT)k=1Nbky(nTkT)\begin{aligned} y(nT) &= \sum_{k=0}^{M} a_k x(nT-kT) - \sum_{k=1}^{N}b_ky(nT-kT) \\ \end{aligned}

である時、そのZ変換が

Y(z)X(z)=k=0Makzk1+k=1Nbkzk\begin{aligned} \frac{Y(z)}{X(z)} &= \frac{\sum_{k=0}^{M} a_k z^{-k}}{1+\sum_{k=1}^{N} b_k z^{-k}} \end{aligned}

なので、係数a0,a1,b1a_0, a_1, b_1

a0=TT+2RC,a1=TT+2RC,b1=T2RCT+2RC a_0 = \frac{T}{T + 2RC}, \quad a_1 = \frac{T}{T + 2RC}, \quad b_1 = \frac{T - 2RC}{T + 2RC}

である。

RC低域通過フィルタは1次のフィルタなので、改めて差分方程式を書くと、

y(nT)=a0x(nT)+a1x(nTT)b1y(nTT)\begin{aligned} y(nT) &= a_0 x(nT) + a_1 x(nT-T) - b_1 y(nT-T) \end{aligned}

である。

カットオフ周波数が1000Hzになるようにパラメータを設定して実装し、振幅特性と位相特性を図示すると下記のようになる。サンプリング周波数は48000Hzである。青色で示されるAnalog RC LPFがアナログフィルタの特性を示し、橙色のDigital RC LPFが上記を実装して作ったデジタルフィルタの特性である。

概ね形がアナログフィルタに近いもののナイキスト周波数に近づくにつれてずれ始めることが分かる。

更にカットオフ周波数を高くすると、指定した周波数より早く減衰が始まってしまう。そこでΩ=2TtanωT2\Omega = \frac{2}{T} \tan \frac{\omega T}{2}の式を用いて事前に補正を掛ける(この処理をプリワーピングと呼ぶ)方法もある。例えばカットオフ周波数を12000Hzにしたいなら、Ω\Omegaが12000Hzの値になるよう全体をスケールする。下図の緑色のグラフがプリワーピングの結果である。

その他の著名な方法(Orfanidis)

双一次変換法は非常に便利だが、オーディオ信号処理においては割と致命的な欠陥を持つ。そこで非常に多くの研究が行われてきた。ここでは比較的有名な研究を紹介する。

1つ目が1997年のS.J.Orfanidisによる研究である。

S. J. Orfanidis, “Digital parametric equalizer design with prescribed Nyquist-frequency gain,” Journal of the Audio Engineering Society, vol. 45, no. 6, pp. 444-455, Jun. 1997.

ナイキスト周波数に近づくにつれてどんどん減衰して行ってしまうので、その分ゲインして補正してあげようというアイデアである。

Orfanidisの手法は2次のピークフィルタでのみ利用できる。詳しくは後述するが、高次のフィルタも演算誤差を抑える為に2次以下のフィルタの連結で表現することが普通であるため、2次フィルタのみ可という制約はそれほど甚大ではない。ベル型以外のフィルターは別の方法を適用する。

まず、ゲインが DC(f=0[Hz]f=0\,[\mathrm{Hz}]) と無限大(f=[Hz]f=\infty\,[\mathrm{Hz}])でG0G_0である 2 次アナログフィルタの伝達関数は、ピーク中心周波数Ω0\Omega_0と係数A, BA,\ Bを用いて、

H(s)=G0s2+Bs+G0Ω02s2+As+Ω02H(s) = \frac{G_0 s^2 + B s + G_0 \Omega_0^2}{s^2 + A s + \Omega_0^2}

のように表せる。なおA, BA,\ Bは、周波数Ω0\Omega_0でのゲインGG、フィルタの幅ΔΩ\Delta \Omega、その幅を持つ時のゲインGBG_Bを用いて下記である。

A=GB2G02G2GB2ΔΩ,B=GAA = \sqrt{\frac{G_B^2 - G_0^2}{G^2 - G_B^2}} \Delta\Omega, \quad B = G A

ここから、ナイキスト周波数がG1G_1である時、f=[Hz]f=\infty\,[\mathrm{Hz}]の地点のゲインもG1G_1であるような新たなフィルタ

H(s)=G1s2+Bs+G0W2s2+As+W2H(s) = \frac{G_1 s^2 + B s + G_0 W^2}{s^2 + A s + W^2}

の係数を求める。詳細な導出は元論文を辿って欲しい。結論を述べると、

W2=G2G12G2G02Ω02,A=C+DG2GB2,B=G2C+GB2DG2GB2C=(ΔΩ)2GB2G122W2(GB2G0G1(GB2G02)(GB2G12))D=2W2(G2G0G1(G2G02)(G2G12))W^2 = \sqrt{\frac{G^2 - G_1^2}{G^2 - G_0^2}} \Omega_0^2, \quad A = \sqrt{\frac{C + D}{|G^2 - G_B^2|}}, \quad B = \sqrt{\frac{G^2 C + G_B^2 D}{|G^2 - G_B^2|}} \\ C = (\Delta\Omega)^2 |G_B^2 - G_1^2| - 2W^2 \left( |G_B^2 - G_0 G_1| - \sqrt{(G_B^2 - G_0^2)(G_B^2 - G_1^2)} \right) \\ D = 2W^2 \left( |G^2 - G_0 G_1| - \sqrt{(G^2 - G_0^2)(G^2 - G_1^2)} \right)

である。これに双一次変換を適応して、以下を得る。

H(z)=(G1+G0W2+B1+W2+A)2(G1G0W21+W2+A)z1+(G1+G0W2B1+W2+A)z212(1W21+W2+A)z1+(1+W2A1+W2+A)z2H(z) = \frac{\left( \frac{G_1+G_0W^2+B}{1+W^2+A} \right) -2 \left( \frac{G_1-G_0W^2}{1+W^2+A} \right)z^{-1} + \left( \frac{G_1+G_0W^2-B}{1+W^2+A} \right)z^{-2}}{1-2\left( \frac{1-W^2}{1+W^2+A} \right)z^{-1} + \left( \frac{1+W^2-A}{1+W^2+A} \right)z^{-2}}

なお双一次変換はs=1z11+z1s=\frac{1-z^{-1}}{1+z^{-1}}を使っており、デジタル領域の周波数は正規化済みであるから、中心周波数f0[Hz]f_0\, \mathrm{[Hz]}とサンプリング周波数fs[Hz]f_s\, \mathrm{[Hz]}の時、ω0=2πf0fs,Δω=2πΔffs\omega_0 = \frac{2 \pi f_0}{f_s}, \Delta \omega = \frac{2 \pi \Delta f}{f_s}として、

Ω0=tan(ω02),ΔΩ=(1+GB2G02GB2G12G2G12G2G02Ω02)tan(Δω2)\Omega_0 = \tan \left( \frac{\omega_0}{2} \right), \quad \Delta \Omega = \left( 1 + \sqrt{\frac{G_B^2 - G_0^2}{G_B^2 - G_1^2}} \sqrt{\frac{G^2 - G_1^2}{G^2 - G_0^2}} \Omega_0^2 \right) \tan \left( \frac{\Delta \omega}{2} \right)

とする。

実際にこの手法を用いてみよう。アナログ2次ピークフィルタの一例として、次のような伝達関数を持つものを考える。RRは抵抗値だがゲインのような働きをする。

H(s)=Ω02s2s2+2RΩ0s+Ω02H(s) = \frac{\Omega_0^2-s^2}{s^2+2R\Omega_0s+\Omega_0^2}

まずWWを求める為にはGG及びG0, G1G_0,\ G_1を求める必要がある。GGは中心周波数におけるゲインであるから、s=jΩ0s=j\Omega_0を代入して

G=H(jΩ0)=Ω02(jΩ0)2(jΩ0)2+2RΩ0(jΩ0)+Ω02=1R\begin{aligned} G=|H(j\Omega_0)| &=\left| \frac{\Omega_0^2-(j\Omega_0)^2}{(j\Omega_0)^2+2R\Omega_0(j\Omega_0)+\Omega_0^2} \right| \\ &= \frac{1}{R} \end{aligned}

G0G_0はDC成分のゲインである。DC成分のゲインはH(0)|H(0)|なので、

G0=H(0)=1G_0 = |H(0)| = 1

G1G_1はナイキスト周波数におけるゲインである。中心周波数f0[Hz]f_0\, \mathrm{[Hz]}とサンプリング周波数fs[Hz]f_s\, \mathrm{[Hz]}の時、ω0=2πf0fs,Δω=2πΔffs\omega_0 = \frac{2 \pi f_0}{f_s}, \Delta \omega = \frac{2 \pi \Delta f}{f_s}として、

G12=G02(ω02π2)2+G2π2(Δω)2(GB2G02)/(G2GB2)(ω02π2)2+π2(Δω)2(GB2G02)/(G2GB2)G_1^2 = \frac{ G_0^2 (\omega_0^2 - \pi^2)^2 + G^2 \pi^2 (\Delta \omega)^2 \left( G_B^2 - G_0^2 \right) / \left( G^2 - G_B^2 \right) }{ (\omega_0^2 - \pi^2)^2 + \pi^2 (\Delta \omega)^2 \left( G_B^2 - G_0^2 \right) / \left( G^2 - G_B^2 \right) }

続いて、AAを求める為にはGBG_BおよびΔΩ\Delta\Omegaが必要である。どちらかを決めればもう片方は自動で決まるので、今回はGB=G0GG_B=\sqrt{G_0G}とする。

サンプリング周波数を48000Hz、中心周波数を10000Hz、R=0.2R=0.2にした時の振幅特性と位相特性を下図に示す。 青色がアナログフィルタの特性を示し、橙色が双一次変換を行って作ったデジタルフィルタ、緑色が双一次変換とプレワーピングを行って作ったデジタルフィルタ、赤色が上記のOrfanidisの手法を実装して作ったデジタルフィルタの特性である。 振幅特性のグラフを見ると、橙・緑・赤の中で赤色のグラフが最も青色に近いことが分かる。 ただし、位相特性のグラフを見ると赤色のグラフは他と傾向が違うことが分かる。これは、Orfanidisの方法は実質、元々のアナログフィルタにハイシェルフを適応させたものと同じであると見なせるからである。

その他の著名な方法(MZTi)

D. W. Gunness and O. S. Chauhan, “Optimizing the magnitude response of matched z-transform filters (“mzti”) for loudspeaker equalization”, journal of the audio engineering society, no. 2, Sep. 2007.

Orfanidisの手法は、通常の双一次変換と比較して大きな改善を達成している。しかし、いくつか問題がある。まず、位相特性がアナログフィルタと大きく異なっている。そして、ナイキスト周波数付近の振幅特性がアナログフィルタと一致するようにデジタルフィルタを設計したが、通常、ナイキスト周波数付近の音は聴覚できない。また、リサンプリングの際に用いるアンチエイリアシングフィルタはナイキスト周波数付近のゲインをゼロに向かわせるため、そこでの特性を一致させることには意味がない。更に、聴覚可能な周波数帯域において、アナログフィルタとの特性の乖離が生じており、問題である。MZTiは、この課題意識から生まれた手法である。

前々節では、アナログフィルタをデジタルフィルタに変換する方法として双一次変換を紹介した。前節のOrfanidisでも双一次変換を使っている。この変換は、s=2T1z11+z1s=\frac{2}{T}\frac{1-z^{-1}}{1+z^{-1}}を代入することで実現される。つまり、何らかの方法でsszzに変換している。実は、この変換にはさまざまな選択肢が存在する。双一次変換は、周波数特性をなるべく保ったままsszzに変換することを目的とした手法である。これから紹介するMZTiは、双一次変換ではなくMatched Z-transform Method (MZT)を用いてsszzに変換し、その後、多少の補正を加える(improved)ことで改善を図る手法である。

Matched Z-transform Method (MZT)は、アナログシステムの全ての極と零点を保ったままデジタルシステムに変換する方法である。具体的には、伝達関数が

H(s)=aMsM++a1s+a0bNsN++b1s+b0=aMbNi=1M(sξi)i=1N(spi)\begin{aligned} H(s) &= \frac{a_Ms^M+\cdots+a_1s+a_0}{b_Ns^N+\cdots+b_1s+b_0} \\ &= \frac{a_M}{b_N} \frac{\prod_{i=1}^M(s-\xi_i)}{\prod_{i=1}^N(s-p_i)} \end{aligned}

と書かれている時、零点ξi\xi_iと極pip_iを、サンプリング周期をTTとしてz=esTz=e^{sT}という対応関係を使って、

H(z)=gaMbNi=1M(zeξiT)i=1N(zepiT)H(z)=g\frac{a_M}{b_N}\frac{\prod_{i=1}^M(z-e^{\xi_iT})}{\prod_{i=1}^N(z-e^{p_iT})}

とする。このように変形することで、元のアナログシステムが安定であれば、変換後のデジタルシステムも安定となる。なお、ggは任意のスケール値であり、例えばH(s)H(s)H(z)H(z)のDC成分のゲインを一致させるように設定する。

なぜMZTiでは双一次変換ではなくMZTを用いるのか。それは、アナログフィルタとデジタルフィルタの特性の差分を考えたとき、MZTの方が差分の形が単純であり、補正が容易だからである。実際に見てみよう。Orfanidisでも扱ったピークフィルタを使う。中心周波数はωc\omega_cである。

H(s)=ωc2s2s2+2Rωcs+ωc2=(sωc)(s+ωc)(s+RωcωcR21)(s+Rωc+ωcR21)\begin{aligned} H(s) &= \frac{\omega_c^2-s^2}{s^2+2R\omega_cs+\omega_c^2} \\ &= -\frac{(s-\omega_c)(s+\omega_c)}{(s+R\omega_c-\omega_c\sqrt{R^2-1})(s+R\omega_c+\omega_c\sqrt{R^2-1})} \end{aligned}

アナログシステムにおける零点はωc-\omega_cωc\omega_cで、極点はRωc±ωcR21-R\omega_c \plusmn \omega_c\sqrt{R^2-1}z=esTz=e^{sT}という対応関係を使って、zz平面上での零点と極点を考えれば、

H(z)=g(zeωcT)(zeωcT)(ze(RωcωcR21)T)(ze(Rωc+ωcR21)T)=gz2+(eωcT+eωcT)z1z2(e(Rωc+ωcR21)T+e(RωcωcR21)T)z+e2RωcT=g1+(eωcT+eωcT)z1z21(e(Rωc+ωcR21)T+e(RωcωcR21)T)z1+e2RωcTz2\begin{aligned} H(z) &= -g\frac{(z-e^{\omega_cT})(z-e^{-\omega_cT})}{(z-e^{(-R\omega_c-\omega_c\sqrt{R^2-1})T})(z-e^{(-R\omega_c+\omega_c\sqrt{R^2-1})T})}\\ &= g\frac{-z^2+(e^{\omega_cT}+e^{-\omega_cT})z-1}{z^2-(e^{(-R\omega_c+\omega_c\sqrt{R^2-1})T}+e^{(-R\omega_c-\omega_c\sqrt{R^2-1})T})z + e^{-2R\omega_cT}} \\ &= g\frac{-1+(e^{\omega_cT}+e^{-\omega_cT})z^{-1}-z^{-2}}{1 - (e^{(-R\omega_c+\omega_c\sqrt{R^2-1})T}+e^{(-R\omega_c-\omega_c\sqrt{R^2-1})T})z^{-1} + e^{-2 R\omega_c T }z^{-2} } \end{aligned}

ここで、coshx=ex+ex2\cosh x = \frac{e^x+e^{-x}}{2}なので

H(z)=g1+(eωcT+eωcT)z1z21(e(Rωc+ωcR21)T+e(RωcωcR21)T)z1+e2RωcTz2=g1+(2cosh(ωcT))z1z21(2eRωcTcosh(ωcTR21))z1+e2RωcTz2\begin{aligned} H(z) &= g\frac{-1+(e^{\omega_cT}+e^{-\omega_cT})z^{-1}-z^{-2}}{1 - (e^{(-R\omega_c+\omega_c\sqrt{R^2-1})T}+e^{(-R\omega_c-\omega_c\sqrt{R^2-1})T})z^{-1} + e^{-2 R\omega_c T }z^{-2}} \\ &= g\frac{-1+(2 \cosh(ω_cT))z^{-1}-z^{-2}}{1 - (2 e^{-R \omega_c T} \cosh( \omega_c T \sqrt{R^2 - 1}))z^{-1} + e^{-2 R\omega_c T }z^{-2}} \\ \end{aligned}

最後にggを求める。DC成分のゲインを基準にするため、H(s)H(s)s=0s=0を代入してH(0)=1H(0)=1を得て、H(z)H(z)z=1z=1を代入して

H(1)=g1+(2cosh(ωcT))11(2eRωcTcosh(ωcTR21))+e2RωcT=g2+2cosh(ωcT)1(2eRωcTcosh(ωcTR21))+e2RωcT=1\begin{aligned} H(1)&=g\frac{-1+(2 \cosh(ω_cT))-1}{1 - (2 e^{-R \omega_c T} \cosh( \omega_c T \sqrt{R^2 - 1})) + e^{-2 R\omega_c T }}\\ &=g\frac{-2+2 \cosh(ω_cT)}{1 - (2 e^{-R \omega_c T} \cosh( \omega_c T \sqrt{R^2 - 1})) + e^{-2 R\omega_c T }}\\ &=1 \end{aligned}

より、

g=1(2eRωcTcosh(ωcTR21))+e2RωcT2+2cosh(ωcT)g = \frac{1 - (2 e^{-R \omega_c T} \cosh( \omega_c T \sqrt{R^2 - 1})) + e^{-2 R\omega_c T }}{-2+2 \cosh(ω_cT)}

サンプリング周波数を48000Hz、中心周波数を10000Hz、R=0.2R=0.2にした時の振幅特性と位相特性を下図に示す。 青色がアナログフィルタの特性を示し、橙色が双一次変換とプリワーピングを行って作ったデジタルフィルタ、緑色がMZTによるデジタルフィルタである。MZTによるデジタルフィルタは、ナイキスト周波数付近で大きなずれはあるが、それ以外は双一次変換のものに比べて悪くなさそうである。

続いて、アナログフィルタの特性とデジタルフィルタの特性の差分をとって比較する。上段のグラフでは、双一次変換とプリワーピングで得たデジタルフィルタとアナログフィルタの振幅特性の差分を緑色のグラフで示している。下段のグラフでは、MZTで得たデジタルフィルタフィルタとアナログフィルタの差分を緑色のグラフで示している。デジタルフィルタに変換した後、何等かのフィルタを使って形状を補正する際、MZTの結果を補正したほうが簡単そうだと分かる。

補正フィルタの導出方法を示す。補正フィルタとしてFIRフィルタを用いる。元のアナログフィルタが2次である時、補正の対象となるMZTによるデジタルフィルタの周波数特性は

HD(ω)=g1+a1ejωT+a2e2jωT1+b1ejωT+b2e2jωTH_D(\omega) = g\frac{1+a_1e^{-j \omega T}+a_2e^{-2j \omega T}}{1+b_1e^{-j \omega T}+b_2e^{-2j \omega T}}

である。一般に、FIRフィルタの伝達関数は

HFIR(z)=k=0MαkzkH_{\mathit{FIR}}(z)=\sum_{k=0}^{M} \alpha_k z^{-k}

と表せるので、タップ数を決めて、いくつかの周波数でアナログフィルタの特性とMZT後のデジタルフィルタの特性が同じになるよう連立方程式をたてて、FIRフィルタの係数を求めれば良い。論文では、式を簡単にするため、ナイキスト周波数を等分するポイントで連立方程式を立式する方法を紹介している。

例えば、FIRフィルタの伝達関数がHFIR(z)=α0+α1z1+α2z2H_{\mathit{FIR}}(z)=\alpha_0+\alpha_1z^{-1}+\alpha_2z^{-2}の時、ナイキスト周波数を3分割した地点のデジタルフィルタの振幅特性は

HD(fN/3)=g1+a1a2+a12+a1a2+a221+b1b2+b12+b1b2+b22HD(2fN/3)=g1a1a2+a12a1a2+a221b1b2+b12b1b2+b22\begin{aligned} |H_D(f_N / 3)| &= g \frac{\sqrt{1 + a_1 - a_2 + a_1^2 + a_1 a_2 + a_2^2}}{\sqrt{1 + b_1 - b_2 + b_1^2 + b_1 b_2 + b_2^2}} \\ |H_D(2f_N / 3)| &= g \frac{\sqrt{1 - a_1 - a_2 + a_1^2 - a_1 a_2 + a_2^2}}{\sqrt{1 - b_1 - b_2 + b_1^2 - b_1 b_2 + b_2^2}} \end{aligned}

であり、同地点の補正FIRフィルタの周波数特性をH1H_1H2H_2とし、DC成分の周波数特性をH0H_0とすれば、

α0=H0α1α2α1=H0H022H12+2H222α2=3(H0α1)3H02+12H126H0α13α126\begin{aligned} \alpha_0 &= H_0 - \alpha_1 - \alpha_2\\ \alpha_1 &= \frac{H_0 - \sqrt{H_0^2 - 2H_1^2 + 2H_2^2}}{2}\\ \alpha_2 &= \frac{3(H_0 - \alpha_1) - \sqrt{-3H_0^2 + 12H_1^2 - 6H_0 \alpha_1 - 3\alpha_1^2}}{6} \end{aligned}

この補正FIRフィルタを、MZT後のデジタルフィルタの後に掛けることで、DC成分・ナイキスト周波数の3分の1の地点・ナイキスト周波数の3分の2の地点の振幅特性がアナログフィルタの特性と一致するフィルタを得ることができる。

サンプリング周波数を48000Hz、中心周波数を10000Hz、R=0.2R=0.2にした時の振幅特性と位相特性を下図に示す。 青色がアナログフィルタの特性を示し、橙色がMZTを行って作ったデジタルフィルタ、緑色がMZTで作ったフィルタにFIRで補正を行って作ったMZTiデジタルフィルタである。DC、ナイキスト周波数の3分の1の地点、3分の2の地点のゲインがアナログフィルタと一致するような補正フィルタを構成している為、ナイキスト周波数におけるゲインはアナログフィルタの値と異なるが、それ以外は一致していることが分かる。

その他の著名な方法(Balance Mastering Magpha EQ / DDMF GrandEQ / Kush Audio q.632)

J. Flynn and J. D. Reiss, “Improving the frequency response magnitude and phase of analogue-matched digital filters,” Journal of the Audio Engineering Society, May 2018.

MZTiはかなり優秀な手法である。MZTiで得たデジタルフィルタの特性はアナログフィルタにかなり近い。が、完璧に一致してはいない。 MZTiを改善しようと試みる時、補正FIRフィルタの算出方法を改善すれば良いのでは?と思うのはとても自然である。MZTiの補正フィルタは、ナイキスト周波数未満を等分した数点の振幅特性がアナログフィルタの振幅特性に一致するよう、連立方程式をたててFIRフィルタの係数を求めている。そうではなく、MZT後のデジタルフィルタの特性とアナログフィルタの特性の差を逆フーリエ変換してFIRフィルタの係数を求めた方が、よりアナログフィルタの特性を近似できるだろうというのは直感的に理解できる。

この改善案を採用したのが、これから紹介する手法である。

これはただの感想ですが…。 既に述べたように、MZTiを知っていれば、この改善案は割と誰でも思いつくレベルだと思います。 そしてMZTiはそれほどマイナーな手法ではありません(Wikipediaにも載ってるレベル)。 なので、Magpha EQ/GrandEQ/q.632以外で、これと似たような方法を実装したEQは数多く存在すると思います。

MZTiの項で述べたように、元のアナログフィルタの伝達関数が

HA(s)=aMsM++a1s+a0bNsN++b1s+b0=aMbNi=1M(sξi)i=1N(spi)\begin{aligned} H_A(s) &= \frac{a_Ms^M+\cdots+a_1s+a_0}{b_Ns^N+\cdots+b_1s+b_0} \\ &= \frac{a_M}{b_N} \frac{\prod_{i=1}^M(s-\xi_i)}{\prod_{i=1}^N(s-p_i)} \end{aligned}

と書かれている時、全ての零点ξi\xi_iと極pip_iを、サンプリング周期をTTとしてz=esTz=e^{sT}という対応関係を使ってMZTしたデジタルフィルタの伝達関数は

HMZT(z)=gaMbNi=1M(zeξiT)i=1N(zepiT)H_{\mathit{MZT}}(z)=g\frac{a_M}{b_N}\frac{\prod_{i=1}^M(z-e^{\xi_iT})}{\prod_{i=1}^N(z-e^{p_iT})}

である。

アナログフィルタの周波数特性はs=jωs=j\omegaを代入して、

HA(jω)=aMbNi=1M(jωξi)i=1N(jωpi)\begin{aligned} H_A(j\omega) = \frac{a_M}{b_N} \frac{\prod_{i=1}^M(j\omega-\xi_i)}{\prod_{i=1}^N(j\omega-p_i)} \end{aligned}

デジタルフィルタの周波数特性はz=ejωz=e^{j\omega}を代入して、

HMZT(ejω)=gaMbNi=1M(ejωeξiT)i=1N(ejωepiT)H_{\mathit{MZT}}(e^{j\omega})=g\frac{a_M}{b_N}\frac{\prod_{i=1}^M(e^{j\omega}-e^{\xi_iT})}{\prod_{i=1}^N(e^{j\omega}-e^{p_iT})}

これら周波数特性の差は、応答の比で表すと

Hdiff(ω)=HA(jω)HMZT(ejω)H_{\mathrm{diff}}(\omega) = \frac{H_A(j\omega)}{H_{\mathit{MZT}}(e^{j\omega})}

この応答の比からサンプル点をNN個取り出して離散的な応答の比とする。デジタル信号のサンプリング周期をTTとすればナイキスト周波数はπT\frac{\pi}{T}であり、サンプル点の個数NNを奇数として、取り出すサンプル点の周波数列ωn\omega_n

ωn=πTN/2×n=2πnNT,n=N12,,2,1,0,1,2,,N12\omega_n = \frac{\frac{\pi}{T}}{N/2}\times n=\frac{2 \pi n}{NT}, \quad n=-\frac{N-1}{2}, \cdots,-2,-1,0,1,2,\cdots,\frac{N-1}{2}

これを代入したHdiff(ωn)H_{\mathrm{diff}}(\omega_n)に逆離散フーリエ変換を行って補正FIRフィルタHdiff(z)H_{\mathrm{diff}}(z)を得る。

最終的に、

HD(z)=HMZT(z)Hdiff(z)H_D(z)=H_{\mathit{MZT}}(z) \cdot H_{\mathrm{diff}}(z)

で、所望のデジタルフィルタを得る。

実際に作って見よう。MZTiでも扱ったピークフィルタを題材とする。

HA(s)=ωc2s2s2+2Rωcs+ωc2=(sωc)(s+ωc)(s+RωcωcR21)(s+Rωc+ωcR21)\begin{aligned} H_A(s) &= \frac{\omega_c^2-s^2}{s^2+2R\omega_cs+\omega_c^2} \\ &= -\frac{(s-\omega_c)(s+\omega_c)}{(s+R\omega_c-\omega_c\sqrt{R^2-1})(s+R\omega_c+\omega_c\sqrt{R^2-1})} \end{aligned}

MZTして、

HMZT(z)=g(zeωcT)(zeωcT)(ze(RωcωcR21)T)(ze(Rωc+ωcR21)T)=g1+(eωcT+eωcT)z1z21(e(Rωc+ωcR21)T+e(RωcωcR21)T)z1+e2RωcTz2\begin{aligned} H_{\mathit{MZT}}(z) &= -g\frac{(z-e^{\omega_cT})(z-e^{-\omega_cT})}{(z-e^{(-R\omega_c-\omega_c\sqrt{R^2-1})T})(z-e^{(-R\omega_c+\omega_c\sqrt{R^2-1})T})}\\ &= g\frac{-1+(e^{\omega_cT}+e^{-\omega_cT})z^{-1}-z^{-2}}{1 - (e^{(-R\omega_c+\omega_c\sqrt{R^2-1})T}+e^{(-R\omega_c-\omega_c\sqrt{R^2-1})T})z^{-1} + e^{-2 R\omega_c T }z^{-2}} \end{aligned}

そしてgg

g=1(2eRωcTcosh(ωcTR21))+e2RωcT2+2cosh(ωcT)g = \frac{1 - (2 e^{-R \omega_c T} \cosh( \omega_c T \sqrt{R^2 - 1})) + e^{-2 R\omega_c T }}{-2+2 \cosh(ω_cT)}

HA(s)H_A(s)HMZT(z)H_{\mathit{MZT}}(z)の周波数特性の比を考える。

Hdiff(ω)=HA(jω)HMZT(ejω)H_{\mathrm{diff}}(\omega) = \frac{H_A(j\omega)}{H_{\mathit{MZT}}(e^{j\omega})}

サンプリング周波数を48000Hz、中心周波数を10000Hz、R=0.2R=0.2にした時ののHA(s)H_A(s)HMZT(z)H_{\mathit{MZT}(z)}およびHdiff(ω)H_{\mathrm{diff}}(\omega)の振幅特性と位相特性は下図のようになる。橙色の特性を青色の特性に近づけるような特性、つまり緑色のグラフのようなものがHdiff(ω)H_{\mathrm{diff}}(\omega)になる。なお、MZTiでは振幅特性のみ補正したが、この方法では位相特性も補正できる。

(※MZTiで紹介したグラフと緑色のグラフの形が違うが、MZTiの項ではDigital - Analogを描画し、ここではAnalog - Digitalを描画しているからである。)

ここから先はグラフを用いながら説明する。

周波数サンプル点の個数をN=63N=63として、Hdiff(ω)H_{\mathrm{diff}}(\omega)をサンプリングする。先のグラフにサンプル点を描画すると次のようになる。横軸が対数なので等間隔には見えない。また、周波数サンプル点は負の周波数も含めて合計NN個であり、下記のグラフは10Hz~24000Hzを描画しているので、サンプル点は31個しか書かれていない。

このサンプル点を逆離散フーリエ変換することで、補正FIRフィルタHdiff(z)H_{\mathrm{diff}}(z)を得る。補正FIRフィルタの特性は次のようなものである。

最後にHD(z)=HMZT(z)Hdiff(z)H_D(z)=H_{\mathit{MZT}}(z) \cdot H_{\mathrm{diff}}(z)により、目的のデジタルフィルタを得る。青色がアナログフィルタの特性を示し、橙色が今回得たデジタルフィルタの特性を示す。アナログフィルタの特性を非常に良く近似出来ていることが分かる。

ちょっと乱暴な方法(双一次変換+オーバーサンプリング)

これまで色々試行錯誤を重ね、アナログフィルタの特性をデジタルフィルタに落とし込んできた。どの手法も、ナイキスト周波数付近で生じる特性の歪みを抑えようと工夫を凝らしてきた。しかし、オーバーサンプリングを行い、ナイキスト周波数を可聴域の外に移せば、特性の歪みも可聴域外に押し出される。そうすれば、アナログフィルタの特性により近いデジタルフィルタを、もっと簡単に実現できるのではないだろうか。

これは、正しい。双一次変換による特性の歪は、アナログフィルタの周波数をΩ\Omega、デジタルフィルタの周波数をω\omegaとして

Ω=2TtanωT2\begin{aligned} \Omega &= \frac{2}{T} \tan \frac{\omega T}{2} \end{aligned}

と書けるのは前に扱った。このグラフを、異なるサンプリング周波数で描画してみよう。横軸と縦軸は10Hzから24000Hzの範囲を描画している。

このグラフから、双一次変換しただけの教科書的な実装のEQでも、サンプリング周波数が192kHzや384kHzであればほぼ理想的な関係Ω=ω\Omega=\omegaが可聴域で得られることが分かる。2倍オーバーサンプリングして96kHzであったとしても、48kHzよりはマシである。

直前に扱ったMagpha EQの手法でも、サンプリング周波数を上げれば補正フィルタが掛かり始める帯域が上方向にずれていく。その結果、ほんのごく僅かながらもフィルタの形状が変わったり、数値演算上の誤差が変わって、音が理論上変わることはあり得る(知覚できるかどうかは置いておいて…)。

普通、「サンプリング周波数を変えたりオーバーサンプリングしたら音が変わった」系の話は、コンプレッサやサチュレータなど非線形歪みを発生させる処理や、エイリアシングフィルタのスペックが違うからという説明で語られることが多い。しかし、ここで話したように、非線形歪みを発生させないEQでも、音が変わることは全然ありえるという事実は頭の片隅に置いておくべきである。

Chapter 3. IIRデジタルフィルタの実装

Chapter 2.では、主にアナログフィルタの伝達関数H(s)H(s)からデジタルフィルタの伝達関数H(z)H(z)を得る方法について述べた。伝達関数H(z)H(z)

H(z)=Y(z)X(z)=k=0Makzk1+k=1NbkzkH(z)=\frac{Y(z)}{X(z)} = \frac{\sum_{k=0}^{M} a_k z^{-k}}{1+\sum_{k=1}^{N} b_k z^{-k}}

のように、有理関数で表すことができる。このように表せたら、差分方程式

y(nT)=a0x(nT)+a1x(nTT)++aMx(nTMT)(b0y(nT)+b1y(nTT)++bMy(nTNT))=k=0Makx(nTkT)k=1Nbky(nTkT)\begin{aligned} y(nT) &= a_0x(nT) + a_1x(nT-T) + \cdots + a_Mx(nT-MT) \\ & \qquad -(b_0y(nT) + b_1y(nT-T) + \cdots + b_My(nT-NT)) \\ &= \sum_{k=0}^{M} a_k x(nT-kT) - \sum_{k=1}^{N}b_ky(nT-kT) \\ \end{aligned}

を計算すれば、入力信号から出力信号を得ることができる。

つまり、これをプログラムで実装すればIIRデジタルフィルタの実装が完了するのだが、実はそう上手くは行かない。何故なら、コンピュータの世界では数値は有限桁数であり、計算には少なからず誤差が生じるからである。極端な場合その誤差が積み重なって、理論上安定なフィルタが不安定になることもあり得る。この章では、浮動小数点演算の誤差について説明した後、計算をブロックダイアグラムで図示するブロック法をまとめ、様々なデジタルフィルタの計算方法をブロックダイアグラムで示し、誤差を抑えたデジタルフィルタの計算方法を実験により調べる。

コンピュータの世界の数値表現(浮動小数点数)と演算誤差

コンピュータは2進数(0と1)で数値を表現する。例えば、10進数における1010は、2進数では1010と表現される。コンピュータでは桁数を固定してメモリに値を格納することが多い。この桁数のことをbit幅と呼ぶ。例えば、44.1kHz/16bitで記録されたCD音質のWAVファイルは、1サンプルの振幅を16bitのbit幅、つまり16桁の0と1で表現している。10進数で1010という振幅値を記録する場合、2進数では0000 0000 0000 1010となる(注1)。

次に小数の表現方法について紹介する。小数の表現には固定小数点と浮動小数点の2種類がある。

固定小数点は、小数点の位置を予め決めておく方法である。例えば、2進数で下位5bitは小数点以下の数字を表す…といった感じである。現代のパソコンでは浮動小数点で小数を扱うことが多い。 浮動小数点は、数を符号部・固定長の指数部・固定長の仮数部で表す方法である。10進数で例えるなら、123.456-123.4561×1.23456×102-1\times1.23456\times10^{2}と書くような感じである。

標準規格IEEE 754に則れば、32bit浮動小数点は符号部1bit・指数部8bit・仮数部23bitである。仮数部は、整数部分が1であるような2進小数の小数部分を示す。つまり、2進数で1010と表せる値を32bit浮動小数点で表現するなら、仮数部は先頭の1を除いて010となる。実質的に仮数部は24bitなので、32bit浮動小数点の10進数における有効桁数は24×log102724\times\log_{10}2 \approx 7桁である。

64bit浮動小数点は符号部1bit・指数部11bit・仮数部52bitである。10進数における有効桁数は53×log1021653\times\log_{10}2 \approx 16桁である。

これから、浮動小数点演算で生じる代表的な演算誤差について、いくつか紹介する。

丸め誤差

浮動小数点数は有限桁の仮数部を持つため、無限に続く循環小数を正確に表現することはできない。例えば、10進数における0.10.1は2進数では0.000110011001100110011000.00011001100110011001100\cdotsという循環小数になるため、コンピュータでは有限のところで打ち切った値を持つことになる。

実際、0.1を32bit浮動小数点(float型)、64bit浮動小数点(double型)で定義して10進数で表示させると、

std::cout << std::setprecision(200) << 0.1f << std::endl;
// -> 0.100000001490116119384765625
std::cout << std::setprecision(200) << 0.1 << std::endl;
// -> 0.1000000000000000055511151231257827021181583404541015625

となり、どちらも0.1ではないことが分かる。これが及ぼす悪影響を見てみよう。

今、float型の0.1を1000回加算するプログラムを書いた。結果は100になるはずだが、実際はそうなっていない。

int main() {
  float x = 0.0;
  for (int i = 0; i < 1000; i++) {
    x += 0.1f;
  }
  std::cout << std::setprecision(200) << x << std::endl;
  // -> 99.99904632568359375

  return 0;
}

double型でも100にならない。

int main() {
  double x = 0.0;
  for (int i = 0; i < 1000; i++) {
    x += 0.1;
  }
  std::cout << std::setprecision(200) << x << std::endl;
  // -> 99.9999999999985931253831950016319751739501953125

  return 0;
}

情報落ち

a+ba+bの演算を行う時、aabbの桁数の差が仮数部の桁数より大きい時に、小さな数の情報が失われてしまう。例えば、10進数で12345600+1=1234560112345600+1=12345601という計算を有効桁数6桁で行うと、1.23456×107+1.00000=1.2345601×1071.23456×1071.23456\times10^{7}+1.00000=1.2345601\times10^{7}\approx1.23456\times10^{7}となり、加算が消えてしまう。

下記のプログラムでは100000000に1を1000回加算しているが、結果は100000000のままである。

int main() {
  float x = 100000000.0;
  for (int i = 0; i < 1000; i++) {
    x += 1.0;
  }
  std::cout << std::setprecision(200) << x << std::endl;
  // -> 100000000

  return 0;
}

桁落ち

aba-bの演算を行う時、aabbの値が極めて近い場合、有効桁数が減少してしまう。

下記のプログラムでは、1.0000011.0=0.000001=1×1061.000001-1.0=0.000001=1\times10^{-6}が本来あってほしい答えだが、そうなってない。

int main() {
  float a = 1.000001;
  float b = 1.0;
  float x = a - b;
  std::cout << std::setprecision(200) << x << std::endl;
  // -> 9.5367431640625e-07

  return 0;
}

注1

簡単の為に説明を省略したが、WAVファイルにおけるint16(符号付き整数型)の内部表現はもう少し複雑である。10を表現するなら本当に0000 0000 0000 1010だが、-10を表現する場合は2の補数表現を用いて216102^{16}-10を2進数で表現し、1111 1111 1111 0110である。ちなみに、プログラムにおけるint16およびint型の内部表現は処理系依存で、負値の表し方は2の補数表現・1の補数表現・符号bitと絶対値、のいずれかである。

ブロック法

この次にデジタルフィルタの計算方法をいくつか紹介したいが、式で表すと直感的でないことがある。そこで、計算の流れをブロックダイアグラムで示す「ブロック法」をまず紹介する。

デジタルフィルタの実現に必要な演算は加算・乗算・1サンプル遅延の3つであり、それぞれブロックで表すと次のようになる。

そして、これらブロックからなる1塊の回路を単位ブロックとみなして、それらの組み合わせを考える。単位ブロックの伝達関数をFFGGとする。

縦続接続

伝達関数を考えれば、

X1Xin=F,XoutX1=G\frac{X_1}{X_{\mathrm{in}}} = F, \quad \frac{X_{\mathrm{out}}}{X_1} = G

なので、

XoutXin=FG\frac{X_{\mathrm{out}}}{X_{\mathrm{in}}}=FG

並列接続

Xout=X1+X2=FXin+GXinX_{\mathrm{out}}=X_1+X_2=FX_{\mathrm{in}}+GX_{\mathrm{in}}なので

XoutXin=F+G\frac{X_{\mathrm{out}}}{X_{\mathrm{in}}}=F+G

帰還接続

関係式を立てると、

X1=XinX2,Xout=X1F,X2=GXoutX_1=X_{\mathrm{in}}-X_2, \quad X_{\mathrm{out}}=X_1F, \quad X_2=GX_{\mathrm{out}}

ここからX1X_1X2X_2を消去して

Xout=F(XinGXout)X_{\mathrm{out}}=F(X_{\mathrm{in}}-GX_{\mathrm{out}})

これを整理すれば

XoutXin=F1+FG\frac{X_{\mathrm{out}}}{X_{\mathrm{in}}}=\frac{F}{1+FG}

デジタルフィルタの計算方法はブロックダイアグラムで表すことができることから、デジタルフィルタの回路と言ったり、デジタルフィルタのトポロジと言ったりする。

直接形I (Direct Form I)

前提知識の章で、離散時間システムの入出力関係の式は差分方程式を用いて

y(nT)=a0x(nT)+a1x(nTT)++aMx(nTMT)(b0y(nT)+b1y(nTT)++bMy(nTNT))=k=0Makx(nTkT)k=1Nbky(nTkT)\begin{aligned} y(nT) &= a_0x(nT) + a_1x(nT-T) + \cdots + a_Mx(nT-MT) \\ & \qquad -(b_0y(nT) + b_1y(nT-T) + \cdots + b_My(nT-NT)) \\ &= \sum_{k=0}^{M} a_k x(nT-kT) - \sum_{k=1}^{N}b_ky(nT-kT) \\ \end{aligned}

で表現でき、これの両辺をZ変換して変形を行い、

Y(z)=k=0MakzkX(Z)k=1NbkzkY(z)Y(z)X(z)=k=0Makzk1+k=1Nbkzk\begin{aligned} Y(z) &= \sum_{k=0}^{M} a_k z^{-k} X(Z) - \sum_{k=1}^{N} b_k z^{-k}Y(z) \\ \frac{Y(z)}{X(z)} &= \frac{\sum_{k=0}^{M} a_k z^{-k}}{1+\sum_{k=1}^{N} b_k z^{-k}} \end{aligned}

とした物が離散時間システムの伝達関数H(z)H(z)であった。つまり、アナログフィルタの伝達関数からデジタルフィルタの伝達関数H(z)H(z)を得たら、それの分母と分子の係数を使って差分方程式を実装すれば、デジタルフィルタの実装が完了する。この差分方程式をそのまま計算する方法を直接形Iと呼ぶ。 ブロックダイアグラムは下記のようになる。

直接形II (Direct Form II)

直接系Iの形を書き換える。加算の部分を境に2つに分割すれば、ブロックFFGGの縦列接続だと分かるので入れ替えることが可能。最後にサンプル遅延ブロックを統合する。

縦続形構成(Biquad Direct Form I)

伝達関数は有理関数で表されるので、これを1次や2次の縦続接続と見なせるように変形を行う。

Y(z)X(z)=k=0Makzk1+k=1Nbkzk=g1+γ0z11+α0z1i=1n1+γiz1+δiz21+aiz1+βiz2\begin{aligned} \frac{Y(z)}{X(z)} &= \frac{\sum_{k=0}^{M} a_k z^{-k}}{1+\sum_{k=1}^{N} b_k z^{-k}} \\ &= g \frac{1+\gamma_0z^{-1}}{1+\alpha_0z^{-1}}\prod_{i=1}^n\frac{1+\gamma_iz^{-1}+\delta_iz^{-2}}{1+a_iz^{-1}+\beta_iz^{-2}} \end{aligned}

この変形により、2次以上の高次フィルタを1次や2次フィルタのカスケード接続に変換している。 これを直接形Iで書く。

縦続形構成(Biquad Direct Form II)

直前に説明した構成を直接形IIで書く。

縦続形構成(Biquad Transposed Direct Form I)

回路中の信号の向きを逆にし、加算器を信号の分岐で置き換えた回路を転置回路という。実は転置回路は元の回路と伝達関数が一致する。

プログラムに実装するとBiquad Direct Form IIと同じ実装になる。

縦続形構成(Biquad Transposed Direct Form II)

同様に、Biquad Direct Form IIを転置する。

実験

実験を行い、どのフィルタ構成が最も良いか確認する。題材となるフィルタは4次のピークフィルタとする。中心周波数をωc\omega_cとする。

H(s)=(ωc2s2s2+2Rωcs+ωc2)2=s42ωc2s2+ωc4s4+4Rωcs3+(2ωc2+4R2ωc2)s2+4Rωc3s+ωc4\begin{aligned} H(s) &= \left( \frac{\omega_c^2-s^2}{s^2+2R\omega_cs+\omega_c^2} \right)^2 \\ &= \frac{s^4-2\omega_c^2s^2+\omega_c^4}{s^4 + 4 R \omega_c s^3 + (2 \omega_c^2 + 4 R^2 \omega_c^2) s^2+ 4 R \omega_c^3 s + \omega_c^4} \end{aligned}

実験条件を単純にするために、双一次変換によりデジタルフィルタを得る。実験の際、カットオフ周波数はナイキスト周波数より十分低いものとする。

H(z)=(ωc2T244+4RωcT+ωc2T2+2ωc2T2+84+4RωcT+ωc2T2z1+ωc2T244+4RωcT+ωc2T2z21+8+2ωc2T24+4RωcT+ωc2T2z1+44RωcT+ωc2T24+4RωcT+ωc2T2z2)2=a0+a1z1+a2z21+b1z1+b2z2a0+a1z1+a2z21+b1z1+b2z2\begin{aligned} H(z) &= \left( \frac{\frac{\omega_c^2T^2-4}{4+4R\omega_cT+\omega_c^2T^2} + \frac{2\omega_c^2T^2+8}{4+4R\omega_cT+\omega_c^2T^2}z^{-1}+\frac{\omega_c^2T^2-4}{4+4R\omega_cT+\omega_c^2T^2}z^{-2}}{1+\frac{-8+2\omega_c^2T^2}{4+4R\omega_cT+\omega_c^2T^2}z^{-1}+\frac{4-4R\omega_cT+\omega_c^2T^2}{4+4R\omega_cT+\omega_c^2T^2}z^{-2}} \right)^2 \\ &= \frac{a_0+a_1z^{-1}+a_2z^{-2}}{1+b_1z^{-1}+b_2z^{-2}}\cdot \frac{a_0+a_1z^{-1}+a_2z^{-2}}{1+b_1z^{-1}+b_2z^{-2}} \end{aligned}

直接形IとIIは次式のパラメータA0,A1,A2,A3,A4,B1,B2,B3,B4A_0, A_1, A_2, A_3, A_4, B_1, B_2, B_3, B_4を使う。

H(z)=a0+a1z1+a2z21+b1z1+b2z2a0+a1z1+a2z21+b1z1+b2z2=a02+2a0a1z1+(2a0a2+a12)z2+2a1a2z3+a22z41+2b1z1+(2b2+b12)z2+2b1b2z3+b22z4=A0+A1z1+A2z2+A3z3+A4z41+B1z1+B2z2+B3z3+B4z4\begin{aligned} H(z) &= \frac{a_0+a_1z^{-1}+a_2z^{-2}}{1+b_1z^{-1}+b_2z^{-2}}\cdot \frac{a_0+a_1z^{-1}+a_2z^{-2}}{1+b_1z^{-1}+b_2z^{-2}} \\ &= \frac{{a_0^2 + 2 a_0 a_1z^{-1} + (2 a_0 a_2 + a_1^2)z^{-2} + 2 a_1 a_2z^{-3} + a_2^2z^{-4}}}{{1 + 2 b_1z^{-1} + (2 b_2 + b_1^2)z^{-2} + 2 b_1 b_2z^{-3} + b_2^2z^{-4} }} \\ &= \frac{A_0+A_1z^{-1}+A_2z^{-2}+A_3z^{-3}+A_4z^{-4}}{1+B_1z^{-1}+B_2z^{-2}+B_3z^{-3}+B_4z^{-4}} \end{aligned}

Biquad DFI・IIとBiquad Transposed DFI・IIは次式のパラメータg,α0,β0,γ0,δ0,α1,β1,γ1,δ1g, \alpha_0, \beta_0, \gamma_0, \delta_0, \alpha_1, \beta_1, \gamma_1, \delta_1を使う。

H(z)=a0+a1z1+a2z21+b1z1+b2z2a0+a1z1+a2z21+b1z1+b2z2=a021+a1a0z1+a2a0z21+b1z1+b2z21+a1a0z1+a2a0z21+b1z1+b2z2=g1+γ0z1+δ0z21+α0z1+β0z21+γ1z1+δ1z21+α1z1+β1z2\begin{aligned} H(z) &= \frac{a_0+a_1z^{-1}+a_2z^{-2}}{1+b_1z^{-1}+b_2z^{-2}}\cdot \frac{a_0+a_1z^{-1}+a_2z^{-2}}{1+b_1z^{-1}+b_2z^{-2}} \\ &= a_0^2 \frac{1+\frac{a_1}{a_0}z^{-1}+\frac{a_2}{a_0}z^{-2}}{1+b_1z^{-1}+b_2z^{-2}}\cdot \frac{1+\frac{a_1}{a_0}z^{-1}+\frac{a_2}{a_0}z^{-2}}{1+b_1z^{-1}+b_2z^{-2}} \\ &=g\frac{1+\gamma_0z^{-1}+\delta_0z^{-2}}{1+\alpha_0z^{-1}+\beta_0z^{-2}} \cdot \frac{1+\gamma_1z^{-1}+\delta_1z^{-2}}{1+\alpha_1z^{-1}+\beta_1z^{-2}} \end{aligned}

サンプリング周波数を48000Hzとし、中心周波数を20Hzと200Hz、RRを0.01と0.1に変化させ、各フィルタ構成のアナログフィルタに対する精度を確認する。演算は全て64bit浮動小数点で行っている。

結果を下記に示す。上から3段目まで、左側のグラフが振幅特性、右側のグラフが位相特性を表す。各1段目のグラフが特性をそのまま示し、2段目のグラフは特性の差(Analog - Digital)、3段目のグラフは特性の差を対数表示したものである。4段目左右のグラフは1000Hz振幅0.0dBFSのサイン波を各実装に処理させ、結果の振幅特性を示した物である。2段目のグラフでは、プロットが0に近い程アナログフィルタと特性が近く、3段目のグラフでは、プロットが-\inftyに近い程アナログフィルタと特性が近い。4段目のグラフはプロットが-\inftyに近いほど低歪で高精度である。 なお、今まで示してきたグラフとは違い、横軸が1Hz~24000Hzの範囲を描画している点に注意せよ。

全体の傾向を見ると、

  • 実装方法に関わらず、
    • 中心周波数が高い方がアナログフィルタの特性を高精度に再現出来る
    • RRが小さい(=ゲインが低く、Qが緩い)方がアナログフィルタの特性を高精度に再現出来る
  • 実装方法の優劣を判断すると
    • 直接形(DFI・DFII)に比べて縦続形(Biquad○○)の方がアナログフィルタの特性再現度が高い
    • 直接形(DFI・DFII)に比べて縦続形(Biquad○○)の方がTHD性能が良い
    • 縦続形(Biquad○○)の中でも、Biquad DFIとBiquad Transposed DF2のTHD性能が良い

と分かる。 グラフ中にBiquad Direct Form IIが見えないが、Biquad Transposed Direct Form Iと完全に重なっている(同じ実装なため)。




サンプリング周波数を48000Hzとし、中心周波数fc=20 [Hz]f_c=20\ [\mathrm{Hz}]R=0.01R=0.01とした時と、fc=200 [Hz]f_c=200\ [\mathrm{Hz}]R=0.1R=0.1にした時の各パラメータを、64bit浮動小数点と1000bit浮動小数点で計算した時の値の違いは次のようになる。 1000bit浮動小数点で計算した結果の方が真値に近いことを考えると、fcf_cRRの値に依らず、64bit浮動小数点でパラメータ計算を行った時の有効桁数は14~16桁であることがわかる。 64bit浮動小数点の理論的な有効桁数は16桁であるため、パラメータ計算において演算誤差はあまり生じてないと言える。

## f_c=20, R=0.01 ##
  64bit float: T=0.000020833333333333333
1000bit float: T=0.000020833333333333333333...

  64bit float: omega_c=125.66370614359172
1000bit float: omega_c=125.66370614359172953...

  64bit float: b_0=4.000111573647065
1000bit float: b_0=4.0001115736470648607...

  64bit float: a_0=-0.9999703939410614
1000bit float: a_0=-0.99997039394106147733...

  64bit float: a_1=1.999947641582895
1000bit float: a_1=1.9999476415828950578...

  64bit float: a_2=-0.9999703939410614
1000bit float: a_2=-0.99997039394106147733...

  64bit float: b_1=-1.9999407878821227
1000bit float: b_1=-1.9999407878821229546...

  64bit float: b_2=0.9999476415828948
1000bit float: b_2=0.99994764158289505784...

  64bit float: A_0=0.9999407887586415
1000bit float: A_0=0.99994078875864168053...

  64bit float: A_1=-3.9997768620302883
1000bit float: A_1=-3.999776862030288790...

  64bit float: A_2=5.9996721465902665
1000bit float: A_2=5.9996721465902674341...

  64bit float: A_3=-3.9997768620302883
1000bit float: A_3=-3.9997768620302887904...

  64bit float: A_4=0.9999407887586415
1000bit float: A_4=0.99994078875864168053...

  64bit float: B_1=-3.9998815757642454
1000bit float: B_1=-3.9998815757642459093...

  64bit float: B_2=5.999658438200355
1000bit float: B_2=5.9996584382003568378...

  64bit float: B_3=-3.99967214829633
1000bit float: B_3=-3.999672148296331671...

  64bit float: B_4=0.9998952859071936
1000bit float: B_4=0.99989528590719395743...

  64bit float: g=0.9999407887586415
1000bit float: g=0.99994078875864168053...

  64bit float: alpha_0=-1.9999407878821227
1000bit float: alpha_0=-1.9999407878821229546...

  64bit float: beta_0=0.9999476415828948
1000bit float: beta_0=0.99994764158289505784...

  64bit float: gamma_0=-2.0000068539036895
1000bit float: gamma_0=-2.000006853903689179...

  64bit float: delta_0=1.0
1000bit float: delta_0=1

  64bit float: alpha_1=-1.9999407878821227
1000bit float: alpha_1=-1.9999407878821229546...

  64bit float: beta_1=0.9999476415828948
1000bit float: beta_1=0.99994764158289505784...

  64bit float: gamma_1=-2.0000068539036895
1000bit float: gamma_1=-2.000006853903689179...

  64bit float: delta_1=1.0
1000bit float: delta_1=1

## f_c=200, R=0.1 ##
  64bit float: T=0.000020833333333333333
1000bit float: T=0.000020833333333333333333...

  64bit float: omega_c=1256.6370614359173
1000bit float: omega_c=1256.6370614359172953...

  64bit float: b_0=4.011157364706486
1000bit float: b_0=4.0111573647064860718...

  64bit float: a_0=-0.9970475469236862
1000bit float: a_0=-0.99704754692368626323...

  64bit float: a_1=1.9947785765753758
1000bit float: a_1=1.9947785765753758914...

  64bit float: a_2=-0.9970475469236862
1000bit float: a_2=-0.99704754692368626323...

  64bit float: b_1=-1.9940950938473725
1000bit float: b_1=-1.994095093847372526...

  64bit float: b_2=0.9947785765753759
1000bit float: b_2=0.9947785765753758914...

  64bit float: A_0=0.9941038108265403
1000bit float: A_0=0.99410381082654036092...

  64bit float: A_1=-3.9777781728608024
1000bit float: A_1=-3.9777781728608023719...

  64bit float: A_2=5.9673491912171635
1000bit float: A_2=5.9673491912171635009...

  64bit float: A_3=-3.9777781728608024
1000bit float: A_3=-3.9777781728608023719...

  64bit float: A_4=0.9941038108265403
1000bit float: A_4=0.99410381082654036092...

  64bit float: B_1=-3.988190187694745
1000bit float: B_1=-3.988190187694745052...

  64bit float: B_2=5.965972396456913
1000bit float: B_2=5.9659723964569132265...

  64bit float: B_3=-3.9673661580268598
1000bit float: B_3=-3.9673661580268596909...

  64bit float: B_4=0.9895844164133311
1000bit float: B_4=0.9895844164133309962...

  64bit float: g=0.9941038108265403
1000bit float: g=0.99410381082654036092...

  64bit float: alpha_0=-1.9940950938473725
1000bit float: alpha_0=-1.994095093847372526...

  64bit float: beta_0=0.9947785765753759
1000bit float: beta_0=0.9947785765753758914...

  64bit float: gamma_0=-2.0006855066542335
1000bit float: gamma_0=-2.0006855066542334901...

  64bit float: delta_0=1.0
1000bit float: delta_0=1

  64bit float: alpha_1=-1.9940950938473725
1000bit float: alpha_1=-1.994095093847372526...

  64bit float: beta_1=0.9947785765753759
1000bit float: beta_1=0.9947785765753758914...

  64bit float: gamma_1=-2.0006855066542335
1000bit float: gamma_1=-2.0006855066542334901...

  64bit float: delta_1=1.0
1000bit float: delta_1=1

Chapter 4. アナログフィルタの伝達関数

Chapter 2.ではアナログフィルタの伝達関数H(s)H(s)からデジタルフィルタの伝達関数H(z)H(z)を得る方法について述べ、Chapter 3.ではデジタルフィルタの伝達関数H(z)H(z)をプログラムに実装する方法を述べた。最後に、アナログフィルタの伝達関数H(s)H(s)を入手する方法を紹介する。

とは言っても、アナログフィルタの伝達関数はインターネット上に多く落ちているため、必要があれば検索した方が早い。ここでは特に代表的な物を紹介するに留める。

アナログ1次フィルタ

Chapter 3.の実験結果から、高次のデジタルフィルタを作る際は1次か2次フィルタのカスケード接続をしたほうが性能が良いことを示した。似たようなことはアナログ回路でも言うことができ、高次のフィルタを作る際は低次のアクティブフィルタを多段縦続接続することが多い。

低域通過フィルタ

カットオフ周波数をωc\omega_cとすると

HLPF(s)=ωcs+ωcH_{\mathrm{LPF}}(s) = \frac{\omega_c}{s+\omega_c}

振幅特性は

HLPF(jω)=ωcω2+ωc2|H_{\mathrm{LPF}}(j\omega)| = \frac{\omega_c}{\sqrt{\omega^2+\omega_c^2}}

であり、カットオフ周波数の地点で振幅が12\frac{1}{\sqrt{2}}、dBで表すなら20log10123.010 [dB]20\log_{10}\frac{1}{\sqrt{2}}\approx-3.010\ [\mathrm{dB}]になる。

スロープは6dB/octである。

高域通過フィルタ

周波数対数スケール上で考えると、高域通過フィルタは低域通過フィルタの特性をωc\omega_cで左右反転したものである。そこで、sωcωcs\frac{s}{\omega_c} \rightarrow \frac{\omega_c}{s}という変数変換を行うことで、

HHPF(s)=ss+ωc\begin{aligned} H_{\mathrm{HPF}}(s) = \frac{s}{s+\omega_c} \end{aligned}

振幅特性は

HHPF(jω)=ωω2+ωc2|H_{\mathrm{HPF}}(j\omega)| = \frac{\omega}{\sqrt{\omega^2+\omega_c^2}}

であり、カットオフ周波数の地点で振幅が12\frac{1}{\sqrt{2}}、dBで表すなら20log10123.010 [dB]20\log_{10}\frac{1}{\sqrt{2}}\approx-3.010\ [\mathrm{dB}]になる。

スロープは6dB/octである。

低域シェルビングフィルタ

DC成分のゲインをA0A_0とすれば伝達関数は

HLSF(s)=s+A0ωcs+ωcH_{\mathrm{LSF}}(s) = \frac{s+A_0\omega_c}{s+\omega_c}

周波数特性は

HLSF(jω)=ω2+A02ωc2ω2+ωc2|H_{\mathrm{LSF}}(j\omega)| = \frac{\sqrt{\omega^2+A_0^2\omega_c^2}}{\sqrt{\omega^2+\omega_c^2}}

形が非対称であり、傾斜も選択できないためデジタルEQではあまり見かけない。

高域シェルビングフィルタ

低域通過フィルタから高域通過フィルタを求めたように、sωcωcs\frac{s}{\omega_c} \rightarrow \frac{\omega_c}{s}という変数変換を行えば、

HHSF(s)=As+ωcs+ωcH_{\mathrm{HSF}}(s) = \frac{A_{\infty}s+\omega_c}{s+\omega_c}

を得る。AA_{\infty}は高域でのゲインを表す。

周波数特性は

HHSF(jω)=A2ω2+ωc2ω2+ωc2|H_{\mathrm{HSF}}(j\omega)| = \frac{\sqrt{A_{\infty}^2\omega^2+\omega_c^2}}{\sqrt{\omega^2+\omega_c^2}}

形が非対称であり、傾斜も選択できないためデジタルEQではあまり見かけない。

1次で実現できるのはこれで全て?

全て。 1次伝達関数の一般形を考えてみる。

H(s)=a1s+a0b1s+b0H(jω)=a12ω2+a02b12ω2+b02H(s) = \frac{a_1s+a_0}{b_1s+b_0} \\ |H(j\omega)| = \frac{\sqrt{a_1^2\omega^2+a_0^2}}{\sqrt{b_1^2\omega^2+b_0^2}}

パラメータが多いので集約してみる。

  • a1=0a_1=0 の時、H(s)=a0b1s+b0H(s)=\frac{a_0}{b_1s+b_0}
    • b1=0b_1=0の時、H(s)=a0b0H(s)=\frac{a_0}{b_0}。これは定数倍ゲイン。
    • b10b_1\neq0の時、H(s)=a0b11s+b0/b1H(s)=\frac{a_0}{b_1}\frac{1}{s+b_0/b_1}。これはゲイン+ローパス
  • a10a_1\neq0の時、a1a_1はゲインと見なしてH(s)=a1s+a0/a1b1s+b0H(s)=a_1\frac{s + a_0/a_1}{b_1s+b_0}
    • b1=0b_1=0の時、H(s)=a1b0(s+a0/a1)H(s)=\frac{a_1}{b_0}(s + a_0/a_1)H(jω)=a1b0ω2+a02a12|H(j\omega)|=\frac{a_1}{b_0}\sqrt{\omega^2+\frac{a_0^2}{a_1^2}}
      • ω\omegaが指数的に大きくなると振幅特性も指数的に大きくなるフィルター。実用的では無い。
    • b10b_1\neq0の時、H(s)=a1b1s+a0/a1s+b0/b1H(s)=\frac{a_1}{b_1}\frac{s+a_0/a_1}{s+b_0/b_1}。これはシェルビングフィルター

アナログ2次フィルタ

アナログ2次フィルタは、1次フィルタに比べると形とパラメータにバリエーションが出てくる。

低域通過フィルタ

カットオフ周波数をωc\omega_c、QをQQとすると、伝達関数は

HLPF(s)=ωc2s2+ωcQs+ωc2H_{\mathrm{LPF}}(s) = \frac{\omega_c^2}{s^2+\frac{\omega_c}{Q}s+\omega_c^2}

振幅特性は

HLPF(jω)=ωc2(ω2ωc2)2+ωc2ω2Q2|H_{\mathrm{LPF}}(j\omega)| = \frac{\omega_c^2}{\sqrt{(\omega^2-\omega_c^2)^2+\frac{\omega_c^2\omega^2}{Q^2}}}

Q=120.707Q=\frac{1}{\sqrt{2}}\approx0.707の時、フィルタはButterworth特性となる。この時、カットオフ周波数地点の振幅特性は12\frac{1}{\sqrt{2}}、dBで表すなら20log10123.010 [dB]20\log_{10}\frac{1}{\sqrt{2}}\approx-3.010\ [\mathrm{dB}]になる。

また、Q=130.577Q=\frac{1}{\sqrt{3}}\approx0.577の時、フィルタはBessel特性となる。

Butterworth特性とは?

代表的なフィルタの特性(振幅特性の形)で、通過域の振幅特性が最大限平坦な特性のこと。 Butterworth特性は振幅特性の式で定義されており、低域通過フィルタが以下の特性を持つ物を指す。

H(jω)2=A021+(ωωc)2n|H(j \omega)|^2 = \frac{A_0^2}{1+\left( \frac{\omega}{\omega_c} \right)^{2n}}

A0A_0はDC成分のゲインで、nnはフィルタの次数である。HLPF(jω)2|H_{\mathrm{LPF}}(j\omega)|^2Q=12Q=\frac{1}{\sqrt{2}}の時、

HLPF(jω)2=ωc4(ω2ωc2)2+2ωc2ω2=ωc4ω42ωc2ω2+ωc4+2ωc2ω2=ωc4ω4+ωc4=11+(ωcω)2×2\begin{aligned} |H_{\mathrm{LPF}}(j\omega)|^2 &= \frac{\omega_c^4}{(\omega^2-\omega_c^2)^2+2\omega_c^2\omega^2} \\ &= \frac{\omega_c^4}{\omega^4-2\omega_c^2\omega^2+\omega_c^4+2\omega_c^2\omega^2}\\ &= \frac{\omega_c^4}{\omega^4+\omega_c^4}\\ &= \frac{1}{1+\left(\frac{\omega_c}{\omega}\right)^{2\times2}}\\ \end{aligned}

となり、2次のButterworth特性を持つ。

Butterworth特性を持つn次LPFの伝達関数の有理関数を求めてみよう。H(jω)2|H(j \omega)|^2からH(s)H(s)を求めれば良いので、s=jωs=j\omegaという関係と、H(jω)2=H(jω)H(jω)|H(j \omega)|^2 = H(j\omega)\overline{H(j \omega)}から、

H(jω)2=H(jω)H(jω)=A021+(ωωc)2nH(jω)H(jω)=A021+(ωωc)2nH(s)H(s)=A021+(jsωc)2n=A021+(s2ωc2)n\begin{aligned} |H(j \omega)|^2 = H(j\omega)\overline{H(j \omega)} &= \frac{A_0^2}{1+\left( \frac{\omega}{\omega_c} \right)^{2n}} \\ H(j\omega)H(-j\omega)&= \frac{A_0^2}{1+\left( \frac{\omega}{\omega_c} \right)^{2n}} \\ H(s)H(-s)&= \frac{A_0^2}{1+\left( \frac{-js}{\omega_c} \right)^{2n}} = \frac{A_0^2}{1+\left( \frac{-s^2}{\omega_c^2} \right)^{n}} \\ \end{aligned}

ここで、伝達関数がH(s)H(s)H(s)H(-s)であるようなシステムの極を考える。極は分母がゼロになる点なので、

1+(s2ωc2)n=0s2ωc2=(1)1n\begin{aligned} 1+\left( \frac{-s^2}{\omega_c^2} \right)^{n} &= 0\\ \frac{-s^2}{\omega_c^2} &= (-1)^{\frac{1}{n}} \end{aligned}

オイラーの公式から、

ej(2k1)π=cos((2k1)π)+jsin((2k1)π)=1(k=1,2,3,)e^{j(2k-1)\pi}=\cos((2k-1)\pi)+j \sin((2k-1)\pi)=-1\quad (k=1,2,3,\cdots)

なので、

s2ωc2=(1)1n=exp{j(2k1)πn}s2=ωc2exp{j(2k1)πn}s2=ωc2exp{j(2k1)πn}exp(jπ)=ωc2exp{j(2k+n1)πn}s=ωcexp{j(2k+n1)π2n}\begin{aligned} \frac{-s^2}{\omega_c^2} &= (-1)^{\frac{1}{n}} = \exp \left\{\frac{j(2k-1)\pi}{n} \right\} \\ -s^2 &= \omega_c^2 \exp\left\{\frac{j(2k-1)\pi}{n}\right\} \\ s^2 &= \omega_c^2 \exp \left\{\frac{j(2k-1)\pi}{n}\right\} \exp(j\pi) = \omega_c^2 \exp \left\{\frac{j(2k+n-1)\pi}{n} \right\} \\ s &= \omega_c \exp \left\{\frac{j(2k+n-1)\pi}{2n} \right\} \end{aligned}

最後に、得られた極を伝達関数H(s)H(s)H(s)H(-s)に分配する。システムの安定性を保つ為、H(s)H(s)の極はss平面上の左側の領域から選ぶこととし、k=1,2,3,nk=1,2,3,\cdots nの範囲とする。

以上より、H(s)H(s)

H(s)=G0k=1nωcssk(k=1,2,3,,n)sk=ωcexp{j(2k+n1)π2n}H(s) = G_0 \prod_{k=1}^n \frac{\omega_c}{s-s_k} \quad (k=1,2,3,\cdots, n) \\ s_k = \omega_c \exp \left\{\frac{j(2k+n-1)\pi}{2n} \right\}

実際の極の位置は次のようになる。半径ωc\omega_cの円周上の内、左側に等間隔に並ぶ。

アナログフィルタもデジタルフィルタも、実装時は1次と2次フィルタの縦続接続を行うので、先ほど得たH(s)H(s)の多項式も1次+2次の形に表したい。

式を見やすくするため、周波数で正規化しsωcs\frac{s}{\omega_c} \rightarrow sという変形を行うと、

H(s)=G0k=1n1ssk(k=1,2,3,,n)sk=exp{j(2k+n1)π2n}H(s) = G_0 \prod_{k=1}^n \frac{1}{s-s_k} \quad (k=1,2,3,\cdots, n) \\ s_k = \exp \left\{\frac{j(2k+n-1)\pi}{2n} \right\}

実軸対称の極をペアと考え、2次方程式の解と係数の関係を使えばH(s)H(s)の分母多項式Bn(s)B_n(s)は次のように表せる。この式をButterworth多項式と言う。

Bn(s)={k=1n2(s22scos((2k+n1)π2n)+1)(nが偶数)(s+1)k=1n12(s22scos((2k+n1)π2n)+1)(nが奇数)B_n(s) = \begin{cases} \prod_{k=1}^{\frac{n}{2}} (s^2 - 2s \cos \left( \frac{(2k+n-1)\pi}{2n} \right) + 1) & \quad (nが偶数) \\ (s+1)\prod_{k=1}^{\frac{n-1}{2}} (s^2 - 2s \cos \left( \frac{(2k+n-1)\pi}{2n} \right) + 1) & \quad (nが奇数) \\ \end{cases}

このButterworth多項式を使えば、次数nnが与えられた時、Butterworth特性を持つフィルタの係数をすぐに求めることができる。

Bessel特性とは?

振幅特性はButterworthに似ているが、群遅延が最大平坦となる特性のこと。群遅延とは位相の周波数微分であり、要は位相の傾きのこと。位相の傾きが最大平坦ということは、最も線形位相に近いということである。

前に見せた周波数特性のグラフに、群遅延のグラフを追加すると次のようになる(3段目)。Q=130.577Q=\frac{1}{\sqrt{3}}\approx0.577の時が、群遅延が一番平坦であることが分かる。

矩形波を入力した時の応答を見てみよう。こちらの方が分かりやすい。Q=130.577Q=\frac{1}{\sqrt{3}}\approx0.577の時が最も応答の振動が少なく、必要以上に矩形が欠けてないことが分かる。

IIRデジタルフィルタでは線形位相を実現できない(※例外は次の補足を参照)。そのため、Bessel特性を持ったIIRフィルタは、線形位相に近い特性を実現したい時に大いに役に立つ。

Bessel特性を持つ低域通過フィルタの伝達関数は、Bessel多項式で表せる。具体的には、逆ベッセル多項式θn(s)\theta_n(s)

θn(s)=k=0n(n+k)!(nk)!k!xnk2k\theta_n(s) = \sum_{k=0}^n \frac{(n+k)!}{(n-k)!k!}\frac{x^{n-k}}{2^k}

とし、

Hn:Bessel:LPF(s)=θn(0)θn(s/ωc)H_{\mathrm{n:Bessel:LPF}}(s) = \frac{\theta_n(0)}{\theta_n(s/\omega_c)}

である。具体的にn=2n=2の時を算出すると

H2:Bessel:LPF(s)=3ωc2s2+3ωcs+3ωc2H_{\mathrm{2:Bessel:LPF}}(s) = \frac{3\omega_c^2}{s^2+3\omega_cs+3\omega_c^2}

になる。これはHLPF(s)H_{\mathrm{LPF}}(s)Q=13Q=\frac{1}{\sqrt{3}}の時の式と異なるが、ωc\omega_cを少しスケールすればH2:Bessel:LPF(s)H_{\mathrm{2:Bessel:LPF}}(s)となり、HLPF(s)H_{\mathrm{LPF}}(s)Q=13Q=\frac{1}{\sqrt{3}}の時Bessel特性を持つと言える。

HLPF(s)=ωc2s2+ωc1/3s+ωc2=ωc2s2+3ωcs+ωc2=(3ωc, scaled)2s2+3(3ωc, scaled)s+(3ωc, scaled)2ωc=3ωc, scaledとスケール=3ωc, scaled2s2+3ωc, scaleds+3ωc, scaled2\begin{aligned} H_{\mathrm{LPF}}(s) &= \frac{\omega_c^2}{s^2+\frac{\omega_c}{1/\sqrt{3}}s+\omega_c^2} \\ &= \frac{\omega_c^2}{s^2+\sqrt{3}\omega_cs+\omega_c^2} \\ &= \frac{(\sqrt{3}\omega_{c,\ \mathrm{scaled}})^2}{s^2+\sqrt{3}(\sqrt{3}\omega_{c,\ \mathrm{scaled}})s+(\sqrt{3}\omega_{c,\ \mathrm{scaled}})^2} \quad \footnotesize ※\omega_c = \sqrt{3}\omega_{c,\ \mathrm{scaled}} とスケール \\ &= \frac{3\omega_{c,\ \mathrm{scaled}}^2}{s^2+3\omega_{c,\ \mathrm{scaled}}s+3\omega_{c,\ \mathrm{scaled}}^2} \end{aligned}

つまり、HLPF(s)H_{\mathrm{LPF}}(s)でカットオフ周波数が1000Hz、Q=13Q=\frac{1}{\sqrt{3}}として作ったフィルタは、カットオフ周波数1000×13577[Hz]1000 \times \frac{1}{\sqrt{3}} \approx 577\, [\mathrm{Hz}]におけるBessel特性のフィルタということになる。

IIRで完璧な線形位相を得る方法

以下のような(トリッキーな)方法を使えば、IIRで線形位相を得られる。

  1. 与えられたサンプル列を通常のように順方向で処理をする。
  2. 処理後のサンプル列を反転する。
  3. 判定したサンプル列に順方向で処理をする。
  4. 処理後のサンプル列を反転する。

この方法をForward-Backwardと言ったりTIIRと言ったりする。順方向で処理した際に生じた位相変化は、逆方向で処理した時に打ち消されるので、結果的に線形位相になるわけだ。

一見魅力的な方法だが、DAWで動くVSTプラグインのように、ブロック単位でサンプル列が与えられる上にそこそこの時間で処理を終えないといけないシステムでは扱い勝手が悪い。 具体的な処理プロセスとして以下のような物が考えられるが、特に、前ブロックと加算する際に適切な処理を行わないとノイズの原因になる。また、仕組み上、フィルタ係数のオートメーション対応(サンプル単位での係数Rampingなど)を行いにくい。線形位相を得るだけならFIRフィルタ使った方が遥かに効率良く、実装もシンプルで、かつ同じ効果を得られるため、この手法を採用する意義は少ない。

Forward-BackwardとFIRのインパルス応答が全く同じ、つまりこの2つの手法が同じ動作であることを実際に確認してみる。IIRフィルタは下記の伝達関数を持つアナログピークフィルタを双一次変換でデジタルフィルタとする。このフィルタの伝達関数をH(z)H(z)とする。実験時、サンプリング周波数を48000Hzとし、中心周波数はナイキスト周波数より十分低い200Hzとする。R=0.2R=0.2とする。

H(s)=ω02s2s2+2Rω0s+ω02H(s) = \frac{\omega_0^2-s^2}{s^2+2R\omega_0s+\omega_0^2}

Forward-Backwardでは、同じフィルタを2回かけることになるので、その振幅特性はH(ejωT)×H(ejωT)|H(e^{j\omega T})|\times|H(e^{j\omega T})|であり、位相特性は定数00となる。 これと同じ特性を持つFIRフィルタのインパルス応答は、H(ejωT)×H(ejωT)|H(e^{j\omega T})|\times|H(e^{j\omega T})|に逆フーリエ変換を施すことで得る。

結果を以下に示す。左側1段目に、インパルス信号にIIRフィルタをForward-Backwardでかけて得たインパルス応答と、同じ特性を持つFIRフィルタのインパルス応答を示す。目視では差が分からないので、左側2段目に差を示す。差はなお小さいためdBFSで表示している。丁度DAWでNullテスト(片方を位相反転させて再生するやつ)を行った時のピークメータと思えば良い。右側1段目と2段目に周波数特性を示している。左側3段目には1000Hzのsin波に対して、Forward-BackwardとFIRの畳み込みを行った結果のTHDを示している。右側3段目は、左側3段目の結果を一部ズームして表示している。

結果から、Forward-Backwardのインパルス応答と、同じ特性を持つFIRフィルタのインパルス応答に殆ど差が無いことが分かる。差はdBFSで-250dB未満であり、知覚できない。更に、THDも特に変わらないことも分かる。

Forward-BackwardとFIRの畳み込みは、殆ど同じ結果が得られる。

高域通過フィルタ

物凄く寄り道してしまった。

周波数対数スケール上で考えると、高域通過フィルタは低域通過フィルタの特性をωc\omega_cで左右反転したものである。そこで、sωcωcs\frac{s}{\omega_c} \rightarrow \frac{\omega_c}{s}という変数変換を行うことで、

HHPF(s)=s2s2+ωcQs+ωc2H_{\mathrm{HPF}}(s) = \frac{s^2}{s^2+\frac{\omega_c}{Q}s+\omega_c^2}

振幅特性は

HHPF(jω)=ω2(ω2ωc2)2+ωc2ω2Q2|H_{\mathrm{HPF}}(j\omega)| = \frac{\omega^2}{\sqrt{(\omega^2-\omega_c^2)^2+\frac{\omega_c^2\omega^2}{Q^2}}}

Q=120.707Q=\frac{1}{\sqrt{2}}\approx0.707の時、フィルタはButterworth特性となる。この時、カットオフ周波数地点の振幅特性は12\frac{1}{\sqrt{2}}、dBで表すなら20log10123.010 [dB]20\log_{10}\frac{1}{\sqrt{2}}\approx-3.010\ [\mathrm{dB}]になる。

また、Q=130.577Q=\frac{1}{\sqrt{3}}\approx0.577の時、フィルタはBessel特性となる。

帯域通過フィルタ

伝達関数は

HBPF(s)=ωcQss2+ωcQs+ωc2H_{\mathrm{BPF}}(s) = \frac{\frac{\omega_c}{Q} s}{s^2+\frac{\omega_c}{Q}s+\omega_c^2}

振幅特性は

HBPF(jω)=ωcQω(ω2ωc2)2+ωc2ω2Q2|H_{\mathrm{BPF}}(j\omega)| = \frac{\frac{\omega_c}{Q} \omega}{\sqrt{(\omega^2-\omega_c^2)^2+\frac{\omega_c^2\omega^2}{Q^2}}}

伝達関数をHBPF(s)=ωcss2+ωcQs+ωc2H_{\mathrm{BPF}}(s) = \frac{\omega_c s}{s^2+\frac{\omega_c}{Q}s+\omega_c^2}にすることで、BPFのスカートのゲイン位置を固定したまま、頂点のゲインを変えられるフィルタにもできる。

このようなフィルタになっても、Q=130.577Q=\frac{1}{\sqrt{3}}\approx0.577の時、フィルタはBessel特性となる。

Notchフィルタ

帯域除去フィルタとも言う。

伝達関数は

HBRF(s)=s2+ωc2s2+ωcQs+ωc2H_{\mathrm{BRF}}(s) = \frac{s^2 + \omega_c^2}{s^2+\frac{\omega_c}{Q}s+\omega_c^2}

振幅特性は

HBRF(jω)=ω2+ωc2(ω2ωc2)2+ωc2ω2Q2|H_{\mathrm{BRF}}(j\omega)| = \frac{|-\omega^2+\omega_c^2|}{\sqrt{(\omega^2-\omega_c^2)^2+\frac{\omega_c^2\omega^2}{Q^2}}}

位相特性のグラフを見ても分かる通り連続では無くなるため、Q=130.577Q=\frac{1}{\sqrt{3}}\approx0.577でBessel特性は持たない

全域通過フィルタ

伝達関数は

HAPF(s)=s2ωcQs+ωc2s2+ωcQs+ωc2H_{\mathrm{APF}}(s) = \frac{s^2-\frac{\omega_c}{Q}s+\omega_c^2}{s^2+\frac{\omega_c}{Q}s+\omega_c^2}

振幅特性は

HAPF(jω)=1|H_{\mathrm{APF}}(j\omega)| = 1

Q=130.577Q=\frac{1}{\sqrt{3}}\approx0.577でBessel特性を持つ。

ピーキングフィルタ

ピークのゲインをAAとして、伝達関数は

伝達関数は

HPKF(s)=s2+AQωcs+ωc2s2+ωcQAs+ωc2H_{\mathrm{PKF}}(s) = \frac{s^2+\frac{\sqrt{A}}{Q}\omega_cs+\omega_c^2}{s^2+\frac{\omega_c}{Q\sqrt{A}}s+\omega_c^2}

振幅特性は

HPKF(jω)=(ω2ωc2)2+Aωc2ω2Q2(ω2ωc2)2+ωc2ω2AQ2|H_{\mathrm{PKF}}(j\omega)| = \frac{\sqrt{(\omega^2-\omega_c^2)^2+\frac{A\omega_c^2\omega^2}{Q^2}}}{\sqrt{(\omega^2-\omega_c^2)^2+\frac{\omega_c^2\omega^2}{AQ^2}}}

Q=130.577Q=\frac{1}{\sqrt{3}}\approx0.577でBessel特性を持つとは言えなさそう。

低域シェルビングフィルタ

伝達関数は

HLSF(s)=As2+A4Qωcs+ωc2AAs2+A4Qωcs+ωc2H_{\mathrm{LSF}}(s) = \sqrt{A}\frac{s^2+\frac{\sqrt[4]{A}}{Q}\omega_cs+\omega_c^2\sqrt{A}}{\sqrt{A}s^2+\frac{\sqrt[4]{A}}{Q}\omega_cs+\omega_c^2}

振幅特性は

HLSF(jω)=A(ω2ωc2A)2+AQ2ωc2ω2(Aω2ωc2)2+AQ2ωc2ω2|H_{\mathrm{LSF}}(j\omega)| = \sqrt{A}\frac{\sqrt{(\omega^2-\omega_c^2\sqrt{A})^2+\frac{\sqrt{A}}{Q^2}\omega_c^2\omega^2}}{\sqrt{(\sqrt{A}\omega^2-\omega_c^2)^2+\frac{\sqrt{A}}{Q^2}\omega_c^2\omega^2}}

Q=120.707Q=\frac{1}{\sqrt{2}}\approx0.707でButterworth特性を持つ。 Q=130.577Q=\frac{1}{\sqrt{3}}\approx0.577でBessel特性を持つ。

高域シェルビングフィルタ

伝達関数は

HHSF(s)=AAs2+A4Qωcs+ωc2s2+A4Qωcs+ωc2AH_{\mathrm{HSF}}(s) = \sqrt{A}\frac{\sqrt{A}s^2+\frac{\sqrt[4]{A}}{Q}\omega_cs+\omega_c^2}{s^2+\frac{\sqrt[4]{A}}{Q}\omega_cs+\omega_c^2\sqrt{A}}

振幅特性は

HHSF(jω)=A(Aω2ωc2)2+AQ2ωc2ω2(ω2ωc2A)2+AQ2ωc2ω2|H_{\mathrm{HSF}}(j\omega)| = \sqrt{A}\frac{\sqrt{(\sqrt{A}\omega^2-\omega_c^2)^2+\frac{\sqrt{A}}{Q^2}\omega_c^2\omega^2}}{\sqrt{(\omega^2-\omega_c^2\sqrt{A})^2+\frac{\sqrt{A}}{Q^2}\omega_c^2\omega^2}}

Q=120.707Q=\frac{1}{\sqrt{2}}\approx0.707でButterworth特性を持つ。 Q=130.577Q=\frac{1}{\sqrt{3}}\approx0.577でBessel特性を持つ。

アナログ高次フィルタ

HPFとLPFは高次フィルタが望まれる場面がある。そこで高次のデジタルフィルタを作るために1次か2次フィルタを単純に縦続接続すると、Qが同じなのにカットオフ周波数地点のゲインが変わってしまう。例えば3次のLPFを作る為に、下記の2つを縦続接続すると次のような結果が得られる。

H1, LPF(s)=ωcs+ωcH_{\mathrm{1,\ LPF}}(s) = \frac{\omega_c}{s+\omega_c} H2, LPF(s)=ωc2s2+ωcQs+ωc2H_{\mathrm{2,\ LPF}}(s) = \frac{\omega_c^2}{s^2+\frac{\omega_c}{Q}s+\omega_c^2} H3, NaiveLPF(s)=ωcs+ωcωc2s2+ωcQs+ωc2H_{\mathrm{3,\ NaiveLPF}}(s) = \frac{\omega_c}{s+\omega_c} \cdot \frac{\omega_c^2}{s^2+\frac{\omega_c}{Q}s+\omega_c^2}

これはあまり望ましくない。そこで、Butterworth特性を基準にQを考え直してみる。「Butterworth特性とは」の項で説明したように、Butterworth多項式を使えば、LPFがButterworth特性を持つ時の分母の係数を知ることができる。

Bn(s)={k=1n2(s22scos((2k+n1)π2n)+1)(nが偶数)(s+1)k=1n12(s22scos((2k+n1)π2n)+1)(nが奇数)B_n(s) = \begin{cases} \prod_{k=1}^{\frac{n}{2}} (s^2 - 2s \cos \left( \frac{(2k+n-1)\pi}{2n} \right) + 1) & \quad (nが偶数) \\ (s+1)\prod_{k=1}^{\frac{n-1}{2}} (s^2 - 2s \cos \left( \frac{(2k+n-1)\pi}{2n} \right) + 1) & \quad (nが奇数) \\ \end{cases}

3次Butterworth多項式はB3(s)=(s+1)(s2+s+1)B_3(s) = (s+1)(s^2+s+1)であり、これはカットオフ周波数で正規化されていることを踏まえれば、3次Butterworth低域通過フィルタの伝達関数は

H3, ButterworthLPF(s)=ωcs+ωcωc2s2+ωcs+ωc2H_{\mathrm{3,\ ButterworthLPF}}(s) = \frac{\omega_c}{s+\omega_c} \cdot \frac{\omega_c^2}{s^2+\omega_cs+\omega_c^2}

である。H2, LPF(s)H_{\mathrm{2,\ LPF}}(s)QQパラメータの位置に倣って、これにQQパラメータを追加すると

H3, LPF(s)=ωcs+ωcωc2s2+ωcQs+ωc2H_{\mathrm{3,\ LPF}}(s) = \frac{\omega_c}{s+\omega_c} \cdot \frac{\omega_c^2}{s^2+\frac{\omega_c}{Q}s+\omega_c^2}

を得る。H3, LPF(s)H_{\mathrm{3,\ LPF}}(s)Q=1Q=1でButterworth特性を持つ。H2, LPF(s)H_{\mathrm{2,\ LPF}}(s)Q=1Q=1でButterworth特性を持つようにしたいので、2次Butterworth多項式はB2(s)=s2+2s+1B_2(s) = s^2+\sqrt{2}s+1であることから、

H2, LPF(s)=ωc2s2+2ωcQs+ωc2H_{\mathrm{2,\ LPF}}(s) = \frac{\omega_c^2}{s^2+\sqrt{2}\frac{\omega_c}{Q}s+\omega_c^2}

と定義しなおせば、H2, LPF(s)H_{\mathrm{2,\ LPF}}(s)Q=1Q=1でButterworth特性を持つようになる。図示すると次のようになり、QQが同じならカットオフ周波数地点のゲインも同じになる。

4次以降の低域通過フィルタを作る時はQQパラメータを追加する位置を工夫する。例えば、4次Butterworth多項式は下記であるから、

B4=(s22scos(58π)+1)(s22scos(78π)+1)B_4 = \left(s^2-2s \cos \left(\frac{5}{8}\pi\right)+1 \right)\left(s^2-2s \cos \left(\frac{7}{8}\pi\right)+1\right)

4次Butterworth低域通過フィルタの伝達関数は、

H4, ButterworthLPF(s)=ωc2s22ωcscos(58π)+ωc2ωc2s22ωcscos(78π)+ωc2H_{\mathrm{4,\ ButterworthLPF}}(s) = \frac{\omega_c^2}{s^2-2\omega_cs \cos \left(\frac{5}{8}\pi\right)+\omega_c^2} \cdot \frac{\omega_c^2}{s^2-2\omega_cs \cos \left(\frac{7}{8}\pi\right)+\omega_c^2}

となる。QQパラメータは、Butterworth多項式でk=1k=1の項に付与する。

H4, LPF(s)=ωc2s22ωcscos(58π)Q+ωc2ωc2s22ωcscos(78π)+ωc2H_{\mathrm{4,\ LPF}}(s) = \frac{\omega_c^2}{s^2- \frac{2\omega_cs \cos \left(\frac{5}{8}\pi\right)}{Q}+\omega_c^2} \cdot \frac{\omega_c^2}{s^2-2\omega_cs \cos \left(\frac{7}{8}\pi\right)+\omega_c^2}

同様にH5, LPF(s)H_{\mathrm{5,\ LPF}}(s)H6, LPF(s)H_{\mathrm{6,\ LPF}}(s)

H5, LPF(s)=ωcs+ωcωc2s22ωcscos(35π)Q+ωc2ωc2s22ωcscos(45π)+ωc2H6, LPF(s)=ωc2s22ωcscos(712π)Q+ωc2ωc2s22ωcscos(34π)+ωc2ωc2s22ωcscos(1112π)+ωc2\begin{aligned} H_{\mathrm{5,\ LPF}}(s) &= \frac{\omega_c}{s+\omega_c} \cdot \frac{\omega_c^2}{s^2- \frac{2\omega_cs \cos \left(\frac{3}{5}\pi\right)}{Q}+\omega_c^2} \cdot \frac{\omega_c^2}{s^2-2\omega_cs \cos \left(\frac{4}{5}\pi\right)+\omega_c^2} \\ H_{\mathrm{6,\ LPF}}(s) &= \frac{\omega_c^2}{s^2- \frac{2\omega_cs \cos \left(\frac{7}{12}\pi\right)}{Q}+\omega_c^2} \cdot \frac{\omega_c^2}{s^2-2\omega_cs \cos \left(\frac{3}{4}\pi\right)+\omega_c^2} \cdot \frac{\omega_c^2}{s^2-2\omega_cs \cos \left(\frac{11}{12}\pi\right)+\omega_c^2} \end{aligned}

図示すると次のようになる。QQに依らず、カットオフ周波数の地点のゲインが同じである。1次LPFはQQパラメータが存在しないので、これは例外である。

Q=1でButterworth特性を持つLPFでBessel特性を持つには?

元々のH2:LPF(s)H_{\mathrm{2:LPF}}(s)は次式であり、このような時Q=13Q=\frac{1}{\sqrt{3}}であればBessel特性を持つと以前述べた。

H2, old, LPF(s)=ωc2s2+ωcQs+ωc2=ωc2s2+ωc1/3s+ωc2=ωc2s2+3ωcs+ωc2H_{\mathrm{2,\ old,\ LPF}}(s) = \frac{\omega_c^2}{s^2+\frac{\omega_c}{Q}s+\omega_c^2} = \frac{\omega_c^2}{s^2+\frac{\omega_c}{1/\sqrt{3}}s+\omega_c^2} = \frac{\omega_c^2}{s^2+\sqrt{3}\omega_cs+\omega_c^2}

新たに定義したH2, LPF(s)H_{\mathrm{2,\ LPF}}(s)でも、分母のssの係数が3\sqrt{3}になればいいので、Q=230.8165Q=\frac{\sqrt{2}}{\sqrt{3}}\approx0.8165とすれば良い。

H2, LPF(s)=ωc2s2+2ωc23s+ωc2=ωc2s2+232ωcs+ωc2=ωc2s2+3ωcs+ωc2\begin{aligned} H_{\mathrm{2,\ LPF}}(s) &= \frac{\omega_c^2}{s^2+\sqrt{2}\frac{\omega_c}{\frac{\sqrt{2}}{\sqrt{3}}}s+\omega_c^2} \\ &= \frac{\omega_c^2}{s^2+\sqrt{2}\frac{\sqrt{3}}{\sqrt{2}}\omega_cs+\omega_c^2} \\ &= \frac{\omega_c^2}{s^2+\sqrt{3}\omega_cs+\omega_c^2} \end{aligned}

なお、3次以上のBessel特性を持つ低域通過フィルタはHn, LPF(s)H_{\mathrm{n,\ LPF}}(s)QQを調整しても得ることができない。

Chapter 5. まとめ

IIRなデジタルEQは

  1. Chapter 4. を元にアナログフィルタの伝達関数H(s)H(s)を選択
  2. Chapter 2. を元にH(s)H(s)からデジタルフィルタの伝達関数H(z)H(z)を獲得
  3. Chapter 3. を元にプログラム実装

の手順で作ることができる。Chapter 2.~4. の背景知識としてChapter 1.の内容を使っている。

おすすめ文献

本記事を書くにあたって多くの本・サイトを参考にした。閲覧した中で特に役立ったものを下記に紹介する。

  • ディジタル信号処理システムの基礎 (森北出版 2008)
    • 著者: 渡部英二
    • 大学で使っていた教科書。
  • 応用解析学の基礎 (森北出版 2014)
    • 著者: 坂和正敏
    • 大学で使っていた教科書。
  • やる夫で学ぶディジタル信号処理
  • Vadim Zavalishin. The Art of VA Filter Design 2.1.2. (2020)
  • Robert Bristow-Johnson, Cookbook formulae for audio equalizer biquad filter coefficients
  • Introduction to Digital Filters: with Audio Applications (2007)
    • https://ccrma.stanford.edu/~jos/filters/
    • デジタル信号処理の教科書。無料で読めるのに文量が多く、充実している。
    • 同じWebサイトにて、音声信号処理に関する他の教科書も閲覧できる。