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 elle, j'entends des questions similaires surgir de façon répétée. Cette mise à jour rapide vise à répondre à certaines des questions les plus fréquentes afin de rendre votre expérience avec l'API Web Audio plus agréable.

Q: Aidez-moi, je n'arrive pas à émettre de sons !

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

Q. Combien de contextes audio dois-je avoir ?

A: En règle générale, 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 entraîner une baisse des performances.

Q: Je dispose d'un AudioBufferSourceNode que je viens de lire avec noteOn(). Je souhaite le lire à nouveau, mais noteOn() ne fait rien. Aidez-moi !

A: Une fois qu'un nœud source a terminé la lecture, il ne peut plus la reprendre. 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 gestionnaire de l'AudioBuffer, vous n'avez pas besoin d'effectuer une autre requête auprès du composant pour lire à nouveau le même son. Si vous devez répéter ce modèle, encapsulez la lecture avec une fonction d'assistance simple comme playSound(buffer).

Q: Pourquoi devez-vous créer un nœud source à chaque fois que vous lisez un son ?

A: L'idée de cette architecture est de dissocier l'élément audio de l'état de lecture. Pour faire une analogie avec un tourne-disque, les tampons sont comparables aux enregistrements et les sources aux têtes de lecture. Étant donné que de nombreuses applications impliquent plusieurs versions du même tampon en lecture simultanée, ce modèle est essentiel.

Q: Comment puis-je traiter le son des balises audio et video ?

A: MediaElementAudioSourceNode est en cours de développement. Lorsqu'il sera disponible, il fonctionnera à peu près comme suit (ajout d'un effet de filtre à un extrait 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 ce crbug. Notez que dans cette configuration, il n'est pas nécessaire d'appeler mediaSourceNode.noteOn(). La balise audio contrôle la lecture.

Q: Quand puis-je entendre le son d'un micro ?

R: La partie de l'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 la lecture d'un AudioSourceNode est terminée ?

R: Actuellement, vous devez utiliser un minuteur JavaScript, car l'API Web Audio n'est pas compatible avec cette fonctionnalité. L'extrait de code suivant du tutoriel "Premiers pas avec l'API Web Audio" en est un exemple:

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

Un bug ouvert permet à l'API Web Audio d'implémenter un rappel plus précis.

Q: Le chargement de sons entraîne le verrouillage de l'ensemble du thread d'UI, et l'UI ne répond plus. Aide !**

A: Utiliser 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, une solution est en cours d'élaboration. Merci de votre patience.

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

R: Cela est probablement dû au fait que vous utilisez setTimeouts, qui se comporte différemment si la page est en arrière-plan. À l'avenir, l'API Web Audio pourra effectuer des rappels à des moments spécifiques à l'aide du minuteur interne de l'audio Web (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 puis-je modifier la hauteur d'un son à l'aide de l'API Web Audio ?

A: Modifier le playbackRate sur le nœud source.

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

A: 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 modification de la hauteur de la voix simple dans la communauté audio. Les techniques connues créent des artefacts, en particulier lorsque le changement de hauteur est important. Il existe deux types d'approches pour résoudre ce problème:

  • Algorithmes de domaine temporel, qui génèrent des artefacts d'échos de segments répétés.
  • Techniques du domaine de fréquence, qui génèrent des artefacts sonores de réverbération.

Bien qu'il n'existe pas de nœud natif pour ces techniques, vous pouvez les utiliser avec un JavaScriptAudioNode. Vous pouvez vous servir de cet extrait de code comme point de départ.

Q: Comment puis-je créer un AudioContext avec un taux d'échantillonnage de mon choix ?

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

Si vous avez d'autres questions, n'hésitez pas à les poser sur StackOverflow en ajoutant la balise web-audio.