Web Audio и объёмный звуковой ландшафт: введение
6К открытий6К показов
Рассказывает Si Robertson
В этом руководстве мы разберемся с основным элементами Web Audio, используемыми для создания объёмных звуковых ландшафтов в интерактивных приложениях с эффектом присутствия, например, 3D играх.
Web Audio API и терминология могут смутить, поэтому целью этого руководства является облегчить понимание принципов работы с Web Audio.
Демонстрация
Эта демонстрация содержит три источника звука, которые вращаются вокруг слушателя, его направление указано стрелкой. Представим, что он — игровой персонаж, тогда врающиеся источники звука могут быть союзниками или врагами.
Исходный код демки и используемые ресурсы даны в конце статьи.
AudioContext
Интерфейс AudioContext
— это основа Web Audio, он предоставляет необходимые для создания различных элементов Web Audio функции и способ передачи звука «железу» и устройствам вывода звука.
Важно, чтобы интерфейс AudioContext
был доступен, так как Web Audio — сравнительно новая технология, и она может не поддерживаться некоторыми браузерами.
Помимо предоставления необходимых функций, этот интерфейс обладает двумя важными свойствами: destination
и listener
, оба read-only. Свойство destination
можно представить как средство связи с аудио-аппаратурой. Свойство listener
представляет собой тот объект, который слушает весь звук в игре, например, персонаж или камера.
Буферы
Интерфейсы AudioBuffer
и AudioBufferSourceNode
позволяют проигрывать звуки. Объекты AudioBuffer
содержат «сырые» звуковые файлы, которые всячески обрабатываются по пути к чьим-то колонкам или наушникам. Объекты AudioBufferSourceNode
используются для запуска и остановки воспроизведения звуков, содержащихся в объектах AudioBuffer
.
Стандартным способом загрузки аудио в объект AudioBuffer
является использование объекта XMLHttpRequest
с установленным в arraybuffer
свойством responseType
. После загрузки файла буфер отправляется объекту AudioContext
для декодирования, и, в случае успеха, мы получаем объект AudioBuffer
.
Функция decodeAudioData()
имеет третий параметр, который принимает второй callback, который вызывается при невозможности декодирования загруженного аудиофайла.
Не все браузеры поддерживают одни и те же форматы аудио (вот хорошая таблица), поэтому вы можете захотеть использовать второй callback для перехода к другому формату. Например, Internet Explorer не поддерживает OGG Vorbis, но поддерживает MP3. Единственной проблемой MP3 является отсутствие возможности бесшовно зацикливать аудио, которая есть в OGG Vorbis.
Когда нам доступен объект AudioBuffer
, мы можем воспроизвести его, используя объект AudioBufferSourceNode
.
Важно помнить, что объекты AudioBufferSourceNode
являются одноразовыми, т.е. вы можете вызвать функцию start()
только один раз. Вам потребуется создать объект AudioBufferSourceNode
и связать его с объектом destination
, внедрённым в AudioContext
, когда мы хотим воспроизвести из него аудиофайл.
Можно облегчить себе жизнь, написав небольшую функцию, которая создаёт, соединяет и запускает за нас объект AudioBufferSourceNode
.
Когда объект AudioBufferSourceCode
заканчивает воспроизведение, и если его ничто не использует, Web Audio автоматически его отключит. Это очень удобно, когда вам нужно запускать не требующие большого внимания короткие звуковые эффекты и т.п.
Если вы хотите зациклить аудио, используя свойство AudioBufferSourceNode
loop
, вам понадобится где-нибудь сохранить ссылку на объект AudioBufferSourceNode
, чтобы можно было вызвать функцию stop()
для остановки аудио.
К этому моменту мы используем буферы для воспроизведения аудио, но это происходит без панорамирования и ориентации в пространстве. Вот где в игру вступают объекты PannerNode
.
Паннеры
Объекты PannerNode
позволяют задать позицию звука в 3D-пространстве, используя прямоугольную систему координат. Именно здесь творится большая часть 3D-магии.
У объекта PannerNode
есть несколько свойств, позволяющих тонко настроить поведение аудио, но сейчас нам интересны лишь два: maxDistance
и panningModel
. Свойство maxDistance
— это то расстояние до слушателя, на котором громкость звука будет равна нулю. Это — произвольное значение, имеющее значение 10000 по умолчанию. panningModel
сообщает Web Audio, как обрабатывать аудио, проходящее через объект PannerNode
. Для объёмных звуковых ландшафтов вам нужно будет установить значение HRTF
(head-related transfer function).
Для установки положения AudioBufferSourceNode
мы используем функцию setPosition()
, внедрённую в объект PannerNode
.
Для понимания обновим ту маленькую функцию, созданную ранее:
Сейчас мы воспроизводим звуки, позиционируя их в пространстве, но остался ещё один важный элемент: аудио-слушатель.
Аудиослушатель
Каждому объекту AudioContext
соответствует объект listener
, который содержит положение и ориентацию в пространстве чего-то, что слушает звук. Обычно этим чем-то является виртуальная камера, закрепленная на голове персонажа, бампер машины, хвост самолёта или что-то другое — главное, чтобы это имело смысл с точки зрения пользователя.
Объект listener
имеет функции setPosition()
и setOrientation()
. Функция setPosition()
помещает слушателя где-то в пространстве, а функция setOrientation()
его вращает.
Функция setPosition()
работает так же, как и аналогичная функция PannerNode
, и принимает три координаты.
Функция setOrientation()
чуть более сложная, она принимает два единичных вектора. Первый вектор отражает вращение слушателя, а второй — вертикальное направление относительно слушателя.
Если вам нужно вращать слушателя лишь по одной оси, вычисления достаточно просты. Например, если вы используете ту же систему координат, что и WebGL, в ней положительное направление x
указывает на правый край экрана, положительное направление y
— на верхний, а z
— из экрана, вы можете вращать слушателя вокруг оси y
, используя один вызов функции cos()
и один вызов функции sin()
.
Демонстрация к этому руководству делает похожую вещь и вращает объекты PannerNode
вокруг одной оси.
Заключение
В этом руководстве мы взглянули на основные элементы Web Audio, используемые для создания объёмных звуковых ландшафтов для интерактивных приложений с эффектом погружения, таких как 3D игры. Надеюсь, эта статья была полезной и предоставила достаточно информации, чтобы понять принципы совместной работы аудиобуферов, паннеров и слушателей.
Ресурсы
Следующий шаг: реализация
В следующей части руководства мы используем всё написанное выше, добавим ещё немного и создадим простой API. В ней мы сосредоточимся на 3D играх, но API будет достаточно обобщённым, чтобы его можно было использовать и в других интерактивных приложениях с эффектом погружения.
6К открытий6К показов