Nos últimos meses, a API Web Audio do WebKit surgiu como uma plataforma atraente para jogos e aplicativos de áudio na Web. À medida que os desenvolvedores se familiarizam com ele, ouço perguntas semelhantes surgirem repetidamente. Esta atualização rápida é uma tentativa de responder a algumas das perguntas mais frequentes para tornar sua experiência com a API Web Audio mais agradável.
P: Ajuda, não consigo emitir sons!
R: Se você não conhece a API Web Audio, confira o tutorial de introdução ou a receita do Eric para reproduzir áudio com base na interação do usuário.
P: Quantos contextos de áudio devo ter?
R: Em geral, você deve incluir um AudioContext por página, e um único contexto de áudio pode oferecer suporte a muitos nós conectados a ele. Embora seja possível incluir vários AudioContexts em uma única página, isso pode prejudicar a performance.
P: Tenho um AudioBufferSourceNode que acabei de reproduzir com noteOn() e quero reproduzir de novo, mas noteOn() não faz nada. Preciso de ajuda!
R: Depois que um nó de origem termina a reprodução, ele não pode reproduzir mais nada. Para reproduzir o buffer subjacente novamente, crie um novo AudioBufferSourceNode e chame noteOn().
Embora recriar o nó de origem possa parecer ineficiente, os nós de origem são altamente otimizados para esse padrão. Além disso, se você mantiver um identificador para o AudioBuffer, não será necessário fazer outra solicitação ao recurso para tocar o mesmo som novamente. Se você precisar repetir esse padrão, encapsule a reprodução com uma função auxiliar simples, como playSound(buffer).
P: Ao reproduzir um som, por que é preciso criar um novo nó de origem a cada vez?
R: A ideia dessa arquitetura é separar o recurso de áudio do estado de reprodução. Usando uma analogia com um toca-discos, os buffers são análogos aos discos e as fontes aos toca-discos. Como muitos aplicativos envolvem várias versões do mesmo buffer sendo reproduzidas simultaneamente, esse padrão é essencial.
P: Como posso processar o som das tags audio e video?
R: MediaElementAudioSourceNode está em desenvolvimento! Quando disponível, ele funciona mais ou menos assim (adicionando um efeito de filtro a uma amostra reproduzida pela tag de áudio):
<audio src="sounds/sample.wav" controls>
var audioElement = document.querySelector('audio');
var mediaSourceNode = context.createMediaElementSource(audioElement);
mediaSourceNode.connect(filter);
filter.connect(context.destination);
Esse recurso é rastreado neste crbug. Nessa configuração, não é necessário chamar mediaSourceNode.noteOn(). A tag de áudio controla a reprodução.
P: Quando posso receber som de um microfone?
R: A parte de entrada de áudio será implementada como parte do WebRTC usando getUserMedia e estará disponível como um nó de origem especial na API Web Audio. Ele vai funcionar em conjunto com createMediaElementSource.
P: Como posso verificar quando um AudioSourceNode terminou de tocar?
R: No momento, você precisa usar um timer JavaScript, já que a API Web Audio não oferece suporte a essa funcionalidade. O snippet a seguir do tutorial "Como começar a usar a API Web Audio" é um exemplo disso em ação:
// Assume source and buffer are previously defined.
source.noteOn(0);
var timer = setTimeout(function() {
console.log('playback finished');
}, buffer.duration * 1000);
Há um bug aberto para que a API Web Audio implemente um callback mais preciso.
P: O carregamento de sons faz com que toda a linha de execução da interface fique bloqueada e a interface pare de responder. Ajuda!**
R: Use a API decodeAudioData para carregamento assíncrono e evite bloquear a linha de execução principal. Confira este exemplo.
P: A API Web Audio pode ser usada para processar sons mais rápido do que em tempo real?
R: Sim, estamos trabalhando em uma solução. Fique ligado!
P: Criei um aplicativo incrível da API Web Audio, mas sempre que a guia em que ele está sendo executado vai para o segundo plano, os sons ficam estranhos.
R: Isso provavelmente acontece porque você está usando setTimeouts, que se comporta de maneira diferente se a página estiver em segundo plano. No futuro, a API Web Audio poderá fazer callbacks em momentos específicos usando o timer interno do Web Audio (atributo context.currentTime). Para mais informações, consulte esta solicitação de recurso.
Em geral, é recomendável interromper a reprodução quando o app vai para segundo plano. É possível detectar quando uma página vai para o segundo plano usando a API Page Visibility.
P: Como posso mudar o tom de um som usando a API Web Audio?
R: Mude o playbackRate no nó de origem.
P: Posso mudar o tom sem alterar a velocidade?
R: A API Web Audio pode ter um PitchNode no contexto de áudio, mas isso é difícil de implementar. Isso acontece porque não há um algoritmo simples de mudança de tom na comunidade de áudio. As técnicas conhecidas criam artefatos, especialmente em casos em que a mudança de tom é grande. Há dois tipos de abordagens para resolver esse problema:
- Algoritmos de domínio de tempo, que causam artefatos de eco de segmento repetidos.
- Técnicas de domínio de frequência, que causam artefatos de som reverberantes.
Embora não haja um nó nativo para fazer essas técnicas, é possível usar um JavaScriptAudioNode. Este snippet de código pode servir como ponto de partida.
P: Como posso criar um AudioContext com uma taxa de amostragem da minha escolha?
R: No momento, não há suporte para isso, mas estamos analisando a possibilidade. Consulte esta solicitação de recurso.
Se tiver mais dúvidas, faça perguntas no StackOverflow usando a tag web-audio.