Все страницы форматов ↓
Графика и медиа

WAV — звуковые эффекты и подключение звуковых банков

Источник: coreprime/kbot @ 0ab97bf · Редактировать на GitHub

Звуковые эффекты Total Annihilation (голоса юнитов, попадания оружия, щелчки интерфейса) — это обычные 8- и 16-битные файлы WAV в PCM, и в самом контейнере нет ничего особенного для TA. Интересно другое — подключение: как FBI юнитов, TDF оружия и глобальный интерфейс передают имена файлов на звуковую шину через три уровня косвенности.

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 Гц (большинство), 11025 Гц (некоторые щелчки интерфейса)
Разрядность 8-битный беззнаковый PCM
Каналы Моно
Длительность 0,1–3 секунды
Размер файла 5 КБ – 200 КБ

Моды иногда поставляют 16-битные стереосэмплы; движок их принимает, но они занимают больше памяти.


Три уровня подключения

Поиск ответа на вопрос «что звучит, когда выделен Командир 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 — SoundCategory в FBI

FBI юнита называет категорию:

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

Категории общие для нескольких юнитов: все варианты Командира ARM или все К-боты ARM указывают на одну и ту же категорию, чтобы голоса при выделении звучали одинаково в пределах стороны.

Уровень 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, …; движок для разнообразия выбирает один из них случайно. Если определён только select1, каждый раз звучит одна и та же реплика.

Для каждого события TA 3.1c читает ключ без номера, если он есть, затем KEY1, KEY2, … до первого пропущенного номера: при select1=kbarmsel; select3=kbarmse2; звучит только kbarmsel, потому что отсутствующий select2 обрывает список. (Отсутствие ключа без номера нумерованные ключи не останавливает.) Пустое значение — это вариант «тишина». Ключи, которых нет среди перечисленных ниже событий, никогда не воспроизводятся.

Уровень 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}) содержат ровно те ключи, которые игра воспроизводит для этих событий, и каждое событие воспроизводит случайный из своих ключей.


Звуки интерфейса — allsound.tdf

События интерфейса (щелчки кнопок, переходы между меню, короткие звуки в конце игры) задаются ключами так же, но живут в секциях вида [GLOBAL_*] файла gamedata/allsound.tdf:

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

На эти секции по имени ссылаются файлы меню .gui. Чтобы сменить звук щелчка кнопки «Схватка», достаточно отредактировать этот 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 работает так же. Звуки оружия настраиваются под каждый выстрел — если вы меняете оружие юнита, уровни звука в TDF оружия тоже придётся подстроить.


Разбор примера — новая реплика при выделении

  1. Положите новый WAV в sounds/ (рекомендуется моно, 22050 Гц, 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 КБ
Попадание оружия 5–30 КБ
Взрыв 30–120 КБ
Музыкальная петля 100 КБ – 1 МБ
gamedata/sound.tdf ~20 КБ (300+ категорий)
gamedata/allsound.tdf ~6 КБ

Подводные камни

Warning

Отсутствующий WAV — это тишина, а не ошибка. Опечатайтесь в select1=cmsdel1 (переставлены буквы), и движок просто ничего не воспроизведёт при выделении — ни сообщения в журнале, ни замены. Изменённые звуки всегда проверяйте в игре.

  • Расширение .wav подразумевается — никогда не пишите его в значении TDF.
  • Частота дискретизации важна. Звуки с частотой, отличной от 8 кГц / 11,025 кГц / 22,05 кГц / 44,1 кГц, могут заикаться на аппаратных путях эпохи Windows 9x, которыми всё ещё пользуются некоторые оригинальные движки. 22050 Гц моно — надёжный вариант по умолчанию.
  • Стерео-WAV движок сводит в моно. Не поставляйте стерео, если у вас нет особой причины, связанной с пространственным звуком.
  • MP3 в sounds/ — здесь движок MP3 игнорирует. У музыкального проигрывателя отдельный путь в коде для music/*.mp3.
  • Cavedog поставляет некоторые WAV в 16-битном PCM и со странными частотами дискретизации (например, 7000 Гц) — они всё равно работают, но если ваш инструмент рассчитывает на 22050/8/моно, вы на них споткнётесь.

См. также

  • TDF — формат, в котором записаны sound.tdf, allsound.tdf и звуковые поля оружия.
  • Интерфейс TA: Kingdoms — виджеты .gui ссылаются на звуковые события интерфейса.
  • Глоссарий — sound category (звуковая категория).