Chrome последовательно и незаметно совершенствует поддержку API веб-аудио . В Chrome 49 (бета-версия выпущена в феврале 2016 г., стабильная версия выйдет в марте 2016 г.) мы обновили несколько функций для отслеживания спецификации, а также добавили один новый узел.
decodeAudioData() теперь возвращает обещание
Метод decodeAudioData () в AudioContext
теперь возвращает Promise
, что позволяет обрабатывать асинхронные шаблоны на основе Promise. Метод decodeAudioData()
всегда принимает в качестве параметров функции обратного вызова успеха и ошибки:
context.decodeAudioData( arraybufferData, onSuccess, onError);
Но теперь вы можете использовать стандартный метод Promise для обработки асинхронного характера декодирования аудиоданных:
context.decodeAudioData( arraybufferData ).then(
(buffer) => { /* store the buffer */ },
(reason) => { console.log("decode failed! " + reason) });
Хотя в одном примере это выглядит более подробно, обещания делают асинхронное программирование проще и более последовательным. В целях совместимости функции обратного вызова Success и Error по-прежнему поддерживаются согласно спецификации.
OfflineAudioContext теперь поддерживает suspend() и возобновить().
На первый взгляд может показаться странным наличие suspend() в OfflineAudioContext . В конце концов, в AudioContext
была добавлена suspend()
, позволяющая переводить аудиооборудование в режим ожидания, что кажется бессмысленным в сценариях, когда вы выполняете рендеринг в буфер (для чего, конечно же, и предназначен OfflineAudioContext
). Однако смысл этой функции заключается в том, чтобы иметь возможность формировать только часть «партитуры» за раз, чтобы минимизировать использование памяти. Вы можете создать больше узлов, остановившись в середине рендеринга.
Например, «Лунная соната» Бетховена содержит около 6500 нот . Каждая «нота», вероятно, деконструируется как минимум на пару узлов аудиографа (например, AudioBuffer и узел усиления). Если вы хотите визуализировать все семь с половиной минут в буфер с помощью OfflineAudioContext
, вы, вероятно, не захотите создавать все эти узлы одновременно. Вместо этого вы можете создавать их по частям:
var context = new OfflineAudioContext(2, length, sampleRate);
scheduleNextBlock();
context.startRendering().then( (buffer) => { /* store the buffer */ } );
function scheduleNextBlock() {
// create any notes for the next blockSize number of seconds here
// ...
// make sure to tell the context to suspend again after this block;
context.suspend(context.currentTime + blockSize).then( scheduleNextBlock );
context.resume();
}
Это позволит вам свести к минимуму количество узлов, которые необходимо предварительно создать в начале рендеринга, и уменьшить требования к памяти.
IIRFilterNode
В спецификацию добавлен узел для аудиофилов, которые хотят создать свой собственный точно заданный бесконечный импульсный отклик : IIRFilterNode . Этот фильтр дополняет BiquadFilterNode, но позволяет полностью указать параметры отклика фильтра (вместо простых в использовании AudioParams
BiquadFilterNode
для типа, частоты, добротности и т. п.). IIRFilterNode
позволяет точно указать фильтры, которые невозможно было создать раньше, например фильтры одного порядка; однако использование IIRFilterNode требует некоторых глубоких знаний о том, как работают БИХ-фильтры, и их также нельзя планировать, как BiquadFilterNodes.
Предыдущие изменения
Я также хочу упомянуть пару улучшений, которые были внесены ранее: в Chrome 48 автоматизация узлов BiquadFilter
начала работать со скоростью звука. Для этого API совсем не изменился, но это означает, что ваши фильтры будут звучать еще более плавно. Также в Chrome 48 мы добавили цепочку в метод AudioNode.connect()
, возвращая узел, к которому мы подключаемся. Это упрощает создание цепочек узлов, как в этом примере :
sourceNode.connect(gainNode).connect(filterNode).connect(context.destination);
На этом пока все, продолжайте качать!