ノイズにも色がある
ノイズは一様な砂嵐とは限らない。各サンプルが互いに無関係なのが白色ノイズ。前のサンプルに少しずつ足し込んで(積分して)作ると茶色ノイズになり、ゆっくりうねる。同じ乱数を種にしても、サンプルどうしの相関の強さで線の質感が変わる。
ノイズの「色」はスペクトルの傾きで決まる。白色ノイズは全周波数が均等(傾き 0)。茶色(ブラウン)ノイズは白色を積分したぶん高域が 1/f² で落ちる。その中間、1/f で落ちるのがピンクノイズで、オクターブごとのエネルギーが一定になる。自然界の音や心地よいゆらぎに多く、武者利光の 1/f ゆらぎの議論で知られる。光のスペクトルになぞらえて白・ピンク・赤(茶)と区別する。
上が白色、下が茶色。白色は各サンプルが独立の乱数で、隣との関係がないので細かく震える。茶色は running += 乱数 で前の値に積み足すので、行き先が前を引きずってゆったり漂う。どちらも毎フレーム右端へ新しい一サンプルを足し、配列を左へずらして流している。
白色は端から端まで等しく荒れ、茶色は山と谷が長く伸びる。0.14 の歩幅を大きくすると茶色の振れが速くなり、白色は歩幅に関係なくいつも同じ荒さで震える。
ピンクノイズは、その中間を別ルートで作る。周波数を倍にした正弦波を何本も用意して、高い波ほど振幅を半分にしながら足し合わせる。低いオクターブが太いうねりを、高いオクターブが細かい震えを受け持ち、各オクターブのエネルギーが揃う。
// 周波数を倍にした正弦波を、1/2ずつ弱めて足す
const pink = () => {
let sum = 0
let weight = 1
let total = 0
for (let i = 0; i < octaves; i++) {
sum += Math.sin(phase[i]) * weight
total += weight
weight *= 0.5
phase[i] += freq[i]
}
return sum / total
}下は上から 7 本のオクターブを周波数の低い順に並べ、いちばん下にその重み付き和を引いた。上ほど波がゆるく、下ほど細かい。最下段の線が、上の 7 本を 1 から 1/64 までの重みで足したピンクノイズ。
上の細かく震える層と下のゆったりうねる層が、和の線の中で重なっている。weight *= 0.5 を weight *= 0.7 に近づけると高いオクターブの効きが残って白寄りに、weight *= 0.3 まで落とすと低い層だけが効いて茶寄りになる。白すぎると無機質、茶すぎると単調で、その間の 1/2 あたりがピンクになる。