Questions fréquentes sur l'audio sur le Web

Boris Smus

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. Au fur et à mesure que les développeurs se familiarisent avec cet outil, des questions similaires s'accumulent souvent. Cette mise à jour rapide vise à répondre à certaines des questions les plus fréquentes afin de rendre votre utilisation de l'API Web Audio plus agréable.

Q: Je ne peux pas émettre de sons.

R: Si vous débutez avec l'API Web Audio, consultez le tutoriel de mise en route ou la recette d'Eric pour lire des contenus audio en fonction des interactions de l'utilisateur.

Q. Combien de contextes audio dois-je avoir ?

R: Généralement, vous devez inclure un AudioContext par page. Un seul contexte audio peut accepter plusieurs nœuds qui y sont connectés. Même s'il est possible d'inclure plusieurs AudioContexts sur une même page, cela peut entraîner une baisse des performances.

Q: Je viens de lire un AudioBufferSourceNode avec noteOn(). Je souhaite le rejouer, mais noteOn() ne produit rien. Aidez-moi !

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

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

Q: Lors de la lecture d'un son, pourquoi devez-vous créer un nouveau nœud source à chaque fois ?

R: Le but de cette architecture est de dissocier l'élément audio de l'état de lecture. Si l'on compare avec un tourne-disque, les tampons sont semblables aux disques et aux sources des têtes de lecture. Étant donné que de nombreuses applications impliquent la lecture simultanée de plusieurs versions du même tampon, ce schéma est essentiel.

Q: Comment traiter le son provenant des balises audio et video ?

R: MediaElementAudioSourceNode est en cours de préparation. Lorsqu'elle est disponible, elle fonctionnera approximativement comme suit (ajout d'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é fait l'objet d'un suivi dans ce bug. 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: 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 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 suivant du tutoriel de prise en main de 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 de mettre en œuvre un rappel plus précis.

Q: Lorsque des sons sont chargés, tout le thread UI se verrouille et l'UI ne répond plus. Aide !**

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, une solution est en cours de développement. Le lancement est prévu pour très bientôt.

Q: J'ai créé une super application qui utilise l'API Web Audio, mais chaque fois que l'onglet dans lequel elle s'exécute passe en arrière-plan, le son semble bizarre !

R: C'est probablement dû au fait que vous utilisez setTimeouts, qui se comporte différemment si la page est mise en arrière-plan. À l'avenir, l'API Web Audio pourra effectuer un rappel à 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 règle générale, il peut être judicieux d'arrêter la lecture lorsque l'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 tonalité d'un son à l'aide de l'API Web Audio ?

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

Q: Puis-je changer le ton sans changer la vitesse ?

R: L'API Web Audio peut avoir un pitchNode dans le contexte audio, mais cela est difficile à implémenter. En effet, il n'existe pas d'algorithme simple de changement de ton dans la communauté audio. Les techniques connues créent des artefacts, en particulier dans les cas où le décalage de la voix est important. Il existe deux types d'approches pour résoudre ce problème:

  • Des algorithmes de domaine temporel, qui entraînent des artefacts d'écho de segments répétés.
  • Les techniques du domaine de fréquence, qui génèrent des artefacts sonores réverbérants.

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

Q: Comment créer un AudioContext au taux d'échantillonnage de mon choix ?

R: Cette fonctionnalité n'est pas encore compatible, mais nous y travaillons. Consultez cette demande de fonctionnalité.

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