Questions fréquentes sur l'audio sur le Web

Au cours des derniers mois, l'API Web Audio de WebKit s'est imposée comme une plate-forme attrayante pour les jeux et les applications audio sur le Web. À mesure que les développeurs se familiarisent avec cet outil, j'entends les mêmes questions revenir sans cesse. Cette brève mise à jour vise à répondre à certaines des questions les plus fréquentes pour rendre votre expérience avec l'API Web Audio plus agréable.

Q : Au secours, je n'entends aucun son !

R : Si vous ne connaissez pas l'API Web Audio, consultez le tutoriel de démarrage ou la recette d'Eric pour lire de l'audio en fonction de l'interaction de l'utilisateur.

Q. Combien de contextes audio dois-je avoir ?

R : En général, vous devez inclure un AudioContext par page. Un seul contexte audio peut prendre en charge de nombreux nœuds qui y sont connectés. Bien que vous puissiez inclure plusieurs AudioContexts sur une même page, cela peut avoir un impact sur les performances.

Q : J'ai un AudioBufferSourceNode que je viens de lire avec noteOn(), et je veux le lire à nouveau, mais noteOn() ne fait rien ! À l'aide !

R : Une fois qu'un nœud source a terminé la lecture, il ne peut plus lire d'autres éléments. Pour lire à nouveau le tampon sous-jacent, vous devez créer un AudioBufferSourceNode et appeler noteOn().

Bien que la recréation du nœud source puisse sembler inefficace, les nœuds sources sont fortement optimisés pour ce modèle. De plus, si vous conservez un handle vers l'AudioBuffer, vous n'avez pas besoin d'envoyer une autre requête à l'élément pour lire à nouveau le même son. Si vous devez répéter ce schéma, encapsulez la lecture avec une fonction d'assistance simple comme playSound(buffer).

Q : Lorsque vous lisez un son, pourquoi devez-vous créer un nœud source à chaque fois ?

R : L'idée de cette architecture est de dissocier le composant audio de l'état de lecture. Si l'on compare les tampons à des disques et les sources à des têtes de lecture, Ce modèle est essentiel, car de nombreuses applications impliquent la lecture simultanée de plusieurs versions du même tampon.

Q : Comment traiter le son des tags audio et video ?

R : MediaElementAudioSourceNode est en cours de développement ! Lorsqu'il est disponible, il fonctionne à peu près comme suit (en ajoutant un effet de filtre à un échantillon lu via la balise audio) :

<audio src="sounds/sample.wav" controls>
var audioElement = document.querySelector('audio');
var mediaSourceNode = context.createMediaElementSource(audioElement);
mediaSourceNode.connect(filter);
filter.connect(context.destination);

Cette fonctionnalité est suivie dans crbug. Notez que dans cette configuration, il n'est pas nécessaire d'appeler mediaSourceNode.noteOn(), car la balise audio contrôle la lecture.

Q : Quand puis-je obtenir du son à partir d'un micro ?

R : La partie d'entrée audio sera implémentée dans WebRTC à l'aide de getUserMedia et sera disponible en tant que nœud source spécial dans l'API Web Audio. Il fonctionnera conjointement avec createMediaElementSource.

Q : Comment savoir quand un AudioSourceNode a fini d'être lu ?

R : Pour le moment, vous devez utiliser un minuteur JavaScript, car l'API Web Audio n'est pas compatible avec cette fonctionnalité. L'extrait suivant du tutoriel sur les premiers pas avec l'API Web Audio est un exemple de cette fonctionnalité en action :

// Assume source and buffer are previously defined.
source.noteOn(0);
var timer = setTimeout(function() {
    console.log('playback finished');
}, buffer.duration * 1000);

Un bug ouvert est en cours de traitement pour que l'API Web Audio implémente un rappel plus précis.

Q : Le chargement des sons bloque l'intégralité du thread UI et mon UI ne répond plus. Aidez-moi !**

R : Utilisez l'API decodeAudioData pour le chargement asynchrone afin d'éviter de bloquer le thread principal. Consultez cet exemple.

Q : L'API Web Audio peut-elle être utilisée pour traiter les sons plus rapidement qu'en temps réel ?

R : Oui, nous travaillons sur une solution. Merci de votre patience.

Q : J'ai créé une super application Web Audio API, mais chaque fois que l'onglet dans lequel elle s'exécute passe en arrière-plan, les sons deviennent étranges !

R : Cela est probablement dû au fait que vous utilisez setTimeouts, qui se comportent différemment si la page est mise en arrière-plan. À l'avenir, l'API Web Audio pourra effectuer des rappels à des moments précis à l'aide du minuteur interne de Web Audio (attribut context.currentTime). Pour en savoir plus, consultez cette demande de fonctionnalité.

En général, il peut être judicieux d'arrêter la lecture lorsque votre application passe en arrière-plan. Vous pouvez détecter quand une page passe en arrière-plan à l'aide de l'API Page Visibility.

Q : Comment modifier la hauteur d'un son à l'aide de l'API Web Audio ?

R : Modifiez le playbackRate sur le nœud source.

Q : Puis-je modifier la hauteur sans modifier la vitesse ?

R : L'API Web Audio peut comporter un PitchNode dans le contexte audio, mais cela est difficile à implémenter. En effet, il n'existe pas d'algorithme de décalage de hauteur simple dans la communauté audio. Les techniques connues créent des artefacts, en particulier lorsque le décalage de hauteur est important. Deux types d'approches permettent de résoudre ce problème :

  • Algorithmes de domaine temporel, qui provoquent des artefacts d'écho de segment répétés.
  • Techniques du domaine fréquentiel, qui provoquent des artefacts sonores réverbérants.

Bien qu'il n'existe pas de nœud natif pour effectuer ces techniques, vous pouvez le faire avec un JavaScriptAudioNode. Cet extrait de code peut vous servir de point de départ.

Q : Comment créer un AudioContext avec la fréquence d'échantillonnage de mon choix ?

R : Cette fonctionnalité n'est pas disponible pour le moment, mais nous y travaillons. Consultez cette demande de fonctionnalité.

Si vous avez d'autres questions, n'hésitez pas à les poser sur Stack Overflow en utilisant le tag web-audio.