iOS / Android 組み込み

エディタの「組み込みキットを生成」が出力する tb_integration_kit/ を使えば、 Swift / Kotlin 開発者は C++ に一切触れずに音を鳴らせます。

前提 — リポジトリ配置の規約

エンジンのリポジトリ ToneBeyondAudioEngine は、ゲームアプリのリポジトリと 兄弟ディレクトリに clone します(iOS / Android 共通の規約):

Projects/
├── ToneBeyondAudioEngine/     ← エンジン + エディタ
└── YourGame/                  ← あなたのアプリ

組み込みキットの中身

ファイル役割
ToneBeyondFacade.h / .mmiOS 用 TBAudio クラス(ObjC++。Swift から直接呼べる)
android/TBAudio.ktAndroid 用 Kotlin ファサード(同じ API 形)
android/tonebeyond_jni.cpp ほかJNI ブリッジとアプリ側 CMake
tb_bank_export.tbbビルド済みサウンドバンク
README_integration.md / android/README_android.md本ページと同じ手順の同梱版(日英)
どちらのファサードにも、バンク内の全イベント名から TBEvent_* 定数が自動生成されています。イベント名のタイプミスは コンパイルエラーになり、IDE の補完にサウンド一覧が出ます。

iOS(Xcode + Swift)

  1. フレームワーク(初回のみ):
    cd ToneBeyondAudioEngine && ./tools/build_xcframework.sh
    できた build/ToneBeyondRuntime.xcframework を Xcode の ターゲット General > Frameworks へドラッグ(Embed は Do Not Embed)。
  2. キットを入れる: ToneBeyondFacade.h / .mmtb_bank_export.tbb をプロジェクトへドラッグ(ターゲットにチェック)。 Swift プロジェクトはブリッジングヘッダ作成を承諾し、 #import "ToneBeyondFacade.h" を1行追加。
  3. 鳴らす:
    TBAudio.start()                                  // 起動時に1回
    TBAudio.loadBankNamed("tb_bank_export")
    TBAudio.postEvent(TBEvent_sword_swing)           // 効果音
    TBAudio.postEvent(TBEvent_boss_roar, x: 3, y: 0, z: -5)  // 3D ワンショット
    TBAudio.setParameter("Danger", value: 0.7)       // RTPC(カーブはエディタ)
    TBAudio.setListenerX(px, y: py, z: pz)           // 毎フレーム
    TBAudio.setBusVolume("BGM", value: 0.5)          // カテゴリ音量(設定スライダー直結)
    TBAudio.stopEvent(TBEvent_bgm_main, fadeMs: 400) // フェード停止

Android(Android Studio + Kotlin)

  1. ファイルを置く: キットの android/tonebeyond_jni.cppandroid/CMakeLists.txtapp/src/main/cpp/ へ、 android/TBAudio.ktapp/src/main/java/jp/tonebeyond/audio/ へコピー。
  2. gradle に追記app/build.gradle):
    android {
        defaultConfig {
            externalNativeBuild { cmake {
                arguments "-DTB_ENGINE_DIR=${rootProject.projectDir}/../ToneBeyondAudioEngine"
            } }
            ndk { abiFilters "arm64-v8a" }
        }
        externalNativeBuild { cmake { path "src/main/cpp/CMakeLists.txt" } }
    }
    ランタイムはここでエンジンのソースから直接ビルドされます (エンジンを更新したらアプリを再ビルドするだけ)。
  3. バンクを置く: tb_bank_export.tbbapp/src/main/assets/ へ。
  4. 鳴らす:
    TBAudio.start()
    TBAudio.loadBankFromAssets(this, "tb_bank_export")  // assets→filesDir コピーも自動
    TBAudio.postEvent(TBEvent_sword_swing)
    TBAudio.setParameter("Danger", 0.7f)
    TBAudio.setBusVolume("BGM", 0.5f)                  // カテゴリ音量
    TBAudio.stopEventFaded(TBEvent_bgm_main, 400f)     // フェード停止

音を差し替えるとき(イテレーション)

Nuendo で音を直す → 同じファイル名で上書き書き出し → エディタで再インポート → 「.tbb をビルド」→ アプリ内の .tbb を置き換え。 イベント名が変わらない限り、アプリのコードは1文字も変わりません

本格運用では bank.json をリポジトリにコミットし、Xcode の Run Script Phase で bankc bank.json Resources/tb_bank_export.tbb を実行すると、⌘B だけでバンクが 常に最新になります(差し替え忘れが構造的に消える)。

CI でバンクを自動ビルド(GitHub Actions)

エンジンリポジトリの templates/game_ci/soundbank.yml をゲームリポジトリの .github/workflows/ にコピーすると、audio/ 配下の変更を push する たびに CI が bankc をビルドして .tbb を焼き、アーティファクトとして添付します。 エディタの「bank.json 書き出し」は相対パスで出力されるので、bank.json と WAV を リポジトリにコミットするだけで動きます(プライベートのエンジンリポジトリを参照する場合は GH_ENGINE_TOKEN シークレットに read 権限の PAT を設定)。ローカルでも tb_editor --db <db> --build-bank <out.tbb> で同じものをヘッドレスに 焼けます。

発注書方式 — コードと音の並行作業

ゲームリポジトリの直下に tb_sound_requests.json を置き、 postEvent を書くコミットで必ず1エントリ追記します (音はまだ無くて構いません — 未登録イベントはランタイムが安全に無視します):

{ "requests": [
    { "name": "coin_pickup", "desc": "コイン取得。明るく短いキラッ",
      "length": "0.3秒前後", "loop": false, "3d": false } ],
  "params": [
    { "name": "Danger", "desc": "危険度 0..1。BGM緊迫ステムの音量を駆動" } ] }

サウンド担当はエディタの「ゲームプロジェクト...」でこのファイルと .tbb を突合し、 未制作の一覧(説明・希望尺つき)を見て Nuendo に向かいます。 スキーマの全項目は リファレンスへ。

実機プロファイリング

実機の検証ビルドで:

ToneBeyond::Engine::StartProfiler("192.168.x.x", 9990);  // Mac の IP

Mac と同一 Wi-Fi なら、エディタ右下に発音状況と RTPC 値がリアルタイム表示されます。 リリースビルドでは呼ばないでください(10Hz の UDP 送信が走ります)。

トラブルシューティング

症状確認すること
start() が false他アプリのオーディオ占有 / デバイス。iOS 実機ではサイレントスイッチも
loadBank が 0.tbb のターゲット所属(iOS)/ assets 配置(Android)/ ファイル名
特定の音だけ鳴らないイベント名のつづり(定数を使えば起きません)。Profiler でイベントが届いているか見る
Android のビルドエラーTB_ENGINE_DIR のパス(兄弟ディレクトリに clone されているか)
音がプチプチ切れる原理上エンジン起因では起きません(ゼロアロケ保証)。Profiler の dropped を確認