UnityのNativeAudioPluginについての情報まとめ。

動作サンプル作ってみました

kzrさんのサンプルを参考に拡張して、
それをIL2CPPでコンパイルしてみたもの。(というかIL2CPPとNativeAudioPluginを組み合わせるテスト)

https://machiaworx.net/wp-content/uploads/2020/04/test_pgm.zip

そもそもNativeAudioPluginって、何をするもの?

公式の説明:
https://docs.unity3d.com/Manual/AudioMixerNativeAudioPlugin.html
(日本語版は単に直訳っぽいので、英語版のURLを参照した)

本来だとMixerに追加するエフェクト、の扱いみたい。
ただ、アウトプットを加工した上で出力することが可能なため(Callback関数で処理)、
インプットをすべてスルーしてアウトプットの処理を書くことで、
シンセサイザー等を実装してコントロールすることが可能。
ちなみにGUIを実装してそれと連携して鳴らすことも可能です。

公式リポジトリ
https://bitbucket.org/Unity-Technologies/nativeaudioplugins/src
(公式)

https://github.com/keijiro/MinimumAudioPlugin
(kzrさん作の最小限構成)

利用手順(ザックリと)

  • プラグイン作成
  • フォルダ配置
  • 名前変更(「audioplugin_XXX」という名前にすることでNativeAudioPluginと認識する
  • ミキサー上にエフェクトとして処理を追加(Add Effect)
  • 各種Callback関数が自動的に処理を開始する

プラグイン作成手順

  • DLL作成準備を行う(プロジェクトファイルが存在するのでそれ使いまわしでもいい)
  • リポジトリ内ファイル「AudioPluginInterface.h」を読み込ませる
  • 各種Callback関数の中身を記載する
  • コンパイル
  • 配置・名前変更(上記利用手順参照)

挙動のTips

  • Mixerに入ってきた音に対して自動的に処理する形
  • エフェクト名称についてはプラグイン内部で定義する。(これはどちらかというと実装Tipsかなあ)
  • ミキサー自体をソロにするとCallbackも止まるケースがある模様
  • AudioSourceへの直接的なアクセスは不可能
    (あくまで出力されたオーディオに対しストリームでアクセスできるだけ)

実装Tips

  • Callback処理については通常特段のコントロールは不要。常に鳴るものとして処理を書いておく
  • サンプリングレートは各環境に依存するため、各種構造体から取得する必要がある。
  • Callback関数の引数・戻り値については「AudioPluginInterface.h」に記載がある
  • Callback関数内に分岐によって「書き込まない」処理を行うとグリッチが発生するので注意
    つまり「何もしない処理を書き込む」前提で処理を行う必要がある
  • Editor上での処理が必要であれば特定Callback関数への値引き渡しで調整可能
  • DLL上で関数を公開することで、C#等からの関数呼び出しが可能
    ただしマングリングが必要なため、書き方は注意が必要。
    記述例:「extern “C” UNITY_AUDIODSP_EXPORT_API void xxx(xxx xxx) {}」
    (好きな関数名・引数・戻り値の型を決められます)
    マングリングについての参考URL:https://albel06.hatenablog.com/entry/2016/03/17/180000
  • 公開した関数は以下記載を追加することでC#での呼び出しが可能
    記載例:[DllImport(“AudioPluginSinOsc”)]private static extern void xxx();
  • Editor上での読み込みは、「常に読み込まれる形になる」ため、
    プラグインの内容を変更する際、Editorですでに読み込んでいる場合はEditorの再起動が必要になる。
  • あとEditor上だとずっと読み込まれてる形なので、状態を保管している場合、初期化されない状態がずっと続くため、繰り返しテストする場合に不具合が起こることが予想される。
    (素直にシーン開始時に実行する自前の変数初期化処理書いたほうがいいかも)