Web Audio API — одна из новинок, которая значительно расширяет возможности web приложений при работе со звуком. Это мощнейший инструмент, без которого Вам сложно будет обойтись в будущем при разработке современных игр и интерактивных веб приложений. API достаточно высокоуровневый, продуман до мелочей, самодостаточен, легок в освоении и особенно элегантно интегрируется в приложения, использующие WebGl и WebRTC.
Если вы лучше воспринимаете видео, можете посмотреть мое выступление по мотивам этой статьи на Web Standards Days в на Yandex Events (Декабрь 2013)
Но, все же, в статье все описано более развернуто ;)
Web audio api yandex web standards days 2013
Немного истории…
Давным давно на заре развития веб Internet explorer предпринял робкую попытку разрушить тишину, царящую в браузере, придумал тэг <bgsound>
, который позволял автоматически проигрывать midi файлы при открытии сайта. В ответ на это разработчики Netscape добавили аналогичную функцию с помощью тега <embed>
. Ни одно из этих решений так и не было стандартизовано, как, в принципе, и не было впоследствии наследовано остальными браузерами.
Прошло несколько лет и в браузерах начали активно использоваться сторонние плагины. Проигрывать аудио стало возможным с помощью Flash, Silverlight, QuickTime и т.п. Все они хорошо выполняли свою роль, но все же плагин имеет кучу недостатков. Поэтому возможность иметь инструмент для работы со звуком, поддерживаемый веб стандартами, уже давно будоражила умы разработчиков. С массовым приходом мобильных браузеров, не поддерживающих Flash, проблема стала еще острее.
Пионером в борьбе с тишиной без плагинов стал элемент <audio>
, появившийся уже в первой спецификации html5. Он позволяет проигрывать аудио файлы и стримы, контролировать воспроизведение, буферизацию и уровень звука. Кроме того, он прост в использовании и понимании. Сейчас он поддерживается всеми мобильными и десктопными браузерами (включая IE9), работает достаточно хорошо, но говорить сегодня мы будем не об <audio>
элементе.
Мы поговорим о Web Audio API, который призван выполнять гораздо более интересные, разносторонние и сложные задачи.
web audio API — это НЕ элемент <audio>
и НЕ его надстройка.
В начале важно понять, что элементы <audio>
и web Audio API
практически никак не связаны между собой. Это два независимых, самодостаточных API, предназначенных для решения разных задач. Единственная связь между ними состоит в том, что <audio>
элемент может быть одним из источников звука для web Audio API
.
Задачи, которые призван решать элемент <audio>
:
- Простой аудио плеер
- Однопоточное фоновое аудио.
- Аудио подсказки, капчи и т.п.
Задачи, которые призван решать Web Audio API
:
- Объемный звук для игр и интерактивных веб приложений
- Приложения для обработки звука
- Аудио синтез
- Визуализация аудио и многое, многое, многое другое…
Преимущества Web Audio API
- Абсолютно синхронное воспроизведение аудио (возможность проигрывать сотни семплов одновременно с разницей в миллисекунды, точно планируя начало и конец воспроизведения каждого из них)
- Возможность обработки звука с помощью десятков встроенных высокоуровневых блоков (фильтров, усилителей, линий задержки, модулей свертки, и т.д.)
- Богатые возможности для синтеза колебаний звуковой частоты с различной формой огибающей. (Можно написать простейший синтезатор за 10 мин)
- Работа с многоканальным аудио (Исходя из спецификации, API обязан поддерживать до 32 каналов аудио!!! Для справки: стерео — это 2 канала, Dolby Digital — это 5 каналов, самый навороченный Dolby TrueHD — 8 каналов, т.е на сегодняшний день у немногих пользователей дома есть звуковые карты с более чем 8-ю каналами :)
- Непосредственный доступ к временным и спектральным характеристикам сигнала (позволяет делать визуализации и анализ аудио потока)
- Высокоуровневое 3D распределение аудио по каналам, в зависимости от положения, направления и скорости источника звука и слушателя (что особенно круто при разработке объемных WebGL игр и приложений)
- Тесная интеграция с WebRTC (как источник звука можно использовать системный микрофон, подключить гитару или микшер. Вы также можете получить аудио из любого внешнего стрима, как, впрочем, и отправить его туда же)
Проблемы на текущий момент (10.2013)
- API все еще находится в стадии черновика и немного меняется. В большинстве своем это изменения в названиях методов и наборе параметров. Например, еще полгода назад для того, чтобы начать воспроизведение, нужно было использовать
source.noteOn(0)
, сейчас этоsource.start(0)
. Проблема небольшая и Вы можете использовать обертку AudioContext-MonkeyPatch, которую при желании можно поддержать своими пулл реквестами. - Поддержка браузерами. На сегодняшний день Chrome, Safari, Opera, FF25+, Chrome android, Safari iOS, поддерживают Web Audio API в полном объеме. IE и некоторые мобильные браузеры думают о поддержке в «ближайшем» будущем. Подробнее можно посмотреть тут caniuse.
- Пока не существует хорошего универсального аудио формата, который можно не задумываясь использовать в web приложениях. Форматов много (mp3, mp4, wma, ogg, aac, WebM,…) и браузеров тоже много. При этом каждый браузер пытается продвигать свой набор форматов. Подробнее можно посмотреть тут. В итоге, ни один из перечисленных форматов не поддерживается всеми браузерами (09.2013). Для решения проблемы Вам иногда могут понадобится одни и те же аудио семплы, представленные в разных форматах для разных браузеров.
Начинаем погружение. Audio context
Одним из основополагающих понятий при работе с Web Audio API является аудио контекст.
JS
var context = new AudioContext();
Пока спецификация находится в черновике, в webkit браузерах нужно использовать webkitAudioContext. Т.е что-то наподобие:
JS
var context;
window.addEventListener('load', function(){
try {
window.AudioContext = window.AudioContext||window.webkitAudioContext;
context = new AudioContext();
}
catch(e) {
alert('Opps.. Your browser do not support audio API');
}
}, false);
У одного документа может быть только один контекст. Этого вполне достаточно для всего спектра задач решаемого Web Audio API. Наличие одного аудио контекста позволяет строить сколь угодно сложные аудио графы с неограниченым количеством источников и получателей звукового сигнала. Практически все методы и конструкторы для создания аудио модулей являются методами аудио контекста.
Возможные источники звукового сигнала:
AudioBufferSourceNode
— аудио буфер (рассмотрим ниже)MediaElementAudioSourceNode
—<audio>
или<video>
элементMediaStreamAudioSourceNode
— внешний аудио поток (стрим) (микрофон или любой другой аудио стрим, в том числе внешний)
Возможные получатели звукового сигнала:
context.destination
— системный звуковой выход по умолчанию (в типичном случае — колонки).MediaStreamAudioDestinationNode
— аудио поток (стрим). Этот поток может быть использован таким же образом, как поток, полученный черезgetUserMedia()
, и, к примеру, может быть отправлен на удаленный RTCPeerConnection с помощью методаaddStream()
.
Строим графы (схемы обработки аудио)
В любой задуманной Вами схеме может быть один или несколько источников и получателей звукового сигнала, а также модули для работы со звуком (далее мы рассмотрим каждый из них подробнее). Схема может быть с прямыми и обратными связями, каждый модуль может иметь сколь угодно много входов/выходов. Всю заботу о правильном функционировании берет на себя API. Ваша задача состоит в том, чтобы соединить все правильно. Давайте представим себе некую абстрактную схему, просто чтобы разобраться, как она строится при помощи кода.
Создатели Web Audio API сделали построение любых графов (схем) изящным и простым для понимания. У каждого модуля есть метод .connect(...)
, который принимает один параметр, собственно говорящий о том, к чему нужно подсоединиться. Вот все, что нужно написать для построения вышеупомянутой схемы:
JS
source1.connect(node1);
source2.connect(node3);
node1.connect(node4);
node1.connect(node2);
node2.connect(destination);
node3.connect(node1);
node4.connect(destination);
node4.connect(node3);
Предзагрузка аудио и воспроизведение
Давайте рассмотрим простейший, но довольно типовой пример работы с web Audio API, где источником звукового сигнала является буфер, созданный из аудио файла, предзагруженного с помощью XMLHttpRequest (AJAX), а получателем является системный звуковой выход.
JS
// создаем аудио контекст
var context = new window.AudioContext(); //
// переменные для буфера, источника и получателя
var buffer, source, destination;
// функция для подгрузки файла в буфер
var loadSoundFile = function(url) {
// делаем XMLHttpRequest (AJAX) на сервер
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'arraybuffer'; // важно
xhr.onload = function(e) {
// декодируем бинарный ответ
context.decodeAudioData(this.response,
function(decodedArrayBuffer) {
// получаем декодированный буфер
buffer = decodedArrayBuffer;
}, function(e) {
console.log('Error decoding file', e);
});
};
xhr.send();
}
// функция начала воспроизведения
var play = function(){
// создаем источник
source = context.createBufferSource();
// подключаем буфер к источнику
source.buffer = buffer;
// дефолтный получатель звука
destination = context.destination;
// подключаем источник к получателю
source.connect(destination);
// воспроизводим
source.start(0);
}
// функция остановки воспроизведения
var stop = function(){
source.stop(0);
}
loadSoundFile('example.mp3');
Давайте опробуем этот код в действии. Этот и все остальные примеры работают в webkit, чтобы объяснить основные принципы API. Целью статьи не было сделать их рабочими во всех браузерах :)
Модули
Web Audio API содержит десятки высокоуровневых, конфигурируемых и готовых к использованию модулей. Это усилители, линии задержки, фильтры, модули свертки, сплитеры и мержеры каналов, 3D паннеры и т.д. Вы можете создавать сложнейшие графы обработки и синтеза звука, просто соединяя готовые блоки и конфигурируя их. По простоте использования это немного напоминает детский конструктор, но, в отличии от него, здесь Вы можете создавать очень крутые вещи!
Давайте рассмотрим основные модули, начиная с самых простых.
Gain (Усилитель)
Модуль позволяет изменять уровень звукового сигнала.
Любой модуль Web Audio API можно создать, используя соответствующий конструктор объекта context. Для того, чтобы получить новый объект gain
, нужно просто вызвать context.createGain()
. Далее Вы можете конфигурировать полученный объект как до начала, так и во время воспроизведения. Конфигурация, a также ее возможности и способы зависят от типа модуля, но в большинстве случаев все сводится к простой установке значений для соответствующих полей объекта. Вот пример того, как создать модуль gain
и изменить его уровень усиления.
JS
var gainNode = context.createGain();
gainNode.gain.value = 0.4; // значение 0..1 (можно изменять динамически)
Вставляем усилитель в вышеописанную схему между источником и получателем:
JS
source.connect(gainNode);
gainNode.connect(destination);
И начинаем воспроизведение:
JS
source.start(0);
Как Вы уже поняли, все действительно круто и продумано. Для более наглядного примера давайте сделаем простой crossfade эффект, которым можно управлять вручную с помощью слайдера. Нам понадобится 2 источника звука и 2 модуля gain
.
Мы не будем приводить код примера, дабы не засорять статью, однако Вы всегда можете открыть пример в новом окне, проинспектировать и посмотреть, как он работает.
Delay (Линия задержки)
Этот модуль позволяет задерживать звук на определенное время.
Создается и конфигурируется по такому же принципу, как вышеописанный gain.
JS
var delayNode = context.createDelay();
delayNode.delayTime.value = 2; // 2 секунды
source.connect(delayNode);
delayNode.connect(destination);
source.start(0);
Давайте для закрепления основных принципов создадим простую схему с бесконечным зацикливанием сигнала, используя gain
для ослабления сигнала и delay
для задержки. Так мы получим простейший «эхо» эффект.
source.connect(gainNode);
gainNode.connect(destination);
gainNode.connect(delayNode);
delayNode.connect(gainNode);
var now = context.currentTime;
source.start(now);
source.stop(now + 0.3);
Надо сказать, что это не самый лучший образец того, как нужно делать «эхо» эффект, и годится он только в качестве примера. Настоящее реалистичное эхо можно достигнуть с помощью модуля свертки звукового сигнала. Давайте рассмотрим его подробнее.
Convolution ( Свертка )
Говоря простым языком, свертка – это математическая операция, такая же как сложение, умножение или интегрирование. При сложении двух исходных чисел получается третье, при свертке — из двух исходных сигналов получается третий сигнал. В теории линейных систем свертка используется для описания отношений между тремя сигналами:
- входным сигналом
- импульсной характеристикой
- выходным сигналом
Другими словами, выходной сигнал равен свертке входного сигнала с импульсной характеристикой системы.
Что такое входной и выходной сигнал, вроде итак понятно. Осталось только разобраться со «страшным» словом импульсная характеристика (impulse response)
:)
Давайте рассмотрим жизненный пример и все сразу станет ясно.
Вы пришли в лес. Громко крикнули что-нибудь своему другу. Что он услышит? Правильно! Ваш голос, только немного искаженный и с эффектом множественного эха. Дело в том, что совокупность аккустических колебаний, генерируемая Вашими связками и гортанью, прежде, чем попасть в ушную раковину Вашего друга, будет несколько изменена под воздействием окружающего пространства. Преломления и искажения возникнут, например, из-за влажности в лесу. Определенная часть энергии аккустического колебания будет поглощена мягким покрытием из мха. Также звук будет отражен от сотен деревьев и окружающих Вас предметов, находящихся на разном удалении. Можно еще долго перечислять все эти факторы, но давайте разберемся в том, какое отношение все это имеет к свертке :)
Вы уже наверно поняли, что в описанной ситуации входным сигналом (источником сигнала) будет то, что кричите Вы. Выходным же сигналом будет то, что слышит Ваш друг. А вот лес можно представить себе как линейную систему, способную изменять характеристики сигнала по неким правилам, зависящим от огромного набора факторов. Не вникая в теорию, всю эту савокупность правил можно представить в виде так называемой импульсной характеристики.
Эхо в пещере, специфический шум при проигрывании старой пластинки, искажения голоса водителя троллейбуса, ворчащего в старый микрофон — все эти звуковые эффекты можно однозначно представить их импульсными характеристиками.
Вот небольшая демка. Переключая эффекты, Вы всего лишь изменяете ту самую импульсную характеристику, которая является основным параметром для модуля свертки.
Модуль свертки создается, подключается и конфигурируется точно также, как и все остальные модули.
JS
convolverNode = context.createConvolver();
convolverNode.buffer = buffer; // impulse response
source.connect(convolverNode);
convolverNode.connect();
Практически во всех типовых случаях нужная Вам импульсная характеристика — это обычный аудио файл (чаще всего .wav). Как и входной сигнал, она должна быть предзагружена, декодирована и записана в буфер.
Где найти импульсные характеристики для различных эффектов? Ищите в гугле что-то типа «download free impulse response» и найдете их в огромном количестве. Например, тут, тут или тут.
В конце статьи будет несколько ссылок для желающих разобраться со сверткой подробнее. Движемся дальше и переходим к не менее интересной теме — фильтрации в Web Audio API.
Filter ( Фильтрация )
Под фильтрацией в цифровой обработке сигналов чаще всего подразумевают частотную фильтрацию. Если Вы знаете, что такое спектр сигнала, преобразование Фурье и амплитудно-частотная характеристика фильтра, то просто посмотрите пример. Если же Вы вообще не в курсе, что это такое, и времени разбираться нет, попробую объяснить на пальцах.
Все пользовались эквалайзером в любимом winamp, aimp, itunes и т.п., наверняка, пробовали разные предустановленные режимы (бас, диско, вокал) и обязательно дергали ползунки на разных частотах, пытаясь добиться нужного звучания. Эквалайзер представляет собой устройство, которое может как усилить, так и ослабить определенные частоты (низкие, высокие частоты и т.п.)
Так вот, не вдаваясь в детали
- Эквалайзер — это и есть частотный фильтр
- Кривая, образованная всеми ползунками — это АЧХ (амплитудно-частотная характеристика) фильтра, а по-английски frequency response function.
Говоря простым языком, с помощью Web Audio API Вы можете добавить такой «эквалайзер» (фильтр) в свой граф обработки сигнала в виде модуля.
С настройкой амплитудно-частотной характеристики все будет немного сложнее. Дело в том, что исторически все распространенные типы фильтров уже имеют физические аналоги, у которых есть определенные параметры, характеризующие эти фильтры.
Вот список фильтров доступных из коробки:
- lowpass — фильтр нижних частот (обрезает все, что выше выбранной частоты)
- highpass — высокочастотный фильтр (обрезает все, что ниже выбранной частоты)
- bandpass — полосовой фильтр (пропускает только определенную полосу частот)
- lowshelf — полка на низких частотах (означает, что усиливается или ослабляется все, что ниже выбранной частоты)
- highshelf — полка на высоких частотах (означает, что усиливается или ослабляется все, что выше выбранной частоты)
- peaking — узкополосный пиковый фильтр (усиливает определенную частоту, народное название — «фильтр-колокол»)
- notch — узкополосный режекторный фильтр (ослабляет определенную частоту, народное название — «фильтр-пробка»)
- allpass — фильтр, пропускающий все частоты сигнала с равным усилением, однако изменяющий фазу сигнала. Происходит это при изменении задержки пропускания по частотам. Обычно такой фильтр описывается одним параметром — частотой, на которой фазовый сдвиг достигает 90°.
Для того, чтобы настраивать эти фильтры, существует несколько параметров, которые, как мы уже сказали, есть у физических аналогов фильтров. Эти параметры можно найти во всех книжках по теории обработки сигналов.
- Frequency — частота, на которой базируется фильтр. Измеряется в герцах (Hz)
- Q — (добротность) — ширина полосы вокруг выбранной частоты, к которой будет применяться усиление или ослабление. Чем выше значение Q, тем уже полоса. Чем ниже — тем шире.
- Gain — уровень усиления или ослабления данной частоты. Измеряется в децибелах (dB). Увеличение мощности сигнала в 2 раза равно 3dB. В 4 раза — 6dB. В 8 раз — 9dB и т.д.
Тут нужно сказать, что не все параметры актуальны для конкретного типа фильтра (подробнее можно посмотреть тут)
Если Вы напуганы обилием новых слов, не расстраивайтесь!
На деле все обстоит намного проще, чем в теории. Давайте пробовать разбираться на живом примере, изменяя параметры. Гарантирую, что все станет намного понятнее.
js
var filterNode = context.createBiquadFilter();
filterNode.type = 1; // High-pass filter (Тип фильтра)
filterNode.frequency.value = 1000; // Cutoff to 1kHZ (Базовая частота)
filterNode.frequency.Q = 1; // Quality factor (Добротность)
//filterNode.gain.value = 1000; // Усиление (не нужно этому типу фильтра)
Анализатор
Анализатор предназначен для того, чтобы получать информацию о частотных и временных параметрах сигнала в виде массива данных. Как только Вы получите этот массив, сможете анализировать и визуализировать все, что происходит со звуком. Типовые примеры использования:
- Отобразить форму или спектр сигнала на canvas
- Смоделировать красивую 3D визуализацию звука в webGL
- Сделать обработку для обнаружения каких-нибудь зависимостей в форме или спектре сигнала
- Анализировать громкость на входе с микрофона
- .. да что угодно, вплоть до текста на странице, прыгающего в такт музыке :)
js
var analyser = context.createAnalyser();
// Размерность преобразования Фурье
// Если не понимаете, что это такое - ставьте 512, 1024 или 2048 ;)
analyser.fftSize = 2048;
// Создаем массивы для хранения данных
fFrequencyData = new Float32Array(analyser.frequencyBinCount);
bFrequencyData = new Uint8Array(analyser.frequencyBinCount);
bTimeData = new Uint8Array(analyser.frequencyBinCount);
// Получаем данные
analyser.getFloatFrequencyData(fFrequencyData);
analyser.getByteFrequencyData(bFrequencyData);
analyser.getByteTimeDomainData(bTimeData);
// дальше у Вас есть массивы fFrequencyData, bFrequencyData, bTimeData, с которыми можно делать все, что вздумается
Генератор
Генератор позволяет синтезировать сигналы различной формы и частоты. Все управляется 3-мя параметрами:
- type — форма сигнала (1 — синусоида, 2 — прямоугольный, 3 — пила, 4 — треугольный)
- frequency — частота генерации
- detune — расстройка (измеряется в центах). Каждая октава состоит из 1200 центов, и каждый полутон состоит из 100 центов. Указав расстройку 1200, Вы можете перейти на одну октаву вверх, а указав расстройку -1200 на одну октаву вниз.
А теперь соединяем генератор с вышеописанным анализатором и смотрим, что получилось.
js
oscillator = context.createOscillator();
analyser = context.createAnalyser();
oscillator.connect(analyser);
analyser.connect(destination);
oscillator.start(0);
Все становится понятнее, если самостоятельно поиграться с демкой.
3D звук
Ну вот мы и добрались до самой крутой штуки в Web Audio API — распределения звука по каналам в трехмерном пространстве. Начнем с примера:
Что мы видим? Это типовая сцена 3D шутера. В ней есть герой, которого мы видим сзади. Он издает несколько звуков (бежит и стреляет), есть много нечисти, которая мечется и издает различные звуки, находясь на разном расстоянии от героя, есть фоновая музыка, есть ветер, который шумит вокруг и т.п.
Для того, чтобы сделать эту звуковую сцену 3D-реалистичной и объемной, нужно очень точно распределить звуки по каналам, в зависимости от положения, координат и скорости каждого из персонажей. В добавок ко всему, каналов может быть 2 (стерео), 5 (Dolby Digital), 8 (Dolby TrueHD), в принципе, сколько угодно, в зависимости от звуковой карты и установок системы. Да еще звуки от движущихся объектов должны иметь доплеровское смещение по частоте. Ну, и самое печальное то, что Ваше положение как слушателя, тоже меняется, если Вы смотрите на героя сбоку.
Возникает вопрос, как все просчитать? И вот она, самая главная фича — Web Audio API все сделает за Вас, т.е. вообще не надо ничего просчитывать. Нужно просто описать несколькими строчками кода координаты, направление и скорость движения каждого из источников звука и слушателя. И все! Всю остальную грязную работу берет на себя API, который распределит звук по каналам, учитывая при этом их количество, добавит доплера там, где надо и создаст сногсшибательный 3D звук.
Как я уже говорил не раз, все очень хорошо продумано. В Web Audio API имеется специальный модуль, который называется паннер (panner). Его можно мысленно представить, как летающую в пространстве колонку. И таких колонок может быть сколь угодно много.
Каждый паннер описывается:
- координатами
- направлением звука
- скоростью движения.
js
// создадим, например, паннер для представления бегающей и гавкающей собаки
var panner = context.createPanner();
// подключаем источник гавканья к паннеру
barkingSource.connect(panner);
// подключаем собачий паннер к выходу
sound.panner.connect(destnation);
// c какой-то периодичностью мы будем указывать
panner.setPosition(q.x, q.y, q.z); // где сейчас находится собака
panner.setOrientation(vec.x, vec.y, vec.z); // в какую сторону она лает
panner.setVelocity(dx/dt, dy/dt, dz/dt); // c какой скоростью она бежит
В добавок к этому Вы, как слушатель ( context.listener
), тоже описываетесь:
- координатами
- направлением звука
- скоростью движения.
js
context.listener.setPosition(q.x, q.y, q.z);
context.listener.setOrientation(vec.x, vec.y, vec.z);
context.listener.setVelocity(dx/dt, dy/dt, dz/dt);
По-моему, это очень круто!
Что еще?
Вот еще несколько интересных модулей с которыми можно что-нибудь придумать:
- ChannelSplitterNode — разделение каналов
- ChannelMergerNode — объединение каналов
- DynamicsCompressorNode — динамический компрессор
- WaveShaperNode — нелинейные искажения
- ScriptProcessorNode — можно делать все что хотим (есть буффер чисел на входе, обрабатываем его и формируем буффер чисел на выходе модуля)
А здесь можно найти спецификацию, что-бы ощутить всю глубину web audio API.
А теперь ссылки и демки!
- Мой хак для LondonMusicHackDay November 2012 (Вам нужно приоткрыть рот, сфоткаться и совместить красные прямоугольники со ртом и глазами. Дальше нажимаем плей.
- Создаем онлайн music band и играем с друзъями по всему миру!
- Крутейший виртуальный микшер
- 3D биьярд в обработкой звука каждого шарика
- Динамический анализ аккордов
- Pedalbord.js — гитарные примочки в браузере
- Web audio toy (визуальный редактор и тестер аудио графов)
- Web audio playground (еще один визуальный редактор и тестер аудио графов)
- Крутейшая онлайн драм машина от гугла
- Один из сотен синтезаторов :)
- 3D игрушка
- Играем на ксилофоне движениями перед вебкамерой
- …. и еще много разных демок тут
Эта статья опубликована во время конференции Minsk Web Standard Days 2013. Сама презентация есть тут и работает в webkit браузерах.
Жду вопросов, эмоций, критики, советов и т.п. в комментариях.
Я что-то не уверен, что EMBED не появился в ответ на OBJECT. А теги AUDIO и VIDEO придумали в Microsoft, в составе технологии HTML+TIME, сто лет назад ещё.
А есть ли обратный процесс к Свертке ? или возможно ли в Свертке от входного сигнала отнимать импульсную характеристику вместо того, чтобы додавать ее ?
Да, есть такое, но правда ни разу не приходилось делать что-то подобное. Вам нужно искать начиная отсюда http://ru.wikipedia.org/wiki/%D0%9E%D0%B1%D1%80%D0%B0%D1%82%D0%BD%D0%B0%D1%8F_%D1%81%D0%B2%D1%91%D1%80%D1%82%D0%BA%D0%B0
http://numero-senario.appspot.com/oscilator_files/oscilator.html
Скажите, как сделать простейший визуалайзер (спектрограмму) ?
Создайте analyser
…. и подключите его (в статье описано как)
Потом с нужным Вам интервалом можно брать данные с анализатора
теперь в массиве bFrequencyData будут лежать данные спеkтра сигнала в текущий момент с этими данными Вы можете делать все что угодно (отображать на canvas и т.п) ;)
Пишите, если совсем непонятно :) сделаю демку
http://0xfe.muthanna.com/wavebox/#
http://numero-senario.appspot.com/Pitch-to-MIDI.html
https://pitch2midi.firebaseapp.com/
getUserMedia() no longer works on insecure origins.
Chrome ends the support for NPAPI
Добречка. Скажите пожалуйста, реально с помощью вашего апи захватить звук без микрофона? Понятно, что можно настроить микшер и выбрать его в списке инпутов. В задачу входит именно запись звука, воспроизводимого на компьютере напрямую без заморочек с микшером.
Здравствуйте! Ну во первых API не наш. )) А ответ на Ваш вопрос, думаю: «нет, невозможно»
Возможные источники звука для работы с web audio API описаны в статье (на основе спецификации). Других нет, да и надо ли? Это веб браузер..
http://bannitsa.appspot.com/Audio_Analysis.html
`// создаем аудио контекст
if (typeof AudioContext == «function») {var audioContext = new AudioContext();
}else if(typeof webkitAudioContext == «function») {var audioContext = new webkitAudioContext();}
var source = audioContext.createBufferSource();
source.connect(audioContext.destination);
var xhr = new XMLHttpRequest();
xhr.open(«GET», «sound/open.wav», true);
xhr.responseType = «arraybuffer»;
xhr.onload = function() {
var buffer_open = audioContext.createBuffer(xhr.response, false);
source.buffer = buffer_open;
};
xhr.send();
// функция начала воспроизведения
var play_open = function(){
// воспроизводим
source.start(0);
}
….//Тут события на клик и воспроизводится звук
`
Но вот при втором клике! я получаю ошибку
1)Вопросы как отследить что звук проигрался?
2)Получается каждый раз нодо заново создавать буффер?
В примере, где говорится о загрузке в буфер через AJAX удобно использовать мелкие файлы.
Но как поступать в случае, когда аудио файл это микс на 120 минут? Есть ли какая то возможность постепенно подгружать в буфер музыку одновременно начинать играть ту часть, которая подгрузилась?
привет, Антон! Можно
Самое адекватное — это использовать тэг
<audio>
как источник звука для web audio apiУ
<audio>
есть постепенная буферизацият.е. когда хоть что-то подгружено — уже можно играть
Пример есть тут :)
простите за лень ума. у вас есть время написать демку, которая из файла аудиокниги (голос сочетается с тишиной) , будет выделять интервалы речи (секунды начала и конца каждой фразы)?
Здравствуйте! Времени нет :(
Мне кажется, это не такая уж тривиальная задача, как кажется на первый взгляд :)
а получить массив из файла , где будут значения децибел звукового сигнала через каждую 0.1 секунды сложно?
чтобы в консоле можно было этот массив посмотреть, например.
Если я правильно понял, есть файл (mp3, wav,..)
Нужно получить значения децибел звукового сигнала через каждую 0.1 секунды и сложить эти значения в массив.
Я бы делал так:
Когда трек играет, через каждую 0.1с:
Эти значения можно использовать для получения уровня сигнала и складывать в массив. Готовое решение писать не буду :)
большое спасибо за ответ.
проделал этот пример с analyzer http://www.developphp.com/view.php?tid=1348 теперь и учитывая ваш ответ всё стало прозрачно
остался только один вопрос — везде этот analyzer работает при проигрывании аудио. А нельзя ли обойтись без проигрывания? чтобы просто из тега аудио получить массив всех значений (как будто они проигрываются) для каждого момента.
Есть ли возможность получить мгновенное значение уровня сигнала на ноде?
привет,
получаете массив спектральных отсчетов с помощью analyser и вычисляете среднее значение:
а функция вычисления среднего значения уровня сигнала getAverageVolume может выглядеть примерно так:
пример есть тут: http://www.smartjava.org/examples/webaudio/example2.html
ну это фигня какая то.. сначала раскладываем сигнал, потом опять все складываем, куча лишних телодвижений. неужели нельзя было одно свойство добавить, чтоб с него снимать уровень
согласен 200% ))) , но пока такой возможности в спеке я не нашел.. и её по ходу нету
в фаерфоксе что ли не работают фильтры? что не выбираю, всегда только ФНЧ включается
Судя по https://developer.mozilla.org/en-US/docs/Web/API/BiquadFilterNode
тип фильтра определяется строковым значением.
В спецификации http://www.w3.org/TR/webaudio/#BiquadFilterNode
тоже предполагается, что тип фильтра должен задаваться строкой.
A у меня в примере он был задан числом 0..7 как в ранних спецификациях.
Хром понимает, FF — нет.
Поправил, спасибо за бдительность ;)
Здравствуйте! Возможно ли в Аудио Апи загружать в буфер сразу кусочки из разных песен, а именно у меня есть песня меня интересует такой-то кусок с 10 секунды по 30, я его загружаю ,потом загружаю следующий фрагмент из другой песни, и в итоге получить некий звуковой трек который можно будет сохранить к себе в mp3 формате?
Здравствуйте
Можно, но там все не очень просто, думаю будут проблемы с сохранением, особенно если нужно что-бы работало везде ;)
Посмотрите как сделаны:
http://plucked.de/
https://github.com/janmyler/web-audio-editor
Спасибо за ответ!
доброго времени суток! уже недели 2 ищу что-нибудь про визуализацию и случайно наткнулся на эту статью. собственно вопрос такой, на сайте нужно сделать визуализацию в реальном времени, эквалайзер. желательно на яве ну или на хтмл (флеш не хотелось бы но возможно), есть какая нибудь информация, может что подскажете, как будет возможность?)
Привет, а нужна визуализация чего? Аудио потока, уровня, спектра? Опишите задачу немного подробнее :)
благодарю за оперативность. делаю интернет-радио, нужна визуализация (эквалайзер) потока в реальном времени…
если не затруднит, подскажите, где мне найти информацию? заранее спасибо
Вот здесь описано, то что вам требуется, как раз тот случай когда в качестве источника выступает стрим из элемента
audio
http://www.michaelbromley.co.uk/blog/42/audio-visualization-with-web-audio-canvas-and-the-soundcloud-api
Вот пример использования: http://webaudiodemos.appspot.com/slides/mediademo/
Hемного подправить и будет то, что вам надо ;)
Спасибо за отзывчивость Дмитрий!
Поставили здесь: graalradio.com
Успехов!
Добрый день, столкнулся со следующей проблемой: createMediaElementSource в хроме отрабатывает хорошо, но в firefox не отрабатывает, вероятно по описанной в ответе здесь причине: http://stackoverflow.com/questions/19708561/firefox-25-and-audiocontext-createjavascriptnote-not-a-function
(origin вещания отличается от origin документа)
Вы сталкивались с такой проблемой ?
Если да, то как ее обошли ?
Забавно, что пример, указанный здесь не работает в FireFox :)
https://developer.mozilla.org/en-US/docs/Web/API/AudioContext.createMediaElementSource
Не хотелось бы перекомпилировать исходники IceCast2 для добавления в header
access-control-allow-origin:*
Попробовал в FF31. Как обойти защиту с Access-Control-Allow-Origin пока не понятно (
Как и описано на stackOverflow работает только с треками с того-же origin ((
По поводу https://developer.mozilla.org/en-US/docs/Web/API/AudioContext.createMediaElementSource
… дааа MediaElementSource в целом очень глючит в FF.
А есть ли стойкие основания использовать именно MediaElementSource?
Если нет, то можно попробовать работать с буфером.
Вот сделал пример (работает в FF) http://jsfiddle.net/nedudi/rnry7gom/
Правда, как и оговаривалось, стрим берется из внешнего источника с (soundcloud.com) c Access-Control-Allow-Origin:*
Спасибо за ответ.
Решил проблему при помощи прокси-перенаправления на 80 порт
Использую Apache, активировал модули:
proxy
proxy_http
proxy_connect
После чего написал в default конфигурацию следующую строку:
ProxyPass /stream http://localhost:[мой порт]/ices
Теперь Web Audio Api работает, но выявился забавный момент: по какой-то причине в FireFox звук идет моно, в отличие от Chrome. Может быть что-нибудь подскажите ?
А есть демо или хотя бы медиа файл (mp3, ogg), который Вы иcпользуете?
graalradio.com/stream
graalradio.com:8123/ices
var audioCtx = new (window.AudioContext || window.webkitAudioContext);
analyser = audioCtx.createAnalyser();
var source = audioCtx.createMediaElementSource(audio);
source.connect(analyser);
analyser.connect(audioCtx.destination);
Пример Выпадающего меню с аудио — http://siteacademy.ru/index.php/htmldev/38-html/musical-drop-down-menu-html-audio
Дмитрий, столкнулись с проблемой звучания миди-файлов непосредственно в браузере.Очень нужно , чтобы звучали файлы МИДИ не с предварительной загрузкой,как это обычно бывает, а на самом сайте. Нигде ничего подобного не нашли, ни на каких форумах. Помогите.) Спасибо.)
Добрый Вечер!
В светлом будущем можно будет проигрывать .mid файлы при помощи web midi api, но пока это далекая перспектива.
А на сегодняшний день, есть такая библиотека midi.js.
Она находится тут https://github.com/mudcube/MIDI.js
Я сделал набольшой пример. Вот что получилось с midi.js
http://html5.by/blogdemo/midijs/test-for-12notes.html
Когда откроете страницу в chrome или firefox, должен заиграть avicii-wake_me_up.mid .
Не знаю будет ли работать в старых браузерах и в internet explorer. Скорее всего — нет.
P.S. Для старых браузеров возможно есть какие-то flash-решения, но я не уверен.
Здравствуйте.
Есть примеры работы с микрофоном. Нужно записывать голос с микрофона в файл.
Заранее спасибо.
Здравствуйте.
Записать дорожку на выходе любого из блоков web Web Audio Api можно с https://github.com/mattdiamond/Recorderjs
А соединить getUserMedia API (например микрофон) и Web Audio Api можно, например, как здесь http://webaudioapi.com/samples/microphone/
Большое спасибо
Здравствуйте
Можно ли сохранить звуковой поток не в WAV а в FLAC. Вместо encodeWAV что то типа encodeFLAC. Заранее спасибо.
Очень интересная статья! Однако хотелось бы чтобы на выходе все таки был пример с плейером и эквалайзером…
Всем привет! Если можете помогите, у меня такая задача: речь идем о общение через веб камеру, надо зделать искажение голоса а звука. подскажите как это сделать, огромное спасибо.
Привет.
Зависти от того, какой тип искажения требуется.
Если это стилистические искажения, а-ля искажения испорченного старого телефона — будет достаточно свертки. Смотрите выше в разделе Convolution ( Свертка ).
Если же нужно исказить голос до неузноваемости, то нужен vocooder. Это уже непростая задача.
Вот демо webaudiodemos.appspot.com/Vocoder
Вот код github.com/cwilso/Vocoder
Можно найти и другие примеры вокодеров сделанных на базе web audio api в Гугле по запросу «Web audio vocoder»
Слишком хвалебно, особенно по поводу мелочей. С помощью Web Audio API нельзя просто так взять, поставить звук на паузу, а потом возобновить. Нет стандартных средств для этого, приходится изобретать велосипед.
Chrome не поддерживает событие onended. То есть его можно добавить, но работать оно не будет.
https://code.google.com/p/chromium/issues/detail?id=280541
Здравствуйте! Отличная статья! А можно ли с помощью Web Audio Api вытащить определенный фрагмент из песни, а затем сохранить в новый файл?
привет, можно :)
у меня немного тупой вопрос.
а можно ли получить сразу массив getByteTimeDomainData,
не подключая анализатор и вообще не проигрывая этот трек.
у меня конечно есть дурацкая идея прогнать просто весь трек на большой скорости через ScriptProcessorNode, который сейчас по другому как-то называется, а потом уже анализировать тот массив, который мы получили, но у меня есть чувство что js не потянет такой длинный массив
А у меня такой вопрос. Я получаю звук из и можно мне как-то узнать мета-данные песни, которая играет в .
Или может есть способ извлечь их напрямую из ..
Спасибо)
Да можно, для mp3 файлов есть вот такая библиотека — https://github.com/43081j/id3
А существует какой-нибудь способ получать данные для визуализации из потока, типа http://pub4.di.fm:80/di_oldschoolelectronica ?
Кто подскажет , как создать playlist и как туда drag and drom вставить файлы чтобы потом скормить это api, где почитать можно?
Писал дипломный проект на тему обработки аудио средствами веб-браузера и вот что у меня получилось, строго не судите ) http://online-audio-redaktor.esy.es/
Молодца! Респектую ;)
«тип фильтра определяется строковым значением»
Подскажите, а как быть с совместимостью со старой спецификацией?
для старой — type:5, для последней — type:’peaking’.
Как это кодом сделать?
Огромное спасибо вам Дмитрий, за труды!
Такой вопрос: а как организовать простейшую трансляцию аудио потока? То есть, чтобы люди зашедшие на сайт, слышали в реальном времени меня с микрофона? И более того, могли также вещать и мы могли разговаривать?
Спасибо.
Спасибо, содержательная статья. Осталось непонятным: можно ли сохранять полученные аудиоданные?
Подскажите кто-нибудь.
Есть плагин, может ли он использовать аудиозапись, которая в данный момент проигрывается в вконтакте??
Хочу сделать аудиовизуляцию.
То есть играет аудиозапись и нужно для нее использовать audio api
А как увидеть код примера Анализатор и увидеть его работу?!