Обновления веб-аудио в Chrome 49

Крис Уилсон
Chris Wilson

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);

На этом пока все, продолжайте качать!

,

Крис Уилсон
Chris Wilson

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);

На этом пока все, продолжайте качать!