O Chrome tem melhorado de forma consistente e silenciosa o suporte à API Web Audio. No Chrome 49 (Beta desde fevereiro de 2016, e esperado que seja estável em março de 2016), atualizamos vários recursos para acompanhar a especificação e também adicionamos um novo nó.
decodeAudioData() agora retorna uma promessa
O método
decodeAudioData()
em AudioContext
agora retorna um Promise
, permitindo o processamento de padrões
assíncronos baseados em promessas. O método decodeAudioData()
sempre usou
funções de callback de sucesso e de erro como parâmetros:
context.decodeAudioData( arraybufferData, onSuccess, onError);
Mas agora você pode usar o método de promessa padrão para processar a natureza assíncrona da decodificação de dados de áudio:
context.decodeAudioData( arraybufferData ).then(
(buffer) => { /* store the buffer */ },
(reason) => { console.log("decode failed! " + reason) });
Embora em um único exemplo isso pareça mais detalhado, as promessas tornam a programação assíncrona mais fácil e consistente. Para compatibilidade, as funções de callback de sucesso e erro ainda têm suporte, conforme a especificação.
O OfflineAudioContext agora oferece suporte a suspend() e resume()
À primeira vista, pode parecer estranho ter suspend() em um
OfflineAudioContext.
Afinal, suspend()
foi adicionado a AudioContext
para permitir que o hardware
de áudio entre no modo de espera, o que parece inútil em cenários em que você está
renderizando para um buffer (para o qual OfflineAudioContext
é destinado, é claro).
No entanto, o objetivo desse recurso é construir apenas parte de uma
"pontuação" por vez para minimizar o uso da memória. É possível criar mais nós enquanto
está suspenso no meio de uma renderização.
Por exemplo, a Sonata ao Luar de Beethoven contém cerca de 6.500 notas.
Cada "nota" provavelmente se decompõe em pelo menos alguns nós do gráfico de áudio
(por exemplo, um AudioBuffer e um nó Gain). Se você quiser renderizar os
sete minutos e meio em um buffer com OfflineAudioContext
, provavelmente
não vai querer criar todos esses nós de uma vez. Em vez disso, crie-as em
intervalos de tempo:
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();
}
Isso vai permitir que você minimize o número de nós que precisam ser pré-criados no início da renderização e reduzir a demanda de memória.
IIRFilterNode
A especificação adicionou um nó para audiófilos que querem criar a própria
resposta-impulso-infinita
especificada com precisão:
o
IIRFilterNode.
Esse filtro complementa o BiquadFilterNode, mas permite a especificação completa
dos parâmetros de resposta do filtro, em vez do AudioParams
de fácil uso do AudioParams
para tipo, frequência, Q e assim por diante.BiquadFilterNode
O
IIRFilterNode
permite a especificação precisa de filtros que não podiam ser criados
antes, como filtros de ordem única. No entanto, o uso do IIRFilterNode requer
algum conhecimento profundo de como os filtros IIR funcionam, e eles também não podem ser programados
como BiquadFilterNodes.
Mudanças anteriores
Também quero mencionar algumas melhorias que foram feitas anteriormente: no
Chrome 48, a automação de nó BiquadFilter
começou a ser executada na taxa de áudio. A API
não mudou nada para fazer isso, mas isso significa que as varreduras de filtro vão soar
ainda mais suaves. Também no Chrome 48, adicionamos a vinculação ao método AudioNode.connect()
retornando o nó ao qual estamos nos conectando. Isso facilita a
criação de cadeias de nós, como neste
exemplo:
sourceNode.connect(gainNode).connect(filterNode).connect(context.destination);
Por enquanto é isso. Continue arrasando!