作ったもの
頭部伝達関数を使って音にエフェクトをかけ、ヘッドホンから出た音が頭の外側で鳴っているような感じで再生されるデモを作りました。
また、手っ取り早く試せるようにWebGLで作成しました。
イヤホン・ヘッドホンを着けて聞いてみると、頭の周りで音が鳴っているような感じがすると思います。
WebGLにるデモ
作ったものはこちら。
HRTF-Demo-WebGL
使い方
- 画面上をタッチする。タッチと同時に音が鳴る。(大きい音がするので注意)
- 緑の円がタッチしたところに表示される。この円はドラッグで動かせる。
- 緑の円の動きに少し遅れて赤い円が動く。
- 赤い円の方向に対応して鳴っている音の方向が変化する。
- 中央黄色い円を押すとサウンドがエフェクトなしで再生される
- 画面下側のボタンを押すと再生される音が変わる
(再生中にノイズが発生しますが仕様です。)
ソースコード
https://github.com/morishift/HRTF-Demo
Unity 2019.4.11f1
実装
音に対して頭部伝達関数と呼ばれるデータ(実際には方向に対応するインパルス応答)を使って、選択した方向から音が鳴っているようなエフェクトをかけています。以下の記事がわかりやすいです。
立体音響を動的に生成する
サウンドファイル
wavファイル、44100Hz,16bitモノラル
(サンプル曲はGaragebandで作成)
畳み込み計算
サウンドデータとインパルス応答との畳み込み計算をするわけですが、
定義通りの畳み込み計算をそのまま実行すると時間がかかりすぎます。
なので、重畳加算法を使います。
頭部伝達関数データ
頭部伝達関数のデータとして、以下を使用しました。
元データには頭に対して上下方向の情報も含まれています。このアプリでは頭と同じ高さのデータのみを利用しています。
Bill Gardner and Keith Martin
MIT Media Lab
HRTF Measurements of a KEMAR Dummy-Head Microphone
https://sound.media.mit.edu/resources/KEMAR.html
無理やりなところ
Unity WebGLのサウンドに関する機能に制限があり、無理やりな事をやっています。
WebGL でオーディオの使用
Unity公式でアナウンスされているように、UnityWebGLではサウンドについては一部機能しか使えません。単純に音を再生するだけなら問題ありませんが、それ以上のことをやろうとしてもあんまり上手く行きません。(別途プラグインを導入すれば解決できるのかも)
AudioClipから波形データが取得できない
Unityではサウンドの波形データはAudioClipオブジェクトから取得できます。
しかしWebGLではそれができません。(AudioClip.GetData()が使えない。SetData()は使える。)
そのため、Unityプロジェクト内にバイナリデータとしてwavファイルを配置しておき、実行時に直接読んで波形データを取得しています。
AudioClipのストリーミング再生ができない
AudioClipでストリーミング再生ができれば音にエフェクトを加えながら再生させることもやりやすくなります。しかし、WebGLではサポートされていません。
そのため、1秒程度のAudioClipを連続的に生成・再生しています。
一つのAudioClipで再生するサウンドデータは32分割し、その分割した断片に方向に対応するインパルス応答を畳み込むようにしました。
音の方向を選択した直後に鳴っている音が変更されず、遅れて反映されるのはこれに起因します。また、AudioClipとAudioClipのつなぎ目のところでかなり大きいノイズが発生します。
既存の立体音響SDK
Unityで使える立体音響SDKはすでにあります。
本気で立体音響の実装を考えるならこれらを試すのが良いと思います。
Audio Spatializer SDK
https://docs.unity3d.com/ja/current/Manual/AudioSpatializerSDK.html
Resonance Audio
https://resonance-audio.github.io/resonance-audio/develop/unity/getting-started