ホワイトノイズからピンクノイズを作るラグ・リードフィルタ

前回、ホワイトノイズを作ったが今度はピンクノイズを作ってみたい。ピンクノイズは、ホワイトノイズに何らかのローパスフィルタをかければ作れそうだ。しかし、ローパスフィルタは一般的に-6dB/octである。ピンクノイズの場合は-3dB/octで減衰させなければならない。ちなみに-3dB/octは「1/fゆらぎ」と呼ばれている。

ピンクノイズとラグ・リードフィルタ
ピンクノイズとラグ・リードフィルタ

どうやってピンクノイズを作るのか?

ピンクノイズフィルター回路
ピンクノイズフィルター回路

さて、どうやったらピンクノイズのフィルタ回路を実現できるだろうかと調べまくった。すると、このような回路図を見つけることができた。

ローパスフィルタに似た形だが、コンデンサと直列に抵抗が入っている。調べると、ラグ・リードフィルタ(lag/lead filter)回路と呼ぶらしい。ちなみに、抵抗1個とコンデンサ1個でつくられるRC回路はラグフィルタと呼ばれるようだ。

巷の回路の定数をそのまま使えばピンクノイズが作れそうだが、普段あまり使わない数値のために電子部品が手持ちになかった。もっと簡単に作れる方法はないだろうかと探し続けた。サクッとピンクノイズを作る予定だったが、実はこのプロジェクトを思い立ってから1週間以上の時間を費やしてしまっている。

ようやく、もっとも簡単なピンクノイズフィルタを見つけることができた。このことは、記事の最後で説明するとしよう。

また、ラグ・リードフィルタの仕組みも調べてみたかったので、この記事ではラグ・リードフィルタの伝達関数や周波数特性をシミュレーションしつつ、もっとも簡単なピンクノイズフィルタの作り方を紹介していく。

ホワイトノイズの作り方はこちら。

ちなみに、ピンクノイズを発生させるモジュールも販売されている。こちらの商品はデジタルICを使っているようだ。

ラグ・リードフィルタの伝達関数

ラグ・リードフィルタの回路図
ラグ・リードフィルタの回路図

Pythonで周波数特性をシミュレーションしたいため、ラグ・リードフィルタの伝達関数を計算してみた。まずは、回路図のような1つだけのラグ・リードフィルタの伝達関数を考えてみよう。

出力先に繋がれる入力インピーダンスを無限大だと仮定すると、

$$v_i(t) = R_1i(t)+v_o(t) \tag{1}$$

より、

$$i(t)=\frac{v_i(t)-v_o(t)}{R_1} \tag{2}$$

である。また、

$$v_o(t)=R_2i(t)+\frac{1}{C}\int i(t)dt \tag{3}$$

である。式2を式3へ代入すると、

$$v_o(t)=\frac{R_2}{R_1}(v_i(t)-v_o(t))+\frac{1}{CR_1}\int(v_i(t)-v_o(t))dt \tag{4}$$

となる。

\(v_i(0)=0, v_o(0)=0\)として式4の両辺をラプラス変換すると、

$$V_o(s)=\frac{R_2}{R_1}(V_i(s)-V_o(s))+\frac{1}{CR_1}(\frac{V_i(s)}{s} - \frac{V_o(s)}{s}) \tag{5}$$

となり、式5を\(V_o(s),V_i(s)\)でまとめていくと

$$(1+\frac{R_2}{R_1}+\frac{1}{CR_1s})V_o(s) = (\frac{R_2}{R_1}+\frac{1}{CR_1s})V_i(s) \tag{6}$$

よって、伝達関数\(H(s)\)は

$$H(s)=\frac{V_o(s)}{V_i(s)}=\frac{1+\frac{R_2}{R_1}+\frac{1}{CR_1s}}{\frac{R_2}{R_1}+\frac{1}{CR_1s}} \tag{7}$$

となる。これを簡潔にまとめると、

$$H(s)=\frac{CR_2s+1}{C(R_1+R_2)s+1} \tag{8}$$

であり、ラグ・リードフィルタの伝達関数が導き出された。

ラプラス変換と伝達関数に関してはこちらの記事を参考に。

ラグ・リードフィルタの周波数特性をPythonで調べてみよう

式8の伝達関数を使って、Pythonでラグ・リードフィルタの周波数特性を調べてみよう。次のプログラムの通りR1、R2、Cの値をいろいろと変えてシミュレーションしてみた。

from control.matlab import *
import matplotlib.pyplot as plt


if __name__ == '__main__':
    R1 = 6.8 * pow(10, 3)  # kΩ
    R2 = 3 * pow(10, 3)  # kΩ
    C = 1 * pow(10, -6)  # μF
    G1 = tf([C*R2, 1], [C*(R1+R2), 1])

    R1 = 6.8 * pow(10, 3)  # kΩ
    R2 = 1 * pow(10, 3)  # kΩ
    C = 267 * pow(10, -9)  # nF
    G2 = tf([C*R2, 1], [C*(R1+R2), 1])

    R1 = 6.8 * pow(10, 3)  # kΩ
    R2 = 300  # Ω
    C = 94 * pow(10, -9)  # nF
    G3 = tf([C*R2, 1], [C*(R1+R2), 1])

    R1 = 6.8 * pow(10, 3)  # kΩ
    R2 = 0
    C = 33 * pow(10, -9)  # nF
    G4 = tf([C*R2, 1], [C*(R1+R2), 1])

    W = logspace(1, 5)  # 対数スケールの配列
    bode(G1, W, Hz=True)
    bode(G2, W, Hz=True)
    bode(G3, W, Hz=True)
    bode(G4, W, Hz=True)
    plt.show()

ラグ・リードフィルタの周波数特性
ラグ・リードフィルタの周波数特性

プログラムの実行結果により、図のようなボード線図が書き出された。各グラフの線は、次のような定数に対応している。

線色R1R2C
6.8k3k1uF
6.8k1k267nF
6.8k30094nF
6.8k033nF

ラグリードフィルタの特徴として、位相が途中で元へ戻り、ゲインの減衰も途中で止まる。赤の線はR2を0Ωに設定しているので、実はRCローパスフィルタ回路である。式8にR2=0を代入すると、RCローパスフィルタの伝達関数になることからもわかる。

並列のラグ・リードフィルタ

並列のラグ・リードフィルタ回路図
並列のラグ・リードフィルタ回路図

さて、ラグ・リードフィルタがどんなものか分かったところで、今度は、並列に繋げられているラグ・リードフィルタの特性を考えてみたい。

この場合は、インピーダンスの並列合成を考えれば伝達関数が導き出せそうである。

$$Z_1=R2+Z_{C1},~Z_2=R3+Z_{C2} \tag{9}$$

とすれば、抵抗の合成の計算によりインピーダンスZは

$$Z=\frac{R_2R_3+R_2Z_{C1}+R_3Z_{C2}+Z_{C1}Z_{C2}}{R_2+Z_{C1}+R_3+Z_{C2}} \tag{10}$$

となる。ただし、

$$Z_{C1}=\frac{1}{sC_1},~Z_{C2}=\frac{1}{sC_2} \tag{11}$$

である。

また、伝達関数は

$$H(s)=\frac{V_o(s)}{V_i(s)}=\frac{Z}{R_1+Z} \tag{12}$$

であるから、式11を式10へ代入し、それをさらに式12へ代入してsについてまとめれば具体的な伝達関数が導き出される。

これを手作業で計算して、なんとか導いた並列ラグ・リードフィルタの伝達関数がこちら。

$$H(s)=\frac{R_2R_3C_1C_2s^2+(R_2C_1+R_3C_2)s+1}{C_1C_2(R_2R_3+R_1R_3+R_1R_2)s^2+(R_2C_1+R_3C_2+R_1C_1+R_1C_2)s+1}\tag{13}$$

手作業は辛いよ。
手作業は辛いよ。

同様にして、並列3つのラグ・リードフィルタの伝達関数を導くことができるだろうが、流石にこれ以上を手書き計算でやる気がしない。よって、今回は2つのラグ・リードフィルタ並列回路に絞ってシュミレーションしていく。

ピンクノイズを作ろう!

幸い、2つだけのラグ・リードフィルタでピンクノイズを作っている回路を見つけることができた。こちらの記事によれば、Minimoogに搭載されているピンクノイズのフィルタ回路のようだ。すばらしい!

Minimoog
Minimoog

その後「minimoog circuit diagram」でググってみると、なんとminimoogの回路図が公開されていた。そして下のサイトの「minimoog schematics 09」に、minimoogらしきピンクノイズフィルタ回路が載っていた。

Minimoogのピンクノイズフィルタ回路
Minimoogのピンクノイズフィルタ回路

Minimoogのピンクノイズのフィルタは、このような回路になっている。

さっそく、式13の伝達関数をつかってPythonで周波数特性をシミュレーションしてみよう!

from control.matlab import *
import matplotlib.pyplot as plt


if __name__ == '__main__':
    R1 = 10 * pow(10, 3)  # kΩ
    R2 = 3.3 * pow(10, 3)  # kΩ
    C1 = 0.12 * pow(10, -6)  # μF
    R3 = 240  # Ω
    C2 = 0.022 * pow(10, -6)  # μF

    R = 47 * pow(10, 3)  # kΩ
    C = 10 * pow(10, -6)  # μF
    K = 1  # ゲイン
    T = R * C  # 時定数
    H_brown = tf([0, K], [T, 1])  # 伝達関数

    H_pink = tf([C1*C2*R2*R3, C1*R2 + C2*R3, 1], [C1*C2*(R2*R3+R1*R3+R1*R2), (R2*C1+R3*C2+R1*C1+R1*C2), 1])  # 伝達関数
    W = logspace(1, 5)  # 対数スケールの配列
    bode(H_pink, W, Hz=True)
    bode(H_brown, W, Hz=True)
    plt.show()

Minimoogピンクノイズフィルタの周波数特性
Minimoogピンクノイズフィルタの周波数特性

シミュレーションの結果がこちら。比較しやすいようにRCローパスフィルタで作った-6dB/Octのブラウンノイズ(橙線)も表示させた。

シミュレーションしたピンクノイズフィルタは、キレイな直線とは言えないが、全体的で見れば-3dB/Oct(-10dB/dec)になっていることが確認できた。よって、可聴音域においては実用的なピンクノイズフィルタであると想像できる。

ちなみにブラウンは人の名前(Robert Brown)であり、ホワイトやピンクのように色で例えるならばレッドノイズである。なぜレッドなのか、それはトンネルで「遠くまで届きやすい光の色は何か?」を想像するとわかりやすいと思う。つまり、赤橙黄緑青藍紫の可視光線で考えれば、赤が一番周波数が低いためローパスフィルタの環境下では一番残りやすい光であるからだ。

ピンクノイズフィルタを電子回路で作ってみよう!

ピンクノイズフィルタの実験
ピンクノイズフィルタの実験

最後に、ピンクノイズフィルタを実際に電子回路で組んで実験してみよう。実際に使ったフィルタの定数は次の通り。手に入りやすい電子部品の値に少し変えてある。

項目
R110k
R23.3k
R3220
C10.1u
C20.033u

ホワイトノイズ発振器の作り方はこちらの記事を参考に。

アナログ回路のピンクノイズ周波数特性
アナログ回路のピンクノイズ周波数特性

Audacityのピンクノイズ周波数特性
Audacityのピンクノイズ周波数特性

Audacityで作ったピンクノイズと実験したフィルタ回路の周波数特性を比較してみた。伝達関数からシミュレーションしたグラフと曲線のゆらぎが似ているのがわかる。だいたい3dB/octで減衰しているようだ。さすがMoog!

また、今回実験したピンクノイズを録音してみたので、よかったら音の違いを聞き比べてみてほしい。アナログ回路のピンクノイズの高域がもう少し伸びればと思ったが、それでもなかなか良い結果が得られた。

モジュール化

1/fフィルタとホワイトノイズモジュール
1/fフィルタとホワイトノイズモジュール

ピンクノイズフィルタが成功したので、せっかくなのでモジュール化してみた。写真左がピンクノイズのパッシブフィルタモジュールで、右がホワイトノイズジェネレータモジュールである。

記事に関するご質問などがあればTwitterへお返事ください。
この記事で紹介した商品
関連記事