Oculus Audio SDKについて調べてみた

Oculus Audio SDKは、Unityなどで３Dオーディオを作れる便利なツールです。Oculus用でないアプリでも使えて、しかも無料！ありがたいですね。

このAudio SDKはVisiSonicsという３Dオーディオの専門会社の技術を活用しています。

VisiSonicsとOculusの提携
http://www.prnewswire.com/news-releases/visisonics-realspace-3d-audio-software-licensed-by-oculus-for-virtual-reality-278413231.html

このVisiSonicのRealSpace3Dという３Dオーディオ技術を使ったデモがこちらにあるので、３Dオーディオと聞いてピンと来ない方は、一度聞いてみましょう。

https://www.youtube.com/watch?v=4T-dGaO-LZc

Audio SDKについては、Oculus公式のマニュアルにすべて必要なことは書いてありますが、量が多くて英語なので、ちょっと読みづらいかもしれません。そこで、以下に簡単にまとめてみます。ちなみに、[Audio SDKを使った簡単な英語学習アプリの記事](http://qiita.com/yanosen_jp/items/2babf27c2c95f481ae69)を、THETA Advent Calenderのほうに乗せているので、そちらもご覧いただけるとうれしいです。

# ３Dオーディオの考え方

##方向の検知

我々人間は、ある音源から発せられた音が、右耳と左耳で微妙に違って聞こえることを利用して、音源の方向を推測することができます。

たとえば、向かって右寄りあるいは左寄りに音源がある場合は、左右の耳で音の到着時間の差(ITD:Interaural Time Difference)や音量の差(ILD:Interaural Level
Difference)が起きるため、左右の違いを知ることができます。
![ファイル 2015-12-19 23 07 15.png](https://qiita-image-store.s3.amazonaws.com/0/58503/24000053-659d-dae2-fa98-0361ab2aa34a.png)
音が前か後ろか、というのは音の左右差ではわからないので、音質の変化で聞きわけます。つまり、前からと後ろからでは、耳介での反射のパターンなどが異なるので、音質が変わるわけです。音の上下についても、音が肩や胸などに反射するパターンを手掛かりにすることが可能です。

こういった左右前後上下の方向による音の変化の性質を計算するのに、HRTF（頭部伝達関数）を用います。HRTFは、生身の人間やダミー人形に対して様々な方向から音を鳴らし、耳に届く時の音の特性を記録したものから割り出します。

## 距離の検知

距離の検知は、すこしやっかいです。自分が知っている音なら、音量である程度推測できますが、聞いたことのない音には使えません。

そこで、Initial Time Delayという、音源から耳に直接入ってくる音とどこかで反射した音の到達時間差を使います。耳に近く壁からは遠い音なら、耳にはすぐに直接音が入り、それからしばらくして壁で反射した音が届きます。壁に近く耳から遠い音なら、直接音と反射音の差は小さくなります。
![ファイル 2015-12-19 23 07 34.png](https://qiita-image-store.s3.amazonaws.com/0/58503/eaf802c6-3103-6e3a-485b-a0c023abab6f.png)

また、直接音は反響Reverberationはありませんが、反射音は反響の成分が入るので、その比を聞きとることも可能です。さらに、遠くの音は高音部が減衰するので、それを手がかりにもできますが、遠くの山の噴火の音のように、かなり離れた音源のみで効果が意味を持つと考えてください。

## 空間の検知

何もない草原で音を聞く場合と異なり、部屋で音を聞くと、音源からの直接音と壁からの反射音が聞こえます。音源→壁で反射→耳 と届く音のことはEarly Reflectionとよばれ、音の位置を知るのに重要です。その後には、壁を何度か反射して届く音Late Reverberation があり、それはいわゆるエコーEchoとして聞こえます。このエコーの大きさや性質で部屋の大きさを感じることができます。
![ファイル 2015-12-19 23 07 53.png](https://qiita-image-store.s3.amazonaws.com/0/58503/a53e7e90-a9d9-a587-ecb4-677a0da9ad32.png)

本来なら、部屋の壁、部屋の中の家具などを考慮して音の反射を完璧に計算するのが理想ですが、それはかなり大変です。そのため、Audio SDKではShoe Boxモデルを用い、部屋を単なる箱と考え、プレイヤーと箱の上下左右前後の壁までの距離を設定して、ReflectionやReverberationを計算しています。
![ファイル 2015-12-19 23 08 13.png](https://qiita-image-store.s3.amazonaws.com/0/58503/05895164-c512-2b3b-90a4-32b08248a5da.png)

# 音源の準備

3Dオーディオを使う際は、モノラル音源を使うのが基本です。あらかじめモノで音源を作ってください。また、低音部が主な音は位置を聞き取りにくいので、３Dオーディオにすることは避けます。また、可能な限り豊富な周波数成分を含む音を使うことで、音の定位がしやすくなります。また、メガホンのように特定の方向に音が出るような設定はできません。

# UnityでのAudio SDKのセットアップ

OculusのHPからAudio SDKをダウンロードし、解凍したら\AudioSDK\Plugins\UnityフォルダのOculusNativeSpatializer.unitypackageというパッケージをインポートします。

次に、EditorのProject Settings/AudioのSpatializer Pluginの選択肢を「OculusSpatializer」にすれば、使用可能になります。DSP Buffer Size もBest latencyにしましょう（と公式ドキュメントには書いてありますが、Oculus Audio SDK Plugins 1.1.4をUnity5.5.0p4や5.6.0p2で使うと、音が遅くなって雑音が入ります。Good latencyのほうが良さそうです）。 
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/58503/0fd12845-a721-63df-7478-4bd409cf84a9.png)

OSPNative/scenes/にRedBallGreenBallというデモシーンで動作確認しましょう。

![redgreen.PNG](https://qiita-image-store.s3.amazonaws.com/0/58503/be300082-06d8-ced0-5127-09a45fa72400.png)


# Unityシーンの設定

3Dオーディオを作るには、音源となるゲームオブジェクトを設定します。それらは、OSNP Audio SourceとAudio Sourceコンポーネントを持つ必要があります。特に、前者の設定が効いてきます。

## OSNP Audio Source

こちらでは、Spatialization Enabledをオンにして３Dオーディオを使えるようにし、反射を考慮したいならReflection Enabledをオンにしましょう。

![image](https://qiita-image-store.s3.amazonaws.com/0/58503/72387145-4551-3bc4-640f-4291573f2d81.png)

Oculus Attenuationは、距離による音量の減衰を計算します。
Rangeですが、Attenuationをオンにしている場合、音源とListenerの距離がMinimumより小さい範囲内（オレンジの円内）では、左右差などを考慮したSpatial Audioになり、MinimumとMaximum（赤の円内）の間では、距離による音量の減衰だけを考慮し、Maximumより離れると音が聞こえなくなります。Spatial Audioの計算負荷を減らすための工夫と思われます。

![image](https://qiita-image-store.s3.amazonaws.com/0/58503/cf9e6ed2-1c9e-a2c4-ca2c-d5aad401e49f.png)


## AudioSource

Outputを"Master(SpatializerMixer)"に設定します。AudioSourceにも３Dオーディオに関するパラメータがありますが、OSNP Audio Sourceを使っている場合は無視されます。

![image](https://qiita-image-store.s3.amazonaws.com/0/58503/45425c33-46dd-28e2-1707-1bf36d1a44dd.png)



## Unity Audio Mixerの設定

Audio SDKには、SpatializerMixerというAudioMixerがついてきます。こちらの"Master"を用いて、Shoe Boxモデルなどの設定を行います。

![image](https://qiita-image-store.s3.amazonaws.com/0/58503/ae607dcc-9abe-4228-8be9-28ad8f04266a.png)


まず、最初のGlobal Scaleで、Unity上の距離の単位を設定します。通常、Unityでは1unit = 1mを前提にしており、その通りにシーンを設定したなら Global Scale = 1で良いですが、小さい空間を作っていて、たとえば1 unit = 1cmにしたなら、Global Scaleを0.01に設定します。

次のEarly Reflection(上記参照）はチェックした方が良いですが、Reverb（Early Reflectionの後に来る反響音）は部屋の性質に応じて選んでください。Reverbは、Early Reflectionを有効にしないと動作しないので注意です。

Room Dimensionsは、Shoe Boxモデルのサイズを決めます。実際のシーンのサイズに合わせるのが基本です。野外のシーンの場合は、想定される音の到達距離に応じて決定します。Wall Reflection Valueは壁での反射を設定します。0なら反射無し、大きいほど反射は強くなります。1にするとフィードバックが出てしまうので、0.97までにしか設定できません。野外のように、地面以外に音の反射が想定されない場合でも、ある程度の反射を設定したほうが、音の定位がしやすくなります。

なお、これらの設定は、AudioMixer Snapshotとして保存できます。SDKのサンプルシーンReadBallGreanBallには、Interior_zoneとInit_Zoneというゲームオブジェクトがあり、それにアタッチされている、ONSP Reflection Zoneコンポーネントによって、それぞれSnapshotを選択し、AudioMixerの設定を変更できます。

![image](https://qiita-image-store.s3.amazonaws.com/0/58503/dd3c1cc3-79d0-b947-470e-31e3cead14a3.png)

たとえば、サンプルシーン内のInterior_Zoneをヒエラルキーで選択すると、シーンに以下の画面が表示されます。

![image](https://qiita-image-store.s3.amazonaws.com/0/58503/70c71b56-827f-7528-2eb4-7ea480b0c463.png)

ここで、緑の箱が、Interior_Zoneの設定が及ぶ領域で、この中にAudioListenerが入ると、Interior_ZoneのONSP Reflection Zoneコンポーネントで選択されているMixer Snapshotが有効になり、その設定でSpatial Audioが再生されます。緑の箱の大きさはScaleで調整可能です。


## 処理負荷の問題

Audio SDKは、それなりにCPUを消費します。Spatializerをつかう音源をシーンに２０個用意して実験すると、以下の通りです。

OculusSpatializerを使う場合のAudioプロファイル
![image](https://qiita-image-store.s3.amazonaws.com/0/58503/9efe94f1-ed97-ba83-6699-9088d21bf542.png)

OculusSpatializerなしの場合のAudioプロファイル
![image](https://qiita-image-store.s3.amazonaws.com/0/58503/dd95a8af-116d-b2bf-46ce-d77670c053be.png)


中の人によると、「モバイルなら３D音源は10個以下にした方がいいかも」とのこと。低音は音源定位しにくいので３Dにしない、モノローグ、BGMも３Dにしない、native audio formatをなるべく使用し、ランタイムでのデコーディングを避ける、といった工夫も可能です。また、Audio SDK使用している場合、DSP Buffer SizeをBest Latencyにすると、Audio CPUを倍くらい消費するので注意してください。



## おわりに

今回はSDKの簡単な解説だけになりましたが、次に機会があれば、３Dオーディオをよりリアルにするためのノウハウとかをまとめてみたいですね。それまでに、いろいろ勉強しておきます！



# 参考資料


Oculus Audio SDK Documentation
https://developer.oculus.com/documentation/audiosdk/latest/

REALSPACE 3D AUDIO UNITY 5 Documentation
http://realspace3daudio.com/unityplugindownloads/