背景
- Android で手っ取り早く C++ で wav 音声を再生したい
- Android Vulkan で compute shader で STFT 処理とか spatial audio 処理した音声データを再生したい
- Vulkan と一緒に使いたいので, Android 8 以降対応でよい.
Native audio library
AAduio(Android 8.0 or later) と OpenSLES がありますが, どちらも低レイヤーなので, wav をお手軽再生とかはできません.
既存ライブラリ
手っ取り早く Android C++ で wav 再生は SoLoud があります.
クロスプラットフォームでよいのですが, Android はあまりメンテされていないようで, CMake 用の設定がなかったり, backend は SLES だけだったり, logcat になぜか多量の debug warning が出たりといまいちです.
Oboe
C++14 or later になりますが(Android NDK は最近 C++17 or later 対応なので問題はない), Oboe https://github.com/google/oboe が推奨っぽいので使ってみます. 実態としては AAudio, OpenSLES のラッパーです.
クロスプラットフォームだとうれしかったですが, Android 限定です. PC を使うときは SoLoud にするなどと切り替えるとよいかもです.
Oboe 自体も, 本体は wav load とかはには対応していませんが, samples の parselib に wav などのローダがあります.
github issue を見ると, 古い Android では動かなかったりあるようですが, とりあえず AAudio(Android 8) 以降の端末では大丈夫そうでしょうか.
C++14
Android で C++14 だと, spdlog と組み合わせるときに不都合がありました. ヘッダのインクルード順にはお気をつけください.
Android NDK + C++14 設定 cmake で no member named make_unique
in namespace std
エラーなどが出る
https://qiita.com/syoyo/items/5274fcde46520ff301f4
組み込む
CMake 設定がありますので, これを参考にするとよいでしょう.
Oboe を使っての wav のロードと再生は, drumthumber サンプルを参考にします.
同じく samples にある, iolib
(play/stop とか簡単に使える API?), parselib
(wav loader) を使っています.
これらは, ファイル数は多くないので, 自前の CMakeLists にソースコードリスト直追加が楽かと思います.
(add_subdirectory だと循環参照があって, --whole-archive
リンカオプションを指定しないとリンクエラーになる)
iolib
に wav をロードして再生する SimpleMultiPlayer
があります. ただ, エラーチェックが無かったり, 初期化せずに wav ロードすると seg fault するなど, コード品質が微妙です.
音声の再生
SimpleMultiPlayer
の triggerDown で再生できます. triggerUp で再生を終了できます.
再生の停止(pause)はなさそうなので自前実装が必要そうです.
wav のロード
dr_libs
https://github.com/mackron/dr_libs
で読んでもいいかもしれません.
Permission は?
audio を鳴らすだけなら, AndroidManifest.xml での permission 設定(+ アプリ側での permission request)は不要です.
マイクから録音するときは permission が必要になります.