ハンズオン教材 · Web Audio で鳴らしながら読む
リバーブの教科書
遅延線とオールパスから Beads のリバーブを組み立て、FDN と比べる
序
この本の読み方部品を 1 つずつ足しながら、耳と図で確かめる
部屋で手を 1 回叩くと、手を止めたあとも音がしばらく残ります。壁や床や天井で跳ね返った音が、少しずつ遅れて何千回も耳に届くからです。Mutable Instruments のモジュール Beads に入っているリバーブは、この「残る音」を、遅延線 10 本と、足し算と掛け算だけで作っています。コードは 200 行もありません。この本では、その中の部品を 1 つずつ取り出して順につないでいき、部品が 1 つ増えるたびに音がどう変わるかを、実際に鳴らして確かめます。
この本で答える問い
- 音を遅らせて足すだけだと、どう聞こえるのか。なぜそれだけでは響きにならないのか。
- 「どの周波数も同じ大きさで通す」はずのオールパスフィルターを通すと、なぜ音が変わって聞こえるのか。
- Beads はなぜ、ループの中の遅延の長さをゆっくり揺らしているのか。
- Beads の quality を切り替えると、なぜ部屋が広くなったように聞こえるのか。
この本の地図
第 2 章と第 5 章は、ほかの章より長めです。どちらも、式から思い浮かべる音と、実際に聞こえる音が食い違うところを扱っているからです。
前提にすること
プログラムで音を扱ったことがあり、「サンプル」と「サンプリング周波数」がわかっていれば読めます。式は出てきますが、どの節も先に言葉と実験で説明し、式はそのあとに置きます。長い計算は「式で確かめる」という折りたたみに入れてあるので、読み飛ばしても先に進めます。
この本で使う言葉
何度も出てくる言葉を、ここでまとめて説明しておきます。いまは全部わからなくても大丈夫です。出てきたときに戻ってきてください。
サンプルと遅延
この本の実験は、1 秒に 48000 個の数 (サンプル) で音を表しています。この 48000 をサンプリング周波数と呼び、$f_s$ と書きます。1 サンプルは 1/48000 秒、約 0.02 ms です。「480 サンプル遅らせる」は「10 ms 遅らせる」と同じことです。音の $n$ 番目のサンプルを $x[n]$ と書き、$x[n-D]$ は「$D$ サンプル前の値」を意味します。
dB (デシベル)
音の大きさの比を、掛け算ではなく足し算で扱えるようにした目盛りです。振幅が 2 倍なら +6 dB、10 倍なら +20 dB、1/1000 なら −60 dB です。「−60 dB まで下がる」は「振幅が 1000 分の 1 になる」という意味で、残響の長さを測るときの基準になります (第 1 章)。
インパルス応答
「パチッ」という 1 サンプルだけの短い音 (インパルス) を入れたときに出てくる音です。部屋で手を 1 回叩いて録音したものが、その部屋のインパルス応答にあたります。遅延と足し算と掛け算でできた処理なら、インパルス応答がわかれば、どんな音を入れたときの出力も決まります。そのため、この本の図の多くはインパルス応答から描いています。
周波数特性
どの高さの音 (周波数) が、どれだけ強められたり弱められたりするかを表したグラフです。横軸が周波数、縦軸が dB です。0 dB の水平線なら、どの高さも同じ大きさで通ることを意味します。インパルス応答をフーリエ変換すると、この周波数特性が得られます。
位相
波の山がどれだけずれているかを表す量です。同じ高さの音でも、遅れて届けば位相がずれます。位相のずれ方が周波数によって違うと、高い音と低い音が違う時刻に届くことになります。第 2 章でこれが大事になります。
伝達関数
処理の中身を、1 つの式にまとめたものです。この本では「$D$ サンプル遅らせる」を $z^{-D}$ と書きます。すると、遅延と足し算と掛け算でできた処理は、どれも「入力に $H(z)$ を掛けると出力になる」と書けます。この $H(z)$ が伝達関数です。$z$ の代わりに、ある周波数を表す数 ($e^{j\omega}$、$\omega=2\pi f/f_s$) を入れると、その周波数の音が何倍になって出てくるか (周波数特性) と、どれだけずれるか (位相) が計算できます。
式で確かめる: 伝達関数の作り方
例として「入力と、それを $D$ サンプル遅らせたものを足す」処理 $y[n]=x[n]+x[n-D]$ を考えます。$x[n-D]$ を $z^{-D}X$ と書くと、$Y=X+z^{-D}X=(1+z^{-D})X$ なので、伝達関数は $H(z)=1+z^{-D}$ です。$z=e^{j\omega}$ を入れた $|1+e^{-j\omega D}|$ が振幅の倍率で、これが 0 になる周波数ではその音が消えます (第 1 章の図 1.2)。
ここで使った書き換えが成り立つのは、係数が時間で変わらない処理だけです。第 5 章で遅延の長さを揺らすと、厳密には伝達関数で書けなくなります。
実験パネルの使い方
各章に「実験」と書いた枠があります。▶ 再生を押すと、選んだ音がその章の部品を通って鳴ります。入力は 7 種類あります。
| 入力 | 中身 | こんなときに |
|---|---|---|
| クリック | 「パチッ」というごく短い音を、一定の間隔で繰り返す | インパルス応答そのものを聞きたいとき |
| 手拍子 | 手を叩いた音に似せて作った短い雑音 | 部屋で手を叩いたときと比べたいとき |
| ドラム | キック・スネア・ハイハットを合成した 2 小節のループ | 音楽にかけたときの響き方を聞きたいとき |
| 声 (合成) | 「あいうえお」を合成したもの | 音程のある音で、響きの色付きを聞きたいとき |
| 弦 (合成) | はじいた弦の音で短い旋律を弾いたもの | 第 5 章の共鳴やコーラスを聞きたいとき |
| マイク | パソコンのマイクの音 | 自分の声や手拍子を通したいとき (ヘッドフォンを使う) |
| ファイル | 手元の音声ファイル | 好きな素材で試したいとき |
つまみを動かすと、音と下の図が同時に変わります。図は音を鳴らしていなくても動きます。画面の右下の小さな枠で、全体の音量を下げたり、音を止めたりできます。戻し量を大きくする実験では音が長く大きく残るので、最初は音量を下げておいてください。
ノートパソコンの内蔵スピーカーは、200 Hz より低い音がほとんど出ません。第 5 章と第 6 章はヘッドフォンで聞くことをすすめます。
図の読み方
- インパルス応答: 横が時間、縦が振幅です。「パチッ」を入れたあと、いつ、どれくらいの大きさの音が出てくるかを見ます。
- 周波数特性 (振幅特性): 横が周波数 (右に行くほど高い音、目盛りは対数)、縦が dB です。どの高さの音が強くなり、どの高さが弱くなるかを見ます。
- スペクトログラム: 横が時間、縦が周波数で、色が濃いほどその時刻のその高さの音が強いことを表します。響きの音色が時間とともにどう変わるかを見ます。
第 4 章からは、残響の長さを測るための 4 つ目の図 (エネルギー減衰曲線) が加わります。
第1章
遅延とフィードバック反射 1 回と、同じ間隔で続くエコー
壁に向かって手を叩くと、少し遅れて音が返ってきます。この「返り」を 1 回だけ作る部品が遅延線です。遅延線から出た音をもう一度遅延線に戻すと、返りが何度も繰り返されて、山びこのようなエコーになります。この章ではこの二つを鳴らして、どちらもまだ「響き」には聞こえないことを確かめます。また、エコーの間隔を短くしていくと、エコーが音程のある音に変わることも聞きます。
1.1 遅延線は「返り 1 回」
遅延線は、入ってきた音を覚えておいて、決まった時間あとに出すだけの部品です。中身は配列が 1 つと、書き込む位置を 1 つずつ進める番号だけです。遅らせる長さを $D$ サンプルとすると、出力は
$$ y[n]=x[n-D] $$で、「$D$ サンプル前の入力」がそのまま出てきます。元の音 (原音) と足し合わせると、手を叩いた音と、壁からの返りが 1 回だけ聞こえる状態になります。
1.2 出口の音を入口に戻す
図 1.1 のように、遅延線から出てきた音を $g$ 倍して、入口に戻します。$g$ を「戻し量」と呼びます。戻した音はもう一度 $D$ サンプル遅れて出てきて、また $g$ 倍されて戻ります。パチッを 1 回入れると、出力はこうなります。
- $D$ サンプル後に、大きさ 1 の音
- $2D$ サンプル後に、大きさ $g$ の音
- $3D$ サンプル後に、大きさ $g^2$ の音
- …と、同じ間隔で、$g$ 倍ずつ小さくなりながら続く
$g=0.5$ なら 1, 0.5, 0.25, 0.125, … と半分ずつになっていきます。この部品をフィードバックコムフィルター (以下「コム」) と呼びます。名前の理由は 1.4 節でわかります。
式で確かめる: コムの式と伝達関数
遅延線に書き込む音を $v[n]$ とすると、$v[n]=x[n]+g\,v[n-D]$、出力は $v[n-D]$ です。$z$ で書くと $V=X+gz^{-D}V$ なので $V=X/(1-gz^{-D})$、伝達関数は
$$ H(z)=\frac{z^{-D}}{1-g\,z^{-D}} $$です。$1/(1-gz^{-D})=1+gz^{-D}+g^2z^{-2D}+\cdots$ と展開すると、上の「1, g, g², …」がそのまま係数として出てきます。
上の実験で、まず戻し量を 0、遅延を 120 ms くらいにして、手拍子を鳴らしてみてください。返ってくる音が 1 回、はっきり分かれて聞こえます。部屋の響きには聞こえません。次に戻し量を 0.6 くらいまで上げると、山びこのようなエコーが同じ間隔で続きます。こちらも、エコーの 1 つ 1 つを聞き分けられます。
1.3 どれくらい続くか
エコーは 1 回返るごとに $g$ 倍になります。振幅が 1000 分の 1 (−60 dB) になるまでに何回返るかを数えれば、エコーが聞こえなくなるまでの時間がわかります。この「−60 dB まで下がる時間」を残響時間と呼び、$T_{60}$ と書きます。
0.8 を何回掛けると 0.001 になるかを数えると、約 31 回です。1 回に 30 ms かかるので、$T_{60}$ は 31 × 30 ms で約 0.93 秒になります。実験で遅延を 30 ms、戻し量を 0.8 にすると、「T60 (式)」に同じ値が出ます。
「何回掛けると 0.001 になるか」は、式で書くと次のようになります。この式は第 4 章と第 7 章でも使います。
$$ T_{60}=\frac{3}{-\log_{10}|g|}\times\frac{D}{f_s} $$左の分数が「返る回数」、右の分数が「1 回にかかる秒数」です。
1.4 間隔を短くすると音程になる
戻し量を 0.8 にしたまま、遅延を 10 ms より短くしていきます。クリックを入れると、エコーの粒が聞き分けられなくなり、「ビーン」という金属的な音程が聞こえてきます。5 ms なら 200 Hz、2 ms なら 500 Hz の音です。同じ形の音が 5 ms ごとに繰り返されれば、それは 1 秒に 200 回振動する音、つまり 200 Hz の音と同じだからです。
周波数特性の図を見ると、同じことが周波数の側から見えます。200 Hz, 400 Hz, 600 Hz, … のところに鋭い山が、その間に谷が、同じ間隔で並びます。この形が櫛 (comb) の歯に見えるので、コムフィルターと呼びます。$g=0.8$ のとき、山は谷より 19 dB (約 9 倍) 高くなります。
遅延が長いと、歯の間隔が狭すぎて耳は音程として聞き取れず、時間方向に分かれたエコーとして聞きます。遅延が短いと歯の間隔が広くなり、音色の変化や音程として聞こえます。同じ部品でも、遅延の長さによって「エコー」にも「音色」にも聞こえるわけです。
式で確かめる: 山と谷の位置と高さ
$z=e^{j\omega}$ を入れると $|H|=1/|1-ge^{-j\omega D}|$ です。分母は $\omega D$ が $2\pi$ の整数倍のときに最小の $1-g$、奇数倍の $\pi$ のときに最大の $1+g$ になります ($g>0$)。周波数でいうと $f=k\,f_s/D$ に高さ $1/(1-g)$ の山、その真ん中に高さ $1/(1+g)$ の谷が並びます。山と谷の比は $(1+g)/(1-g)$ で、$g=0.8$ なら $1.8/0.2=9$ 倍 (19.1 dB) です。
戻し量が 0 でも、原音と足せば櫛の歯ができます (図 1.2)。1 ms 遅れた音と足すと、500 Hz の音は半周期ずれて重なるので、山と谷が打ち消し合って消えます。1500 Hz, 2500 Hz, … も同じです。実験で戻し量を 0、遅延を 1〜20 ms にして「原音も出す」を入れると、エコーではなく、こもったような音色の変化に聞こえます。フランジャーはこの仕組みを使っています。
戻し量をマイナスにすると、返ってくる音の符号が 1 回ごとに反転します。同じ形に戻るまでに 2 回かかるので、聞こえる音程は 1 オクターブ下がります。実験で −0.8 を試してみてください。
1.5 なぜまだ響きに聞こえないのか
本物の部屋と比べると、足りないものが二つあります。
一つは返ってくる音の数です。部屋では、音は壁に当たるたびに別々の向きに跳ね返り、経路がどんどん枝分かれします。時間がたつほど、届く反射の数が増えていきます。体積 200 m³ くらいの部屋なら、手を叩いて 0.1 秒後には 1 ms あたり約 25 個、0.2 秒後には約 100 個の反射が届きます (届く数は経過時間の 2 乗に比例して増えます)。コムでは、何秒たっても $D$ ごとに 1 個のままです。
もう一つは周波数の並び方です。コムの山は等間隔に並ぶので、耳は 1 つの音程として聞いてしまいます。部屋の共鳴は不規則な間隔で、高い音ほど密に並んでいます。
つまり、返ってくる音を時間とともに増やし、しかも櫛の歯を作らない部品が必要です。それが次の章のオールパスです。
M. R. Schroeder は 1962 年の論文 “Natural Sounding Artificial Reverberation” で、長さの違うコムを 4 本並べ、その後ろにオールパスを 2 段つなぐ構成を示しました。4 本の遅延を互いに割り切れない長さにすると、それぞれの櫛の歯がずれて重なり、特定の音程が目立たなくなります。この構成が、デジタルリバーブの出発点になりました。第 7 章の FDN で「行列を単位行列にする」と、ちょうどこの並べたコムと同じ形になります。
- 遅延線 1 本は返り 1 回。出口を入口に戻すと、同じ間隔のエコーになる。
- エコーの間隔が短いと、間隔の逆数の音程 (櫛の歯) として聞こえる。
- エコーの数が時間とともに増えないので、まだ響きには聞こえない。
練習問題 1
- 遅延 10 ms (480 サンプル)、戻し量 0.5 のコムで、周波数特性の山と谷はどの周波数にあり、それぞれ何 dB か。
- 戻し量 0.9、遅延 50 ms のコムの残響時間 $T_{60}$ を求めよ。
- 戻し量をマイナスにすると音程が 1 オクターブ下がる理由を、インパルス応答の形から説明せよ。
第2章
オールパス音色を変えずに、音を時間方向にばらまく
前の章のコムは、エコーを繰り返すと同時に、音色に櫛の歯を刻んでしまいました。エコーは増やしたいけれど、櫛の歯は要りません。この二つを両立させる部品がオールパスフィルターです。名前のとおり、どの高さの音も同じ大きさで「全部通す (all-pass)」部品です。ところが、実際に鳴らしてみると、オールパスを通した音ははっきり変わって聞こえることがあります。この章では、その食い違いがどこから来るのかを、遅延の長さを 1 サンプルから少しずつ伸ばしながら確かめていきます。
2.1 コムに 1 本の配線を足す
オールパスは、コムに配線を 1 本足しただけの部品です (図 2.1)。下半分はコムとまったく同じで、出口の音を $g$ 倍して入口に戻しています。足したのは上のオレンジの配線で、遅延線の入口の音を $-g$ 倍して、そのまま出力に足しています。
Beads のコードでは、オールパス 1 段がこの 2 行です。
c.Read(ap1 TAIL, kap); // 遅延の出口の音を kap 倍して足す (下の戻り)
c.WriteAllPass(ap1, -kap); // それを遅延の入口に書き、-kap 倍して、出口の音を足す (上の配線)kap が図の $g$ で、Beads では 0.625 です。acc という変数に途中の計算をためながら、図 2.1 を左から順に計算しています。
式で確かめる: オールパスの式と伝達関数
遅延線に書き込む音を $v[n]$ とすると
$$ v[n]=x[n]+g\,v[n-D],\qquad y[n]=-g\,v[n]+v[n-D] $$前半がコムと同じ部分、後半の $-g\,v[n]$ がオレンジの配線です。$V=X/(1-gz^{-D})$ と $Y=(-g+z^{-D})V$ から、伝達関数は
$$ H(z)=\frac{-g+z^{-D}}{1-g\,z^{-D}} $$になります。本によっては $(g+z^{-D})/(1+gz^{-D})$ と符号を逆にして書きますが、$g$ を $-g$ に置き換えただけで、どちらもオールパスです。
Beads の遅延線は Reserve<150> のように長さを宣言し、最後の位置 (TAIL) から読みます。そのため Reserve<150> の遅延は 150 ではなく 149 サンプルになります。この本では実際の遅延 (149, 213, 318, 526, …) で書きます。
2.2 本当に「全部通す」のか
オールパスの周波数特性は、どの周波数でもぴったり 0 dB (1 倍) になります。強められる音も弱められる音もありません。変わるのは、周波数ごとの届く時刻 (位相) だけです。
式で確かめる: どの周波数でも 1 倍になる理由
$|g|<1$ のとき、$H(z)=(-g+z^{-D})/(1-gz^{-D})$ はすべての $\omega$ で $|H(e^{j\omega})|=1$ を満たす。
$\theta=\omega D$ とおくと、分子は $-g+e^{-j\theta}=e^{-j\theta}(1-ge^{j\theta})$ と書き直せます。$|e^{-j\theta}|=1$ なので、分子の大きさは $|1-ge^{j\theta}|$ です。これは分母 $1-ge^{-j\theta}$ の複素共役 (虚部の符号を反転したもの) なので、大きさが分母と同じです。分子と分母の大きさが等しいので、比は 1 になります。∎
2.3 パチッを入れると何が出てくるか
オールパスにパチッを 1 回入れると、出力はこうなります ($g=0.625$ の場合)。
- すぐに、符号が逆の小さな音 (−0.625)。オレンジの配線を通った音です。
- $D$ サンプル後に 0.609、$2D$ 後に 0.381、$3D$ 後に 0.238、…と、$g$ 倍ずつ小さくなる音の列。下の戻りを通った音です。
後ろの列はコムのインパルス応答とほとんど同じ形です。違うのは、先頭に符号の逆の音が 1 つ付いていることだけです。この先頭の 1 つが、あとに続く列と組み合わさって、櫛の歯の山と谷をちょうど打ち消し、周波数特性を平らにしています。
式で確かめる: インパルス応答とエネルギー
$1/(1-gz^{-D})$ を等比級数に展開して $(-g+z^{-D})$ を掛けると
$$ h[0]=-g,\qquad h[kD]=(1-g^2)\,g^{k-1}\quad(k\ge1) $$になります。2 乗の和 (エネルギー) は $g^2+(1-g^2)^2/(1-g^2)=1$ で、入ったエネルギーがそのまま出てきます。$g=0.625$, $D=4$ で計算すると $h[0]=-0.625$, $h[4]=0.609$, $h[8]=0.381$, $h[12]=0.238$ となり、この本の DSP コードの出力と一致します。
下の実験では、コムのほうも音量を調整して、オールパスとエネルギー (音の量の合計) をそろえてあります。切り替えたとき、音量の違いではなく音の形の違いが聞こえるようにするためです。
2.4 聞き比べ: 平らなはずなのに音が変わる
上の実験で、入力をクリックにして、遅延 D を次の順に変えてみてください。オールパスとコムを切り替えながら聞くと違いがわかりやすくなります。
- D = 1〜30 サンプル: オールパスにすると、元のクリックとほとんど区別がつきません。コムにすると、高い音が強くなったり削れたりして音色が変わります。
- D = 100〜300 サンプル (2〜6 ms): オールパスでも「ビッ」という音程のある音が聞こえます。コムに切り替えても、音程も余韻の長さもほとんど同じです。
- D = 500〜900 サンプル (10〜19 ms): どちらも「ブルル」という粗いうなりに聞こえ、粒が聞こえはじめます。
- D = 2000 サンプル (約 42 ms): どちらも、1 つずつ分かれたエコーに聞こえます。
2 番と 3 番では、どの周波数も 1 倍で通すはずのオールパスから、コムとそっくりの音程が聞こえます。図を見ると、黒い線 (応答全体から計算した周波数特性) はたしかに 0 dB でまっすぐです。ところがオレンジの線 (応答の最初の 10 ms だけから計算した周波数特性) は、D = 30 では平らなのに、D = 300 では大きく波打っています。
耳は「少しずつ区切って」聞いている
「どの周波数も 1 倍」というのは、インパルス応答を最初から最後まで全部まとめて見たときの話です。2.3 節で見たように、先頭の音とあとに続く列が打ち消し合って平らになるのは、列が最後まで出そろってからです。
ところが耳は、音を最後まで待ってからまとめて聞くわけではありません。数 ms から数十 ms くらいの短い区間ごとに、「いまどんな音色か」を聞いています。この区間の長さを、この本では「耳の窓」と呼ぶことにします。実験パネルでは耳の窓を 5〜50 ms で変えられ、最初は 10 ms にしてあります。
耳の窓の中に、オールパスの応答がどこまで入るかで、聞こえ方が変わります。
- D が短いとき: 応答の列がほとんど全部、1 つの窓の中に入ります。窓の中で打ち消し合いが完成するので、音色は変わりません。ずれるのは位相だけで、耳にはほとんどわかりません。
- D が窓の 1/5 から窓と同じくらいのとき: 窓の中には、先頭の音と、そのあとの 1〜4 本しか入りません。打ち消し合いが途中までしか進んでいないので、窓の中ではコムと同じ櫛の歯が見えます。耳はこれを音程やうなりとして聞きます。先頭の音 (0.625) と次の音 (0.609) はほぼ同じ大きさなので、窓に 2 本しか入らないときは特に深い櫛の歯になります (図では最大 38 dB)。
- D が窓より長いとき: 窓の中には、いつも 1 本ずつしか入りません。どの窓で見ても音色は元のままですが、時間方向に分かれているので、エコーとして聞こえます。
実験パネルの 4 枚目の図は、遅延 D を 1 から 2400 まで動かしたときに、耳の窓の中で周波数特性がどれだけ波打つかを描いたものです。窓が 10 ms (480 サンプル) なら、D が 100 サンプルを越えたあたりから波打ちはじめ、250〜480 サンプルで最大になり、480 サンプルを越えると 0 に戻ります。上の三つの段階がそのまま見えます。「耳の窓」のつまみを動かすと、この山が左右に動きます。
耳の時間の細かさは、音の高さや種類によって変わるので、境目は 1 本の線ではなく幅のある帯です。それでも、「応答の長さが数 ms を越えると、オールパスにも音色が付いて聞こえはじめ、数十 ms を越えるとエコーとして分かれて聞こえる」という傾向は変わりません。
式で確かめる: 窓の中の本数と、波打ちの大きさ
先頭の音と、そのあと $K$ 本だけを残して打ち切った応答の周波数特性 $|H_K|$ は、次の範囲に入ります ($0<g<1$)。
$$ 1-(1+g)g^K\ \le\ |H_K(e^{j\omega})|\ \le\ 1+(1+g)g^K $$打ち切った残り (尾) は等比級数の和として $(1-g^2)g^Ke^{-j(K+1)\theta}/(1-ge^{-j\theta})$ と書けます。分母の大きさは $1-g$ と $1+g$ の間にあるので、尾の大きさは $(1+g)g^K$ 以下です。$H_K=H-(\text{尾})$ で $|H|=1$ なので、上の範囲に入ります。
$g=0.625$ で計算すると、波打ちの幅は $K=2$ で最大 13.0 dB、$K=3$ で 7.3 dB、$K=4$ で 4.4 dB、$K=5$ で 2.7 dB、$K=7$ で 1.1 dB です。窓の中にパルスが 5 本くらい入っていれば、波打ちは 3 dB 以下に収まります。「D が窓の 1/5 より短ければ平ら」という目安は、ここから来ています。
リバーブがオールパスに求めるのは、2 番目の段階 (音程が聞こえてしまう領域) を避けながら、返ってくる音を増やすことです。そのために第 3 章では、短めのオールパスを何段も重ねて、窓の中の音の数を一気に増やします。
2.5 周波数ごとの「届く時刻」
オールパスが変えるのは、周波数ごとの届く時刻だけでした。どの周波数がどれだけ遅れて届くかを表したものを群遅延と呼びます。実験パネルの 3 枚目の図がこれで、単位はサンプルです。
$g=0.625$ のオールパスでは、いちばん遅れる周波数は D の 4.33 倍、いちばん早い周波数は D の 0.23 倍の時間で届きます。D を変えながら図を見ると、次のことがわかります。
- D = 1: 低い音が約 4 サンプル、高い音が約 0.2 サンプル遅れるだけです。どれも 0.1 ms 未満なので、時間のずれとしては聞こえません。こういう短いオールパスは、位相をそろえたり、1 サンプルより細かい遅延を作ったりするのに使われます。
- D が大きいとき: 群遅延のグラフが細かく激しく上下します。隣り合う周波数どうしが、0.23D と 4.33D という大きく違う時刻に届きます。周波数ごとに届く時刻がばらばらになること、これが「時間方向にばらまく」ということの中身です。
式で確かめる: 群遅延の式
位相を $\phi(\omega)=\arg H(e^{j\omega})$ とすると、群遅延は $\tau(\omega)=-d\phi/d\omega$ です。オールパスでは
$$ \tau(\omega)=\frac{D\,(1-g^2)}{1-2g\cos(\omega D)+g^2} $$となります (練習問題 2.3)。$\cos(\omega D)=1$ のとき最大の $D(1+g)/(1-g)$、$-1$ のとき最小の $D(1-g)/(1+g)$ をとり、$g=0.625$ では $4.33D$ と $0.23D$ です。
2.6 原音と混ぜると平らでなくなる
実験の「原音と半分ずつ混ぜる」を入れると、オールパスでも周波数特性に谷ができます。オールパスを通った音は周波数ごとに位相がずれているので、ちょうど半周期ずれた周波数では、原音と打ち消し合って消えるからです。リバーブの中では、オールパスの出力を原音と混ぜずに、そのまま次の部品に渡すことで、平らな特性を守っています。逆にこの性質を利用して、オールパスを通した音を原音と混ぜ、係数をゆっくり動かして谷を動かすのがフェイザーです。
2.7 コムとオールパスの違い
| コム | オールパス | |
|---|---|---|
| パチッを入れると | D ごとの音の列 | 符号の逆の音 1 つのあとに、D ごとの音の列 |
| 減り方 | 1 回ごとに g 倍 | 1 回ごとに g 倍 (同じ) |
| 応答全体の周波数特性 | 櫛の歯 | 平ら |
| D が短いと | 音色が変わる | 元の音とほとんど同じ |
| D が長いと | 音程、エコー | 音程、エコー (コムとほぼ同じ) |
1 段だけを長い遅延で聞く限り、オールパスとコムの違いは小さく見えます。違いがはっきりするのは、何段もつないだときです。コムをつなぐと櫛の歯の山どうしが掛け合わされ、特定の音程だけが極端に強くなります。オールパスは何段つないでも平らなままで、返ってくる音の数だけが増えていきます。次の章で、これを確かめます。
- オールパスは、どの周波数も 1 倍で通し、周波数ごとの届く時刻だけを変える。
- 耳は短い区間ごとに聞くので、応答が数 ms より長いと、オールパスにも音程が付いて聞こえる。
- D が短いうちは「位相をずらすだけのフィルター」、長くなると「音を時間方向にばらまく部品」として働く。
練習問題 2
- $g=0.5$ のオールパスのインパルス応答 $h[0], h[D], h[2D], h[3D]$ を求め、2 乗の和が 1 に近づくことを確かめよ。
- Beads の最初のオールパス ($D=149$, $g=0.625$) で、いちばん遅れる周波数といちばん早い周波数の群遅延を、サンプルと ms で求めよ。
- 群遅延の式 $\tau(\omega)=D(1-g^2)/(1-2g\cos\omega D+g^2)$ を導け。ヒント: $\phi(\omega)=\arg(-g+e^{-j\theta})-\arg(1-ge^{-j\theta})$ ($\theta=\omega D$) と分けて考える。
- オールパスと原音を半分ずつ混ぜたとき、音が消える周波数を求めよ。
第3章
拡散器オールパスを何段もつないで、返ってくる音を一気に増やす
オールパス 1 段にパチッを入れると、同じ間隔の音の列が出てきました。この列を、長さの違う 2 段目のオールパスに通すと、列の中の音 1 つ 1 つが、それぞれ新しい列に広がります。段を足すたびに、返ってくる音の数は掛け算で増えていきます。しかも、何段つないでも周波数特性は平らなままです。Beads は、入力の直後にオールパスを 4 段並べて、音をループに入れる前に細かくばらまいています。この 4 段を拡散器 (ディフューザー) と呼びます。
3.1 つないでも平らなまま
部品を順につなぐと、全体の倍率は各段の倍率の掛け算になります。オールパスはどの周波数でも 1 倍なので、何段つないでも 1 × 1 × 1 × 1 = 1 倍です。コムをつなぐと、各段の櫛の歯の山が掛け合わされて、特定の音程だけが極端に強くなります。オールパスではそれが起きません。
3.2 音の数はどう増えるか
小さな例で考えます。遅延 3 サンプルと 5 サンプルのオールパスを順につなぎ、パチッを入れます。
- 1 段目からは、0, 3, 6, 9, … サンプル目に音が出ます。
- 2 段目は、そのそれぞれを 0, 5, 10, … サンプルずらした列に広げます。
- 結果として、「3 の倍数 + 5 の倍数」の時刻すべてに音が出ます。0, 3, 5, 6, 8, 9, 10, 11, … です。
段を足すたびに、足し合わせる倍数の種類が 1 つ増えます。1 段なら時間に比例して、2 段なら時間の 2 乗に比例して、4 段なら時間の 4 乗に比例して、音の数が増えます。実際には、何度も $g$ を掛けられた音は小さくなるので、耳に届く大きさの音の数はこれより少なくなります。
次の実験では、最初の 100 ms の中で、いちばん大きい音から −40 dB (100 分の 1) より大きいサンプルの数を数えます。
Beads の長さで段を 0 から 4 まで足していくと、数は 1 → 11 → 76 → 416 → 1812 と増えます。1 段足すごとにおよそ 4〜7 倍です。クリックを入れて聞くと、1 段では「ビッ」という音程のある音、2 段では粗いざらつき、3〜4 段では「シュッ」という短い雑音のような音に変わっていきます。
3.3 割り切れる長さを選ぶと
実験の「長さ」を「割り切れる (120, 240, 360, 480)」に切り替えてみてください。4 つの遅延がすべて 120 の倍数なので、どの経路を通っても、音が届く時刻は 120 の倍数になります。100 ms (4800 サンプル) の中にある 120 の倍数は 40 個しかないので、何段足しても音の数は 40 個を越えません。実験では 11 → 23 → 39 → 39 と、3 段目で止まります。経路の数は増えているのに、違う経路の音が同じ時刻に重なってしまうのです。
聞いてみると、Beads の長さでは雑音のようだった 4 段の出力が、120 サンプルごとに繰り返す音、つまり 400 Hz のブザーのような音になります。ばらまいたつもりが、きれいに並んだ音の列を作ってしまっています。
遅延の長さは、互いに割り切れない数、できれば共通の約数がない数を選びます。Beads の 149, 213, 318, 526 は、149 が素数、213 = 3 × 71、318 = 2 × 3 × 53、526 = 2 × 263 です。2 つずつの最大公約数は 1, 2, 3 にとどまっています。
3.4 係数 g を変えると
$g$ を 0 にすると、オールパスはただの遅延になり、何段通しても音は 1 つのままです。$g$ を大きくすると、1 段ごとの列が長く続くので、音の数は増えます。ただし 1 段ごとの応答が長くなるので、第 2 章で見た「音程が聞こえてしまう」領域に入りやすくなります。Beads は 4 段とも $g=0.625$ にしています。Dattorro の 1997 年の論文に載っている構成例では、0.75 を 2 段、0.625 を 2 段使っています。
3.5 拡散器だけでは響きにならない
4 段の拡散器の応答は、長くても 100 ms くらいで消えます。どれだけ細かくばらまいても、拡散器にできるのは「短くばらまく」ことだけで、1 秒、2 秒と残る響きは作れません。長く残すには、音をループの中で回し続ける必要があります。次の章で、拡散器の出力をループに入れます。
- オールパスを順につなぐと、周波数特性は平らなまま、返ってくる音の数が段ごとに掛け算で増える。
- 遅延の長さに大きな公約数があると、音が同じ時刻に重なってしまい、数が増えない。
- 拡散器は短くばらまくだけで、長い響きは作れない。
練習問題 3
- オールパスを何段つないでも周波数特性が 1 倍のままであることを説明せよ。
- 遅延 3 サンプルと 5 サンプルのオールパスをつないだとき、時刻 15 までに音が届く時刻をすべて挙げよ。(1 段目の回数, 2 段目の回数) の組はいくつあり、届く時刻は何種類あるか。
- 4 段の遅延がすべて $m$ の倍数なら、音が届く時刻もすべて $m$ の倍数になることを示せ。$m=120$ ($f_s=48$ kHz) のとき、聞こえる音程は何 Hz か。
第4章
タンクループで回して残響を伸ばし、2 本をたすき掛けにして左右に広げる
拡散器で細かくばらまいた音を、今度はループの中で回し続けます。1 周するたびに少しだけ音量を下げれば (戻し量 krt を掛ければ)、第 1 章のコムと同じように、響きは少しずつ小さくなりながら長く残ります。ループの中にもオールパスを 2 段入れて、回るたびにさらにばらまきます。Dattorro の論文では、このループを「タンク」と呼んでいます。この章では、まずループ 1 本で残響の長さを測り、次にループの中にローパスを入れて響きを暗くし、最後にループを 2 本にして左右に広げます。
4.1 ループ 1 本
Beads のタンクの片側には、次の順に部品が並んでいます。
- 拡散器から来た音に、ループを 1 周してきた音を krt 倍して足す
- ローパス (高い音を少し削るフィルター) を通す
- オールパスを 2 段通す (遅延 2181 と 2689)
- 長い遅延線に入れて、4460 サンプル後に 1. に戻す
1 周の遅延を足すと 2181 + 2689 + 4460 = 9330 サンプル、約 194 ms です。
残響の長さの測り方
リバーブの応答は、細かい音がぎっしり詰まった雑音のような波形です。波形を見て「ここで −60 dB になった」と読むのは難しいので、次のように測ります。
- 各時刻について、「その時刻より後に残っている音のエネルギーの合計」を計算する。
- それを dB にしてグラフに描く。これをエネルギー減衰曲線と呼ぶ (Schroeder が 1965 年に示した方法)。
- 後ろから足し合わせるので細かいギザギザがならされ、なめらかな右下がりの線になる。この線が −60 dB に届く時刻が $T_{60}$。
実際には −60 dB まで測るのは難しいので、この本では曲線が −5 dB から −25 dB まで下がる部分に直線を引き、その傾きを −60 dB まで伸ばして $T_{60}$ としています。
「1 本のループ」で、戻し量 krt を 0.3, 0.5, 0.7 と上げていくと、残響が長くなります。ローパスを効かせない (係数 1) とき、測った $T_{60}$ は krt = 0.5 で約 3.0 秒、krt = 0.7 で約 5.6 秒です。
計算と測定がずれる
第 1 章の式に、戻し量 0.5、1 周 9330 サンプルを入れると、$T_{60}$ は 1.94 秒になります。測った値 (3.0 秒) より 1.5 倍ほど短い値です。
原因は、ループの中のオールパスです。第 2 章で見たように、オールパスを通る時間は周波数によって違い、短い周波数では D の 0.23 倍、長い周波数では 4.33 倍かかります。そのため、ループを 1 周する時間も周波数によって違い、約 5600 サンプルから約 25600 サンプルまでの幅があります。1 周に時間がかかる周波数ほど、1 秒あたりに krt を掛けられる回数が少ないので、ゆっくり小さくなります。響きの後半はこのゆっくり減る成分が占めるので、測った値は単純な計算より長くなります。
実験の「ループの中のオールパス」を外すと、ループはただの遅延 (9330 サンプル) になり、krt = 0.5 で測った $T_{60}$ は約 2.0 秒と、計算に近くなります。そのかわり、第 1 章と同じ等間隔のエコーに戻ってしまいます。
4.2 ループの中のローパス
Beads は、ループの入口にローパスを 1 つ置いています。コードでは 1 行だけです。
c.Lp(lp_1_, klp); // state += klp * (acc - state); acc = state;「前回の出力を、今回の入力のほうへ klp の割合だけ近づける」という計算です。klp が 1 なら入力をそのまま通し、小さいほど急な変化 (高い音) についていけなくなって、高い音が削られます。klp = 0.7 なら約 10.6 kHz から、Beads の digital の値 0.6 なら約 7.6 kHz から上が弱くなります。
1 回通るだけなら、高い音が少し削れるだけです。でもこのローパスはループの中にあるので、響きは 1 周するたびに通ります。10 周すれば 10 回削られます。そのため高い音ほど早く消え、響きは時間とともに暗くなっていきます。実験でローパス係数を 0.3 くらいまで下げてスペクトログラムを見ると、上のほうの色が先に消えて、低い音だけが長く残ります。本物の部屋でも、空気や壁が高い音を多く吸うので、同じことが起きます。
式で確かめる: ローパスの −3 dB の周波数
$y[n]=y[n-1]+k(x[n]-y[n-1])$ の伝達関数は $H(z)=k/(1-pz^{-1})$ ($p=1-k$) です。振幅の 2 乗は $k^2/(1-2p\cos\omega+p^2)$ なので、これが $1/2$ になる周波数 $f_c$ は
$$ \cos\!\left(\frac{2\pi f_c}{f_s}\right)=\frac{1+p^2-2k^2}{2p} $$から求まります (練習問題 4.2)。
4.3 ループを 2 本にして左右に分ける
ループ 1 本の音を左右の両方に出すと、左右がまったく同じ音になり、響きが頭の真ん中に固まって聞こえます。左右の音がどれくらい似ているかを、実験では「左右の相関」という数で表示しています。1 なら左右がまったく同じ、0 なら無関係です。ループ 1 本では 1 になります。
Beads のタンクは、長さの違う 2 本の片側からできています (左: 2181, 2689, 4460、右: 2524, 2196, 6261)。この 2 本のつなぎ方を、実験の「形」で切り替えられます。
- 2 本を別々に: 左は左だけで、右は右だけで回る。2 本の独立したループ。
- たすき掛け: 左の出口の音を右の入口へ、右の出口の音を左の入口へ戻す (図 4.1)。音は左 → 右 → 左 → … と 8 の字に回り、全体では 1 本の長いループ (20311 サンプル、約 423 ms) になる。Beads はこちら。
実験で測った値を表にまとめます (拡散器 4 段あり、揺らしなし、ローパスなし、krt = 0.7)。
| 形 | 左右の相関 | T60 (L) | T60 (R) | 1 周の遅延 |
|---|---|---|---|---|
| 1 本のループ | 1.00 | 5.58 s | 5.58 s | 9330 |
| 2 本を別々に | 0.08 | 5.58 s | 5.94 s | 9330 と 10981 |
| たすき掛け | 0.10 | 4.95 s | 4.94 s | 20311 |
左右の相関は、別々に回しても、たすき掛けにしても、0.1 前後まで下がります。どちらでも響きは左右に広がって聞こえます。左右を似ていない音にするだけなら、たすき掛けにする必要はありません。
違いが出るのは別のところです。
- 左右の長さがそろう: 別々に回すと、左右でループの長さが違うので、残響の長さが 0.36 秒ずれます。響きの終わりのほうが片側に寄って聞こえることがあります。たすき掛けでは、音は必ず左右を交互に通るので、左右の残響の長さがそろいます。
- 共鳴が細かく並ぶ: たすき掛けは全体で 1 本の長いループなので、ループの共鳴 (第 5 章で扱います) が 2.4 Hz 間隔で並びます。別々のループ (約 5.1 Hz と 4.4 Hz 間隔) より 2 倍ほど細かく並ぶので、1 つ 1 つの共鳴が聞き分けにくくなります。
Beads のコードには、このリバーブは Dattorro の論文に書かれた Griesinger の構成だ、というコメントがあります。Dattorro は 1997 年の論文 “Effect Design, Part 1: Reverberator and Other Filters” で、Lexicon 社の David Griesinger の流儀によるものとして、拡散器 4 段とたすき掛けのタンクからなる構成を説明しています。論文の構成では、左右の出力をタンクの中の 7 か所から足し合わせて作ります。Beads は各片側の 1 か所ずつから取り出していて、そのぶん計算が少なくなっています。
- ループで回すと響きが長く残る。krt を上げるほど長い。ループの中にオールパスがあると、単純な計算より長くなる。
- ループの中のローパスを通るたびに高い音が削れ、響きは時間とともに暗くなる。
- 2 本を左右に分けると響きが広がる。たすき掛けにすると、左右の長さがそろい、共鳴も細かく並ぶ。
練習問題 4
- ループ 1 本 (1 周 9330 サンプル) で krt = 0.7 のときの $T_{60}$ を、第 1 章の式で計算せよ。測った値 (約 5.6 秒) より長いか短いか、その理由も述べよ。
- ローパス $y[n]=y[n-1]+k(x[n]-y[n-1])$ の振幅の 2 乗が $k^2/(1-2p\cos\omega+p^2)$ ($p=1-k$) になることを示し、−3 dB の周波数の式を導け。$k=0.6$, $f_s=48$ kHz と、$k=0.4$, $f_s=24$ kHz の場合の値を求めよ。
- たすき掛けのタンクでは、片側を通るたびに krt が 1 回掛かる。全体のループ 1 周 (20311 サンプル) では何回掛かるか。krt = 0.7 で、ループの中のオールパスを外したときの $T_{60}$ を計算せよ。
第5章
揺らす遅延の長さをゆっくり動かして、耳につく共鳴を消す
第 4 章のタンクは、遅延の長さも係数も、時間がたっても変わらない回路でした。こういう回路では、ある高さの共鳴が、音を入れるたびに同じ高さで、同じ長さだけ鳴ります。残響を長くすると、この共鳴のいくつかが「キーン」「ウォーン」という金属的な鳴きとして耳につくようになります。Beads は、タンクの中の 2 本の長い遅延と、拡散器の 1 段目の中身を、1 秒に 0.3 回と 0.5 回という、ゆっくりした速さで揺らしています。この章では、揺らすと何が起きるのかを、ループ 1 本から順に確かめます。最後に、揺らしを深くするとコーラスになることも聞きます。
5.1 ループの共鳴
ループの中を回る音は、1 周して戻ってきたときに、波の山と山がそろう高さで強め合います。1 周が 23 ms のループなら、1 周の間にちょうど 1 回、2 回、3 回、…振動する高さ、つまり約 43.5 Hz, 87 Hz, 130 Hz, …で強め合います。これがループの共鳴です。第 1 章のコムの櫛の歯の山は、この共鳴でした。戻し量が 1 に近いほど、共鳴は鋭く、長く鳴ります。
次の実験は、1 周 23 ms のループ 1 本です。スペクトログラムでは、共鳴が横にまっすぐ伸びる線として見えます。時間がたっても変わらない回路なので、線はずっと同じ高さにあり、同じ速さで薄くなっていきます。
「揺れ幅」を 0 から 20 サンプルまで上げてみてください。スペクトログラムの横線が波打ちはじめ、高い線ほど大きく上下します。「揺れの速さ」を 2〜3 Hz に上げると、線は一つの高さに留まらなくなります。弦の入力で聞くと、揺れなしでは旋律の後ろで「ビーン」という音がずっと鳴り続けますが、揺らすとそれが「シュワー」と広がった音に変わります。
実験パネルの数値のうち、二つがこの変化を表しています。
- 尖り: 響きの中で、いちばん強い高さの音が、まわりより何 dB 飛び出しているか。鋭い共鳴があるほど大きい。揺れなしで 31 dB、揺れ幅 20 サンプルで 9 dB になります。
- 模様の持続: 響きの前半と後半で、スペクトルの細かい凸凹がどれくらい同じか。前半に鳴っていた共鳴が後半でも同じ高さで鳴っていれば 1 に近い。揺れなしで 1.00、揺れ幅 20 サンプルで 0.79 になります。
5.2 揺らすと何が起きるか
「揺らす」とは、遅延の長さを、時間とともに長くしたり短くしたりすることです。遅延の長さは整数とは限らないので、隣り合う 2 つのサンプルの間を直線でつないで読み出します (線形補間)。Beads の Interpolate も同じことをしています。
音程が少しずれる
遅延がだんだん長くなっている間は、出口から読み出す位置が、入口に書き込む位置よりゆっくり進みます。ゆっくり読み出した音は、少し低くなります。逆に遅延が短くなっている間は、少し高くなります。救急車のサイレンが、近づくときは高く、遠ざかるときは低く聞こえるのと同じ仕組み (ドップラー効果) です。
どれくらいずれるかは、揺れ幅と揺れの速さで決まります。音程のずれは cent という単位で表します。100 cent が半音 1 つです。
Beads は右側の長い遅延を、6261〜6311 サンプルの間で、1 秒に 0.3 回の速さで揺らしています。揺れ幅は中心から ±25 サンプルです。これで音程は最大 1.7 cent ずれます。左側 (4460〜4500、±20 サンプル、0.5 回/秒) は 2.3 cent、拡散器の 1 段目の中の揺れ (±40 サンプル、0.5 回/秒) は 4.5 cent です。
1 回通るごとのずれは半音の 50 分の 1 くらいで、1 回だけなら聞いてもわかりません。
式で確かめる: 音程のずれの計算
遅延を $d(t)=d_0+A\sin(2\pi f_m t)$ と揺らします ($A$ は揺れ幅 [サンプル]、$f_m$ は揺れの速さ [Hz])。遅延が 1 サンプルあたり $d'$ だけ伸びると、読み出す速さは $1-d'$ 倍になり、音の周波数も $1-d'$ 倍になります。$d'$ のいちばん大きい値は $2\pi f_m A/f_s$ なので、周波数のずれの割合は
$$ \Delta=\frac{2\pi f_m A}{f_s},\qquad \text{cent で表すと}\ \ 1200\log_2(1+\Delta) $$です。Beads の右側なら $\Delta=2\pi\times0.3\times25/48000=9.8\times10^{-4}$ で、1.7 cent になります。
共鳴の高さが動く
同じことを共鳴の側から見てみます。ループの共鳴の高さは、ループの長さで決まっていました。ループが長くなれば共鳴は低く、短くなれば高くなります。遅延を揺らせば、共鳴の高さも一緒に揺れます。
Beads の右側の遅延は、長さが約 0.4% 変わります。すると 1 kHz あたりの共鳴は ±4 Hz 動きます。第 4 章で見たように、たすき掛けのタンクの共鳴は 2.4 Hz 間隔で並んでいたので、1 kHz あたりの共鳴は、隣の共鳴の位置を越えるくらい動くことになります。
共鳴の高さが動き続けると、ある高さにたまった音は、1 周するたびに少しずつ別の高さへずらされます。何十周もすると、元の高さからは離れてしまいます。揺らさなければ同じ高さで何十周も重なって鋭く育つはずだった共鳴が、育つ前にぼかされるわけです。
ループ 1 本の場合は、どの共鳴も同じ割合で上下するだけなので、並び方は保たれます。タンクのように長さの違う遅延を別々の速さで揺らすと、ループ全体の長さの変わり方が一定でなくなり、共鳴の並びそのものが 1 周ごとに組み変わります。次の節でこれを確かめます。
揺らした回路は「時間がたっても変わらない回路」ではなくなるので、第 2 章や第 4 章の周波数特性の話は、揺れがゆっくりで小さいときの目安になります。また、線形補間は 2 つのサンプルの平均をとるので、高い音を少し削るローパスとしても働きます。そのため、揺らすと残響が少し短くなります。この章の実験では、ループ 1 本で $T_{60}$ が 5.2 秒から 4.5 秒に、タンクで 13.7 秒から 11.7 秒に縮みます。
5.3 タンクで確かめる
次の実験は、第 4 章のたすき掛けのタンクに、Beads と同じ 2 つの揺れを加えたものです。共鳴を目立たせるために、最初は krt = 0.9 にして、ループの中のオールパスを外してあります (オールパスを外すと、ループはただの長い遅延の並びになり、共鳴がきれいに並んで鳴きやすくなります)。揺れ幅の「×1」が Beads と同じ値です。
実験パネルの 1 枚目の図は、響きの前半 (1.0〜2.4 秒、黒) と後半 (5.0〜6.4 秒、オレンジ) のスペクトルを、2000〜2060 Hz の範囲で重ねたものです。×0 では、黒とオレンジの山の位置がほぼぴったり重なります。前半に鳴っていた共鳴が、4 秒たっても同じ高さで鳴っているということです。×1 にすると、山の位置がずれます。「模様の持続」は、この二つの線がどれくらい似ているかを、100 Hz〜4 kHz の範囲で計算した数です。
弦の入力で、揺れ幅を ×0 と ×1 で切り替えて聞いてみてください。×0 では、旋律が終わったあとの響きの中に、特定の高さの音がいつまでも残ります。旋律を何回繰り返しても、残る音の高さは同じです。×1 にすると、その音が残らなくなり、高さのはっきりしない広がった響きになります。
測った値は次のとおりです (krt = 0.9、ローパスなし)。
| ループの中のオールパス | 揺れ幅 | T60 | 模様の持続 |
|---|---|---|---|
| なし | ×0 | 13.7 s | 0.90 |
| なし | ×1 | 11.7 s | 0.23 |
| あり | ×0 | 15.4 s | 0.57 |
| あり | ×1 | 12.7 s | 0.51 |
| あり | ×4 | 12.2 s | 0.25 |
オールパスなしでは、Beads の揺れ幅だけで、模様の持続が 0.90 から 0.23 まで下がります。オールパスありでは、揺れなしでも 0.57 と低めで、×1 での下がり方は小さくなります。オールパスで周波数ごとに届く時刻がばらばらになるので、共鳴の並びがもともと不規則になり、目立つ共鳴が少ないからです。なお、この「模様の持続」は、共鳴がとても細かく並んでいると値がぶれやすいので、だいたいの目安として見てください。
5.4 深く揺らすとコーラスになる
揺れ幅を ×10、×40 と大きくしていきます。×40 は右側の遅延で ±1000 サンプルにあたり、1 回通るごとに 67 cent (半音の 3 分の 2) ずれます。弦やドラムを通すと、響きの音程がうねるように上下して、コーラスやテープの揺れのような音になります。速さも上げると、うねりはビブラートに近づきます。
揺らす量は、二つの条件の間で決まります。
- 共鳴をぼかすには、共鳴の高さが隣の共鳴との間隔より大きく動く必要がある。
- 一方で、音程の揺れとして聞こえてしまってはいけない。
Beads の 1.7〜2.3 cent は、1 kHz で共鳴の間隔を越える程度に動かしつつ、音程のずれとしては聞こえない大きさです。揺れをゆっくり (0.3 回/秒と 0.5 回/秒) にしているのも、音程の変わり方を小さく抑えるためです。
拡散器の中の揺れ
Beads は、タンクのほかに、拡散器の 1 段目の中身も揺らしています。
c.Interpolate(ap1, 10.0f, LFO_1, 80.0f, 1.0f); // ap1 の 10〜90 サンプル目を読む
c.Write(ap1, 100, 0.0f); // それを ap1 の 100 サンプル目に書き戻す1 段目のオールパスの遅延線の中で、少し前に書いた音を揺れる位置から読み、別の位置に書き戻しています。遅延線の中身の一部が、伸び縮みしながら並べ替えられるわけです。タンクに入る前の段階で、音の間隔が少しずつ変わり続けるので、拡散器の出力も時間とともに変わります。実験の「AP1 の中の揺らし」で、入れたり外したりできます。
- 時間で変わらない回路では、同じ高さの共鳴が鳴り続け、長い残響では金属的な鳴きになる。
- 遅延を揺らすと共鳴の高さが動き、共鳴が鋭く育つ前にぼかされる。
- Beads の揺れは音程にして 2 cent 前後。深く揺らすとコーラスになる。
練習問題 5
- Beads の左側の遅延 (揺れ幅 ±20 サンプル、0.5 回/秒、$f_s=48$ kHz) の揺れで、音程は最大何 cent ずれるか。
- 右側の遅延の揺れ (長さの変化 25/6261) で、1 kHz の共鳴は何 Hz 動くか。たすき掛けのタンクの共鳴の間隔 ($f_s/20311$) と比べよ。
- 揺れの速さ 0.3 回/秒で、1 回通るごとのずれを 10 cent にしたい。揺れ幅を何サンプルにすればよいか。
第6章
Beads のリバーブ全部の部品をつないで、つまみの式と quality の効き方を読む
ここまでで、拡散器 (第 3 章)、タンクとローパス (第 4 章)、揺らし (第 5 章) を 1 つずつ見てきました。この章では、それらを Beads の reverb.h と同じ順につないで、完成形を鳴らします。あわせて、Beads の REVERB つまみの値から係数を作る式 (processor.cc) を読みます。最後に、Beads の quality を切り替えると部屋の大きさが変わって聞こえる理由を確かめます。
6.1 全体の流れ
音の流れは次のとおりです。
- 左右の入力を足して 1 本にし、send 倍する。
- 拡散器 (オールパス 4 段) でばらまく。1 段目の中身は揺らしてある。
- たすき掛けのタンクで回す。タンクの中では krt を掛け、ローパスを通し、2 本の長い遅延を揺らす。
- タンクの左右の出口を wet 倍し、dry 倍した原音に足す。
遅延線の長さを表にまとめます。Beads の内部は quality によって 48 kHz, 32 kHz, 24 kHz で動くので、同じサンプル数でも時間の長さが変わります。
| 名前 | 役割 | 遅延 (サンプル) | 48 kHz のとき | 24 kHz のとき |
|---|---|---|---|---|
| ap1–ap4 | 拡散器 | 149, 213, 318, 526 | 3.1–11.0 ms | 6.2–21.9 ms |
| dap1a, dap1b | 左のタンクの AP | 2181, 2689 | 45.4, 56.0 ms | 90.9, 112.0 ms |
| del1 | 左のタンクの遅延 | 4460–4500 | 92.9–93.8 ms | 185.8–187.5 ms |
| dap2a, dap2b | 右のタンクの AP | 2524, 2196 | 52.6, 45.8 ms | 105.2, 91.5 ms |
| del2 | 右のタンクの遅延 | 6261–6311 | 130.4–131.5 ms | 260.9–263.0 ms |
del1 と del2 は揺らしてあるので、長さに幅があります。10 本の遅延線は 32768 サンプル分のメモリ 1 枚に詰めて置かれていて、値は 16 ビットの整数で保存されます。
6.2 つまみの式
Beads の REVERB つまみの値を $r$ (0〜1) とします。processor.cc は、$r$ から次の 3 つを作ります。
ローパスの係数 lp は quality ごとに決まっていて、digital が 0.6、vintage digital が 0.75、tape が 0.4 です。reverb.h はさらに、mix と krt から音量の倍率を作ります。
(コードでは send と dry を少し違う形で書いていますが、展開するとこの形になります。練習問題 6.3 で確かめます。)
それぞれの式が何をしているかを、言葉で書くとこうなります。
- dry: mix が小さいうちは、原音はほとんど減りません。0.5 まで上げても 0.75 倍です。
- send: mix が少しでも上がると、すぐに大きくなります。mix = 0.2 でもう 0.59 です。つまみを少し上げただけで響きが聞こえはじめるのはこのためです。
- input_gain と wet: krt が大きい (残響が長い) ほど、タンクに入れる音を小さく絞ります。長く回すほど音がたまって、16 ビットのメモリからあふれやすくなるからです。出口では同じ比だけ大きくして戻すので、聞こえる響きの大きさは krt によらずほぼ一定になります。
- krt: $r^3$ で増えるので、つまみの下半分ではあまり変わらず、上のほうで急に伸びます。
mix = 0.9 × 0.25 = 0.225、krt = 0.3 + 0.6 × 0.125 = 0.375 です。dry = 1 − 0.225² = 0.949、send の前半は 1 − 0.775⁴ = 0.639、input_gain = 0.2 × (1 − 0.333 × 0.375) = 0.175 になります。
ドラムの入力で、REVERB を 0 から 1 までゆっくり上げてみてください。0.5 あたりまでは響きが短く、部屋の空気が少し加わる程度です。0.8 を越えると急に長くなり、1 では十数秒残ります。上の図はインパルス応答から計算したもので、図を描くときだけは 16 ビットの丸めを外しています。1 サンプルのパチッは小さすぎて、16 ビットに丸めると響きの終わりが早く消えてしまい、残響の長さを正しく測れないからです。
6.3 quality で部屋の大きさが変わる
quality を digital (48 kHz) から tape (24 kHz) に切り替えると、遅延のサンプル数は同じまま、1 サンプルの時間が 2 倍になります。タンク 1 周の時間は 423 ms から 846 ms になり、エコーの間隔も 2 倍、共鳴の間隔は半分になります。耳はこれを、2 倍の大きさの部屋の響きとして聞きます。揺らしの速さ (Hz) は quality によらず同じに設定されています。
krt を 0.5 に固定し、ローパスを外して比べると、測った $T_{60}$ は 48 kHz で 2.0 秒、32 kHz で 3.2 秒、24 kHz で 4.3 秒になり、ほぼ処理の速さに反比例します。実際の Beads では、digital 以外は krt の式とローパスの係数も変わるので、REVERB つまみと残響の長さの関係は次の図のようになります。
ローパスの効き方も、処理の速さで変わります。tape の lp = 0.4 は、24 kHz では約 2.0 kHz から上を弱めます。digital (lp = 0.6、48 kHz) の約 7.6 kHz よりずっと低い位置です。さらに 24 kHz で処理すると、12 kHz より上の音はそもそも扱えません。tape の響きが「広くて暗い部屋」に聞こえるのは、この二つが重なるからです。
この本の実験は 48 kHz で動いているので、32 kHz と 24 kHz の quality は、入力を間引いてからリバーブを回し、出力を 48 kHz に戻して再現しています。実機の Beads では原音側もこの速さで処理され、リバーブの前後にリミッターも入るので、細かいところの音は実機と同じではありません。dirty tape の揺れ (wow and flutter) も入れていません。
6.4 部品を外して聞く
実験パネルのスイッチで、部品を 1 つずつ外して聞いてみてください。それぞれの章で見たことが、完成形の中でもそのまま起きます。
- 入力の拡散器を外す (第 3 章): 手拍子やスネアの直後に、「パタパタ」とした粗いエコーが聞こえるようになります。タンクのオールパスだけでは、最初の数十 ms の音の数が足りません。
- 揺らしを外す (第 5 章): REVERB を 0.9 以上にして弦を鳴らすと、響きの中に特定の高さの音が残ります。
- 16 ビットを外す: 音楽の大きさの音では、ほとんど違いは聞こえません。響きが小さくなった最後の部分で、16 ビットのほうが少し早く途切れます。
- Beads のリバーブは、拡散器 4 段 → たすき掛けのタンク (ローパスと揺らし入り) という順に並んでいる。
- REVERB つまみは mix と krt を同時に動かし、krt はつまみの上のほうで急に伸びる。
- quality を下げると同じサンプル数がより長い時間になり、部屋が広く、暗く聞こえる。
練習問題 6
- REVERB = 0.8、quality = vintage digital のとき、mix, krt, dry, send (input_gain を掛ける前) を求めよ。
- del2 の中心の遅延 6261 サンプルは、48 kHz, 32 kHz, 24 kHz でそれぞれ何 ms か。
- コードでは $s=\text{mix}(2-\text{mix})$、send の前半を $s(2-s)$、dry を $(1-\text{mix})(1+\text{mix})$ と書いている。これらが $1-(1-\text{mix})^4$ と $1-\text{mix}^2$ に等しいことを示せ。
第7章
FDN遅延線を行列で混ぜる作り方と比べ、残響の長さを狙って作る
Beads のリバーブは、オールパスと遅延を手でたすき掛けにつないだ回路でした。krt を上げれば残響は長くなりますが、第 4 章で見たように、「ちょうど 2 秒にしたい」と思っても、その krt を計算で出すのは難しい回路です。これとは違う考え方で作るのが、フィードバック・ディレイ・ネットワーク (FDN) です。何本もの遅延線の出口の音を、決まった割合で混ぜ合わせてから、それぞれの入口に戻します。Stautner と Puckette が 1982 年に 4 本の遅延線による構成を示し、Jot と Chaigne が 1991 年に、高さごとの残響の長さを式で決める方法を加えました。この章では、線の数と混ぜ方を変えて響きの違いを聞き、狙った長さの残響を作ってみます。
7.1 しくみ
FDN は、次のことを 1 サンプルごとに繰り返します。
- $N$ 本の遅延線 (長さはばらばら) の出口から、音を 1 つずつ取り出す。
- それぞれに、少し小さくする係数 $g_i$ を掛ける。
- $N$ 個の音を、行列 $A$ で混ぜ合わせる。「1 本目の入口には、1 本目の音を何割、2 本目の音を何割、…」という配合表が行列です。
- 混ぜた音に入力を足して、それぞれの遅延線の入口に書き込む。
出力は、遅延線の出口の音を足し合わせて作ります。この本の実験では、左と右で足し方 (符号の組み合わせ) を変えて、左右が似ない音にしています。
7.2 音の量を保つ混ぜ方
混ぜる行列には、1 つ条件があります。係数 $g_i$ をすべて 1 にしたとき、何周回っても音の量 (エネルギー) が増えも減りもしないことです。増えると音がどんどん大きくなって壊れますし、勝手に減ると残響の長さを $g_i$ で決められなくなります。この条件を満たす行列を直交行列と呼びます。実験では、次の 3 種類を比べられます。
- Hadamard 行列: どの線の音も、すべての線に同じ大きさで配る混ぜ方です。成分は全部 $\pm1/\sqrt N$ です。線の数は 2 のべき (4, 8, 16, …) に限られます。足し算と引き算だけで速く計算できます。
- Householder 行列: 「全部の線の合計の $2/N$ を、各線から引く」という混ぜ方です。計算がいちばん軽く済みます。
- 単位行列: 混ぜません。各線が自分の中だけで回るので、コムを $N$ 本並べたのと同じになります。第 1 章のコラムの Schroeder の構成と同じ形です。
Householder 行列は、線の数が多いと混ぜ方が弱くなります。16 本では、1 周するたびに音の量の約 77% が同じ線に戻ってしまいます (Hadamard なら 1/16、約 6%)。そのため 16 本で Householder を使うときは、4 × 4 の Householder 行列を組み合わせる方法もあります。この本の実験で数えた音の数は Hadamard とほとんど変わりませんが、聞き比べてみてください。
式で確かめる: 直交行列と FDN の式
時刻 $n$ の遅延線の出口の音を並べたものを $\mathbf{s}[n]$、係数を並べた対角行列を $\Gamma$ とすると、各線の入口に書き込む音は $A\,\Gamma\,\mathbf{s}[n]+\mathbf{b}\,x[n]$、出力は $\mathbf{c}^{\mathsf T}\Gamma\,\mathbf{s}[n]$ です ($\mathbf{b}$ は入力の配り方、$\mathbf{c}$ は出力の取り出し方)。$A$ が直交行列 ($A^{\mathsf T}A=I$) なら $\|A\mathbf{s}\|=\|\mathbf{s}\|$ で、混ぜても音の量 (ベクトルの長さの 2 乗) が変わりません。Householder 行列は $A=I-\tfrac{2}{N}\mathbf{1}\mathbf{1}^{\mathsf T}$ で、対角成分が $1-2/N$、それ以外が $-2/N$ です。$N=16$ なら対角は $7/8$ で、$(7/8)^2\approx0.77$ が同じ線に戻ります。
7.3 狙った長さの残響を作る
ここが FDN のいちばん便利なところです。考え方はこうです。
- どの線を通っても、1 秒あたりに同じ dB だけ小さくなるようにしておけば、どう混ぜても全体が同じ速さで小さくなる。
- $T_{60}$ 秒で −60 dB にしたいなら、1 秒あたり $60/T_{60}$ dB 小さくすればよい。
- 長い線は 1 回通るのに時間がかかるので、そのぶん 1 回で大きく小さくする。
これを式にすると、長さ $m_i$ サンプルの線の係数は次のようになります。
$$ g_i=10^{-3m_i/(f_sT_{60})} $$$g=10^{-3\times1601/(48000\times2)}=10^{-0.0500}=0.891$ です。8 本の FDN (平均 40 ms) の 4 本目の線が、ちょうどこの長さです。
高い音を早く消す
部屋の響きは、高い音ほど早く消えます。Jot と Chaigne は、各線の係数 $g_i$ を、ローパスつきの係数に置き換える方法を示しました。低い音にはさっきの $g_i$ をそのまま掛け、高い音にはもっと小さい値を掛けます。この本の実験では、「低い音の $T_{60}$」と「高い音 (ナイキスト周波数 24 kHz 付近) の $T_{60}$ が低い音の何倍か (α)」を指定できます。
16 本、低い音の $T_{60}$ = 3 秒で、高さごとに測った値を表にします。
| α (高い音の目標) | 250 Hz | 4 kHz | 12 kHz | 18 kHz |
|---|---|---|---|---|
| 1.0 (3.0 s) | 2.92 s | 2.99 s | 3.00 s | 3.00 s |
| 0.5 (1.5 s) | 2.91 s | 2.63 s | 1.90 s | 1.51 s |
| 0.25 (0.75 s) | 2.86 s | 1.81 s | 1.07 s | 0.72 s |
18 kHz で測った値が、狙った値とほぼ一致しています。Beads の krt と lp では、このように秒数を指定することはできません。
式で確かめる: Jot の吸収フィルター
各線の係数を $H_i(z)=g_i\,(1-p_i)/(1-p_iz^{-1})$ に置き換えます。低い音 (直流) では $H_i=g_i$、ナイキスト周波数では $g_i(1-p_i)/(1+p_i)$ になります。ナイキストでの残響を $\alpha T_{60}$ にするには
$$ p_i=\frac{\ln10}{4}\,\log_{10}g_i\left(1-\frac{1}{\alpha^2}\right) $$とします ($p_i$ が小さいとして近似した式)。この本の実験はこの式を使っています。
7.4 線の数で変わるもの
最初の 100 ms の中で、いちばん大きい音から −40 dB より大きいサンプルの数を数えました (平均 40 ms、$T_{60}$ = 2 秒、α = 1)。α を小さくすると音がローパスでなまって横に広がり、数えるサンプルが増えるので、実験パネルの最初の設定 (α = 0.5) では表より大きな数が出ます。
| 混ぜ方 | 4 本 | 8 本 | 16 本 |
|---|---|---|---|
| Hadamard | 15 | 66 | 301 |
| Householder | 16 | 68 | 306 |
| 単位行列 (混ぜない) | 10 | 18 | 38 |
混ぜると、1 本の線から出た音が次の周回では $N$ 本に分かれるので、音の数は周回ごとにおよそ $N$ 倍に増えます。線を 2 倍にすると、100 ms までの数は 4 倍以上になります。混ぜないと、各線は自分の間隔で音を繰り返すだけなので、数は線の数に比例してしか増えません。
聞いてみると、4 本では手拍子のあとに「パラパラ」と粒の粗いエコーが聞こえ、響きに金属的な色が付きます。共鳴の数は遅延の長さの合計に比例するので、4 本では 8 本の半分しかなく、まばらな共鳴が色として聞こえるのです。16 本では粒が聞こえなくなり、なめらかな響きになります。
7.5 Beads と比べる
| Beads (Griesinger 型) | FDN | |
|---|---|---|
| 部品 | オールパス 8 段と遅延 2 本 | 遅延 N 本と、混ぜる行列 1 つ |
| 混ぜ方 | タンクの中のオールパスと、たすき掛けのつなぎ方 | 直交行列で全部の線を混ぜる |
| 最初の音の細かさ | 入力の拡散器で作る | 線の数と行列で決まる (拡散器を前に置くこともある) |
| 残響の長さ | krt で変える。秒数は計算で決まらない | $g_i=10^{-3m_i/(f_sT_{60})}$ で秒数を指定できる |
| 高い音の消え方 | ループの中のローパス (lp) | 各線のローパスつき係数 (Jot) |
| 共鳴を消す工夫 | 遅延を揺らす | この本の実験では揺らしていない (揺らす作り方も多い) |
| 1 サンプルの計算量 | 遅延線の読み書き約 20 回 | N 本の読み書きと、行列の計算 |
Beads の構成は、少ないメモリと計算で、ばらまき・減衰・左右の広がり・揺らしを一度に作れるように組まれています。FDN は、線を増やせば音を細かくでき、残響の長さを高さごとに式で決められます。どちらも、「返ってくる音を時間とともに増やす」「音の量を保ったまま回し、決まった速さで小さくする」「共鳴を目立たせない」という同じ課題を、別の部品で解いています。
- FDN は、何本もの遅延線の出口を、音の量を保つ行列で混ぜてから入口に戻す。
- どの線も 1 秒あたり同じ dB だけ小さくすれば、残響の長さを秒数で指定できる。高い音の長さも別に決められる。
- 線が多いほど、返ってくる音が細かくなり、色付きが減る。
練習問題 7
- 長さ 1601 サンプル、$T_{60}$ = 2 秒のときの $g$ を求めよ。長さ 2789 サンプルならどうなるか。
- Householder 行列 $A=I-2\mathbf{u}\mathbf{u}^{\mathsf T}$ ($\mathbf{u}=\mathbf{1}/\sqrt N$) が直交行列であることを示せ。
- 16 本の Householder 行列で、1 本の線から出た音の量のうち、同じ線に戻る割合を求めよ。Hadamard 行列ではいくらか。
終章
まとめと限界学んだことの表、実験でわからないこと、読書案内
学んだこと
| 章 | 問い | 答え |
|---|---|---|
| 1 | 遅延線 1 本とフィードバックで、何が聞こえるか | 反射 1 回と、等間隔のエコー。間隔が短いと $f_s/D$ の音程になる。エコーの密度が増えないので響きには聞こえない |
| 2 | 振幅特性が平らなオールパスで、なぜ音が変わるのか | 平らなのは応答全体で見たとき。耳の窓 (数 ms〜数十 ms) の中にパルスが数本しか入らないと、櫛の歯の色が付いて聞こえる |
| 3 | オールパスを直列にすると何が起きるか | 振幅特性は平らなまま、パルスの数が段ごとに掛け算で増える。遅延の長さに大きな公約数があると増えない |
| 4 | 長い残響と左右の広がりはどう作るか | ループで回して krt を掛ける。ループの中のローパスで響きが暗くなる。たすき掛けで左右の残響時間をそろえ、共鳴を密にする |
| 5 | なぜ遅延を揺らすのか | 時間で変わらない回路の共鳴は、同じ周波数で鳴り続ける。揺らすと共鳴の周波数が動き、鋭く育つ前にぼかされる。深く揺らすとコーラスになる |
| 6 | Beads の quality でなぜ部屋の大きさが変わるか | 同じサンプル数の遅延を低いレートで回すと、時間が長くなる。24 kHz では 48 kHz の 2 倍の大きさの部屋に聞こえる |
| 7 | FDN は何が違うか | 遅延線を直交行列で混ぜ、各線の減衰を $g_i=10^{-3m_i/(f_sT_{60})}$ にすると、狙った残響時間を周波数ごとに作れる |
この本の実験でわからないこと
この本の数値は、この本の DSP コードで計算したインパルス応答から求めたものです。数字を読むときは、次の点に気をつけてください。
- 数え方で変わる数字があります。 音の数は「−40 dB を超えるサンプル」、残響の長さは「エネルギー減衰曲線の −5〜−25 dB に引いた直線」、模様の持続は「前半と後半のスペクトルの似ている度合い」と、それぞれ 1 つの決め方で測っています。決め方を変えれば数字も変わるので、比べるときは同じ決め方の数字どうしで比べてください。
- 「耳の窓」は単純化です。 第 2 章では、耳が一定の長さの区間で音を聞くと仮定しました。実際の耳の時間の細かさは、音の高さや大きさ、種類で変わります。
- 揺らした回路のインパルス応答は 1 つに決まりません。 パチッを入れた瞬間に揺れがどこにいたかで、応答が少し変わります。
- Beads の実機と同じ音ではありません。 32 kHz と 24 kHz の quality は 48 kHz の中で再現していて、原音側の処理、リミッター、dirty tape の揺れは入れていません (第 6 章の注意)。
- 部屋の音響を計算したものではありません。 この本のリバーブはどれも、部屋の形や壁の材質から計算したものではありません。「響きに聞こえる」ための条件 (返ってくる音が多いこと、なめらかに小さくなること、高い音が早く消えること、左右が似ていないこと) を、少ない計算で満たすように作った回路です。
この先で出会う話題
- 初期反射: 最初の数十 ms の反射の並び方で、部屋の形や音源までの距離の感じが変わります。途中から何か所も取り出す遅延線 (タップつき遅延線) で、別に作ることが多い部分です。
- 畳み込みリバーブ: 本物の部屋で録ったインパルス応答を、そのまま入力の音に重ね合わせる方法です。FFT を使って速く計算します。
- FDN の設計の続き: 遅延の長さの選び方、色付きを補正するフィルター、揺らす FDN などがあります。
- Dattorro の論文の続き: 同じ論文の後半と Part 2 では、コーラスやフランジャー、ピッチシフターなど、遅延線を使うほかのエフェクトを扱っています。
読書案内
- J. Dattorro, “Effect Design, Part 1: Reverberator and Other Filters,” Journal of the Audio Engineering Society, 45(9), 1997. 本書の第 3〜5 章の構成の元になった論文。
- M. R. Schroeder, “Natural Sounding Artificial Reverberation,” Journal of the Audio Engineering Society, 10(3), 1962. コムとオールパスによるリバーブの最初の論文。
- M. R. Schroeder, “New Method of Measuring Reverberation Time,” Journal of the Acoustical Society of America, 37, 1965. エネルギー減衰曲線 (後ろからの積分) の論文。
- J. Stautner and M. Puckette, “Designing Multi-Channel Reverberators,” Computer Music Journal, 6(1), 1982. 4 本の遅延線を行列で混ぜる構成。
- J.-M. Jot and A. Chaigne, “Digital Delay Networks for Designing Artificial Reverberators,” 90th Convention of the Audio Engineering Society, 1991. FDN と、周波数ごとの残響時間の設計。
- V. Välimäki, J. D. Parker, L. Savioja, J. O. Smith, J. S. Abel, “Fifty Years of Artificial Reverberation,” IEEE Transactions on Audio, Speech, and Language Processing, 20(5), 2012. 人工残響の 50 年を整理した総説。
- J. O. Smith III, Physical Audio Signal Processing, W3K Publishing, 2010 (CCRMA のサイトで全文が読める)。オールパス、FDN、Jot の吸収フィルターの導出がある。
- Mutable Instruments, eurorack のソースコード (MIT ライセンス)。
beads/dsp/fx/reverb.hとfx_engine.h。同じ FxEngine は Clouds や Rings のリバーブにも使われている。
付録A
練習問題の解答
練習問題 1
1.1 の解答
山は $f=k f_s/D=k\times100$ Hz (0, 100, 200, … Hz)、高さは $1/(1-0.5)=2$ で $+6.02$ dB。谷は 50, 150, 250, … Hz、高さは $1/(1+0.5)=0.667$ で $-3.52$ dB。
1.2 の解答
$-\log_{10}0.9=0.0458$ なので $k=3/0.0458=65.6$ 回。$T_{60}=65.6\times0.05=3.28$ 秒。
1.3 の解答
$g<0$ のとき、インパルス応答は $1, g, g^2, \dots$ で符号が 1 回ごとに反転する ($g=-0.8$ なら $1, -0.8, 0.64, -0.512, \dots$)。符号まで含めて同じ形がくり返されるのは $2D$ ごとなので、周期は $2D$、基本周波数は $f_s/(2D)$ で、$g>0$ のときの $f_s/D$ の 1 オクターブ下になる。山は $f_s/(2D)$ の奇数倍だけに立つ。
練習問題 2
2.1 の解答
$h[0]=-0.5$, $h[D]=1-0.25=0.75$, $h[2D]=0.375$, $h[3D]=0.1875$。2 乗の和は $0.25+0.5625+0.140625+0.0352=0.988$ で、残りの項 $(1-g^2)^2\sum_{k\ge4}g^{2(k-1)}=0.0117$ を足すと 1 になる。
2.2 の解答
最大 $149\times1.625/0.375=645.7$ サンプル (13.45 ms)、最小 $149\times0.375/1.625=34.4$ サンプル (0.72 ms)。
2.3 の解答
$\theta=\omega D$ とする。$-g+e^{-j\theta}=e^{-j\theta}(1-ge^{j\theta})$ で、$1-ge^{j\theta}$ は $1-ge^{-j\theta}$ の共役なので偏角は符号が逆である。よって $\phi=-\theta-2\arg(1-ge^{-j\theta})$。$\arg(1-ge^{-j\theta})=\arctan\dfrac{g\sin\theta}{1-g\cos\theta}$ を $\theta$ で微分すると、分子 $N=g\sin\theta$、分母 $M=1-g\cos\theta$ として $\dfrac{N'M-NM'}{M^2+N^2}=\dfrac{g\cos\theta-g^2}{1-2g\cos\theta+g^2}$。したがって
$$ \frac{d\phi}{d\theta}=-1-\frac{2(g\cos\theta-g^2)}{1-2g\cos\theta+g^2}=-\frac{1-g^2}{1-2g\cos\theta+g^2} $$$\tau=-d\phi/d\omega=-D\,d\phi/d\theta$ から求める式を得る。
2.4 の解答
$H(e^{j\omega})=-1$ を解く。$-g+e^{-j\theta}=-1+ge^{-j\theta}$ より $e^{-j\theta}(1-g)=-(1-g)$、つまり $e^{-j\theta}=-1$。$\theta=\omega D=(2k+1)\pi$ なので、$f=(2k+1)f_s/(2D)$。原音と遅延を足しただけの櫛 (図 1.2) と同じ位置に谷ができる。
練習問題 3
3.1 の解答
直列の伝達関数は積 $H=H_1H_2\cdots H_N$ で、$|H|=|H_1|\cdots|H_N|$。定理 2.1 より各因子は 1 なので $|H|=1$。
3.2 の解答
到着時刻は $3a+5b$ の形で、15 以下のものは 0, 3, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15。組 $(a,b)$ は $b=0$ で 6 組、$b=1$ で 4 組、$b=2$ で 2 組、$b=3$ で 1 組の計 13 組。15 は $(5,0)$ と $(0,3)$ の 2 組で重なるので、異なる時刻は 12 個。
3.3 の解答
$d_i=m\,e_i$ ($e_i$ は整数) なら $\sum a_id_i=m\sum a_ie_i$ で、$m$ の倍数。出力は周期 $m$ サンプルのパルス列に近くなり、$f_s/m=48000/120=400$ Hz の音程が聞こえる。
練習問題 4
4.1 の解答
$T_{60}=3\times(9330/48000)/(-\log_{10}0.7)=3\times0.1944/0.1549=3.76$ 秒。測った値 (5.6 秒) のほうが長い。ループの中のオールパスの群遅延が周波数によって $0.23D$〜$4.33D$ に変わり、1 周が長い周波数の成分がゆっくり減衰して、エネルギー減衰曲線の後半を占めるからである。オールパスを外して測ると 3.8 秒になり、式とほぼ合う。
4.2 の解答
$y[n]=(1-k)y[n-1]+kx[n]$ なので $H(z)=k/(1-pz^{-1})$。$|1-pe^{-j\omega}|^2=1-2p\cos\omega+p^2$ より $|H|^2=k^2/(1-2p\cos\omega+p^2)$。これを $1/2$ とおくと $\cos\omega=(1+p^2-2k^2)/(2p)$。$k=0.6$ ($p=0.4$) では $\cos\omega=0.55$、$\omega=0.988$ で $f_c=0.988/(2\pi)\times48000=7.55$ kHz。$k=0.4$ ($p=0.6$) では $\cos\omega=0.867$、$\omega=0.522$ で $f_c=0.522/(2\pi)\times24000=2.00$ kHz。
4.3 の解答
1 周で片側を 2 回通るので krt が 2 回掛かる。$T_{60}=3\times(20311/48000)/(2\times0.1549)=4.10$ 秒。実験で測ると 4.16 秒になる。
練習問題 5
5.1 の解答
$\Delta=2\pi\times0.5\times20/48000=1.31\times10^{-3}$、$1200\log_2(1.00131)=2.26$ cent。
5.2 の解答
$1000\times25/6261=3.99$ Hz。共鳴の間隔 $48000/20311=2.36$ Hz より大きく、隣の共鳴の位置まで動く。
5.3 の解答
$1+\Delta=2^{10/1200}=1.00579$ より $\Delta=5.79\times10^{-3}$。$A=\Delta f_s/(2\pi f_m)=5.79\times10^{-3}\times48000/(2\pi\times0.3)=147.5$ サンプル。
練習問題 6
6.1 の解答
mix $=0.9\times0.64=0.576$。vintage digital は digital 以外なので krt $=0.45+0.5\times0.512=0.706$。dry $=1-0.576^2=0.668$。send の前半 $=1-(1-0.576)^4=1-0.424^4=0.968$。
6.2 の解答
48 kHz で 130.4 ms、32 kHz で 195.7 ms、24 kHz で 260.9 ms。
6.3 の解答
$s=\text{mix}(2-\text{mix})=1-(1-\text{mix})^2$。同じ形で $s(2-s)=1-(1-s)^2$。$1-s=(1-\text{mix})^2$ を代入すると $1-(1-\text{mix})^4$。dry は $(1-\text{mix})(1+\text{mix})=1-\text{mix}^2$ (和と差の積)。
練習問題 7
7.1 の解答
$m=1601$ で $g=10^{-0.0500}=0.891$。$m=2789$ で $g=10^{-3\times2789/96000}=10^{-0.0872}=0.818$。
7.2 の解答
$A$ は対称なので $A^{\mathsf T}A=A^2=(I-2\mathbf{u}\mathbf{u}^{\mathsf T})^2=I-4\mathbf{u}\mathbf{u}^{\mathsf T}+4\mathbf{u}(\mathbf{u}^{\mathsf T}\mathbf{u})\mathbf{u}^{\mathsf T}$。$\mathbf{u}^{\mathsf T}\mathbf{u}=1$ なので $I$ になる。
7.3 の解答
Householder の対角成分は $1-2/16=7/8$ で、エネルギーの割合は $(7/8)^2=49/64\approx0.77$。Hadamard ではすべての成分が $\pm1/4$ なので $1/16\approx0.06$。
付録B
記号と用語
| 記号・用語 | 意味 | 初出 |
|---|---|---|
| $f_s$ | サンプリング周波数 (本書では 48000 Hz) | 序 |
| $z^{-D}$ | $D$ サンプルの遅延 | 序 |
| $H(z)$, $|H(e^{j\omega})|$ | 伝達関数、振幅特性 | 序 |
| $D$ | 遅延の長さ (サンプル) | 1.1 |
| $g$ | 戻し量 (コム)、係数 (オールパス)。Beads では kap = 0.625 | 1.2, 2.1 |
| $T_{60}$ | 残響時間。エネルギーが −60 dB 下がるまでの時間 | 1.3 |
| コム | フィードバックコムフィルター $z^{-D}/(1-gz^{-D})$ | 1.2 |
| オールパス | $(-g+z^{-D})/(1-gz^{-D})$。振幅特性がどこでも 1 | 2.1 |
| 耳の窓 $W$ | 短時間振幅特性を計算する区間の長さ | 2.4 |
| $\tau(\omega)$ | 群遅延。周波数ごとの到着時刻の遅れ (サンプル) | 2.5 |
| 拡散器 | 直列につないだオールパス。Beads では 4 段 | 第 3 章 |
| タンク | 音を回し続けるループ。Beads では 2 本の片側がたすき掛け | 第 4 章 |
| krt | Beads のタンクの戻し量 (reverb_time) | 4.1 |
| klp, lp | Beads のタンクの 1 次ローパスの係数 | 4.2 |
| エネルギー減衰曲線 | 残りのエネルギーを後ろから積分して dB にした曲線 | 4.1 |
| $\rho$ | 左右のインパルス応答の相関係数 | 4.3 |
| $A$, $f_m$ | 遅延の揺れ幅 (サンプル)、揺れの速さ (Hz) | 5.2 |
| cent | 音程の単位。100 cent が半音 | 5.2 |
| mix, send, dry, wet | Beads のつまみから作る倍率 | 6.2 |
| $N$, $m_i$ | FDN の遅延線の本数と長さ | 7.1 |
| $A$ (第 7 章) | FDN の帰還行列 | 7.1 |
| $\alpha$ | ナイキストでの $T_{60}$ と直流での $T_{60}$ の比 | 7.3 |
この本の音は、Mutable Instruments の Beads のソースコード (Emilie Gillet 作、MIT ライセンス) を JavaScript に移したもので鳴らしている。