Звуковой движок и звуковое ядро


Deprecated: Function eregi_replace() is deprecated in /hlds/web/u138079p19/code4life.ru/htdocs/wp-content/plugins/wp-note/wp-note.php on line 43

Deprecated: Function eregi_replace() is deprecated in /hlds/web/u138079p19/code4life.ru/htdocs/wp-content/plugins/wp-note/wp-note.php on line 43

Deprecated: Function eregi_replace() is deprecated in /hlds/web/u138079p19/code4life.ru/htdocs/wp-content/plugins/wp-note/wp-note.php on line 43

Deprecated: Function eregi_replace() is deprecated in /hlds/web/u138079p19/code4life.ru/htdocs/wp-content/plugins/wp-note/wp-note.php on line 43

Deprecated: Function eregi_replace() is deprecated in /hlds/web/u138079p19/code4life.ru/htdocs/wp-content/plugins/wp-note/wp-note.php on line 43

Deprecated: Function eregi_replace() is deprecated in /hlds/web/u138079p19/code4life.ru/htdocs/wp-content/plugins/wp-note/wp-note.php on line 43

Deprecated: Function eregi_replace() is deprecated in /hlds/web/u138079p19/code4life.ru/htdocs/wp-content/plugins/wp-note/wp-note.php on line 43

Deprecated: Function eregi_replace() is deprecated in /hlds/web/u138079p19/code4life.ru/htdocs/wp-content/plugins/wp-note/wp-note.php on line 43

Deprecated: Function eregi_replace() is deprecated in /hlds/web/u138079p19/code4life.ru/htdocs/wp-content/plugins/wp-note/wp-note.php on line 43

Deprecated: Function eregi_replace() is deprecated in /hlds/web/u138079p19/code4life.ru/htdocs/wp-content/plugins/wp-note/wp-note.php on line 43

Notice: Функция get_currentuserinfo с версии 4.5.0 считается устаревшей! Используйте wp_get_current_user(). in /hlds/web/u138079p19/code4life.ru/htdocs/wp-includes/functions.php on line 3840

Звуковой движок (в нашем случае это называется звуковое ядро) имеет не так много кода по сравнению с некоторыми другими частями. Однако он содержит множество нюансов, это и каналы воспроизведения, инстансы звуков, наборы, воспроизведения с задержками и прочие присущие звуковому движку моменты. Взялся я недавно доделать одну мелочь в звуковом ядре, но застрял там на несколько недель ибо оказалось работы там много shock

Эта статья является составной для статьи «из чего состоит движок для игры».

Звуковой движок (sound engine) — компонент игрового движка, который предоставляет возможность управления звуками для имитации игрового мира. Содержит определенные надстройки соответствующие концепции определенного игрового движка. Переносим только совместно с концепцией игрового движка, даже в минимальном соответствии.

Звуковое ядро (sound core) — компонент звукового или игрового движка, предоставляющий базовые возможности управления звуком без надстроек для игрового использования. Такой вид управления звуком легче переносим и содержит весь функционал, который можно обернуть в звуковой движок для конкретного проекта.

То есть, звуковой движок обязательно состоит из звукового ядра и оно является его главным составным элементом.

У нас вышел спор по поводу организации звука в движке. Вообще мы назвали его как звуковое ядро, но хотели иметь в нем функционал движка. В итоге решили оставить его ядром, а дальше будет видно aggressive

Форматы файлов

Для начала нужно определиться с воспроизводимыми данными. Мы взяли обычные wav файлы и ogg.

Wav данные не сжаты поэтому имеют большой объем, но надо было на чем-то тестировать, тем более не всегда под рукой есть ogg конвертер.

Формат ogg открытый и свободный, не имеет патентных или лицензионных ограничений. Хорошо сжимает данные, используется во некоторых движках, к примеру в X-Ray. Простая работа с этим форматом на C++ (как на статической загрузке, так и на потоковой). Исходники качал отсюда libogg и libvorbis.

Однажды была проблема с одним звуком, то ли со стороны ogg то ли с DirectSound8, пришлось пере конвертировать звук в wav затем обратно в ogg поменяв параметры и все заработало dash

Средство управления

Существует несколько решений, среди которых такие низкоуровневые как DirectSound8 и OpenAL. Работать с DirectSound8 начинал по этому материалу, все достаточно просто и понятно. Со вторым было много непоняток и достаточной информации не удалось найти на момент разработки, сейчас думаю уже ее много unknw

Средство управления звука использовали DirectSound8 так как изначально использовали DirectX 9, а значит были нацелены только на Windows платформу. Использовать DirectSound8 просто.

Вкратце о DirectSound8. Есть первичный буфер, который будет производить смешивание звуков (микширование) из вторичных буферов, куда и загружаются воспроизводимые звуки. Также первичный буфер будет регулировать общие параметры воспроизведения (громкость, позиционирование и прочее). Вторичные буферы поддерживают инстанцирование, это когда один звуковой буфер используется для нескольких экземпляров для одного и того же звука, для экономии памяти, что крайне удобно.

Составные части звукового ядра

Казалось бы, загрузил звук, проиграл, какие проблемы? Не все так просто laugh

Загрузка звука может быть нескольких видов:

  • статическая — звук загружается в оперативную память целиком и остается там до выгрузки
  • динамическая, или потоковое воспроизведение — звук загружается частями для воспроизведения этой части, при достижении ее конца загружается другая часть звука и так до конца файла

Как правило статическая загрузка используется для малых звуков, длина которых не превышает нескольких десятков секунд, а динамическая для длинны звуков (более минуты).

Воспроизведение звука, в контексте пространства, может быть:

  • фоновым (2d) — звук не имеет положения в пространстве и всегда слышен слушателю (звуки меню, эмбиент звуки уровня и прочее)
  • пространственным (3d) — звук имеет позицию и дальность слышимости/силу звука и его слышимость для слушателя зависит от позиции звука и позиции слушателя.

Бывают ситуации, когда необходимо воспроизвести множество копий одного и того же звука, к примеру выстрелы, причем это должно быть крайне мало затратно. DirectSound8 позволяет создавать множество инсансов одного и того же звукового буфера, однако это действует только для статически загруженных звуков и буферы не должны иметь эффекты.

Таковые звуки имеют небольшую длину и множество игровых объектов, которые могут их воспроизводить (выстрелы, шаги, взрывы, мелкие фразы и прочее), под множеством в данном случае подразумевается возможное наличие двух и более потенциальных воспроизводителей звука (к примеру несколько пистолетов).

Исходя из вышесказанного звуки должны быть 2 видов:

  • индивидуальные — принадлежащие владельцу (тот кто их загрузил)
  • инстацирующиеся — не имеющие одного владельца и способные выдавать свои копии для воспроизведения всем желающим

Наборы звуков необходимы для случайного воспроизведения звука из набора для имитации реальности либо разнообразия, к примеру для ходьбы. У нас основаны на инстансах.

Существуют звуки для анимации, которые надо синхронизировать с анимацией, к примеру для перезарядки. В этом случае воспроизведение таких звуков для синхронизации их звучания с производимыми действиями анимации необходимо в точности. Здесь возможно 2 очевидных момента:

  • редактировать звук и подстраивать его под анимацию, однако в звук придется вставлять пустые места что увеличит занимаемую им память, а в случае незначительного изменения анимации звук придется переделывать
  • подстраивать анимацию под звук.

Но есть третий вариант — воспроизведение звука с задержками. Приведу пример как сделано у нас:

UINT arr[] = { 400, 350, 1000, 800, 300 };
SSCore_SndPlay2d(idSnd, false, false, arr, 4);

В данном коде будет происходить:

  • после поступления команды воспроизведения, начинаем воспроизводить через 400 млсек
  • воспроизведение звука до позиции 350 млсек
  • остановка звука на 1000 млсек
  • воспроизведение звука до позиции 800 млсек (то есть еще 450 млсек)
  • остановка звука на 300 млсек
  • проигрывание остатка звука

В итоге для синхронизации звука с анимацией, достаточно будет установить нужные параметры задержек при воспроизведении и все bravo

Каналы воспроизведения нужны в том случае, когда требуется отделить звуки меню от звуков игрового мира. По сути канал это простая абстракция, в нашем случае простой идентификатор (int32_t) который относит звук к одному из доступных каналов.

Каналы должны:

  • останавливать все звуки которые принадлежат останавливаемому каналу
  • воспроизводить все воспроизводимые звуки принадлежащие каналу

Реализация всего перечисленного достаточно простая, однако до понимая сущности состава и его организации у нас ушло несколько лет, думаю данный материал позволит сэкономить большое количество времени big_boss

Поделиться:

2 Replies to “Звуковой движок и звуковое ядро”

    • А низкоуровневое программирование никто не отменял, тот инструмент что делает высокоуровневую работу построен на низкоуровневых функциях. От того-то он и движок что делает такую работу)

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*