AVFoundation 3Dオーディオメモ

# AVAudioEnvironmentNode

AVAudioEnvironmentNode（環境ノード）は3Dオーディオ環境をシミュレートするミキサーノードで、AVAudioPlayerNode などの AVAudioMixing プロトコルに準拠するノードをソースとして接続することができる。AVAudio3DMixing プロトコルに準拠しているが、これは現在は  AVAudioEnvironmentNode のみで実装されている。

<img width="500" src="https://qiita-image-store.s3.amazonaws.com/0/3603/de1838c7-be25-d09e-e887-50c5ce9382f3.png">
*WWDC15 507 What's New in Core Audioより*

環境ノードは暗黙の「リスナー」を持っていて、リスナーの位置と方向を制御することにより、ユーザーは仮想世界にいるような体験をすることができる。また環境を特徴づける補助的な距離減衰（障害物など）や残響（リバーブ）のプロパティを定義することもできる。

環境ノードは現在は2チャンネル以上のフォーマットの合成をサポートしていない。ある入力がステレオの場合はそのオーディオは空間化されずにそのまま通される（ステレオには何も効果がない）。なのでモノラルの入力を接続して空間化しなければならない。

<img width="500" src="https://qiita-image-store.s3.amazonaws.com/0/3603/6e11d0dd-ba17-8e95-9822-2b14ca3fe72d.png">
*WWDC15 507 What's New in Core Audioより*

有効なレンダリングアルゴリズムは AVAudioEnvironmentNode の`applicableRenderingAlgorithms` メソッドで取得可能。

# AVAudio3DMixingRenderingAlgorithm

定義されているオーディオレンダリングアルゴリズムの種類。入力ノードに対して `renderingAlgorithm` を設定する。

## .EqualPowerPanning

デフォルトのレンダリングアルゴリズム。
最も単純なパンニング（左右に動かす）アルゴリズムで、ステレオフィールドにミキサーバスのデータをパンする。

## .StereoPassThrough

モノラル／ステレオ入力を直接ミキサーに渡す。3D レンダリングを無効にする。

## .SoundField

マルチチャンネル（サラウンド）へレンダリングするためのアルゴリズム。

## .SphericalHead

シンプルなバイノーラル合成アルゴリズム。HRTF よりも CPU を使わない。

## .HRTF

頭部伝達関数 (Head Related Transfer Function) を利用した高品質なバイノーラル合成アルゴリズム。ヘッドホンで3次元空間をエミュレートする。SphericalHead よりも CPU を消費する。

# オーディオの空間化

空間化のためにソースオーディオの位置を設定する。position では `AVAudioMake3DPoint` で3次元空間内の位置を指定できる。障害物の設定には obstruction, occlusion を使用する。

<img width="500" src="https://qiita-image-store.s3.amazonaws.com/0/3603/c8a32538-e03c-614e-2dd3-6f352d9c29c5.png">
*WWDC15 507 What's New in Core Audioより*

<img width="500" src="https://qiita-image-store.s3.amazonaws.com/0/3603/bbe600c9-c9af-691a-a711-bf46b6161f9d.png">
*WWDC14 502 AVAudioEngine in practiceより*

<img width="500" src="https://qiita-image-store.s3.amazonaws.com/0/3603/ccd74f3d-b3dc-bf75-385d-55851671f3e0.png">
*WWDC14 502 AVAudioEngine in practiceより*

<img width="500" src="https://qiita-image-store.s3.amazonaws.com/0/3603/bab4b4a6-161f-3079-eb10-f9b32804b8c0.png">
*WWDC14 502 AVAudioEngine in practiceより*

環境ノードのリスナーの位置と方向を設定して、オーディオの聞こえ方を制御する。
listenerPosition は `AVAudioMake3DPoint` で3次元空間内の位置を、`listenerAngularOrientation` は、yaw, pitch, roll の3要素で角度を指定する。

<img width="500" src="https://qiita-image-store.s3.amazonaws.com/0/3603/dd70ea38-0405-efbd-7f38-4e020bd99203.png">
*WWDC14 502 AVAudioEngine in practiceより*

## 補足：yaw, pitch, roll

<img width=400 src="https://qiita-image-store.s3.amazonaws.com/0/3603/fede64d6-5092-b269-f056-9771582ce8a5.png">
*https://ja.wikipedia.org/wiki/ローリング*

yaw … 船体の左右の向き
pitch … 船体の上下の向き
roll … 船体の前後を軸とした回転

# 資料

## リファレンス

AVAudio3DMixing
https://developer.apple.com/library/ios/documentation/AVFoundation/Reference/AVAudio3DMixing_Protocol/

AVAudioEnvironmentNode
https://developer.apple.com/library/ios/documentation/AVFoundation/Reference/AVAudioEnvironmentNode_Class/index.html

## 参考になる WWDC セッション

- [WWDC2016 Delivering an Exceptional Audio Experience](https://developer.apple.com/videos/play/wwdc2016/507/)
- [WWDC2015 What's New in Core Audio](https://developer.apple.com/videos/wwdc/2015/?id=507)
- [WWDC2015 Audio Unit Extensions](https://developer.apple.com/videos/wwdc/2015/?id=508)
- [WWDC2014 What's New in Core Audio](https://developer.apple.com/videos/wwdc/2014/?id=501)
- [WWDC2014 AVAudioEngine in Practice](https://developer.apple.com/videos/wwdc/2014/?id=502)


## 実装例など

AVAudioEngine 3D Audio Example
https://developer.apple.com/library/mac/samplecode/AVAEGamingExample/Introduction/Intro.html

Details on using the AVAudioEngine
http://stackoverflow.com/questions/33155925/details-on-using-the-avaudioengine

iOS 3D Audio Test
https://github.com/lazerwalker/ios-3d-audio-test

How to set an AVAudio3DMixingRenderingAlgorithm for binaural mixing
http://stackoverflow.com/questions/33941606/how-to-set-an-avaudio3dmixingrenderingalgorithm-for-binaural-mixing

http://www.gdomc.com/0503/attaching-audiounit-effects-to-scnaudiosource-nodes-in-scenekit/

https://github.com/ooper-shlab/AVAEGamingExample-Swift