ゲームの壁は音に何をするのか:Web Audio での計測
Earshot の薄い壁の設定は -6 dB ですが、これを通したホワイトノイズは 14.4 dB 小さくなり、高域は 23.7 dB 小さくなりました。ローパスフィルターは明るさだけでなくエネルギーも取り除くので、ゲインの設定値だけでは壁が奪う量を少なく見積もることになります。Earshot のデフォルトの材質をそれぞれオフラインでレンダリングして、これらの数値を得ました。ホワイトノイズの数値なので、音声では異なります。
| 経路(リスナーから 1 タイル) | フィルターとゲインの設定 | 全体の減衰 | 高域の減衰 |
|---|---|---|---|
| 遮るものなし | なし | 0 dB | 0 dB |
| 薄い壁 | 2000 Hz、-6 dB | 14.4 dB | 23.7 dB |
| 厚い壁 | 1200 Hz、-12 dB | 22.5 dB | 38.5 dB |
| 薄い壁と厚い壁 | 700 Hz、-18 dB | 30.9 dB | 54.0 dB |
ゲインの設定値が減衰量にならない理由
ゲインはすべての周波数に等しく効きます。ローパスフィルターはそれに重なり、高い周波数ほど多く取り除きます。ホワイトノイズは 1 Hz あたりのエネルギーが等しいので、エネルギーの大半は 2 kHz より上にあり、2000 Hz のフィルターはその多くを取り除きます。薄い壁の設定値と全体の減衰の差 8.4 dB は、これで説明できます。
音声のエネルギーはもっと低い帯域に集まっているので、声なら全体の減衰は小さくなると予想しています。ただし、今回は計測していません。子音はそれより高い帯域にあるので、言葉が聞き取れるかどうかは、全体の減衰より壁の高域の減衰によく表れます。薄い壁は、言葉が聞き取れるようになるまで耳で調整しました。
これらの値を調整するときは、2 つを一緒に変えてください。カットオフを下げると壁の音も小さくなるので、暗い音の壁なら、最初に考えたほどゲインを下げなくて済むかもしれません。
リバーブの残響
リバーブは音が止まった後に現れます。音源を 3 秒で止め、3.2 秒から 3.4 秒までを計測しました。
| 設定 | 残響のレベル(再生中の遮るものなしの経路は -18.3 dB) |
|---|---|
| リバーブなし | 無音 |
| 部屋、0.4 秒、ウェット -18 dB | -90.6 dB |
| 洞窟、1.8 秒、ウェット -12 dB | -49.4 dB |
音源の再生中のレベルは、どちらも遮るものなしの経路との差が 0.1 dB 以内でした。Earshot はドライ信号を残したまま、そこにリバーブを足すからです。各リバーブは、中にあるすべての音源が送る共有の ConvolverNode 1 つです。コンボルバーは負荷が高いので、ボイスの数に応じて増やすべきではありません。
手法
テストは test/offline.mjs で、Earshot のテストスイートの一部として実行されます。
- Playwright のヘッドレス Chromium で、48 kHz の
OfflineAudioContextを使用しました。 - 振幅 0.3 のホワイトノイズ 3 秒をレンダリングごとに新しく生成し、2 秒から 3 秒までを RMS で計測しました。
- 高域の数値は、同じ出力の 2 つ目のチャンネルに通した 4 kHz のハイパスフィルターから得ています。このフィルターは 12 dB/オクターブのバイクアッドなので、4 kHz のすぐ下のエネルギーも含まれます。
- 表は 1 回の実行の結果で、0.1 dB まで読み取りました。ノイズとリバーブのインパルスはランダムなので、数値は実行ごとに動きます。再実行では、壁で約 0.1 dB、洞窟の残響で 0.4 dB 動きました。
オフラインでレンダリングするのは、ヘッドレスブラウザのライブ音声が計測に向かないからです。私たちの実行では、ライブの AudioContext のクロックは実時間の約 0.8 倍で進みました。これに合わせて計った時間はずれていきます。
この結果からわからないこと
- 音声。 すべてホワイトノイズの結果で、声のエネルギー分布とは異なります。
- 現実の壁。 材質は耳で調整したゲームの設定で、音響モデルの裏付けはありません。
- 人の知覚。 デシベルからは、言葉が聞き取れるかどうかはわかりません。聞き取りは耳で判断しましたが、正式な聴取テストはしていません。
- 他のブラウザ。 フィルターは Web Audio の仕様に従いますが、計測したのは Chromium だけです。
自分で試すには、debuffjp/earshot をクローンして npm ci、npm run build、node test/offline.mjs を実行します。材質を変えて、何が動くか見てみてください。