すべての形式のページ ↓
グラフィックとメディア

WAV — 効果音とサウンドバンクの結び付け

出典:coreprime/kbot @ 0ab97bf · GitHubで編集

Total Annihilationの効果音(ユニットの音声サンプル、武器の着弾音、UIのクリック音)は、ごく普通の8ビット / 16ビットPCMのWAVファイルです。入れ物としてTA独自の要素は何もありません。面白いのは結び付けの部分です。ユニットのFBI、武器のTDF、そして全体のUIが、3段階の間接参照を通じてファイル名をサウンドバスへと送る仕組みです。

Tip

自分で試す

# Play one directly
ls $(kbot ctx path)/sounds/ | head
afplay $(kbot ctx path)/sounds/cmdsel1.wav   # macOS
aplay  $(kbot ctx path)/sounds/cmdsel1.wav   # Linux

# The web UI also previews WAV/MP3 inline
kbot mount $(kbot ctx path) --server

ディスク上はただのWAV

WAVファイルはsounds/にあります。標準のRIFF WAVE形式に従っているので、WAVを再生できるものなら何でもこれを再生できます。kbotはこれを独自の形式としては解析せず、エクスプローラーはブラウザーの<audio>要素に任せています。

Cavedogが同梱したファイルの典型的なエンコード:

項目 値
サンプリングレート 22050 Hz(大半)、11025 Hz(一部のUIのクリック音)
ビット深度 8ビット符号なしPCM
チャンネル モノラル
長さ 0.1〜3秒
ファイルサイズ 5 KB – 200 KB

MODでは16ビットのステレオのサンプルを同梱していることもときどきあります。エンジンはそれも受け付けますが、メモリを多く使います。


結び付けの3つの層

「ARMコマンダーを選択したときに何が鳴るか」を調べると、次のような連鎖をたどります。

   FBI                gamedata/sound.tdf            sounds/
┌─────────────┐     ┌───────────────────────┐    ┌──────────────┐
│ units/      │     │ [ARM_COM]             │    │ cmdsel1.wav  │
│ armcom.fbi  │     │   {                   │    │              │
│             │ ──▶ │     select1=cmdsel1;  │ ──▶│              │
│ Sound       │     │     ok1=cmdok1;       │    │              │
│ Category=   │     │     ...               │    │              │
│   ARM_COM;  │     │   }                   │    │              │
└─────────────┘     └───────────────────────┘    └──────────────┘
   1. FBI picks       2. sound.tdf maps             3. WAV file
      a category         event → filename              on disk

第1層 — FBIのSoundCategory

ユニットのFBIがカテゴリを指定します。

[UNITINFO]
{
    UnitName=ARMCOM;
    SoundCategory=ARM_COM;     // ← points at [ARM_COM] in sound.tdf
    ...
}

カテゴリはユニットの間で共有されます。ARMコマンダーのすべての派生型や、ARMのすべてのKボットが同じカテゴリを指すので、選択時の音声が陣営の中で統一されます。

第2層 — gamedata/sound.tdf

このTDFは、カテゴリの中で、エンジンのイベントをWAVのファイル名に結び付けます。

[ARM_COM]
{
    select1=cmdsel1;       // Selecting the unit
    ok1=cmdok1;            // Movement order acknowledged
    arrived1=cmdarvd1;     // Reached destination
    cant1=cantdo4;         // Order rejected ("I can't do that")
    underattack=warning1;  // Took damage
    count5=count1;         // Commander self-destruct countdown (5)
    count0=count6;         // …countdown (now)
    canceldestruct=cancel2;
}

ほとんどのイベント名に、1という接尾辞が付いている点に注目してください。どのイベントにも、選択肢の一群を持たせることができます。番号のないキー(select)と、番号付きのキーselect1、select2、select3…です。エンジンは変化を出すために、その中から1つをランダムに選びます。select1しか定義していなければ、毎回同じ音声が鳴ります。

TA 3.1cは各イベントについて、番号のないキーがあればそれを読み、続いてKEY1、KEY2…を最初に抜けている番号まで読みます。select1=kbarmsel; select3=kbarmse2;の場合は、select2が抜けているところでリストが終わるので、鳴るのはkbarmselだけです(番号のないキーがなくても、番号付きのキーの読み込みは止まりません)。空の値は、無音の選択肢になります。下に挙げるイベント以外のキーは、決して再生されません。

第3層 — sounds/<name>.wav

TDFの値はステム(.wavの拡張子を除いた名前)です。エンジンは仮想ファイルシステムでsounds/<stem>.wavを探します。

Important

.wavの接尾辞は暗黙に付きます。TDFにselect1=cmdsel1.wavと書くと、エンジンはsounds/cmdsel1.wav.wavを探そうとし、何も知らせずに何も再生しません。


標準のイベントキー

TA 3.1cは、ユニットのサウンドカテゴリから23個のイベントを読みます。どれも、番号のないキーと、上で説明した番号付きの一群(ok、ok1、ok2…)として読まれます。

イベント 発生するタイミング
select ユニットが選択された。
underattack ユニットがダメージを受けた。
activate / deactivate オン/オフの切り替え(レーダー、妨害装置、防壁)。
ok 命令が受け付けられた。
arrived ユニットが移動を終えた。
cant 命令が拒否された(地形、建設の予約など)。
unitcomplete ユニットの建設が完了した。
build 建設ユニットが建設を始めた。
repair 建設ユニットが修理を始めた。
working 建設ユニットが回収 / 蘇生をしている。
load / unload 輸送ユニットがユニットを積み込んだ / 降ろした。
cloak / uncloak ユニットがクロークした / クロークを解除した(コマンダー)。
capture コマンダーや捕獲能力のあるユニットが捕獲を始めた。
count5 … count0 自爆のカウントダウンが進んだ。
canceldestruct 自爆が中止された。

それぞれのキーには、対応するKEYtextのエントリ(select1text)を置くことができ、その音声の字幕になります。カテゴリ内のそれ以外のキーは無視されます。

KBot Studioのユニットビューアーとサンドボックスも同じ規則に従います。ユニットのメタデータ(/api/studio/unit/{name})は、これらのイベントのためにゲームが再生するキーをちょうどそのまま持ち、各イベントはそのキーの中から1つをランダムに再生します。


UIのサウンド — allsound.tdf

UIのイベント(ボタンのクリック、メニューの切り替え、ゲーム終了時のジングル)も同じようにキーで指定しますが、こちらはgamedata/allsound.tdfの[GLOBAL_*]風のセクションにあります。

[BIGBUTTON]   { sound=butmain1; }
[SMLBUTTON]   { sound=button1;  }
[SKIRMISH]    { sound=butnskir; }
[BGM]         { sound=drone2;   }   // Background music ID

これらのセクションは、メニューの.guiファイルから名前で参照されます。「Skirmish」ボタンのクリック音を変えたいなら、このTDFを編集するだけで済み、.guiを編集する必要はありません。


武器のサウンド

武器のTDF(TDF)は、間接参照の層を挟まず、自分のサウンドのキーを直接持っています。

[LIGHTLASER] {
    ...
    soundstart=lasrmas1;     // On fire
    soundhit=lasrhit1;       // On impact
    soundwater=splshbig;     // On water hit (overrides soundhit)
    soundtrigger=1;          // Play soundstart on each burst pulse, not just first
}

同じようにsounds/<stem>.wavが探されます。武器のサウンドは1発ごとに調整されているので、ユニットの武器を変えた場合は、武器のTDFにあるサウンドの音量も調整し直す必要があります。


実例 — 新しい選択時の音声を追加する

  1. 新しいWAVをsounds/に置きます(モノラル、22050 Hz、8ビットを推奨)。

    mymod/sounds/cmdsel_grunt.wav
  2. gamedata/sound.tdfに新しいイベントを追加します。

    [ARM_COM]
    {
        select1=cmdsel1;       // Existing
        select2=cmdsel_grunt;  // Your new line, randomly selected
    }
  3. FBIを変更する必要はありません。既存のSoundCategory=ARM_COMの参照で十分です。

  4. まとめてテストします。

    kbot hpi pack ./mymod --target mymod.ufo

これで、コマンダーを選択したときに、エンジンがcmdsel1.wavとcmdsel_grunt.wavを切り替えながら鳴らすようになります。


典型的なサイズ

アセット Cavedogのアセットで見られる範囲
ユニットのボイス 5–60 KB
武器の着弾音 5–30 KB
爆発音 30–120 KB
音楽のループ 100 KB – 1 MB
gamedata/sound.tdf 約20 KB(300以上のカテゴリ)
gamedata/allsound.tdf 約6 KB

注意点

Warning

WAVが見つからなくても、エラーにはならず無音になるだけです。select1=cmsdel1(文字が入れ替わっている)と綴りを間違えると、エンジンは選択時に何も再生しません。ログのメッセージもなく、代わりの音も鳴りません。変更したサウンドは、必ずゲーム内でテストしてください。

  • .wavの拡張子は暗黙に付きます。TDFの値には決して書かないでください。
  • サンプリングレートは重要です。8 kHz / 11.025 kHz / 22.05 kHz / 44.1 kHz以外で再生されるサウンドは、製品版のエンジンの一部が今も使っているWindows 9x時代のハードウェア経路で、音が途切れることがあります。22050 Hzのモノラルが安全な既定値です。
  • ステレオのWAVは、エンジンがモノラルにミックスダウンします。空間的な特別な理由がない限り、ステレオで配布しないでください。
  • sounds/の中のMP3:エンジンはここにあるMP3を無視します。音楽プレーヤーには、music/*.mp3用の別の処理経路があります。
  • Cavedogは、16ビットPCMで、奇妙なサンプリングレート(例:7000 Hz)のWAVもいくつか同梱しています。それでも動作しますが、22050/8/モノラルを前提にしたツールを作っていると、これにつまずきます。

関連項目

  • TDF:sound.tdf、allsound.tdf、武器のサウンドのフィールドが使う形式。
  • TA: KingdomsのGUI:.guiのウィジェットはUIのサウンドイベントを参照します。
  • 用語集:sound category(サウンドカテゴリ)。