ピンクノイズ回路|ホワイトノイズとラグ・リードフィルタで作る
前回、ホワイトノイズを作ったが今度はピンクノイズを作ってみたい。ピンクノイズは、ホワイトノイズに何らかのローパスフィルタをかければ作れそうだ。しかし、ローパスフィルタは一般的に-6dB/octである。ピンクノイズの場合は-3dB/octで減衰させなければならない。ちなみに-3dB/octは「1/fゆらぎ」と呼ばれている。
どうやってピンクノイズを作るのか?
さて、どうやったらピンクノイズのフィルタ回路を実現できるだろうかと調べまくった。すると、このような回路図を見つけることができた。
ローパスフィルタに似た形だが、コンデンサと直列に抵抗が入っている。調べると、ラグ・リードフィルタ(lag/lead filter)回路と呼ぶらしい。ちなみに、抵抗1個とコンデンサ1個でつくられるRC回路はラグフィルタと呼ばれるようだ。
巷の回路の定数をそのまま使えばピンクノイズが作れそうだが、普段あまり使わない数値のために電子部品が手持ちになかった。もっと簡単に作れる方法はないだろうかと探し続けた。サクッとピンクノイズを作る予定だったが、実はこのプロジェクトを思い立ってから1週間以上の時間を費やしてしまっている。 ようやく、もっとも簡単なピンクノイズフィルタを見つけることができた。このことは、記事の最後で説明するとしよう。 また、ラグ・リードフィルタの仕組みも調べてみたかったので、この記事ではラグ・リードフィルタの伝達関数や周波数特性をシミュレーションしつつ、もっとも簡単なピンクノイズフィルタの作り方を紹介していく。
ホワイトノイズの作り方はこちら。
ラグ・リードフィルタの伝達関数
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()
プログラムの実行結果により、図のようなボード線図が書き出された。各グラフの線は、次のような定数に対応している。
線色 | R1 | R2 | C |
---|---|---|---|
青 | 6.8k | 3k | 1uF |
橙 | 6.8k | 1k | 267nF |
緑 | 6.8k | 300 | 94nF |
赤 | 6.8k | 0 | 33nF |
ラグリードフィルタの特徴として、位相が途中で元へ戻り、ゲインの減衰も途中で止まる。赤の線は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に搭載されているピンクノイズのフィルタ回路のようだ。すばらしい! 3.3Vノイズジェネレータ(3)-シンセ・アンプラグド
その後「minimoog circuit diagram」でググってみると、なんとminimoogの回路図が公開されていた。そして下のサイトの「minimoog schematics 09」に、minimoogらしきピンクノイズフィルタ回路が載っていた。 Mini moog Operation Manual, Mini moog Schematics, Mini moog Sound Charts
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()
シミュレーションの結果がこちら。比較しやすいようにRCローパスフィルタで作った-6dB/Octのブラウンノイズ(橙線)も表示させた。 シミュレーションしたピンクノイズフィルタは、キレイな直線とは言えないが、全体的で見れば-3dB/Oct(-10dB/dec)になっていることが確認できた。よって、可聴音域においては実用的なピンクノイズフィルタであると想像できる。 ちなみにブラウンは人の名前(Robert Brown)であり、ホワイトやピンクのように色で例えるならばレッドノイズである。なぜレッドなのか、それはトンネルで「遠くまで届きやすい光の色は何か?」を想像するとわかりやすいと思う。つまり、赤橙黄緑青藍紫の可視光線で考えれば、赤が一番周波数が低いためローパスフィルタの環境下では一番残りやすい光であるからだ。
ピンクノイズフィルタを電子回路で作ってみよう!
最後に、ピンクノイズフィルタを実際に電子回路で組んで実験してみよう。実際に使ったフィルタの定数は次の通り。手に入りやすい電子部品の値に少し変えてある。
項目 | 値 |
---|---|
R1 | 10k |
R2 | 3.3k |
R3 | 220 |
C1 | 0.1u |
C2 | 0.033u |
ホワイトノイズ発振器の作り方はこちらの記事を参考に。
Audacityで作ったピンクノイズと実験したフィルタ回路の周波数特性を比較してみた。伝達関数からシミュレーションしたグラフと曲線のゆらぎが似ているのがわかる。だいたい3dB/octで減衰しているようだ。さすがMoog!
また、今回実験したピンクノイズを録音してみた。アナログ回路のピンクノイズの高域がもう少し伸びればと思ったが、それでもなかなか良い結果が得られた。
ホワイトノイズ&ピンクノイズ発振器の回路図
ホワイトノイズとピンクノイズを発生させるノイズジェネレータを作ってみた。モジュラーシンセではRandom Signal Generatorなどとも呼ばれる。 写真は、モジュラーシンセに触発されて作ったノイズジェネレータのモジュラーエフェクターである。独自規格のラックにマウントできるようにしてみた。
ノイズジェネレータの制作にあたって、ホワイトノイズとピンクノイズは以前こちらの記事で制作したモジュールを使用している。
これらのモジュールにバッファー回路と、増幅回路を付け足して音量バランスを整えたものがこちらの回路だ。 聴覚上、ホワイトノイズとピンクノイズは同じような音量に聴こえるよう調整している。 回路図の一番左のトランジスタがノイズ発振源。つまりホワイトノイズを発生させる回路である。
トランジスタは2SC1815を使用。ただし、電源電圧が9Vだと、ギリギリノイズが発生するかしないかの境目。電池が消耗して電圧降下すると、多分ノイズが発生しなくなる。それもあって、12V電池を使用している。これなら間違いなくノイズを発振してくれる。 また、電源をスタンドアロンにすることで他のモジュラーエフェクタへの影響を少なくする意図もある。 ノイズ発振回路の後は、もう1つのトランジスタで信号を増幅させ、オペアンプのバッファー回路に繋いだ。非反転入力のところを見ると、バイアス抵抗も何もなく直で繋いでいるので「アレ?」っと思われるかもしれないが、バイアス抵抗があってもなくても出力に影響がなかったので取ってしまった。詳しい理由はわからないが、信号源がノイズだからこそなし得るワザなのかもしれない。
バッファー回路を通った後は、信号の一部を取り出してピンクノイズを作り出すフィルター回路に入る。10kΩの抵抗を介して、2つのラグリードフィルタ回路でフィルタリングされる。これにより、-3dB/octの擬似ピンクノイズが作れるのだ。 フィルタルングによって、ホワイトノイズに比べて聴覚上の音量がグンと下がってしまう。だから、オペアンプで7倍ほど増幅させてホワイトノイズとの音量バランスを整えた。 オペアンプには、TL072を使用した。
モジュール化
ピンクノイズフィルタが成功したので、せっかくなのでモジュール化してみた。写真左がピンクノイズのパッシブフィルタモジュールで、右がホワイトノイズジェネレータモジュールである。