Web Audio и объёмный звуковой ландшафт: реализация
5К открытий5К показов
Рассказывает Si Robertson
В этом руководстве мы создадим простой Web Audio API для воспроизведения звуков в объёмном пространстве, который можно использовать в интерактивных приложениях с эффектом погружения.
Это вторая и последняя часть этого руководства. Если вы ещё не прочитали первую часть руководства, вам стоит это сделать: в ней разбираются принципы работы основных элементов Web Audio.
Демонстрация
Прежде чем мы начнём, вот небольшая демка, использующая упрощённый API, о котором пойдёт речь. Звуки (представленные квадратиками) позиционируются случайным образом и воспроизводятся при помощи функции HRTF, предоставляемой Web Audio.
Обзор
Поскольку упрощённый API (AudioPlayer) уже был создан и доступен для загрузки, мы внимательно ознакомимся с AudioPlayer API и его кодом.
AudioPlayer
Класс AudioPlayer
содержит наш API и внедрен в объект window
, а также в стандартные классы Web Audio, но только если Web Audio поддерживается браузером. Это значит, что мы должны удостовериться в существовании класса, прежде чем пытаться работать с ним.
Мы могли бы попробовать создать новый объект AudioPlayer
внутри try...catch
, но простая проверка тоже прекрасно работает.
За кадром: audioPlayer
создаёт новые объекты AudioContext
и AudioGainNode
и подключает объект GainNode
к ноде destination
, внедрённой в объект AudioContext
.
При создании и воспроизведении звуки будут подключены к ноде m_gain
, что позволит нам контролировать их громкость.
audioPlayer
также конфигурирует listener
, внедрённый в m_context
, таким образом, чтобы его система координат соответствовала в WebGL. Ось z
направлена из экрана, ось y
— вверх, ось x
— вправо.
Позиция listener
— всегда ноль; он расположен в центре координат.
Загрузка звуков
Прежде чем мы сможем создавать или проигрывать звуки, мы должны загрузить звуковые файлы; к счастью, audioPlayer
берет на себя всю сложную работу. В него внедрена функция load(...)
, которая используется для загрузки звуков, и три обработчика событий, позволяющих отслеживать процесс загрузки.
Набор поддерживаемых звуковых форматов зависит от браузера. Например, Chrome и Firefox поддерживают OGG Vorbis, а IE — нет. Все три браузера поддерживают MP3, но проблемой MP3 является отсутствие возможности бесшовно зацикливать аудио, которая есть в OGG Vorbis.
Вызывая функцию load(...)
несколько раз, audioPlayer
создает очередь запросов и загружает их по очереди. Когда все звуки загружены и декодированы, вызывается хэндлер onloadcomplete
.
За кадром: audioPlayer
использует один объект XMLHttpRequest
для загрузки звуков. responseType
запроса установлен в "arraybuffer"
, и, когда файл загружен, буфер отправляется в m_context
для декодирования.
Если файл был успешно загружен и декодирован, audioPlayer
либо загрузит следующий файл в очереди, либо даст знать, что все файлы загружены.
Создание звуков
Теперь, когда мы загрузили звуковые файлы, мы можем создавать и воспроизводить звуки. Сначала мы должны дать команду audioPlayer
создать звуки, что можно сделать, используя функцию create(...)
, внедрённую в audioPlayer
.
Мы можем создавать сколько угодно звуков, даже если у нас есть всего один звуковой файл.
Путь, передаваемый функции create(...)
, говорит audioPlayer
, какой файл должен использовать созданный звук. Если при вызове create(...)
соответствующий файл не был загружен, будет выброшена ошибка выполнения.
Воспроизведение звуков
После создания одного или нескольких звуков мы можем воспроизводить их в любое время. Для этого мы используем функцию play(...)
, внедрённую в audioPlayer
.
Для того, чтобы понять, нужно ли зациклить звук, мы можем также передать функции play(...)
булевскую величину. Если она равна true
, звук будет повторяться до принудительного выключения.
Для остановки воспроизведения используется функция stop(...)
.
Функция isPlaying(...)
показывает, воспроизводится ли сейчас тот или иной звук.
За кадром: audioPlayer
приходится делать немало работы для воспроизведения звука из-за модульной структуры Web Audio. При получения запроса на воспроизведение звука audioPlayer
создаёт новые объекты AudioSourceBufferNode
и PannerNode
, настраивает и подключает их, а затем подключает звук к ноде m_gain
. К счастью, Web Audio хорошо оптимизирован, поэтому создание и настройка новых аудиоузлов несильно нагружает систему.
Воспроизведение звуков — штука, безусловно, полезная, но назначением audioPlayer
является воспроизведение звуков в объёмной системе координат, поэтому сперва нам нужно задать позиции звуков. audioPlayer
содержит для этого несколько функций.
Позиционирование звуков
- Функции
setX(...)
иgetX(...)
, внедрённые вaudioPlayer
, используются для установки и получения координаты звука по осиx
. - Функции
setY(...)
иgetY(...)
используются для установки и получения координаты звука по осиy
. - Функции
setZ(...)
иgetZ(...)
используются для установки и получения координаты звука по осиz
. - И наконец, функция
setPosition(...)
используется для установки координат звука в пространстве.
Чем дальше звук от центра, тем он тише. На расстоянии 10000
(стандарт Web Audio) громкость будет равна нулю.
Громкость
Мы можем управлять громкостью звуков, используя функции setVolume(...)
и getVolume(...)
, внедренные в audioPlayer
.
Функция setVolume(...)
имеет второй параметр, который использует для постепенного затихания звука. Например, чтобы звук затих за две секунды, мы можем сделать следующее:
Это используется в демке для плавного затухания звуков.
За кадром: audioPlayer
просто отдает ноде m_gain
команду линейно изменять значение gain
.
audioPlayer
использует 0.01
секунду в качестве минимального значения времени затухания, чтобы не возникало резких звуковых артефактов.
Заключение
В этом руководстве мы взглянули на способ создания простого Web Audio API, который используется для воспроизведения звуков в трёхмерной системе координат.
Файлы AudioPlayer и демки доступны на GitHub. Исходники снабжены хорошими комментариями, поэтому в них стоит заглянуть.
5К открытий5К показов