Аудиоресурсы и воспроизведение
Документация, принадлежащая движку. Это руководство описывает переиспользуемое запекание аудио, runtime-декодирование, воспроизведение, позиционирование, микширование и проверку в
cvet/fonline. Игра отвечает за каталог звуков, сопоставление понятий с путями, автомат состояний музыки, пространственную политику, мастеринг, лицензии и слышимую приёмку.
Когда важны точные стабильные идентификаторы, привязки к исходникам или машиночитаемые значения, используйте сгенерированный справочник audio.
Карта исходников
Source/Tools/AudioBaker.*принимает авторские WAV и Ogg, проверяет вход и выдаёт payload Ogg Vorbis, сохраняя авторский путь ресурса.Source/Client/AudioManager.*индексирует пути и отвечает за декодирование, streaming, handles, позиционирование, повтор, остановку и текущее состояние громкости.Source/Scripting/ClientGlobalScriptMethods.cppэкспортируетGame.PlaySound,Game.UpdateSoundиGame.PlayMusic.Source/Frontend/Application.*отвечает за SDL-аудиоустройство, преобразование, микширование и синхронизацию callback;ApplicationHeadless.cppзадаёт headless-границу без аудио.Source/Common/Settings.incвладеет неизменяемыми начальными настройками.Source/Tests/Test_AudioBaker.cppиTest_AudioManager.cppисполняют сфокусированный нативный контракт.BuildTools/AudioInterface.jsonявляется проверяемым контрактом документации.
Поддерживаемые ресурсы
Граница авторинга принимает две формы исходников:
| Авторский суффикс | Допустимый вход | Результат baker | Runtime-декодер |
|---|---|---|---|
.wav |
RIFF/WAVE PCM с разрядностью 8, 16, 24 или 32 бита; IEEE float с разрядностью 32 бита | Нормализация в interleaved signed 16-bit и кодирование в Ogg Vorbis | libvorbisfile |
.ogg |
Битовый поток Ogg с аудио Vorbis | Проверка и копирование без ещё одного прохода с потерями | libvorbisfile |
Runtime-пути ACM больше нет. MP3, FLAC, Opus, AAC, произвольные форматы SDL и контейнеры Ogg с кодеком, отличным от Vorbis, не поддерживаются.
Авторский суффикс обозначает путь исходника, а не байты после запекания. Ресурс
Sfx/Door.wav сохраняет этот путь, но его payload становится Vorbis. Поэтому
runtime использует один декодер и для сохранённых путей .wav, и для нативных
путей .ogg; кодек не выбирается по суффиксу.
Доставка аудио
Включайте baker Audio в каждый ресурсный пакет с клиентским аудио:
[ResourcePack]
Name = Sound
InputDirs = Resources/Sound
IncludePatterns = **
ClientOnly = True
Bakers = Audio
Аудио больше не относится к семейству RawCopy. WAV преобразуется с качеством
Baking.AudioVorbisQuality, а авторский Ogg проверяется перед passthrough. Оба
маршрута подтверждают, что результат открывается как Vorbis. Baker сообщает
число кодированных и скопированных ресурсов и суммарные входные/выходные байты.
AudioManager.IndexFiles() записывает пути с суффиксами из
Audio.SoundFileExtensions (обычно wav ogg). Каталог нужен для инспекции;
само воспроизведение получает точный путь выбранного ресурса.
Воспроизведение эффектов
Game.PlaySound(path) возвращает непереиспользуемый uint32 handle времени
жизни:
uint sound = Game.PlaySound("Sfx/DoorOpen.wav");
if (sound == 0) {
// No live sound was started.
}
Передавайте точный путь запечённого ресурса с авторским расширением и регистром. Fallback расширения, нормализации основы в нижний регистр и автоматического поиска по понятию нет.
Нумерованные варианты
Движок не обнаруживает и не выбирает случайно нумерованные варианты. Если игра
содержит Footstep_1.wav — Footstep_4.wav, проектный код сам выбирает вариант
и передаёт точный путь. Так политика каталога и рандомизации остаётся за
пределами переиспользуемого mixer.
Позиционированное воспроизведение
Если у звука есть текущее положение, используйте overload с attenuation и pan:
uint sound = Game.PlaySound("Sfx/Generator.wav", attenuation, pan);
- attenuation не больше нуля возвращает нулевой handle до файлового ввода;
- pan ограничивается диапазоном
-1..1: отрицательное значение ослабляет правый канал, положительное — левый; - ближний канал остаётся с единичным усилением, поэтому панорамирование не усиливает сигнал до clipping.
При движении источника или listener обновляйте существующий экземпляр:
bool alive = Game.UpdateSound(sound, attenuation, pan);
false означает нулевой handle, неактивное аудио или завершившееся
воспроизведение. Handles никогда не переиспользуются, поэтому устаревший handle
не попадёт в более поздний звук. Кривые расстояния, выбор listener, occlusion и
фильтрация получателей остаются политикой проекта.
Воспроизведение музыки
Game.PlayMusic(path, repeatTime) принимает точный путь. Пустой путь
останавливает текущую музыку и возвращает успех. Новая композиция останавливает
существующую до загрузки замены; ошибка замены не восстанавливает старую.
Активна только одна музыкальная группа. Музыка не использует поиск по понятию или fallback суффикса.
Интервал повтора
Нулевой repeatTime означает однократное воспроизведение. Ненулевое значение
сохраняет объект и перезапускает его после завершения:
- значения больше одной миллисекунды добавляют указанную задержку;
- значения не больше одной миллисекунды повторяют немедленно;
- сохранённые потоки Vorbis перед повтором перематываются к нулевой позиции.
Интервал начинается после окончания воспроизведения: это пауза, а не период, включающий продолжительность композиции.
Детали форматов
Авторинг WAV
AudioBaker обходит RIFF-чанки в любом порядке, пропускает неизвестные,
проверяет границы и учитывает выравнивание нечётного размера. Требуются один
пригодный чанк fmt и непустой data. Поддерживаются PCM (1) с разрядностью
8/16/24/32 бита и IEEE float (3) с разрядностью 32 бита. Число каналов и
частота должны быть положительными, выравнивание блока — соответствовать форме
кадра, а обрезанный кадр приводит к ошибке запекания.
Каждый принятый sample нормализуется в signed 16-bit PCM до кодирования Vorbis. Проверяйте точный экспортированный исходник: неверные метаданные остаются ошибкой авторинга, даже если редактор способен воспроизвести файл.
Runtime Ogg Vorbis
Авторский Ogg и сгенерированный результат открываются через libvorbisfile во
время запекания. В runtime AudioManager открывает каждый аудиоресурс как
Vorbis и декодирует начальную порцию 64 KiB на native либо 128 KiB на Web.
Короткие файлы становятся резидентными; длинные сохраняют OggStream и
продолжают декодирование из audio callback.
Преобразование устройства и микширование
AppAudio::ConvertAudio преобразует декодированные каналы, частоту и формат в
формат активного устройства SDL. Callback начинает с тишины, запрашивает у
AudioManager активные данные, применяет per-instance attenuation и pan, затем
микширует их с текущей громкостью звуков или музыки.
Audio.SoundVolume и Audio.MusicVolume — неизменяемые начальные значения.
Для изменений в runtime используйте Game.SetSoundVolume и
Game.SetMusicVolume; frontend ограничивает каждое микширование диапазоном
0..100.
Операции play, stop и обновления позиции синхронизируются lock аудиоустройства. Нативные расширения не должны изменять хранилище mixer из callback.
Отключённое аудио и headless
Audio.DisableAudio = true, недоступное устройство SDL и headless/stub
frontend оставляют аудио неактивным. Тогда PlayMusic является успешной no-op
операцией, а PlaySound возвращает нулевой handle.
Эти результаты не являются проверкой существования ресурса. Запекание подтверждает путь и payload, а видимый клиент с активным устройством — преобразование, планирование callback, микширование и слышимый вывод.
Рекомендуемая проектная практика
- Помещайте авторские WAV/Ogg в клиентский пакет с baker
Audio. - Храните точные пути в проектных каталогах; разрешайте понятия и варианты до вызова движка.
- Используйте WAV как редактируемый/master-вход, а нативный Ogg — когда важно избежать ещё одного кодирования с потерями.
- Централизуйте кривые расстояния, выбор listener, ambient, cooldown и музыкальные переходы в проектном коде.
- Отделяйте сервер-авторитетные игровые решения от локального воспроизведения.
- Храните masters, licenses, attribution и разрешение на распространение вне запечённого вывода.
- Проверяйте репрезентативные ресурсы и движение позиционированного звука на каждой поддерживаемой платформе.
Диагностика
Считайте все исключения AudioBaker ошибками контента. Обычные причины:
отсутствующий или обрезанный RIFF-чанк, неподдерживаемая кодировка/разрядность
WAV, несогласованное выравнивание, пустой Ogg или поток Ogg без Vorbis.
В runtime ошибки открытия/декодирования Ogg и преобразования устройства пишутся в лог и входят в debugger. Нулевой handle говорит только об отсутствии живого эффекта и не заменяет гейт baker.
Процесс проверки
Запустите документационные и сфокусированные нативные проверки:
python BuildTools\docs_audio.py --check
python -m pytest BuildTools\tests\test_docs_audio.py
cmake --build <build-dir> --config RelWithDebInfo --target RunUnitTests
Test_AudioBaker покрывает преобразование PCM/float WAV, passthrough нативного
Ogg и ошибочные входы. Test_AudioManager покрывает вывод decoder/mixer, pan,
позиционированный запуск, текущие обновления, истечение handles и поведение,
важное для синхронизации.
Затем запеките реальный пакет встраиваемого проекта. Проверьте сохранённые пути, счётчики baker и открытие каждого результата как Vorbis. В видимом клиенте воспроизведите ресурс с WAV-путём и нативным Ogg-путём, переместите звук, замените музыку, проверьте немедленный/отложенный повтор и крайние значения громкости на каждой заявленной платформе.
Граница проекта
Встраиваемый проект владеет каталогами, понятиями, вариантами, маршрутизацией server/client, политикой расстояния и occlusion, ambient и состоянием музыки, бюджетами одновременности, loudness/accessibility, masters, licenses, attribution и слышимой приёмкой. Движок предоставляет запекание, единый путь декодера, клиентский mixer, handles и параметры позиционирования.
Сопровождение
Изменения допустимых входов, преобразования baker, сохранённых путей, streaming
Vorbis, handles, позиционирования, повтора, script-сигнатур, текущей громкости,
преобразования устройства, доставки package или headless-поведения требуют
обновления документации. Обновите BuildTools/AudioInterface.json и это
руководство, перегенерируйте справочник, запустите сфокусированные тесты и
сводный contract diff, а для публичных изменений добавьте инструкции миграции.