Steam Audio SDKを使ってみた

# Steam Audio SDKとは 
![625f26e30c0b81e904fb97c2ed7c783e3921ec14.png](https://qiita-image-store.s3.amazonaws.com/0/82250/4802f1ad-4654-05c3-70c2-5b56f036b2ab.png)

日本時間2/24(金)付で米Valve社がリリースしたVRコンテンツ向けのAudio SDK。
[Steam Audio](https://valvesoftware.github.io/steam-audio/)

HRTF(頭部伝達関数)ベースのバイノーラルオーディオから、レイキャストオクルージョン、部分オクルージョン、反響、さらには照明の焼き付けのように音の伝搬や反響の焼き付けも行えるという代物。

今までこうしたVRコンテンツにおけるSDKと言えばOculus社のものが主流だったが、やっとSteam公式のものもリリースされたといった感じ。

元々1月にValve社が3D音響メーカーのimpulsonicを買収したというニュースを聞いて、Valveも本格的にAudio周りの着手を行ったか～と思っていたら1か月後にはリリースというスピード感である。
[3D音響メーカーimpulsonic、SteamVRを提供するValveに買収される](http://vrinside.jp/news/impulsonic/)

さっそくどんなことができるかDocumentを読みながら軽く触ってみた。

## 今回作成したデモ
<blockquote class="twitter-video" data-lang="ja"><p lang="ja" dir="ltr">Steam Audio SDKが2/24にリリースされたので備忘録替わりにQiitaにまとめた。<br>音の回り込みの表現とかが比較的簡単に実装可能。<br><br>Steam Audio SDKを使ってみた <a href="https://twitter.com/Qiita">@Qiita</a> <a href="https://t.co/C3CwDTmM6d">https://t.co/C3CwDTmM6d</a> <a href="https://t.co/wOV556NQD9">pic.twitter.com/wOV556NQD9</a></p>&mdash; go (@0505_lab) <a href="https://twitter.com/0505_lab/status/835773384608788481">2017年2月26日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

## ダウンロード方法
Steam公式サイトからダウンロード。
[Download Steam Audio](https://valvesoftware.github.io/steam-audio/downloads.html)
Unityで使用する場合はUnityPackageをダウンロードします。現在のverは2.0-beta.1
あとは自分のプロジェクトにimportし、ひたすらDocumentを読む。

## まず始めに
1. インポートするとWindowにPhononというボタンが追加されているのでクリック
2. Generalタブをクリックし、Audio Engineに「Unity Audio」が選択されているのを確認
3. 一旦シーンを保存

ここで気がついたのだが、Steam Audio SDKの中身は紛れもなくimpulsonicが作っていた「Phonon」であることがわかる。
Audioの再生処理自体は既存のUnityのシステムを使用し、HRTFや反響のシュミレーションをPononが行うためここでUnity Audioを選択する。
 
## HRTFを用いた3Dオーディオ化(バイノーラルオーディオ)
![SnapCrab_NoName_2017-2-26_16-12-58_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/82250/645a02b7-231a-848d-9413-3bec12f12529.png)

1. Audio SourceのアタッチされたGame Objectを選択
2. **Phonon Effect**コンポーネントをアタッチ

- *Direct Binaural Enabled* : チェックボックスをオンにすることでHRTFを使用
- *HRTF Interpolation* : NearestとBilinearから補完方法の選択
    - Nearest : 最も近い方向からHRTFを計算
    - Bilinear : ４方向からHRTFを計算、周囲を見回したときBilinearの方がなめらかに補完されるが、Nearestに比べてCPU使用量は大きい
- *Direct Occulution Option* : AudioSourceからListenerの間に遮蔽物があるか判断するか選択する
    - None : 遮蔽物を無視する
    - Raycast : 1本のRayを飛ばして遮蔽物があるか判断、ある場合にはListenerに届く音をブロックする
    - Partial : Source Radiusの設定に基づいていくつかのRayを飛ばす、サウンドの音量はListenerからどれくらいAudioSourceが見えているかで決定される

Raycast、Partialを使用する場合は後述する**Steam Audio**の設定が必須

- *Physics Based Attenuation* : 距離減衰させるかを選択、UnityのAudio SourceにもAttenuationのパラメーターがあるため、2重で適用されるのを防ぐためどちらかオフにする
- *Direct Mix Fraction* : 全体にどのくらいミックスさせるか

## Steam Audioの設定方法
オクルージョンや環境依存のエフェクトを適用するには、影響させるオブジェクトに対して、ジオメトリのタグ付けと音響マテリアルの設定、Listenerに対して環境エフェクト用コンポーネントの設定が必要

### ジオメトリのタグ付け
Mesh Rendererを持つGame Objectに対してタグ付けをする際には**Phonon Geometry**コンポーネントを使用する

![SnapCrab_NoName_2017-2-26_16-14-29_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/82250/53f1aee1-aab8-4b39-f502-77684f869927.png)


1. Mesh Rendererを持つGame Objectを選択
2. **Phonon Geometry**コンポーネントをアタッチ

子オブジェクトにMesh Rendererを持つGame Objectの入った親オブジェとに対してPhonon Geometryをアタッチすることですべての子要素をタグ付けすることも可能。その際にはExport All Childrenをオンにする。


### 音響マテリアルの設定
Phonon GeometryコンポーネントをアタッチしたGame Objectに**Phonon Material**コンポーネントをアタッチする。
さきほど同様、ルートオブジェクトにアタッチすることで全ての子要素に設定を反映させることも可能。

![SnapCrab_NoName_2017-2-26_16-15-6_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/82250/76951da3-c23c-3fef-9ea5-77be7374ff9b.png)

1. Phonon GeometryコンポーネントをアタッチしたGame Objectを選択
2. **Phonon Material**コンポーネントをアタッチ

多くのオブジェクトが同一のマテリアルで個別に設定するのが大変な時は、PhononウィンドウにあるSceneタブのグローバルデフォルト設定が適用されるので個別設定しなくても大丈夫。
Presetはだいたいの使用が想定されるマテリアルは揃っている。それでも該当しない場合はCustom設定を作成することも可能。

### Audio Listenerの設定

![SnapCrab_NoName_2017-2-26_16-15-49_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/82250/116744ac-9115-ee97-0e34-bab5c44d14c9.png)

1. Audio Listenerを持つGame Objectを選択
2. **Environment Component**、**Environment Renderer Component**をアタッチ

この2つがないとエラーログで怒られる

### Pre-Export
ジオメトリのタグ付け、音響マテリアルの設定が終わったらSceneのPre-Exportを行う

![SnapCrab_NoName_2017-2-26_16-16-40_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/82250/e25b6922-9901-bada-b3d0-ae40ebd2c33d.png)

1. UnityメニューのWindowからPhononを選択
2. Sceneタブをクリックし、Pre-Export Sceneボタンをクリック
3. 出力されたデータはStreaming Assets以下に.phononsceneというファイル名で保存される

## 環境エフェクトの設定方法

ここでは音の反射などの環境依存のエフェクトに対してAudio Source側の設定を行います

![SnapCrab_NoName_2017-2-26_16-17-29_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/82250/b5728f4d-51cb-dcba-2983-b19a80a982c8.png)

1. Audio SourceのアタッチされたGame Objectを選択
2. **Phonon Effect**コンポーネントをアタッチ
3. Phonon EffectのReflected Sound設定を調整

Audio Listenerに対してアタッチすることも可能で、その場合はListener側のミックスされた音に対して環境エフェクトが適用される。これによってAudio SourceとListenerの間に遮蔽物があっても反響音が計算されるため、より現実に近いまわり込む音を表現することができる。

- *Enable Reflectionsd* : オンにすることで物理ベースの環境エフェクト(音の反射計算)が適用される
- *Simulate Mode* : RealtimeとBakedから環境エフェクトの計算方法を選択する
    - Realtime : ゲームプレイ中、常に環境エフェクトの計算が行われる、変化に対して柔軟に対応させることが可能だが、CPU使用量は大きい
    - Baked : あらかじめ計算を行い、シーンと一緒に保存しておく、主に静的シーンにおいてメモリ消費量の増加におけるCPUコストを削減することができる
- *Indirect Mix Fraction* : 反響音のミックス全体に対して占める割合を調整する
- *Indirect Binaural Enabled* : オンにするとHRTFベースの3Dサウンドに間接音をレンダリングする、これによって反射音に対する指向性が向上し、没入間を高めることができる、ただしCPU使用量が少し大きくなる

## Phonon Mixer Componentの適用

Audio Listenerに**Phonen Mixer Component**をアタッチすることで、環境エフェクトの計算にSteam Audioを使用することができる

![SnapCrab_NoName_2017-2-26_16-18-4_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/82250/b87db018-1764-ed8b-9085-1359dcdf7f3f.png)

1. Audio ListenerのアタッチされたGame Objectを選択
2. **Phonon Mixer Component**をアタッチ

Phonon Mixer Componentを使用することですべてのPhonon Effect ComponentはUnityのAudio Pipelineを通らずに処理される。ミックスされたものをAudio Listenerに返す前に最適化されたミックスを行うのでCPU使用量を小さくすることができる。しかし、UnityのAudio Pipelineを通ることはないのでPhonon Effectを適用した後は追加のエフェクトを適用することができない。
Audio Listenerに同時にPhonon EffectとPhonon Mixer Componentをアタッチすることはできないので注意。

- *Indirect Binaural Enabled* : オンにすることで反響音に対してHRTFを適用することができる
Phonon Mixer ComponentのIndirect Binaural Enabledをオンにすると、Phonon Effectのものは上書きされる

## 環境エフェクトのBake

ライトマップのBakeのように反響計算を適用する静的なオブジェクトやListenerに対してはあらかじめBakeを行うことができます。
今回は自分の使用用途に当てはまらなさそうなので割愛します。
いずれ時間のある時に追記としてまとめたいと思います。

## まとめ
事前準備として、既存のGame ObjectやListenerに対していくつかのコンポーネントをアタッチする必要はあるが、遮蔽物に対しての音の遮断やまわり込み、反響を表現できるのは大きい。
音の定位感に関してはOculus SDKのものとそれほど差は感じなかったが、Occlusionとの組み合わせやさらなるチューニング次第で音の上下感、前後感の表現も可能だと感じた。