diff options
author | julieng <julien.gattelier@gmail.com> | 2021-10-02 17:20:24 +0200 |
---|---|---|
committer | SphinxKnight <SphinxKnight@users.noreply.github.com> | 2021-10-02 17:30:20 +0200 |
commit | 1407c8fdef01ecd0ffb8a8bd46e7113f119b9fde (patch) | |
tree | 30a56efd3eff3a01bd1611e1840fdbbfacf544a4 /files/fr/web/api/web_audio_api | |
parent | c05efa8d7ae464235cf83d7c0956e42dc6974103 (diff) | |
download | translated-content-1407c8fdef01ecd0ffb8a8bd46e7113f119b9fde.tar.gz translated-content-1407c8fdef01ecd0ffb8a8bd46e7113f119b9fde.tar.bz2 translated-content-1407c8fdef01ecd0ffb8a8bd46e7113f119b9fde.zip |
convert content to md
Diffstat (limited to 'files/fr/web/api/web_audio_api')
5 files changed, 862 insertions, 813 deletions
diff --git a/files/fr/web/api/web_audio_api/basic_concepts_behind_web_audio_api/index.md b/files/fr/web/api/web_audio_api/basic_concepts_behind_web_audio_api/index.md index 6e5c9cae01..503ef5e776 100644 --- a/files/fr/web/api/web_audio_api/basic_concepts_behind_web_audio_api/index.md +++ b/files/fr/web/api/web_audio_api/basic_concepts_behind_web_audio_api/index.md @@ -3,343 +3,404 @@ title: Les concepts de base de la Web Audio API slug: Web/API/Web_Audio_API/Basic_concepts_behind_Web_Audio_API translation_of: Web/API/Web_Audio_API/Basic_concepts_behind_Web_Audio_API --- +Cet article explique une partie de la théorie sur laquelle s'appuient les fonctionnalités de la Web Audio API. Il ne fera pas de vous un ingénieur du son, mais vous donnera les bases nécessaires pour comprendre pourquoi la Web Audio API fonctionne de cette manière, et vous permettre de mieux l'utiliser. -<p>Cet article explique une partie de la théorie sur laquelle s'appuient les fonctionnalités de la Web Audio API. Il ne fera pas de vous un ingénieur du son, mais vous donnera les bases nécessaires pour comprendre pourquoi la Web Audio API fonctionne de cette manière, et vous permettre de mieux l'utiliser.</p> +## Graphes audio -<h2 id="Graphes_audio">Graphes audio</h2> +La Web Audio API implique d'effectuer le traitement du son dans un **contexte** **audio**; elle a été conçue sur le principe de **routage modulaire**. Les opérations basiques sont effectuées dans **noeuds audio**, qui sont liés entre eux pour former un **graphe de routage audio**. Un seul contexte peut supporter plusieurs sources — avec différentes configurations de canaux. Cette architecture modulaire assure la flexibilité nécessaire pour créer des fonctions audio complexes avec des effets dynamiques. -<p>La Web Audio API implique d'effectuer le traitement du son dans un <strong>contexte </strong> <strong>audio</strong>; elle a été conçue sur le principe de <strong>routage modulaire</strong>. Les opérations basiques sont effectuées dans <strong>noeuds audio</strong>, qui sont liés entre eux pour former un <strong>graphe de routage audio</strong>. Un seul contexte peut supporter plusieurs sources — avec différentes configurations de canaux. Cette architecture modulaire assure la flexibilité nécessaire pour créer des fonctions audio complexes avec des effets dynamiques.</p> +Les noeuds audio sont liés au niveau de leur entrée et leur sortie, formant une chaîne qui commence avec une ou plusieurs sources, traverse un ou plusieurs noeuds, et se termine avec une sortie spécifique (bien qu'il ne soit pas nécessaire de spécifier une sortie si, par exemple, vous souhaitez seulement visualiser des données audio). Un scénario simple, représentatif de la Web Audio API, pourrait ressembler à ceci : -<p>Les noeuds audio sont liés au niveau de leur entrée et leur sortie, formant une chaîne qui commence avec une ou plusieurs sources, traverse un ou plusieurs noeuds, et se termine avec une sortie spécifique (bien qu'il ne soit pas nécessaire de spécifier une sortie si, par exemple, vous souhaitez seulement visualiser des données audio). Un scénario simple, représentatif de la Web Audio API, pourrait ressembler à ceci :</p> +1. Création d'un contexte audio +2. Dans ce contexte, création des sources — telles que `<audio>`, oscillateur, flux +3. Création des noeuds d'effets, tels que réverb, filtres biquad, balance, compresseur +4. Choix final de la sortie audio, par exemple les enceintes du système +5. Connection des sources aux effets, et des effets à la sortie. -<ol> - <li>Création d'un contexte audio</li> - <li>Dans ce contexte, création des sources — telles que <code><audio></code>, oscillateur, flux</li> - <li>Création des noeuds d'effets, tels que réverb, filtres biquad, balance, compresseur</li> - <li>Choix final de la sortie audio, par exemple les enceintes du système </li> - <li>Connection des sources aux effets, et des effets à la sortie.</li> -</ol> +![Diagramme simple composé de trois rectangles intitulés Sources, Effets et Sortie, reliés par des flèches, de gauche à droite, qui indiquent le sens du flux d'informations audio.](webaudioapi_en.svg) -<p><img alt="Diagramme simple composé de trois rectangles intitulés Sources, Effets et Sortie, reliés par des flèches, de gauche à droite, qui indiquent le sens du flux d'informations audio." src="webaudioapi_en.svg"></p> +Chaque entrée ou sortie est composée de plusieurs **canaux,** chacun correspondant à une configuration audio spécifique. Tout type de canal discret est supporté, y compris *mono*, _stereo_, _quad_, _5.1_, etc. -<p>Chaque entrée ou sortie est composée de plusieurs <strong>canaux, </strong>chacun correspondant à une configuration audio spécifique. Tout type de canal discret est supporté, y compris <em>mono</em>, <em>stereo</em>, <em>quad</em>, <em>5.1</em>, etc.</p> +![Diagramme qui montre comment les AudioNodes sont reliés par leurs entrées et sorties, et la configuration des canaux à l'intérieur de ces entrées/sorties.](audionodes.svg) -<p><img alt="Diagramme qui montre comment les AudioNodes sont reliés par leurs entrées et sorties, et la configuration des canaux à l'intérieur de ces entrées/sorties." src="audionodes.svg"></p> +Les sources audio peuvent être de provenance variée : -<p>Les sources audio peuvent être de provenance variée :</p> +- générées directement en JavaScript avec un noeud audio (tel qu'un oscillateur) +- créées à partir de données PCM brutes (le contexte audio a des méthodes pour décoder les formats audio supportés) +- fournies par une balise HTML media (telle que {{HTMLElement("video")}} ou {{HTMLElement("audio")}}) +- récupérées directement avec [WebRTC](/en-US/docs/WebRTC) {{domxref("MediaStream")}} (une webcam ou un microphone) -<ul> - <li>générées directement en JavaScript avec un noeud audio (tel qu'un oscillateur)</li> - <li>créées à partir de données PCM brutes (le contexte audio a des méthodes pour décoder les formats audio supportés)</li> - <li>fournies par une balise HTML media (telle que {{HTMLElement("video")}} ou {{HTMLElement("audio")}})</li> - <li>récupérées directement avec <a href="/en-US/docs/WebRTC">WebRTC</a> {{domxref("MediaStream")}} (une webcam ou un microphone)</li> -</ul> +## Données audio: ce qu'on trouve dans un échantillon -<h2 id="Données_audio_ce_qu'on_trouve_dans_un_échantillon">Données audio: ce qu'on trouve dans un échantillon</h2> +Lors du traitement d'un signal audio, **l'échantillonage** désigne la conversion d'un [signal continu](http://en.wikipedia.org/wiki/Continuous_signal) en [signal discret](http://en.wikipedia.org/wiki/Discrete_signal); formulé autrement, une onde de son continue, comme un groupe qui joue en live, est convertie en une séquence d'échantillons (un signal temporel discret) qui permet à l'ordinateur de traiter le son en blocs distincts. -<p>Lors du traitement d'un signal audio, <strong>l'échantillonage</strong> désigne la conversion d'un <a href="http://en.wikipedia.org/wiki/Continuous_signal">signal continu</a> en <a class="mw-redirect" href="http://en.wikipedia.org/wiki/Discrete_signal">signal discret</a>; formulé autrement, une onde de son continue, comme un groupe qui joue en live, est convertie en une séquence d'échantillons (un signal temporel discret) qui permet à l'ordinateur de traiter le son en blocs distincts.</p> +On peut trouver davantage de détails sur la page Wikipedia [Echantillonage (signal)](<https://fr.wikipedia.org/wiki/%C3%89chantillonnage_(signal)>). -<p>On peut trouver davantage de détails sur la page Wikipedia <a href="https://fr.wikipedia.org/wiki/%C3%89chantillonnage_(signal)">Echantillonage (signal)</a>.</p> +## Mémoire tampon : trames, échantillons et canaux -<h2 id="Mémoire_tampon_trames_échantillons_et_canaux">Mémoire tampon : trames, échantillons et canaux</h2> +Un {{ domxref("AudioBuffer") }} prend comme paramètres un nombre de canaux (1 pour mono, 2 pour stéréo, etc), une longueur, qui correspond au nombre de trames d'échantillon dans la mémoire tampon, et un taux d'échantillonage, qui indique le nombre de trames d'échantillons lues par seconde. -<p>Un {{ domxref("AudioBuffer") }} prend comme paramètres un nombre de canaux (1 pour mono, 2 pour stéréo, etc), une longueur, qui correspond au nombre de trames d'échantillon dans la mémoire tampon, et un taux d'échantillonage, qui indique le nombre de trames d'échantillons lues par seconde.</p> +Un échantillon est une valeur float32 unique, qui correspond à la valeur du flux audio à un point précis dans le temps, sur un canal spécifique (gauche ou droit dans le cas de la stéréo). Une trame, ou trame d'échantillon est l'ensemble de toutes les valeurs pour tous les canaux (deux pour la stéréo, six pour le 5.1, etc.) à un point précis dans le temps. -<p>Un échantillon est une valeur float32 unique, qui correspond à la valeur du flux audio à un point précis dans le temps, sur un canal spécifique (gauche ou droit dans le cas de la stéréo). Une trame, ou trame d'échantillon est l'ensemble de toutes les valeurs pour tous les canaux (deux pour la stéréo, six pour le 5.1, etc.) à un point précis dans le temps.</p> +Le taux d'échantillonage est le nombre d'échantillons (ou de trames, puisque tous les échantillons d'une trame jouent en même temps) qui sont joués en une seconde, exprimés en Hz. Plus le taux d'échantillonage est élevé, meilleure est la qualité du son. -<p>Le taux d'échantillonage est le nombre d'échantillons (ou de trames, puisque tous les échantillons d'une trame jouent en même temps) qui sont joués en une seconde, exprimés en Hz. Plus le taux d'échantillonage est élevé, meilleure est la qualité du son.</p> +Prenons deux {{ domxref("AudioBuffer") }}, l'un en mono et l'autre en stéréo, chacun d'une durée de 1 seconde et d'une fréquence de 44100Hz: -<p>Prenons deux {{ domxref("AudioBuffer") }}, l'un en mono et l'autre en stéréo, chacun d'une durée de 1 seconde et d'une fréquence de 44100Hz:</p> +- le mono aura 44100 échantillons, et 44100 trames. Sa propriété `length` vaudra 44100. +- le stéréo aura 88200 échantillons, et 44100 trames. Sa propriété `length` vaudra aussi 44100, puisqu'elle correspond au nombre de trames. -<ul> - <li>le mono aura 44100 échantillons, et 44100 trames. Sa propriété <code>length</code> vaudra 44100.</li> - <li>le stéréo aura 88200 échantillons, et 44100 trames. Sa propriété <code>length</code> vaudra aussi 44100, puisqu'elle correspond au nombre de trames.</li> -</ul> +![Le diagramme montre une succession de tames dans un buffer audio. Comme le buffer est composé de deux canaux (stéréo), chaque trame contient deux échantillons.](sampleframe.svg) -<p><img alt="Le diagramme montre une succession de tames dans un buffer audio. Comme le buffer est composé de deux canaux (stéréo), chaque trame contient deux échantillons." src="sampleframe.svg"></p> +Lorsqu'un noeud de mémoire tampon est lu, on entend d'abord la trame la trame la plus à gauche, puis celle qui la suit à droite, etc. Dans le cas de la stéréo, on entend les deux canaux en même temps. Les trames d'échantillon sont très utiles, car elles représentent le temps indépendamment du nombre de canaux. -<p>Lorsqu'un noeud de mémoire tampon est lu, on entend d'abord la trame la trame la plus à gauche, puis celle qui la suit à droite, etc. Dans le cas de la stéréo, on entend les deux canaux en même temps. Les trames d'échantillon sont très utiles, car elles représentent le temps indépendamment du nombre de canaux.</p> +> **Note :** Pour obtenir le temps en secondes à partir du nombre de trames, diviser le nombre de trames par le taux d'échantillonage. Pour obtenir le nombre de trames à partir du nombre d'échantillons, diviser le nombre d'échantillons par le nombre de canaux. -<div class="note"> -<p><strong>Note :</strong> Pour obtenir le temps en secondes à partir du nombre de trames, diviser le nombre de trames par le taux d'échantillonage. Pour obtenir le nombre de trames à partir du nombre d'échantillons, diviser le nombre d'échantillons par le nombre de canaux.</p> -</div> +Voici quelques exemples simples: -<p>Voici quelques exemples simples:</p> +```js +var contexte = new AudioContext(); +var memoireTampon = contexte.createBuffer(2, 22050, 44100); +``` -<pre class="brush: js">var contexte = new AudioContext(); -var memoireTampon = contexte.createBuffer(2, 22050, 44100);</pre> +> **Note :** **44,100 [Hz](https://en.wikipedia.org/wiki/Hertz)** (que l'on peut aussi écrire **44.1 kHz**) est un [taux d'échantillonage](https://en.wikipedia.org/wiki/Sampling_frequency) couramment utilisé. Pourquoi 44.1kHz ? +> +> D'abord, parce ce que le [champ auditif](https://en.wikipedia.org/wiki/Hearing_range) qui peut être perçu par des oreilles humaines se situe à peu près entre 20 Hz et 20,000 Hz, et que selon le [théorème d'échantillonage de Nyquist–Shannon](https://en.wikipedia.org/wiki/Nyquist%E2%80%93Shannon_sampling_theorem) la fréquence d'échantillonage doit être supérieure à deux fois la fréquence maximum que l'on souhaite reproduire; le taux d'échantillonage doit donc être supérieur à 40 kHz. +> +> De plus, le signal doit être traité par un [filtre passe-bas](https://en.wikipedia.org/wiki/Low-pass_filter) avant d'être échantilloné, afin d'éviter le phénomène d'[aliasing](https://en.wikipedia.org/wiki/Aliasing), et, si en théorie un filtre passe-bas idéal devrait être capable de laisser passer les fréquences inférieures à 20 kHz (sans les atténuer) et de couper parfaitement les fréquences supérieures à 20 kHz, en pratique une [bande de transition](https://en.wikipedia.org/wiki/Transition_band) dans laquelle les fréquences sont partiellement atténuées est nécessaire. Plus la bande de transition est large, plus il est facile et économique de faire un [filtre anti-aliasing](https://en.wikipedia.org/wiki/Anti-aliasing_filter). Le taux d'échantillonage 44.1 kHz laisse une bande de transition de 2.05 kHz. -<div class="note"> -<p><strong>Note :</strong> <strong>44,100 <a href="https://en.wikipedia.org/wiki/Hertz">Hz</a></strong> (que l'on peut aussi écrire <strong>44.1 kHz</strong>) est un <a href="https://en.wikipedia.org/wiki/Sampling_frequency">taux d'échantillonage</a> couramment utilisé. Pourquoi 44.1kHz ?<br> - <br> - D'abord, parce ce que le <a href="https://en.wikipedia.org/wiki/Hearing_range">champ auditif</a> qui peut être perçu par des oreilles humaines se situe à peu près entre 20 Hz et 20,000 Hz, et que selon le <a href="https://en.wikipedia.org/wiki/Nyquist%E2%80%93Shannon_sampling_theorem">théorème d'échantillonage de Nyquist–Shannon</a> la fréquence d'échantillonage doit être supérieure à deux fois la fréquence maximum que l'on souhaite reproduire; le taux d'échantillonage doit donc être supérieur à 40 kHz.<br> - <br> - De plus, le signal doit être traité par un <a href="https://en.wikipedia.org/wiki/Low-pass_filter">filtre passe-bas</a> avant d'être échantilloné, afin d'éviter le phénomène d'<a href="https://en.wikipedia.org/wiki/Aliasing">aliasing</a>, et, si en théorie un filtre passe-bas idéal devrait être capable de laisser passer les fréquences inférieures à 20 kHz (sans les atténuer) et de couper parfaitement les fréquences supérieures à 20 kHz, en pratique une <a href="https://en.wikipedia.org/wiki/Transition_band">bande de transition</a> dans laquelle les fréquences sont partiellement atténuées est nécessaire. Plus la bande de transition est large, plus il est facile et économique de faire un <a href="https://en.wikipedia.org/wiki/Anti-aliasing_filter">filtre anti-aliasing</a>. Le taux d'échantillonage 44.1 kHz laisse une bande de transition de 2.05 kHz.</p> -</div> +Ce code génère une mémoire tampon stéréo (deux canaux) qui, lorsqu'elle est lue dans un AudioContext à 44100Hz (configuration répandue, la plupart des cartes sons tournant à cette fréquence), dure 0.5 secondes: 22050 trames / 44100Hz = 0.5 secondes. -<p>Ce code génère une mémoire tampon stéréo (deux canaux) qui, lorsqu'elle est lue dans un AudioContext à 44100Hz (configuration répandue, la plupart des cartes sons tournant à cette fréquence), dure 0.5 secondes: 22050 trames / 44100Hz = 0.5 secondes.</p> +```js +var contexte = new AudioContext(); +var memoireTampon = context.createBuffer(1, 22050, 22050); +``` -<pre class="brush: js">var contexte = new AudioContext(); -var memoireTampon = context.createBuffer(1, 22050, 22050);</pre> +Ce code génère une mémoire tampon mono (un seul canal) qui, lorsqu'elle est lue dans un AudioContext à 44100Hzz, est automatiquement \*rééchantillonnée\* à 44100Hz (et par conséquent produit 44100 trames), et dure 1.0 seconde: 44100 frames / 44100Hz = 1 seconde. -<p>Ce code génère une mémoire tampon mono (un seul canal) qui, lorsqu'elle est lue dans un AudioContext à 44100Hzz, est automatiquement *rééchantillonnée* à 44100Hz (et par conséquent produit 44100 trames), et dure 1.0 seconde: 44100 frames / 44100Hz = 1 seconde.</p> +> **Note :** le rééchantillonnage audio est très similaire à la redimension d'une image : imaginons que vous ayiez une image de 16 x 16, mais que vous vouliez remplir une surface de 32x32: vous la redimensionnez (rééchantillonnez). Le résultat est de qualité inférieure (il peut être flou ou crénelé, en fonction de l'algorithme de redimensionnement), mais cela fonctionne, et l'image redimensionnée prend moins de place que l'originale. C'est la même chose pour le rééchantillonnage audio — vous gagnez de la place, mais en pratique il sera difficle de reproduire correctement des contenus de haute fréquence (c'est-à-dire des sons aigus). -<div class="note"> -<p><strong>Note :</strong> le rééchantillonnage audio est très similaire à la redimension d'une image : imaginons que vous ayiez une image de 16 x 16, mais que vous vouliez remplir une surface de 32x32: vous la redimensionnez (rééchantillonnez). Le résultat est de qualité inférieure (il peut être flou ou crénelé, en fonction de l'algorithme de redimensionnement), mais cela fonctionne, et l'image redimensionnée prend moins de place que l'originale. C'est la même chose pour le rééchantillonnage audio — vous gagnez de la place, mais en pratique il sera difficle de reproduire correctement des contenus de haute fréquence (c'est-à-dire des sons aigus).</p> -</div> +### Mémoire tampon linéaire ou entrelacée -<h3 id="Mémoire_tampon_linéaire_ou_entrelacée">Mémoire tampon linéaire ou entrelacée</h3> +La Web Audio API utilise un format de mémoire tampon linéaire : les canaux gauche et droite sont stockés de la façon suivante : -<p>La Web Audio API utilise un format de mémoire tampon linéaire : les canaux gauche et droite sont stockés de la façon suivante :</p> + LLLLLLLLLLLLLLLLRRRRRRRRRRRRRRRR (pour un buffer de 16 trames) -<pre>LLLLLLLLLLLLLLLLRRRRRRRRRRRRRRRR (pour un buffer de 16 trames)</pre> +C'est assez courant dans le traitement audio, car cela permet de traiter facilement chaque canal de façon indépendante. -<p>C'est assez courant dans le traitement audio, car cela permet de traiter facilement chaque canal de façon indépendante.</p> +L'alternative est d'utiliser un format entrelacé: -<p>L'alternative est d'utiliser un format entrelacé:</p> + LRLRLRLRLRLRLRLRLRLRLRLRLRLRLRLR (pour un buffer de 16 trames) -<pre>LRLRLRLRLRLRLRLRLRLRLRLRLRLRLRLR (pour un buffer de 16 trames)</pre> +Ce format est communément utilisé pour stocker et lire du son avec très peu de traitement, comme par exemple pour un flux de MP3 décodé. -<p>Ce format est communément utilisé pour stocker et lire du son avec très peu de traitement, comme par exemple pour un flux de MP3 décodé.<br> - <br> - La Web Audio API expose *uniquement* des buffer linéaires, car elle est faite pour le traitement du son. Elle fonctionne en linéaire, mais convertit les données au format entrelacé au moment de les envoyer à la carte son pour qu'elles soient jouées. A l'inverse, lorsqu'un MP3 est décodé, le format d'origine entrelacé est converti en linéaire pour le traitement.</p> +La Web Audio API expose \*uniquement\* des buffer linéaires, car elle est faite pour le traitement du son. Elle fonctionne en linéaire, mais convertit les données au format entrelacé au moment de les envoyer à la carte son pour qu'elles soient jouées. A l'inverse, lorsqu'un MP3 est décodé, le format d'origine entrelacé est converti en linéaire pour le traitement. -<h2 id="Canaux_audio">Canaux audio</h2> +## Canaux audio -<p>Une mémoire tampon audio peut contenir différents nombres de canaux, depuis les configurations simple mono (un seul canal) ou stéréo (canal gauche et canal droit) en allant jusquà des configurations plus complexe comme le quad ou le 5.1, pour lesquels chaque canal contient plusieurs échantillons de sons, ce qui permet une expérience sonore plus riche. Les canaux sont généralement représentés par les abbréviations standard détaillées dans le tableau ci-après :</p> +Une mémoire tampon audio peut contenir différents nombres de canaux, depuis les configurations simple mono (un seul canal) ou stéréo (canal gauche et canal droit) en allant jusquà des configurations plus complexe comme le quad ou le 5.1, pour lesquels chaque canal contient plusieurs échantillons de sons, ce qui permet une expérience sonore plus riche. Les canaux sont généralement représentés par les abbréviations standard détaillées dans le tableau ci-après : <table class="standard-table"> - <tbody> - <tr> - <td><em>Mono</em></td> - <td><code>0: M: mono</code></td> - </tr> - <tr> - <td><em>Stereo</em></td> - <td><code>0: L: gauche<br> - 1: R: droit</code></td> - </tr> - <tr> - <td><em>Quad</em></td> - <td><code>0: L: gauche<br> - 1: R: droit<br> - 2: SL: surround gauche<br> - 3: SR: surround droit</code></td> - </tr> - <tr> - <td><em>5.1</em></td> - <td><code>0: L: gauche<br> - 1: R: droit<br> - 2: C: centre<br> - 3: LFE: subwoofer<br> - 4: SL: surround gauche<br> - 5: SR: surround droit</code></td> - </tr> - </tbody> + <tbody> + <tr> + <td><em>Mono</em></td> + <td><code>0: M: mono</code></td> + </tr> + <tr> + <td><em>Stereo</em></td> + <td> + <code>0: L: gauche<br />1: R: droit</code> + </td> + </tr> + <tr> + <td><em>Quad</em></td> + <td> + <code + >0: L: gauche<br />1: R: droit<br />2: SL: surround gauche<br />3: SR: + surround droit</code + > + </td> + </tr> + <tr> + <td><em>5.1</em></td> + <td> + <code + >0: L: gauche<br />1: R: droit<br />2: C: centre<br />3: LFE: + subwoofer<br />4: SL: surround gauche<br />5: SR: surround droit</code + > + </td> + </tr> + </tbody> </table> -<h3 id="Conversion_ascendante_et_descendante">Conversion ascendante et descendante</h3> +### Conversion ascendante et descendante -<p>Lorsque le nombre de canaux n'est pas le même en entrée et en sortie, on effectue une conversion ascendante ou descendante selon les règles suivantes. Cela peut être plus ou moins controllé en assignant la valeur <code>speakers</code> ou <code>discrete</code> à la propriété {{domxref("AudioNode.channelInterpretation")}} .</p> +Lorsque le nombre de canaux n'est pas le même en entrée et en sortie, on effectue une conversion ascendante ou descendante selon les règles suivantes. Cela peut être plus ou moins controllé en assignant la valeur `speakers` ou `discrete` à la propriété {{domxref("AudioNode.channelInterpretation")}} . <table class="standard-table"> - <thead> - <tr> - <th scope="row">Interprétation</th> - <th scope="col">Canaux d'entrée</th> - <th scope="col">Canaux de sortie</th> - <th scope="col">Règles de conversion</th> - </tr> - </thead> - <tbody> - <tr> - <th colspan="1" rowspan="13" scope="row"><code>speakers</code></th> - <td><code>1</code> <em>(Mono)</em></td> - <td><code>2</code> <em>(Stéréo)</em></td> - <td><em>Conversion ascendante de mono vers stéréo</em>.<br> - Le canal d'entrée <code>M</code> est utilisé pour les deux canaux de sortie (<code>L</code> et <code>R</code>).<br> - <code>output.L = input.M<br> - output.R = input.M</code></td> - </tr> - <tr> - <td><code>1</code> <em>(Mono)</em></td> - <td><code>4</code> <em>(Quad)</em></td> - <td><em>Conversion ascendante de mono vers quad.</em><br> - Le canal d'entrée <code>M</code> est utilisé pour les canaux de sortie autres que surround (<code>L</code> et <code>R</code>). Les canaux de sortie surround (<code>SL</code> et <code>SR</code>) sont silencieux.<br> - <code>output.L = input.M<br> - output.R = input.M<br> - output.SL = 0<br> - output.SR = 0</code></td> - </tr> - <tr> - <td><code>1</code> <em>(Mono)</em></td> - <td><code>6</code> <em>(5.1)</em></td> - <td><em>Conversion ascendante de mono vers 5.1.</em><br> - Le canal d'entrée <code>M</code> est utilisé pour le canal de sortie central (<code>C</code>). Tous les autres canaux (<code>L</code>, <code>R</code>, <code>LFE</code>, <code>SL</code>, et <code>SR</code>) sont silencieux.<br> - <code>output.L = 0<br> - output.R = 0</code><br> - <code>output.C = input.M<br> - output.LFE = 0<br> - output.SL = 0<br> - output.SR = 0</code></td> - </tr> - <tr> - <td><code>2</code> <em>(Stéréo)</em></td> - <td><code>1</code> <em>(Mono)</em></td> - <td><em>Conversion descendante de stéréo vers mono</em>.<br> - Les deux canaux d'entrée (<code>L</code> et <code>R</code>) sont combinées pour produire l'unique canal de sortie (<code>M</code>).<br> - <code>output.M = 0.5 * (input.L + input.R)</code></td> - </tr> - <tr> - <td><code>2</code> <em>(Stéréo)</em></td> - <td><code>4</code> <em>(Quad)</em></td> - <td><em>Conversion ascendante de stéréo vers quad.</em><br> - Les canaux d'entrée <code>L</code> et <code>R </code>input sont utilisés pour leurs équivalents respectifs non-surround en sortie (<code>L</code> et <code>R</code>). Les canaux de sortie surround (<code>SL</code> et <code>SR</code>) sont silencieux.<br> - <code>output.L = input.L<br> - output.R = input.R<br> - output.SL = 0<br> - output.SR = 0</code></td> - </tr> - <tr> - <td><code>2</code> <em>(Stéréo)</em></td> - <td><code>6</code> <em>(5.1)</em></td> - <td><em>Conversion ascendante de stéréo vers 5.1.</em><br> - Les canaux d'entrée <code>L</code> et <code>R </code>sont utilisés pour leurs équivalents respectifs non-surround en sortie (<code>L</code> et <code>R</code>). Les canaux de sortie surround (<code>SL</code> et <code>SR</code>), ainsi que le canal central (<code>C</code>) et le canal subwoofer (<code>LFE</code>) restent silencieux.<br> - <code>output.L = input.L<br> - output.R = input.R<br> - output.C = 0<br> - output.LFE = 0<br> - output.SL = 0<br> - output.SR = 0</code></td> - </tr> - <tr> - <td><code>4</code> <em>(Quad)</em></td> - <td><code>1</code> <em>(Mono)</em></td> - <td><em>Conversion descendante de quad vers mono</em>.<br> - Les quatre canaux de sortie (<code>L</code>, <code>R</code>, <code>SL</code>, et <code>SR</code>) sont combinés pour produire l'unique canal de sortie (<code>M</code>).<br> - <code>output.M = 0.25 * (input.L + input.R + </code><code>input.SL + input.SR</code><code>)</code></td> - </tr> - <tr> - <td><code>4</code> <em>(Quad)</em></td> - <td><code>2</code> <em>(Stéréo)</em></td> - <td><em>Conversion descendante de quad vers stéréo</em>.<br> - Les deux canaux d'entrée à gauche (<code>L</code> and <code>SL</code>) sont combinés pour produire l'unique canal de sortie à gauche (<code>L</code>). De la même façon, les deux canaux d'entrée à droite (<code>R</code> et <code>SR</code>) sont combinés pour produire l'unique canal de sortie à droite (<code>R</code>).<br> - <code>output.L = 0.5 * (input.L + input.SL</code><code>)</code><br> - <code>output.R = 0.5 * (input.R + input.SR</code><code>)</code></td> - </tr> - <tr> - <td><code>4</code> <em>(Quad)</em></td> - <td><code>6</code> <em>(5.1)</em></td> - <td><em>Conversion ascendante de quad vers 5.1.</em><br> - Les canaux d'entrée <code>L</code>, <code>R</code>, <code>SL</code>, et <code>SR</code> sont utilisés pour leur canaux de sortie équivalents respectifs (<code>L</code> and <code>R</code>). Le canal central (<code>C</code>) et le canal subwoofer (<code>LFE</code>) restent silencieux.<br> - <code>output.L = input.L<br> - output.R = input.R<br> - output.C = 0<br> - output.LFE = 0<br> - output.SL = input.SL<br> - output.SR = input.SR</code></td> - </tr> - <tr> - <td><code>6</code> <em>(5.1)</em></td> - <td><code>1</code> <em>(Mono)</em></td> - <td><em>Conversion descendante de 5.1 vers mono.</em><br> - Les canaux de gauche (<code>L</code> et <code>SL</code>), de droite (<code>R</code> et <code>SR</code>) et central sont tous mixés ensemble. Les canaux surround sont légèrement atténués et la puissance des canaux latéraux est compensée pour la faire compter comme un seul canal en la multipliant par <code>√2/2</code>. Le canal subwoofer (<code>LFE</code>) est perdu.<br> - <code>output.M = 0.7071 * (input.L + input.R) + input.C + 0.5 * (input.SL + input.SR)</code></td> - </tr> - <tr> - <td><code>6</code> <em>(5.1)</em></td> - <td><code>2</code> <em>(Stéréo)</em></td> - <td><em>Conversion descendante de 5.1 vers stéréo.</em><br> - Le canal central (<code>C</code>) est additionné avec chacun des canaux latéraux (<code>SL</code> et <code>SR</code>) puis combiné avec chacun des canaux latéraux (L et R). Comme il est converti en deux canaux, il est mixé à une puissance inférieure : multiplié par <code>√2/2</code>. Le canal subwoofer (<code>LFE</code>) est perdu.<br> - <code>output.L = input.L + 0.7071 * (input.C + input.SL)<br> - output.R = input.R </code><code>+ 0.7071 * (input.C + input.SR)</code></td> - </tr> - <tr> - <td><code>6</code> <em>(5.1)</em></td> - <td><code>4</code> <em>(Quad)</em></td> - <td><em>Conversion descendante de 5.1 vers quad.</em><br> - Le canal central (<code>C</code>) est combiné avec les canaux latéraux non-surround (<code>L</code> et <code>R</code>). Comme il est converti en deux canaux, il est mixé à une puissance inférieure : multiplié par <code>√2/2</code>. Les canaux surround restent inchangés. Le canal subwoofer (<code>LFE</code>) est perdu.<br> - <code>output.L = input.L + 0.7071 * input.C<br> - output.R = input.R + 0.7071 * input.C<br> - <code>output.SL = input.SL<br> - output.SR = input.SR</code></code></td> - </tr> - <tr> - <td colspan="2" rowspan="1">Autres configurations non-standard</td> - <td>Les configurations non-standard sont traitées comme si la propriété <code>channelInterpretation</code> avait la valeur <code>discrete</code>.<br> - La spécification autorise explicitement la définition à venir de nouvelles configurations de sortie pour les enceintes. Ce cas de figure n'est par conséquent pas garanti dans le futur, car le comportement des navigateurs pour un nombre spécifique de canaux pourrait être amené à changer.</td> - </tr> - <tr> - <th colspan="1" rowspan="2" scope="row"><code>discrete</code></th> - <td rowspan="1">tout (<code>x</code>)</td> - <td rowspan="1">tout (<code>y</code>) pour lequel <code>x<y</code></td> - <td><em>Conversion ascendante de canaux discrets.</em><br> - Remplit chaque canal de sortie avec son équivalent en entrée, c'est-à-dire le canal qui a le même index. Les canaux de sortie qui n'ont pas d'équivalent en entrée restent silencieux.</td> - </tr> - <tr> - <td rowspan="1">tout (<code>x</code>)</td> - <td rowspan="1">tout (<code>y</code>) pour lequel <code>x>y</code></td> - <td><em>Conversion descendante de canaux discrets.</em><br> - Remplit chaque canal de sortie avec son équivalent en entrée, c'est-à-dire le canal qui a le même index. Les canaux d'entrée qui n'ont pas d'équivalent en sortie sont perdus.</td> - </tr> - </tbody> + <thead> + <tr> + <th scope="row">Interprétation</th> + <th scope="col">Canaux d'entrée</th> + <th scope="col">Canaux de sortie</th> + <th scope="col">Règles de conversion</th> + </tr> + </thead> + <tbody> + <tr> + <th colspan="1" rowspan="13" scope="row"><code>speakers</code></th> + <td><code>1</code> <em>(Mono)</em></td> + <td><code>2</code> <em>(Stéréo)</em></td> + <td> + <em>Conversion ascendante de mono vers stéréo</em>.<br />Le canal + d'entrée <code>M</code> est utilisé pour les deux canaux de sortie + (<code>L</code> et <code>R</code>).<br /><code + >output.L = input.M<br />output.R = input.M</code + > + </td> + </tr> + <tr> + <td><code>1</code> <em>(Mono)</em></td> + <td><code>4</code> <em>(Quad)</em></td> + <td> + <em>Conversion ascendante de mono vers quad.</em><br />Le canal d'entrée + <code>M</code> est utilisé pour les canaux de sortie autres que surround + (<code>L</code> et <code>R</code>). Les canaux de sortie surround (<code + >SL</code + > + et <code>SR</code>) sont silencieux.<br /><code + >output.L = input.M<br />output.R = input.M<br />output.SL = 0<br />output.SR + = 0</code + > + </td> + </tr> + <tr> + <td><code>1</code> <em>(Mono)</em></td> + <td><code>6</code> <em>(5.1)</em></td> + <td> + <em>Conversion ascendante de mono vers 5.1.</em><br />Le canal d'entrée + <code>M</code> est utilisé pour le canal de sortie central + (<code>C</code>). Tous les autres canaux (<code>L</code>, + <code>R</code>, <code>LFE</code>, <code>SL</code>, et <code>SR</code>) + sont silencieux.<br /><code>output.L = 0<br />output.R = 0</code + ><br /><code + >output.C = input.M<br />output.LFE = 0<br />output.SL = 0<br />output.SR + = 0</code + > + </td> + </tr> + <tr> + <td><code>2</code> <em>(Stéréo)</em></td> + <td><code>1</code> <em>(Mono)</em></td> + <td> + <em>Conversion descendante de stéréo vers mono</em>.<br />Les deux + canaux d'entrée (<code>L</code> et <code>R</code>) sont combinées pour + produire l'unique canal de sortie (<code>M</code>).<br /><code + >output.M = 0.5 * (input.L + input.R)</code + > + </td> + </tr> + <tr> + <td><code>2</code> <em>(Stéréo)</em></td> + <td><code>4</code> <em>(Quad)</em></td> + <td> + <em>Conversion ascendante de stéréo vers quad.</em><br />Les canaux + d'entrée <code>L</code> et <code>R </code>input sont utilisés pour leurs + équivalents respectifs non-surround en sortie (<code>L</code> et + <code>R</code>). Les canaux de sortie surround (<code>SL</code> et + <code>SR</code>) sont silencieux.<br /><code + >output.L = input.L<br />output.R = input.R<br />output.SL = 0<br />output.SR + = 0</code + > + </td> + </tr> + <tr> + <td><code>2</code> <em>(Stéréo)</em></td> + <td><code>6</code> <em>(5.1)</em></td> + <td> + <em>Conversion ascendante de stéréo vers 5.1.</em><br />Les canaux + d'entrée <code>L</code> et <code>R </code>sont utilisés pour leurs + équivalents respectifs non-surround en sortie (<code>L</code> et + <code>R</code>). Les canaux de sortie surround (<code>SL</code> et + <code>SR</code>), ainsi que le canal central (<code>C</code>) et le + canal subwoofer (<code>LFE</code>) restent silencieux.<br /><code + >output.L = input.L<br />output.R = input.R<br />output.C = 0<br />output.LFE + = 0<br />output.SL = 0<br />output.SR = 0</code + > + </td> + </tr> + <tr> + <td><code>4</code> <em>(Quad)</em></td> + <td><code>1</code> <em>(Mono)</em></td> + <td> + <em>Conversion descendante de quad vers mono</em>.<br />Les quatre + canaux de sortie (<code>L</code>, <code>R</code>, <code>SL</code>, et + <code>SR</code>) sont combinés pour produire l'unique canal de sortie + (<code>M</code>).<br /><code + >output.M = 0.25 * (input.L + input.R + </code + ><code>input.SL + input.SR</code><code>)</code> + </td> + </tr> + <tr> + <td><code>4</code> <em>(Quad)</em></td> + <td><code>2</code> <em>(Stéréo)</em></td> + <td> + <em>Conversion descendante de quad vers stéréo</em>.<br />Les deux + canaux d'entrée à gauche (<code>L</code> and <code>SL</code>) sont + combinés pour produire l'unique canal de sortie à gauche + (<code>L</code>). De la même façon, les deux canaux d'entrée à droite + (<code>R</code> et <code>SR</code>) sont combinés pour produire l'unique + canal de sortie à droite (<code>R</code>).<br /><code + >output.L = 0.5 * (input.L + input.SL</code + ><code>)</code><br /><code>output.R = 0.5 * (input.R + input.SR</code + ><code>)</code> + </td> + </tr> + <tr> + <td><code>4</code> <em>(Quad)</em></td> + <td><code>6</code> <em>(5.1)</em></td> + <td> + <em>Conversion ascendante de quad vers 5.1.</em><br />Les canaux + d'entrée <code>L</code>, <code>R</code>, <code>SL</code>, et + <code>SR</code> sont utilisés pour leur canaux de sortie équivalents + respectifs (<code>L</code> and <code>R</code>). Le canal central + (<code>C</code>) et le canal subwoofer (<code>LFE</code>) restent + silencieux.<br /><code + >output.L = input.L<br />output.R = input.R<br />output.C = 0<br />output.LFE + = 0<br />output.SL = input.SL<br />output.SR = input.SR</code + > + </td> + </tr> + <tr> + <td><code>6</code> <em>(5.1)</em></td> + <td><code>1</code> <em>(Mono)</em></td> + <td> + <em>Conversion descendante de 5.1 vers mono.</em><br />Les canaux de + gauche (<code>L</code> et <code>SL</code>), de droite (<code>R</code> et + <code>SR</code>) et central sont tous mixés ensemble. Les canaux + surround sont légèrement atténués et la puissance des canaux latéraux + est compensée pour la faire compter comme un seul canal en la + multipliant par <code>√2/2</code>. Le canal subwoofer (<code>LFE</code>) + est perdu.<br /><code + >output.M = 0.7071 * (input.L + input.R) + input.C + 0.5 * (input.SL + + input.SR)</code + > + </td> + </tr> + <tr> + <td><code>6</code> <em>(5.1)</em></td> + <td><code>2</code> <em>(Stéréo)</em></td> + <td> + <em>Conversion descendante de 5.1 vers stéréo.</em><br />Le canal + central (<code>C</code>) est additionné avec chacun des canaux latéraux + (<code>SL</code> et <code>SR</code>) puis combiné avec chacun des canaux + latéraux (L et R). Comme il est converti en deux canaux, il est mixé à + une puissance inférieure : multiplié par <code>√2/2</code>. Le canal + subwoofer (<code>LFE</code>) est perdu.<br /><code + >output.L = input.L + 0.7071 * (input.C + input.SL)<br />output.R = + input.R </code + ><code>+ 0.7071 * (input.C + input.SR)</code> + </td> + </tr> + <tr> + <td><code>6</code> <em>(5.1)</em></td> + <td><code>4</code> <em>(Quad)</em></td> + <td> + <em>Conversion descendante de 5.1 vers quad.</em><br />Le canal central + (<code>C</code>) est combiné avec les canaux latéraux non-surround + (<code>L</code> et <code>R</code>). Comme il est converti en deux + canaux, il est mixé à une puissance inférieure : multiplié par + <code>√2/2</code>. Les canaux surround restent inchangés. Le canal + subwoofer (<code>LFE</code>) est perdu.<br /><code + >output.L = input.L + 0.7071 * input.C<br />output.R = input.R + + 0.7071 * input.C<br /><code + >output.SL = input.SL<br />output.SR = input.SR</code + ></code + > + </td> + </tr> + <tr> + <td colspan="2" rowspan="1">Autres configurations non-standard</td> + <td> + Les configurations non-standard sont traitées comme si la propriété + <code>channelInterpretation</code> avait la valeur + <code>discrete</code>.<br />La spécification autorise explicitement la + définition à venir de nouvelles configurations de sortie pour les + enceintes. Ce cas de figure n'est par conséquent pas garanti dans le + futur, car le comportement des navigateurs pour un nombre spécifique de + canaux pourrait être amené à changer. + </td> + </tr> + <tr> + <th colspan="1" rowspan="2" scope="row"><code>discrete</code></th> + <td rowspan="1">tout (<code>x</code>)</td> + <td rowspan="1"> + tout (<code>y</code>) pour lequel <code>x<y</code> + </td> + <td> + <em>Conversion ascendante de canaux discrets.</em><br />Remplit chaque + canal de sortie avec son équivalent en entrée, c'est-à-dire le canal qui + a le même index. Les canaux de sortie qui n'ont pas d'équivalent en + entrée restent silencieux. + </td> + </tr> + <tr> + <td rowspan="1">tout (<code>x</code>)</td> + <td rowspan="1">tout (<code>y</code>) pour lequel <code>x>y</code></td> + <td> + <em>Conversion descendante de canaux discrets.</em><br />Remplit chaque + canal de sortie avec son équivalent en entrée, c'est-à-dire le canal qui + a le même index. Les canaux d'entrée qui n'ont pas d'équivalent en + sortie sont perdus. + </td> + </tr> + </tbody> </table> -<h2 id="Visualisations">Visualisations</h2> +## Visualisations -<p>Une visualisation audio consiste en général à utiliser un flux de données audio dans le temps (souvent des informations de gain ou de fréquence) pour générer un affichage graphique (comme un graphe). La Web Audio API possède un {{domxref("AnalyserNode")}} qui n'altère pas le signal audio qui le traverse, permettant de générer des données qui peuvent être utilisées par une technologie de visualisation telle que {{htmlelement("canvas")}}.</p> +Une visualisation audio consiste en général à utiliser un flux de données audio dans le temps (souvent des informations de gain ou de fréquence) pour générer un affichage graphique (comme un graphe). La Web Audio API possède un {{domxref("AnalyserNode")}} qui n'altère pas le signal audio qui le traverse, permettant de générer des données qui peuvent être utilisées par une technologie de visualisation telle que {{htmlelement("canvas")}}. -<p><img alt="Le noeud permet de récupérer la fréquence et le domaine temporel en utilisant FFT, et ce sans modifier le flux audio" src="fttaudiodata.svg"></p> +![Le noeud permet de récupérer la fréquence et le domaine temporel en utilisant FFT, et ce sans modifier le flux audio](fttaudiodata.svg) -<p>On peut accéder aux données en utilisant les méthodes suivantes:</p> +On peut accéder aux données en utilisant les méthodes suivantes: -<dl> - <dt>{{domxref("AnalyserNode.getFloatFrequencyData()")}}</dt> - <dd>Copie les données de fréquence dans le tableau {{domxref("Float32Array")}} passé en argument.</dd> -</dl> +- {{domxref("AnalyserNode.getFloatFrequencyData()")}} + - : Copie les données de fréquence dans le tableau {{domxref("Float32Array")}} passé en argument. -<dl> - <dt>{{domxref("AnalyserNode.getByteFrequencyData()")}}</dt> - <dd>Copies les données de fréquence dans le tableau d'octets non signés {{domxref("Uint8Array")}} passé en argument.</dd> -</dl> +<!----> -<dl> - <dt>{{domxref("AnalyserNode.getFloatTimeDomainData()")}}</dt> - <dd>Copie les données de l'onde de forme, ou domaine temporel, dans le {{domxref("Float32Array")}} passé en argument.</dd> - <dt>{{domxref("AnalyserNode.getByteTimeDomainData()")}}</dt> - <dd>Copie les données de l'onde de forme, ou domaine temporel, dans le tableau d'octets non signés {{domxref("Uint8Array")}} passé en argument.</dd> -</dl> +- {{domxref("AnalyserNode.getByteFrequencyData()")}} + - : Copies les données de fréquence dans le tableau d'octets non signés {{domxref("Uint8Array")}} passé en argument. -<div class="note"> -<p><strong>Note :</strong> Pour plus d'informations, voir notre article <a href="/en-US/docs/Web/API/Web_Audio_API/Visualizations_with_Web_Audio_API">Visualizations with Web Audio API</a>.</p> -</div> +<!----> -<h2 id="Spatialisations">Spatialisations</h2> +- {{domxref("AnalyserNode.getFloatTimeDomainData()")}} + - : Copie les données de l'onde de forme, ou domaine temporel, dans le {{domxref("Float32Array")}} passé en argument. +- {{domxref("AnalyserNode.getByteTimeDomainData()")}} + - : Copie les données de l'onde de forme, ou domaine temporel, dans le tableau d'octets non signés {{domxref("Uint8Array")}} passé en argument. -<div> -<p>Une spatialisation audio (gérée par les noeuds {{domxref("PannerNode")}} et {{domxref("AudioListener")}} dans la Web Audio API) permet de modéliser la position et le comportement d'un signal audio situé dans l'espace, ainsi que l'auditeur qui perçoit ce signal.</p> +> **Note :** Pour plus d'informations, voir notre article [Visualizations with Web Audio API](/en-US/docs/Web/API/Web_Audio_API/Visualizations_with_Web_Audio_API). -<p>La position du panoramique est décrite avec des coodonnées cartésiennes selon la règle de la main droite, son mouvement à l'aide d'un vecteur de vélocité (nécessaire pour la création d'effets Doppler) et sa direction avec un cone de direction. Le cone peut être très large, par exemple dans le cas de sources omnidirectionnelles.</p> -</div> +## Spatialisations -<p><img alt="Le PannerNode donne la position dans l'espace, la vélocité et la direction d'un signal donné" src="pannernode.svg"></p> +Une spatialisation audio (gérée par les noeuds {{domxref("PannerNode")}} et {{domxref("AudioListener")}} dans la Web Audio API) permet de modéliser la position et le comportement d'un signal audio situé dans l'espace, ainsi que l'auditeur qui perçoit ce signal. -<div> -<p>La position de l'auditeur est décrite avec des coodonnées cartésiennes selon la règle de la main droite, son mouvement à l'aide d'un vecteur de vélocité et la direction vers laquelle elle pointe en utilisant deux vecteurs de direction : haut et face. Ceux-ci définissent respectivement la direction vers laquelle pointent le haut de la tête et le bout du nez de l'auditeur, et forment un angle droit entre eux.</p> -</div> +La position du panoramique est décrite avec des coodonnées cartésiennes selon la règle de la main droite, son mouvement à l'aide d'un vecteur de vélocité (nécessaire pour la création d'effets Doppler) et sa direction avec un cone de direction. Le cone peut être très large, par exemple dans le cas de sources omnidirectionnelles. -<p><img alt="On voit la position d'un auditeur, ainsi que les vecteurs de direction haut et de face qui forment un angle de 90°" src="listener.svg"></p> +![Le PannerNode donne la position dans l'espace, la vélocité et la direction d'un signal donné](pannernode.svg) -<div class="note"> -<p><strong>Note :</strong> For more information, see our <a href="/en-US/docs/Web/API/Web_Audio_API/Web_audio_spatialization_basics">Web audio spatialization basics</a> article.</p> -</div> +La position de l'auditeur est décrite avec des coodonnées cartésiennes selon la règle de la main droite, son mouvement à l'aide d'un vecteur de vélocité et la direction vers laquelle elle pointe en utilisant deux vecteurs de direction : haut et face. Ceux-ci définissent respectivement la direction vers laquelle pointent le haut de la tête et le bout du nez de l'auditeur, et forment un angle droit entre eux. -<h2 id="Fan-in_et_Fan-out">Fan-in et Fan-out</h2> +![On voit la position d'un auditeur, ainsi que les vecteurs de direction haut et de face qui forment un angle de 90°](listener.svg) -<p>En audio, <strong>fan-in</strong> désigne le processus par lequel un {{domxref("ChannelMergerNode")}} prend une série d'entrées mono entrée et restitue un seul signal multi-canaux :</p> +> **Note :** For more information, see our [Web audio spatialization basics](/en-US/docs/Web/API/Web_Audio_API/Web_audio_spatialization_basics) article. -<p><img alt="" src="fanin.svg"></p> +## Fan-in et Fan-out -<p><strong>Fan-out</strong> désigne le processus opposé, par lequel un {{domxref("ChannelSplitterNode")}} prend une source multi-canaux en entrée et restitue plusieurs signaux mono en sortie:</p> +En audio, **fan-in** désigne le processus par lequel un {{domxref("ChannelMergerNode")}} prend une série d'entrées mono entrée et restitue un seul signal multi-canaux : -<p><img alt="" src="fanout.svg"></p> +![](fanin.svg) + +**Fan-out** désigne le processus opposé, par lequel un {{domxref("ChannelSplitterNode")}} prend une source multi-canaux en entrée et restitue plusieurs signaux mono en sortie: + +![](fanout.svg) diff --git a/files/fr/web/api/web_audio_api/index.md b/files/fr/web/api/web_audio_api/index.md index 087d05a380..4a873b52ac 100644 --- a/files/fr/web/api/web_audio_api/index.md +++ b/files/fr/web/api/web_audio_api/index.md @@ -3,186 +3,157 @@ title: Web Audio API slug: Web/API/Web_Audio_API translation_of: Web/API/Web_Audio_API --- -<div> -<p>La Web Audio API propose un système puissant et flexible pour contrôler les données audio sur internet. Elle permet notamment de sélectionner des sources audio (microphone, flux media), d'y ajouter des effets, de créer des visualisations, d'appliquer des effets de spatialisation (comme la balance), etc.</p> -</div> - -<h2 id="Concepts_et_usages">Concepts et usages</h2> - -<p>La Web Audio API effectue des opérations dans un <strong>contexte audio</strong>; elle a été conçue pour supporter le <strong>routing modulaire</strong>. Les opérations audio basiques sont réalisées via des <strong>noeuds audio</strong> reliés entre eux pour former un <strong>graphe de routage audio</strong>. Plusieurs sources - avec différents types d'agencements de canaux - peuvent être supportées, même dans un seul contexte. Ce design modulaire et flexible permet de créer des fonctions audio complexes avec des effets dynamiques.</p> - -<p>Les noeuds audio sont reliés au niveau de leurs entrées et sorties, formant des chaînes ou des réseaux simples. Il peut y avoir une ou plusieurs sources. Les sources fournissent des tableaux d'intensités sonores (échantillons), souvent plusieurs dizaines de milliers par seconde. Ceux-ci peuvent être calculées mathématiquement (avec un {{domxref("OscillatorNode")}}), ou peuvent provenir de fichiers sons ou vidéos (comme {{domxref("AudioBufferSourceNode")}} ou {{domxref("MediaElementAudioSourceNode")}}) ou de flux audio ({{domxref("MediaStreamAudioSourceNode")}}). En réalité, les fichiers sons sont eux-même des enregistrements d'intensités sonores, qui viennent de microphones ou d'instruments électriques, et sont mixés dans une seule onde complexe.</p> - -<p>Les sorties de ces noeuds peuvent être liées aux entrées d'autres noeuds, qui mixent ces flux d'échantillons sonores ou les séparent en différents flux. Une modification courante est la multiplications des échantillons par une valeur afin d'en augmenter ou diminuer le volume sonore (comme c'est le cas pour le {{domxref("GainNode")}}). Le son est ensuite lié à une destination ({{domxref("AudioContext.destination")}}), qui l'envoie aux enceintes ou au casque audio. Cette dernière connexion n'est utile que si le son doit être entendu.<br> - <br> - Un processus de développement typique avec web audio ressemble à ceci :</p> - -<ul> - <li>Création d'un contexte audio</li> - <li>Dans ce contexte, création des sources — comme <code><audio></code>, oscillator, stream</li> - <li>Création de noeuds d'effets, comme la réverbération, les filtres biquad, la balance, le compresseur</li> - <li>Choix de la sortie audio (appelée destination), par exemple les enceintes du système</li> - <li>Connection des sources aux effets, et des effets à la destination</li> -</ul> - -<p><img alt="Un diagramme de boîte avec une boîte extérieure intitulée contexte audio et trois boîtes à l'intérieur intitulées source, effets et destination. Les trois boîtes intérieures ont des flèches qui pointent de la gauche vers la droite, indiquant le sens du flux de l'information audio." src="audio-context_.png"></p> - -<p>Le timing est contrôlé avec une grande précision et une latence faible, ce qui permet aux développeurs d'écrire un code qui réagit précisément aux événements et qui est capable de traiter des échantillons précis, même avec un taux d'échantillonnage élevé. Cela permet d'envisager des applications telles que des boîtes à rythme ou des séquenceurs.</p> - -<p>La Web Audio API permet également de contrôler la <em>spatialisation</em> du son. En utilisant un système basé sur le modèle <em>émetteur - récepteur, </em>elle permet le contrôle de la balance ainsi que la gestion de l'atténuation du son en fonction de la distance, ou effet doppler, induite par un déplacement de la source sonore (ou de l'auditeur).</p> - -<div class="note"> -<p><strong>Note :</strong> Vous pouvez lire d'avantage de détails sur la Web Audio API en vous rendant sur notre article<a href="/en-US/docs/Web/API/Web_Audio_API/Basic_concepts_behind_Web_Audio_API"> Concepts de base de la Web Audio API</a>.</p> -</div> - -<h2 id="Interface_de_la_Web_Audio_API">Interface de la Web Audio API</h2> - -<p>La Web Audio API expose 28 interfaces avec des événements associés, classés selon leur fonction en 9 catégories.</p> - -<h3 id="Définition_du_graphe_audio">Définition du graphe audio</h3> - -<p>Conteneurs et définitions qui donnent sa forme au graphe audio</p> - -<dl> - <dt>{{domxref("AudioContext")}}</dt> - <dd>Un objet <strong><code>AudioContext</code></strong> désigne un graphe de traitement audio construit à partir de modules reliés entre eux, chacun représenté par un noeud audio ({{domxref("AudioNode")}}). Le contexte audio contrôle la création des noeuds qu'il contient, ainsi que l'exécution du traitement audio, et du décodage. Il est nécessaire de créer un <code>AudioContext</code> avant de faire quoi que ce soit d'autre, puisque tout se passe dans un contexte.</dd> - <dt>{{domxref("AudioNode")}}</dt> - <dd>Un objet <strong><code>AudioNode</code></strong><strong> </strong>est un module de traitement audio, tel qu'une <em>source audio</em> (c'est-à-dire un élément HTML {{HTMLElement("audio")}} ou {{HTMLElement("video")}}), une <em>destination audio</em>, un <em>module de traitement intermédiaire</em> (par exemple un filtre {{domxref("BiquadFilterNode")}}), ou un contrôle du volume {{domxref("GainNode")}}).</dd> - <dt>{{domxref("AudioParam")}}</dt> - <dd>Un objet <strong><code>AudioParam</code></strong><strong> </strong>est un paramètre audio, qui est lié à un {{domxref("AudioNode")}}. On peut lui assigner une valeur ou un changement de valeur, que l'on peut programmer à un moment spécifique et/ou selon un motif particulier.</dd> - <dt>{{event("ended_(Web_Audio)", "ended")}} (event)</dt> - <dd>L'évènement <code>ended</code> est diffusé lorsque la lecture s'arrête en arrivant à la fin d'un media.</dd> -</dl> - -<h3 id="Définition_des_sources_audio">Définition des sources audio</h3> - -<dl> - <dt>{{domxref("OscillatorNode")}}</dt> - <dd>Un objet <strong><code>OscillatorNode</code></strong><strong> </strong>est un module de traitement audio qui génère la création d'une onde sinusoïdale d'une certaine fréquence.</dd> - <dt>{{domxref("AudioBuffer")}}</dt> - <dd>Un objet <strong><code>AudioBuffer</code></strong> est un petit morceau de contenu audio monté en mémoire. Il peut être créé à partir d'un fichier audio avec la méthode {{ domxref("AudioContext.decodeAudioData()") }}, ou à partir de données brutes en utilisant {{ domxref("AudioContext.createBuffer()") }}. Une fois décodé sous cette forme, la source audio peut être placée dans un {{ domxref("AudioBufferSourceNode") }}.</dd> - <dt>{{domxref("AudioBufferSourceNode")}}</dt> - <dd>Un objet <strong><code>AudioBufferSourceNode</code></strong> est une source audio composée de données audio montées en mémoire dans un {{domxref("AudioBuffer")}}. C'est un {{domxref("AudioNode")}} qui se comporte comme une source audio.</dd> - <dt>{{domxref("MediaElementAudioSourceNode")}}</dt> - <dd>Un objet <code><strong>MediaElementAudio</strong></code><strong><code>SourceNode</code></strong> est une source audio composée d'un élément HTML5 {{ htmlelement("audio") }} ou {{ htmlelement("video") }}. C'est un {{domxref("AudioNode")}} qui se comporte comme une source audio.</dd> - <dt>{{domxref("MediaStreamAudioSourceNode")}}</dt> - <dd>Un objet <code><strong>MediaStreamAudio</strong></code><strong><code>SourceNode</code></strong> est une source audio composée d'un <a href="/en-US/docs/WebRTC">WebRTC</a> {{domxref("MediaStream")}} (tel qu'une webcam ou un microphone). C'est un {{domxref("AudioNode")}} qui se comporte comme une source audio.</dd> -</dl> - -<h3 id="Définition_des_filtres_d'effets_audio">Définition des filtres d'effets audio</h3> - -<dl> - <dt>{{domxref("BiquadFilterNode")}}</dt> - <dd>Un objet <strong><code>BiquadFilterNode</code> </strong>est un simple filtre de bas niveau. Il peut s'agir de différents types de filtres, contrôle du volume ou égaliseurs graphiques. Un <code>BiquadFilterNode</code> a toujours exactement une entrée et une sortie.</dd> - <dt>{{domxref("ConvolverNode")}}</dt> - <dd>Un objet <code><strong>Convolver</strong></code><strong><code>Node</code></strong><strong> </strong>est un {{domxref("AudioNode")}} qui exécute une circonvolution linéaire sur un AudioBuffer donné, souvent utilisé pour créer un effet de réverbération.</dd> - <dt>{{domxref("DelayNode")}}</dt> - <dd>Un objet <strong><code>DelayNode</code></strong><strong> </strong>est une ligne à retard numérique, c'est-à-dire un module de traitement automatique qui provoque un délai entre l'arrivée du son en entrée et sa propagation en sortie.</dd> - <dt>{{domxref("DynamicsCompressorNode")}}</dt> - <dd>Un objet <strong><code>DynamicsCompressorNode</code></strong> permet un effet de compression, qui réduit le volume des parties les plus fortes du signal de façon à éviter les effets de clipping et la distortion qui peuvent se produire lorsque des sons multiples sont diffusés simultanément.</dd> - <dt>{{domxref("GainNode")}}</dt> - <dd>Un objet <strong><code>GainNode</code></strong><strong> </strong> représente une modification du volume sonore. C'est un module de traitement audio qui provoque l'application d'un <em>gain</em> aux données récupérées en entrée avant leur propagation vers la sortie.</dd> - <dt>{{domxref("WaveShaperNode")}}</dt> - <dd>Un objet <strong><code>WaveShaperNode</code></strong> représente une distortion non linéaire. C'est un {{domxref("AudioNode")}} qui utilise une courbe pour appliquer au signal une distortion de mise en forme des ondes. En dehors de l'effet de distortion évident, il est souvent utilisé pour donner un caractère plus chaleureux au son. </dd> - <dt>{{domxref("PeriodicWave")}}</dt> - <dd>Un objet {{domxref("PeriodicWave")}} est utilisé pour définir une forme d'onde périodique qui peut être utilisée pour façonner la sortie d'un {{ domxref("OscillatorNode") }}.</dd> -</dl> - -<h3 id="Définition_des_destinations_audio">Définition des destinations audio</h3> - -<p>Une fois que le signal audio a été traité, ces interfaces définissent sa destination.</p> - -<dl> - <dt>{{domxref("AudioDestinationNode")}}</dt> - <dd>Un noeud <strong><code>AudioDestinationNode</code></strong> représente la destination finale d'une source audio source dans un contexte donné — en général les enceintes du matériel.</dd> - <dt>{{domxref("MediaStreamAudioDestinationNode")}}</dt> - <dd>Un noeud <code><strong>MediaStreamAudio</strong></code><strong><code>DestinationNode</code></strong> représente une destination audio constituée d'un {{domxref("MediaStream")}} <a href="/en-US/docs/WebRTC">WebRTC</a> à une seule piste <code>AudioMediaStreamTrack</code>; il peut être utilisé de façon similaire à un {{domxref("MediaStream")}} obtenu avec {{ domxref("Navigator.getUserMedia") }}. C'est un {{domxref("AudioNode")}} qui se comporte comme une destination audio.</dd> -</dl> - -<h3 id="Analyse_des_données_et_visualisation">Analyse des données et visualisation</h3> - -<dl> - <dt>{{domxref("AnalyserNode")}}</dt> - <dd>Un objet <strong><code>AnalyserNode</code></strong> fournit en temps réel des informations concernant la fréquence et le temps, afin de les analyser et les visualiser.</dd> -</dl> - -<h3 id="Division_et_fusion_des_pistes_audio">Division et fusion des pistes audio</h3> - -<dl> - <dt>{{domxref("ChannelSplitterNode")}}</dt> - <dd>Un noeud <code><strong>ChannelSplitterNode</strong></code> prend en entrée une source audio et sépare ses différentes pistes en une série de sorties <em>mono</em>.</dd> - <dt>{{domxref("ChannelMergerNode")}}</dt> - <dd>Un noeud <code><strong>ChannelMergerNode</strong></code> réunit différentes entrées mono en une seule sortie. Chaque entrée devient une des pistes de la sortie unique.</dd> -</dl> - -<h3 id="Spatialisation_audio">Spatialisation audio</h3> - -<dl> - <dt>{{domxref("AudioListener")}}</dt> - <dd>Un objet <strong><code>AudioListener</code></strong><strong> </strong>représente la position et l'orientation de l'unique personne écoutant la scene audio utilisée dans la spatialisation audio.</dd> - <dt>{{domxref("PannerNode")}}</dt> - <dd>Un noeud <strong><code>PannerNode</code></strong> représente le comportement d'un signal dans l'espace. C'est un module de traitement audio qui décrit sa position avec des coordonnées cartésiennes fondées sur la règle de la main droite; ses mouvements utilisent un vecteur de vélocité et sa directionnalité un cône de direction.</dd> -</dl> - -<h3 id="Traitement_audio_avec_JavaScript">Traitement audio avec JavaScript</h3> - -<div class="note"> -<p><strong>Note :</strong> Au jour de la publication de la spécification Web Audio API le 29 août 2014, ces fonctionnalités sont dépréciées, et seront bientôt remplacées par {{ anch("Audio_Workers") }}.</p> -</div> - -<dl> - <dt>{{domxref("ScriptProcessorNode")}}</dt> - <dd>Un noeud <strong><code>ScriptProcessorNode</code></strong><strong> </strong>permet de générer, traiter ou analyser du son avec JavaScript. C'est un module de traitement audio qui est lié à deux buffers, l'un en entrée, et l'autre en sortie. Un évènement implémentant {{domxref("AudioProcessingEvent")}} est envoyé à l'objet à chaque fois que le buffer d'entrée reçoit de nouvelles données, et le gestionnaire d'évènement prend fin lorsque les nouvelles données ont été communiquées au buffer de sortie. </dd> - <dt>{{event("audioprocess")}} (event)</dt> - <dd>L'évènement <code>audioprocess</code> est émis lorsque le buffer d'entrée d'un {{domxref("ScriptProcessorNode")}} de la Web Audio API est prêt à être traité.</dd> - <dt>{{domxref("AudioProcessingEvent")}}</dt> - <dd>L'objet <code>AudioProcessingEvent </code>est envoyé aux fonctions de callback qui écoutent l'évènement <code>audioprocess.</code></dd> -</dl> - -<h3 id="Traitement_audio_hors_ligne_ou_en_tâche_de_fond">Traitement audio hors ligne ou en tâche de fond</h3> - -<p>Il est possible de traiter et exporter un graphe audio très rapidement en tâche de fond — en l'exportant dans un {{domxref("AudioBuffer")}} plutôt que sur les enceintes du matériel — grâce aux objets suivants.</p> - -<dl> - <dt>{{domxref("OfflineAudioContext")}}</dt> - <dd>Un objet <strong><code>OfflineAudioContext</code></strong> est un {{domxref("AudioContext")}} qui représente un graphe de traitement audio construit à partir de noeuds audio. A la différence du <code>AudioContext </code>standard, un <code>OfflineAudioContext</code> n'exporte pas vraiment le son, mais le génère, aussi vite que possible, dans un buffer.</dd> - <dt>{{event("complete")}} (event)</dt> - <dd>Un évènement <code>complete</code> est émis lorsque le rendu d'un {{domxref("OfflineAudioContext")}} est terminé.</dd> - <dt>{{domxref("OfflineAudioCompletionEvent")}}</dt> - <dd>The <code>OfflineAudioCompletionEvent</code> est envoyé aux fonctions de callback qui écoutent l'évènement {{event("complete")}} event implements this interface.</dd> -</dl> - -<h3 id="Audio_Workers">Audio Workers</h3> - -<p>Les Audio workers offrent la possibilité de traiter le son directement dans le contexte d'un <a href="/en-US/docs/Web/Guide/Performance/Using_web_workers">web worker</a>. En date du 29 August 2014, ils ne sont encore implémentés par aucun navigateur. Lorsqu'ils seront implémentés, ils remplaceront {{domxref("ScriptProcessorNode")}}, et les autres fonctionnalités mentionnées dans la section <a href="#Audio_processing_via_JavaScript">Traitement audio avec JavaScript</a> ci-avant.</p> - -<dl> - <dt>{{domxref("AudioWorkerNode")}}</dt> - <dd>Un objet AudioWorkerNode représente un {{domxref("AudioNode")}} qui interagit avec le thread d'un worker pour générer, traiter, ou analyse le son directement.</dd> - <dt>{{domxref("AudioWorkerGlobalScope")}}</dt> - <dd>Un objet <code>AudioWorkerGlobalScope</code> est un objet dérivé d'un objet <code>DedicatedWorkerGlobalScope</code>. Il représente le contexte d'un worker dans lequel un script de traitement audio est lancé; il est conçu pour permettre la génération, le traitement, et l'analyse de données audio directement avec JavaScript dans le thread d'un worker.</dd> - <dt>{{domxref("AudioProcessEvent")}}</dt> - <dd>UN objet <code>Event</code> est transmis aux objets {{domxref("AudioWorkerGlobalScope")}} pour effectuer un traitement audio.</dd> -</dl> - -<h2 id="Example">Objets obsolètes</h2> - -<p>Les objets suivants étaient définis dans les versions précédentes de la spécification, mais sont maintenant obsolètes et ont été remplacés.</p> - -<dl> - <dt>{{domxref("JavaScriptNode")}}</dt> - <dd>Utilisé pour le traitement du son directement en Javascript. Cet objet est obsolète, et a été remplacé par {{domxref("ScriptProcessorNode")}}.</dd> - <dt>{{domxref("WaveTableNode")}}</dt> - <dd>Utilisé pour définir une forme d'onde périodique. Cet objet est obsolète, et a été remplacé par {{domxref("PeriodicWave")}}.</dd> -</dl> - -<h2 id="Example">Exemple</h2> - -<p>Cet exemple montre l'utilisation d'un grand nombre de fonctions Web Audio. La démo est disponible en ligne sur <a href="http://mdn.github.io/voice-change-o-matic/">Voice-change-o-matic</a> (voir aussi le <a href="https://github.com/mdn/voice-change-o-matic"> code source complet sur Github</a>) —c'est une démo expérimentale d'application pour modifier la voix; baissez le son de vos enceintes pour l'utiliser, au moins au début !</p> - -<p>Les lignes qui concernent la Web Audio API sont surlignées; si vous voulez en savoir davantage sur les différentes méthodes, consultez la documentation.</p> +La Web Audio API propose un système puissant et flexible pour contrôler les données audio sur internet. Elle permet notamment de sélectionner des sources audio (microphone, flux media), d'y ajouter des effets, de créer des visualisations, d'appliquer des effets de spatialisation (comme la balance), etc. -<pre class="brush: js">var contexteAudio = new (window.AudioContext || window.webkitAudioContext)(); // définition du contexte audio +## Concepts et usages + +La Web Audio API effectue des opérations dans un **contexte audio**; elle a été conçue pour supporter le **routing modulaire**. Les opérations audio basiques sont réalisées via des **noeuds audio** reliés entre eux pour former un **graphe de routage audio**. Plusieurs sources - avec différents types d'agencements de canaux - peuvent être supportées, même dans un seul contexte. Ce design modulaire et flexible permet de créer des fonctions audio complexes avec des effets dynamiques. + +Les noeuds audio sont reliés au niveau de leurs entrées et sorties, formant des chaînes ou des réseaux simples. Il peut y avoir une ou plusieurs sources. Les sources fournissent des tableaux d'intensités sonores (échantillons), souvent plusieurs dizaines de milliers par seconde. Ceux-ci peuvent être calculées mathématiquement (avec un {{domxref("OscillatorNode")}}), ou peuvent provenir de fichiers sons ou vidéos (comme {{domxref("AudioBufferSourceNode")}} ou {{domxref("MediaElementAudioSourceNode")}}) ou de flux audio ({{domxref("MediaStreamAudioSourceNode")}}). En réalité, les fichiers sons sont eux-même des enregistrements d'intensités sonores, qui viennent de microphones ou d'instruments électriques, et sont mixés dans une seule onde complexe. + +Les sorties de ces noeuds peuvent être liées aux entrées d'autres noeuds, qui mixent ces flux d'échantillons sonores ou les séparent en différents flux. Une modification courante est la multiplications des échantillons par une valeur afin d'en augmenter ou diminuer le volume sonore (comme c'est le cas pour le {{domxref("GainNode")}}). Le son est ensuite lié à une destination ({{domxref("AudioContext.destination")}}), qui l'envoie aux enceintes ou au casque audio. Cette dernière connexion n'est utile que si le son doit être entendu. + +Un processus de développement typique avec web audio ressemble à ceci : + +- Création d'un contexte audio +- Dans ce contexte, création des sources — comme `<audio>`, oscillator, stream +- Création de noeuds d'effets, comme la réverbération, les filtres biquad, la balance, le compresseur +- Choix de la sortie audio (appelée destination), par exemple les enceintes du système +- Connection des sources aux effets, et des effets à la destination + +![Un diagramme de boîte avec une boîte extérieure intitulée contexte audio et trois boîtes à l'intérieur intitulées source, effets et destination. Les trois boîtes intérieures ont des flèches qui pointent de la gauche vers la droite, indiquant le sens du flux de l'information audio.](audio-context_.png) + +Le timing est contrôlé avec une grande précision et une latence faible, ce qui permet aux développeurs d'écrire un code qui réagit précisément aux événements et qui est capable de traiter des échantillons précis, même avec un taux d'échantillonnage élevé. Cela permet d'envisager des applications telles que des boîtes à rythme ou des séquenceurs. + +La Web Audio API permet également de contrôler la _spatialisation_ du son. En utilisant un système basé sur le modèle _émetteur - récepteur,_ elle permet le contrôle de la balance ainsi que la gestion de l'atténuation du son en fonction de la distance, ou effet doppler, induite par un déplacement de la source sonore (ou de l'auditeur). + +> **Note :** Vous pouvez lire d'avantage de détails sur la Web Audio API en vous rendant sur notre article[ Concepts de base de la Web Audio API](/en-US/docs/Web/API/Web_Audio_API/Basic_concepts_behind_Web_Audio_API). + +## Interface de la Web Audio API + +La Web Audio API expose 28 interfaces avec des événements associés, classés selon leur fonction en 9 catégories. + +### Définition du graphe audio + +Conteneurs et définitions qui donnent sa forme au graphe audio + +- {{domxref("AudioContext")}} + - : Un objet **`AudioContext`** désigne un graphe de traitement audio construit à partir de modules reliés entre eux, chacun représenté par un noeud audio ({{domxref("AudioNode")}}). Le contexte audio contrôle la création des noeuds qu'il contient, ainsi que l'exécution du traitement audio, et du décodage. Il est nécessaire de créer un `AudioContext` avant de faire quoi que ce soit d'autre, puisque tout se passe dans un contexte. +- {{domxref("AudioNode")}} + - : Un objet **`AudioNode`\*\*** \**est un module de traitement audio, tel qu'une *source audio* (c'est-à-dire un élément HTML {{HTMLElement("audio")}} ou {{HTMLElement("video")}}), une *destination audio*, un *module de traitement intermédiaire\* (par exemple un filtre {{domxref("BiquadFilterNode")}}), ou un contrôle du volume {{domxref("GainNode")}}). +- {{domxref("AudioParam")}} + - : Un objet **`AudioParam`\*\*** \*\*est un paramètre audio, qui est lié à un {{domxref("AudioNode")}}. On peut lui assigner une valeur ou un changement de valeur, que l'on peut programmer à un moment spécifique et/ou selon un motif particulier. +- {{event("ended_(Web_Audio)", "ended")}} (event) + - : L'évènement `ended` est diffusé lorsque la lecture s'arrête en arrivant à la fin d'un media. + +### Définition des sources audio + +- {{domxref("OscillatorNode")}} + - : Un objet **`OscillatorNode`\*\*** \*\*est un module de traitement audio qui génère la création d'une onde sinusoïdale d'une certaine fréquence. +- {{domxref("AudioBuffer")}} + - : Un objet **`AudioBuffer`** est un petit morceau de contenu audio monté en mémoire. Il peut être créé à partir d'un fichier audio avec la méthode {{ domxref("AudioContext.decodeAudioData()") }}, ou à partir de données brutes en utilisant {{ domxref("AudioContext.createBuffer()") }}. Une fois décodé sous cette forme, la source audio peut être placée dans un {{ domxref("AudioBufferSourceNode") }}. +- {{domxref("AudioBufferSourceNode")}} + - : Un objet **`AudioBufferSourceNode`** est une source audio composée de données audio montées en mémoire dans un {{domxref("AudioBuffer")}}. C'est un {{domxref("AudioNode")}} qui se comporte comme une source audio. +- {{domxref("MediaElementAudioSourceNode")}} + - : Un objet **`MediaElementAudio`\*\***`SourceNode`\*\* est une source audio composée d'un élément HTML5 {{ htmlelement("audio") }} ou {{ htmlelement("video") }}. C'est un {{domxref("AudioNode")}} qui se comporte comme une source audio. +- {{domxref("MediaStreamAudioSourceNode")}} + - : Un objet **`MediaStreamAudio`\*\***`SourceNode`\*\* est une source audio composée d'un [WebRTC](/en-US/docs/WebRTC) {{domxref("MediaStream")}} (tel qu'une webcam ou un microphone). C'est un {{domxref("AudioNode")}} qui se comporte comme une source audio. + +### Définition des filtres d'effets audio + +- {{domxref("BiquadFilterNode")}} + - : Un objet **`BiquadFilterNode` **est un simple filtre de bas niveau. Il peut s'agir de différents types de filtres, contrôle du volume ou égaliseurs graphiques. Un `BiquadFilterNode` a toujours exactement une entrée et une sortie. +- {{domxref("ConvolverNode")}} + - : Un objet **`Convolver`\*\***`Node`\***\* **est un {{domxref("AudioNode")}} qui exécute une circonvolution linéaire sur un AudioBuffer donné, souvent utilisé pour créer un effet de réverbération. +- {{domxref("DelayNode")}} + - : Un objet **`DelayNode`\*\*** \*\*est une ligne à retard numérique, c'est-à-dire un module de traitement automatique qui provoque un délai entre l'arrivée du son en entrée et sa propagation en sortie. +- {{domxref("DynamicsCompressorNode")}} + - : Un objet **`DynamicsCompressorNode`** permet un effet de compression, qui réduit le volume des parties les plus fortes du signal de façon à éviter les effets de clipping et la distortion qui peuvent se produire lorsque des sons multiples sont diffusés simultanément. +- {{domxref("GainNode")}} + - : Un objet **`GainNode`\*\*** \** représente une modification du volume sonore. C'est un module de traitement audio qui provoque l'application d'un *gain\* aux données récupérées en entrée avant leur propagation vers la sortie. +- {{domxref("WaveShaperNode")}} + - : Un objet **`WaveShaperNode`** représente une distortion non linéaire. C'est un {{domxref("AudioNode")}} qui utilise une courbe pour appliquer au signal une distortion de mise en forme des ondes. En dehors de l'effet de distortion évident, il est souvent utilisé pour donner un caractère plus chaleureux au son. +- {{domxref("PeriodicWave")}} + - : Un objet {{domxref("PeriodicWave")}} est utilisé pour définir une forme d'onde périodique qui peut être utilisée pour façonner la sortie d'un {{ domxref("OscillatorNode") }}. + +### Définition des destinations audio + +Une fois que le signal audio a été traité, ces interfaces définissent sa destination. + +- {{domxref("AudioDestinationNode")}} + - : Un noeud **`AudioDestinationNode`** représente la destination finale d'une source audio source dans un contexte donné — en général les enceintes du matériel. +- {{domxref("MediaStreamAudioDestinationNode")}} + - : Un noeud **`MediaStreamAudio`\*\***`DestinationNode`\*\* représente une destination audio constituée d'un {{domxref("MediaStream")}} [WebRTC](/en-US/docs/WebRTC) à une seule piste `AudioMediaStreamTrack`; il peut être utilisé de façon similaire à un {{domxref("MediaStream")}} obtenu avec {{ domxref("Navigator.getUserMedia") }}. C'est un {{domxref("AudioNode")}} qui se comporte comme une destination audio. + +### Analyse des données et visualisation + +- {{domxref("AnalyserNode")}} + - : Un objet **`AnalyserNode`** fournit en temps réel des informations concernant la fréquence et le temps, afin de les analyser et les visualiser. + +### Division et fusion des pistes audio + +- {{domxref("ChannelSplitterNode")}} + - : Un noeud **`ChannelSplitterNode`** prend en entrée une source audio et sépare ses différentes pistes en une série de sorties *mono*. +- {{domxref("ChannelMergerNode")}} + - : Un noeud **`ChannelMergerNode`** réunit différentes entrées mono en une seule sortie. Chaque entrée devient une des pistes de la sortie unique. + +### Spatialisation audio + +- {{domxref("AudioListener")}} + - : Un objet **`AudioListener`\*\*** \*\*représente la position et l'orientation de l'unique personne écoutant la scene audio utilisée dans la spatialisation audio. +- {{domxref("PannerNode")}} + - : Un noeud **`PannerNode`** représente le comportement d'un signal dans l'espace. C'est un module de traitement audio qui décrit sa position avec des coordonnées cartésiennes fondées sur la règle de la main droite; ses mouvements utilisent un vecteur de vélocité et sa directionnalité un cône de direction. + +### Traitement audio avec JavaScript + +> **Note :** Au jour de la publication de la spécification Web Audio API le 29 août 2014, ces fonctionnalités sont dépréciées, et seront bientôt remplacées par {{ anch("Audio_Workers") }}. + +- {{domxref("ScriptProcessorNode")}} + - : Un noeud **`ScriptProcessorNode`\*\*** \*\*permet de générer, traiter ou analyser du son avec JavaScript. C'est un module de traitement audio qui est lié à deux buffers, l'un en entrée, et l'autre en sortie. Un évènement implémentant {{domxref("AudioProcessingEvent")}} est envoyé à l'objet à chaque fois que le buffer d'entrée reçoit de nouvelles données, et le gestionnaire d'évènement prend fin lorsque les nouvelles données ont été communiquées au buffer de sortie. +- {{event("audioprocess")}} (event) + - : L'évènement `audioprocess` est émis lorsque le buffer d'entrée d'un {{domxref("ScriptProcessorNode")}} de la Web Audio API est prêt à être traité. +- {{domxref("AudioProcessingEvent")}} + - : L'objet `AudioProcessingEvent `est envoyé aux fonctions de callback qui écoutent l'évènement `audioprocess.` + +### Traitement audio hors ligne ou en tâche de fond + +Il est possible de traiter et exporter un graphe audio très rapidement en tâche de fond — en l'exportant dans un {{domxref("AudioBuffer")}} plutôt que sur les enceintes du matériel — grâce aux objets suivants. + +- {{domxref("OfflineAudioContext")}} + - : Un objet **`OfflineAudioContext`** est un {{domxref("AudioContext")}} qui représente un graphe de traitement audio construit à partir de noeuds audio. A la différence du `AudioContext `standard, un `OfflineAudioContext` n'exporte pas vraiment le son, mais le génère, aussi vite que possible, dans un buffer. +- {{event("complete")}} (event) + - : Un évènement `complete` est émis lorsque le rendu d'un {{domxref("OfflineAudioContext")}} est terminé. +- {{domxref("OfflineAudioCompletionEvent")}} + - : The `OfflineAudioCompletionEvent` est envoyé aux fonctions de callback qui écoutent l'évènement {{event("complete")}} event implements this interface. + +### Audio Workers + +Les Audio workers offrent la possibilité de traiter le son directement dans le contexte d'un [web worker](/en-US/docs/Web/Guide/Performance/Using_web_workers). En date du 29 August 2014, ils ne sont encore implémentés par aucun navigateur. Lorsqu'ils seront implémentés, ils remplaceront {{domxref("ScriptProcessorNode")}}, et les autres fonctionnalités mentionnées dans la section [Traitement audio avec JavaScript](#Audio_processing_via_JavaScript) ci-avant. + +- {{domxref("AudioWorkerNode")}} + - : Un objet AudioWorkerNode représente un {{domxref("AudioNode")}} qui interagit avec le thread d'un worker pour générer, traiter, ou analyse le son directement. +- {{domxref("AudioWorkerGlobalScope")}} + - : Un objet `AudioWorkerGlobalScope` est un objet dérivé d'un objet `DedicatedWorkerGlobalScope`. Il représente le contexte d'un worker dans lequel un script de traitement audio est lancé; il est conçu pour permettre la génération, le traitement, et l'analyse de données audio directement avec JavaScript dans le thread d'un worker. +- {{domxref("AudioProcessEvent")}} + - : UN objet `Event` est transmis aux objets {{domxref("AudioWorkerGlobalScope")}} pour effectuer un traitement audio. + +## Objets obsolètes + +Les objets suivants étaient définis dans les versions précédentes de la spécification, mais sont maintenant obsolètes et ont été remplacés. + +- {{domxref("JavaScriptNode")}} + - : Utilisé pour le traitement du son directement en Javascript. Cet objet est obsolète, et a été remplacé par {{domxref("ScriptProcessorNode")}}. +- {{domxref("WaveTableNode")}} + - : Utilisé pour définir une forme d'onde périodique. Cet objet est obsolète, et a été remplacé par {{domxref("PeriodicWave")}}. + +## Exemple + +Cet exemple montre l'utilisation d'un grand nombre de fonctions Web Audio. La démo est disponible en ligne sur [Voice-change-o-matic](http://mdn.github.io/voice-change-o-matic/) (voir aussi le [code source complet sur Github](https://github.com/mdn/voice-change-o-matic)) —c'est une démo expérimentale d'application pour modifier la voix; baissez le son de vos enceintes pour l'utiliser, au moins au début ! + +Les lignes qui concernent la Web Audio API sont surlignées; si vous voulez en savoir davantage sur les différentes méthodes, consultez la documentation. + +```js +var contexteAudio = new (window.AudioContext || window.webkitAudioContext)(); // définition du contexte audio // les navigateurs avec un moteur Webkit/blink demandent un préfixe var voixSelectionnee = document.getElementById("voice"); // case à cocher pour la sélection d'effets de voix @@ -202,7 +173,7 @@ function creerCourbeDistorsion(taille) { // fonction qui crée une forme de cour angle = Math.PI / 180, i = 0, x; - for ( ; i < nombre_echantillons; ++i ) { + for ( ; i < nombre_echantillons; ++i ) { x = i * 2 / nombre_echantillons - 1; courbe[i] = ( 3 + k ) * x * 20 * angle / ( Math.PI + k * Math.abs(x) ); } @@ -266,7 +237,7 @@ function genererVisualisation(flux) { var sliceWidth = LARGEUR * 1.0 / tailleBuffer; var x = 0; - for(var i = 0; i < tailleBuffer; i++) { + for(var i = 0; i < tailleBuffer; i++) { var v = tableauDonnees[i] / 128.0; var y = v * HAUTEUR/2; @@ -337,93 +308,73 @@ function muterVoix() { // allumer / éteindre le son silence.innerHTML = "Mute"; } } -</pre> - -<h2 id="Specifications">Spécifications</h2> - -<table class="standard-table"> - <thead> - <tr> - <th scope="col">Spécification</th> - <th scope="col">Statut</th> - <th scope="col">Commentaire</th> - </tr> - </thead> - <tbody> - <tr> - <td>{{SpecName('Web Audio API')}}</td> - <td>{{Spec2('Web Audio API')}}</td> - <td></td> - </tr> - </tbody> -</table> - -<h2 id="Browser_compatibility">Compatibilité des navigateurs</h2> - -<p>{{Compat("api.AudioContext", 0)}}</p> - -<h2 id="See_also">Voir aussi</h2> - -<ul> - <li><a href="/fr/docs/Web/API/Web_Audio_API/Using_Web_Audio_API">Utiliser la Web Audio API</a></li> - <li><a href="/en-US/docs/Web/API/Web_Audio_API/Visualizations_with_Web_Audio_API">Visualizations with Web Audio API</a></li> - <li><a href="http://mdn.github.io/voice-change-o-matic/">Voice-change-O-matic example</a></li> - <li><a href="http://mdn.github.io/violent-theremin/">Violent Theremin example</a></li> - <li><a href="/en-US/docs/Web/API/Web_Audio_API/Web_audio_spatialisation_basics">Web audio spatialisation basics</a></li> - <li><a href="http://www.html5rocks.com/tutorials/webaudio/positional_audio/">Mixing Positional Audio and WebGL</a></li> - <li><a href="http://www.html5rocks.com/tutorials/webaudio/games/">Developing Game Audio with the Web Audio API</a></li> - <li><a href="/en-US/docs/Web/API/Web_Audio_API/Porting_webkitAudioContext_code_to_standards_based_AudioContext">Porting webkitAudioContext code to standards based AudioContext</a></li> - <li><a href="https://github.com/bit101/tones">Tones</a>: a simple library for playing specific tones/notes using the Web Audio API.</li> - <li><a href="https://github.com/goldfire/howler.js/">howler.js</a>: a JS audio library that defaults to <a href="https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html">Web Audio API</a> and falls back to <a href="http://www.whatwg.org/specs/web-apps/current-work/#the-audio-element">HTML5 Audio</a>, as well as providing other useful features.</li> - <li><a href="https://github.com/mattlima/mooog">Mooog</a>: jQuery-style chaining of AudioNodes, mixer-style sends/returns, and more.</li> -</ul> - -<h3 id="guides">Guides</h3> - - <ul> - <li><a href="/fr/docs/Web/API/Web_Audio_API/Basic_concepts_behind_Web_Audio_API">Les concepts de base de la Web Audio API</a></li> - <li><a href="/fr/docs/Web/API/Web_Audio_API/Using_Web_Audio_API">Utiliser la Web Audio API</a></li> - <li><a href="/en-US/docs/Web/API/Web_Audio_API/Visualizations_with_Web_Audio_API">Visualizations with Web Audio API</a></li> - <li><a href="/en-US/docs/Web/API/Web_Audio_API/Web_audio_spatialisation_basics">Web audio spatialisation basics</a></li> - <li><a href="/en-US/docs/Web/API/Web_Audio_API/Porting_webkitAudioContext_code_to_standards_based_AudioContext">Porting webkitAudioContext code to standards based AudioContext</a></li> - </ul> - -<h3 id="démos">Démos</h3> - <ul> - <li><a href="http://mdn.github.io/voice-change-o-matic/">Voice-change-O-matic</a></li> - <li><a href="http://mdn.github.io/violent-theremin/">Violent Theremin</a></li> - </ul> - -<h3 id="api">API</h3> - <ul> - <li>{{domxref("AnalyserNode")}}</li> - <li>{{domxref("AudioBuffer")}}</li> - <li>{{domxref("AudioBufferSourceNode")}}</li> - <li>{{domxref("AudioContext")}}</li> - <li>{{domxref("AudioDestinationNode")}}</li> - <li>{{domxref("AudioListener")}}</li> - <li>{{domxref("AudioNode")}}</li> - <li>{{domxref("AudioParam")}}</li> - <li>{{event("audioprocess")}} (event)</li> - <li>{{domxref("AudioProcessingEvent")}}</li> - <li>{{domxref("BiquadFilterNode")}}</li> - <li>{{domxref("ChannelMergerNode")}}</li> - <li>{{domxref("ChannelSplitterNode")}}</li> - <li>{{event("complete")}} (event)</li> - <li>{{domxref("ConvolverNode")}}</li> - <li>{{domxref("DelayNode")}}</li> - <li>{{domxref("DynamicsCompressorNode")}}</li> - <li>{{event("ended_(Web_Audio)", "ended")}} (event)</li> - <li>{{domxref("GainNode")}}</li> - <li>{{domxref("MediaElementAudioSourceNode")}}</li> - <li>{{domxref("MediaStreamAudioDestinationNode")}}</li> - <li>{{domxref("MediaStreamAudioSourceNode")}}</li> - <li>{{domxref("OfflineAudioCompletionEvent")}}</li> - <li>{{domxref("OfflineAudioContext")}}</li> - <li>{{domxref("OscillatorNode")}}</li> - <li>{{domxref("PannerNode")}}</li> - <li>{{domxref("PeriodicWave")}}</li> - <li>{{domxref("ScriptProcessorNode")}}</li> - <li>{{domxref("WaveShaperNode")}}</li> - </ul> - +``` + +## Spécifications + +| Spécification | Statut | Commentaire | +| ---------------------------------------- | ------------------------------------ | ----------- | +| {{SpecName('Web Audio API')}} | {{Spec2('Web Audio API')}} | | + +## Compatibilité des navigateurs + +{{Compat("api.AudioContext", 0)}} + +## Voir aussi + +- [Utiliser la Web Audio API](/fr/docs/Web/API/Web_Audio_API/Using_Web_Audio_API) +- [Visualizations with Web Audio API](/en-US/docs/Web/API/Web_Audio_API/Visualizations_with_Web_Audio_API) +- [Voice-change-O-matic example](http://mdn.github.io/voice-change-o-matic/) +- [Violent Theremin example](http://mdn.github.io/violent-theremin/) +- [Web audio spatialisation basics](/en-US/docs/Web/API/Web_Audio_API/Web_audio_spatialisation_basics) +- [Mixing Positional Audio and WebGL](http://www.html5rocks.com/tutorials/webaudio/positional_audio/) +- [Developing Game Audio with the Web Audio API](http://www.html5rocks.com/tutorials/webaudio/games/) +- [Porting webkitAudioContext code to standards based AudioContext](/en-US/docs/Web/API/Web_Audio_API/Porting_webkitAudioContext_code_to_standards_based_AudioContext) +- [Tones](https://github.com/bit101/tones): a simple library for playing specific tones/notes using the Web Audio API. +- [howler.js](https://github.com/goldfire/howler.js/): a JS audio library that defaults to [Web Audio API](https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html) and falls back to [HTML5 Audio](http://www.whatwg.org/specs/web-apps/current-work/#the-audio-element), as well as providing other useful features. +- [Mooog](https://github.com/mattlima/mooog): jQuery-style chaining of AudioNodes, mixer-style sends/returns, and more. + +### Guides + +- [Les concepts de base de la Web Audio API](/fr/docs/Web/API/Web_Audio_API/Basic_concepts_behind_Web_Audio_API) +- [Utiliser la Web Audio API](/fr/docs/Web/API/Web_Audio_API/Using_Web_Audio_API) +- [Visualizations with Web Audio API](/en-US/docs/Web/API/Web_Audio_API/Visualizations_with_Web_Audio_API) +- [Web audio spatialisation basics](/en-US/docs/Web/API/Web_Audio_API/Web_audio_spatialisation_basics) +- [Porting webkitAudioContext code to standards based AudioContext](/en-US/docs/Web/API/Web_Audio_API/Porting_webkitAudioContext_code_to_standards_based_AudioContext) + +### Démos + +- [Voice-change-O-matic](http://mdn.github.io/voice-change-o-matic/) +- [Violent Theremin](http://mdn.github.io/violent-theremin/) + +### API + +- {{domxref("AnalyserNode")}} +- {{domxref("AudioBuffer")}} +- {{domxref("AudioBufferSourceNode")}} +- {{domxref("AudioContext")}} +- {{domxref("AudioDestinationNode")}} +- {{domxref("AudioListener")}} +- {{domxref("AudioNode")}} +- {{domxref("AudioParam")}} +- {{event("audioprocess")}} (event) +- {{domxref("AudioProcessingEvent")}} +- {{domxref("BiquadFilterNode")}} +- {{domxref("ChannelMergerNode")}} +- {{domxref("ChannelSplitterNode")}} +- {{event("complete")}} (event) +- {{domxref("ConvolverNode")}} +- {{domxref("DelayNode")}} +- {{domxref("DynamicsCompressorNode")}} +- {{event("ended_(Web_Audio)", "ended")}} (event) +- {{domxref("GainNode")}} +- {{domxref("MediaElementAudioSourceNode")}} +- {{domxref("MediaStreamAudioDestinationNode")}} +- {{domxref("MediaStreamAudioSourceNode")}} +- {{domxref("OfflineAudioCompletionEvent")}} +- {{domxref("OfflineAudioContext")}} +- {{domxref("OscillatorNode")}} +- {{domxref("PannerNode")}} +- {{domxref("PeriodicWave")}} +- {{domxref("ScriptProcessorNode")}} +- {{domxref("WaveShaperNode")}} diff --git a/files/fr/web/api/web_audio_api/using_web_audio_api/index.md b/files/fr/web/api/web_audio_api/using_web_audio_api/index.md index 26ea00da32..59727d0cbc 100644 --- a/files/fr/web/api/web_audio_api/using_web_audio_api/index.md +++ b/files/fr/web/api/web_audio_api/using_web_audio_api/index.md @@ -3,129 +3,117 @@ title: Utiliser la Web Audio API slug: Web/API/Web_Audio_API/Using_Web_Audio_API translation_of: Web/API/Web_Audio_API/Using_Web_Audio_API --- +La [Web Audio API](/en-US/docs/Web_Audio_API) offre un méchanisme à la fois simple et puissant pour implémenter et manipuler le contenu audio dans une application web. Elle permet de manipuler mixages audio, effets, balance, etc. Cet article donne les bases pour l'utiliser, à travers quelques exemples simples. -<p>La <a href="/en-US/docs/Web_Audio_API">Web Audio API</a> offre un méchanisme à la fois simple et puissant pour implémenter et manipuler le contenu audio dans une application web. Elle permet de manipuler mixages audio, effets, balance, etc. Cet article donne les bases pour l'utiliser, à travers quelques exemples simples.</p> +La Web Audio API ne vient pas remplacer l'élément [\<audio>](/en-US/docs/Web/HTML/Element/audio), mais plutôt le compléter, de même que l'API Canvas 2D coexiste avec l'élément [\<video>](/en-US/docs/Web/HTML/Element/Img). Si vous avez seulement besoin de contrôler la lecture d'un fichier audio, \<audio> est probablement une meilleure solution, plus rapide. Si vous voulez procéder à un traitement audio plus complexe et à la lecture d'une source, la Web Audio API offre davantage de possibilités en termes de puissance et de contrôle. -<div> -<p>La Web Audio API ne vient pas remplacer l'élément <a href="/en-US/docs/Web/HTML/Element/audio"><audio></a>, mais plutôt le compléter, de même que l'API Canvas 2D coexiste avec l'élément <a href="/en-US/docs/Web/HTML/Element/Img"><video></a>. Si vous avez seulement besoin de contrôler la lecture d'un fichier audio, <audio> est probablement une meilleure solution, plus rapide. Si vous voulez procéder à un traitement audio plus complexe et à la lecture d'une source, la Web Audio API offre davantage de possibilités en termes de puissance et de contrôle.</p> +L'une des particularités de la Web Audio API est qu'elle n'a pas de limites au niveau de la programmation du son. Par exemple, le nombre de sons que l'on peut appeler en même temps n'est pas plafonnée. Certains processeurs sont potentiellement capables de jouer plus d'un millier de sons simultanément sans saccades. -<p>L'une des particularités de la Web Audio API est qu'elle n'a pas de limites au niveau de la programmation du son. Par exemple, le nombre de sons que l'on peut appeler en même temps n'est pas plafonnée. Certains processeurs sont potentiellement capables de jouer plus d'un millier de sons simultanément sans saccades.</p> -</div> +## Exemples -<h2 id="Exemples">Exemples</h2> +Afin d'expliquer l'utilisation de la Web Audio API, nous avons créé un certain nombre d'exemples qui seront étoffés au fur et à mesure. N'hésitez pas à en ajouter d'autres et à suggérer des améliorations ! -<p>Afin d'expliquer l'utilisation de la Web Audio API, nous avons créé un certain nombre d'exemples qui seront étoffés au fur et à mesure. N'hésitez pas à en ajouter d'autres et à suggérer des améliorations !</p> +Notre premier exemple est [Voice-change-O-matic](http://github.com/mdn/voice-change-o-matic), une application web de déformation de la voix, qui permet de choisir différents effets et modes de visualisation. Cette application est rudimentaire, mais elle permet de montrer l'utilisation de plusieurs fonctionnalités de la Web Audio API combinées ensemble ([run the Voice-change-O-matic live](http://mdn.github.io/voice-change-o-matic/)). -<p>Notre premier exemple est <a href="http://github.com/mdn/voice-change-o-matic">Voice-change-O-matic</a>, une application web de déformation de la voix, qui permet de choisir différents effets et modes de visualisation. Cette application est rudimentaire, mais elle permet de montrer l'utilisation de plusieurs fonctionnalités de la Web Audio API combinées ensemble (<a href="http://mdn.github.io/voice-change-o-matic/">run the Voice-change-O-matic live</a>).</p> +![Une boîte à rythme avec des contrôles pour la lecture, le volume et le pan](boombox.png) -<p><img alt="Une boîte à rythme avec des contrôles pour la lecture, le volume et le pan" src="boombox.png"></p> +## Concepts de base -<h2 id="Concepts_de_base">Concepts de base</h2> +> **Note :** la plupart des extraits de code dans cette section viennent de l'exemple [Violent Theremin](https://github.com/mdn/violent-theremin). -<div class="note"> -<p><strong>Note :</strong> la plupart des extraits de code dans cette section viennent de l'exemple <a href="https://github.com/mdn/violent-theremin">Violent Theremin</a>.</p> -</div> +La Web Audio API impliqe de réaliser les opérations de traitement audio dans un **contexte audio**, et elle a été conçue pour permettre le **routage modulaire**. Les opérations de traitement de base sont réalisées par des **noeuds audio**, qui sont reliés entre eux pour former un **graphe de routage audio**. Plusieurs sources — avec différentes configuration de canaux — peuvent cohabiter dans un seul contexte. Ce design modulaire offre la flexibilité nécessaire pour créer des fonctions complexes avec des effets dynamiques. -<p>La Web Audio API impliqe de réaliser les opérations de traitement audio dans un <strong>contexte audio</strong>, et elle a été conçue pour permettre le <strong>routage modulaire</strong>. Les opérations de traitement de base sont réalisées par des <strong> noeuds audio</strong>, qui sont reliés entre eux pour former un<strong> graphe de routage audio</strong>. Plusieurs sources — avec différentes configuration de canaux — peuvent cohabiter dans un seul contexte. Ce design modulaire offre la flexibilité nécessaire pour créer des fonctions complexes avec des effets dynamiques.</p> +Les noeuds audio sont reliés au niveau de leurs entrées et sorties. Ils forment une chaîne qui commence avec une ou plusieurs sources, traverse un ou plusieurs noeuds de traitement, et se termine par une destination (bien qu'il ne soit pas néessaire d'avoir une destination si l'on souhaite simplement visualiser des données audio). Un scénario simple, représentatif de la Web Audio API, pourrait ressembler à ceci : -<p>Les noeuds audio sont reliés au niveau de leurs entrées et sorties. Ils forment une chaîne qui commence avec une ou plusieurs sources, traverse un ou plusieurs noeuds de traitement, et se termine par une destination (bien qu'il ne soit pas néessaire d'avoir une destination si l'on souhaite simplement visualiser des données audio). Un scénario simple, représentatif de la Web Audio API, pourrait ressembler à ceci :</p> +1. Création d'un contexte audio +2. Dans ce contexte, création des sources — telles que `<audio>`, oscillateur, flux +3. Création des noeuds d'effets, tels que réverb, filtres biquad, balance, compresseur +4. Choix final de la sortie audio, par exemple les enceintes du système +5. Connection des sources aux effets, et des effets à la sortie. -<ol> - <li>Création d'un contexte audio</li> - <li>Dans ce contexte, création des sources — telles que <code><audio></code>, oscillateur, flux</li> - <li>Création des noeuds d'effets, tels que réverb, filtres biquad, balance, compresseur</li> - <li>Choix final de la sortie audio, par exemple les enceintes du système </li> - <li>Connection des sources aux effets, et des effets à la sortie.</li> -</ol> +### Création d'un contexte audio -<h3 id="Création_d'un_contexte_audio">Création d'un contexte audio</h3> +Commencez par créer une instance de [`AudioContext`](/en-US/docs/Web/API/AudioContext) sur laquelle vous allez créer un graphe audio. L'exemple le plus simple ressemblerait à ceci: -<p>Commencez par créer une instance de <a href="/en-US/docs/Web/API/AudioContext"><code>AudioContext</code></a> sur laquelle vous allez créer un graphe audio. L'exemple le plus simple ressemblerait à ceci:</p> +```js +var contexteAudio = new AudioContext(); +``` -<pre class="brush: js">var contexteAudio = new AudioContext(); -</pre> +> **Note :** On peut créer plusieurs contextes audio dans le même document, bien que ce soit probablement superflu dans la plupart des cas. -<div class="note"> -<p><strong>Note :</strong> On peut créer plusieurs contextes audio dans le même document, bien que ce soit probablement superflu dans la plupart des cas.</p> -</div> +Il faut rajouter une version préfixée pour les navigateurs Webkit/Blink browsers, tout en conservant la version non préfixée pour Firefox (desktop/mobile/OS). Ce qui donne : -<p>Il faut rajouter une version préfixée pour les navigateurs Webkit/Blink browsers, tout en conservant la version non préfixée pour Firefox (desktop/mobile/OS). Ce qui donne :</p> +```js +var contexteAudio = new (window.AudioContext || window.webkitAudioContext)(); +``` -<pre class="brush: js">var contexteAudio = new (window.AudioContext || window.webkitAudioContext)(); -</pre> +> **Note :** Safari risque de planter si l'objet `window` n'est pas explicitement mentionné lors de la création d'un contexte audio -<div class="note"> -<p><strong>Note :</strong> Safari risque de planter si l'objet <code>window</code> n'est pas explicitement mentionné lors de la création d'un contexte audio</p> -</div> +### Création d'une source audio -<h3 id="Création_d'une_source_audio">Création d'une source audio</h3> +Maintenant que nous avons créé un contexte, nous allons utiliser les méthodes de ce contexte pour quasiment tout ce qui nous reste à faire. La première étape consiste à créer une source audio. Les sources peuvent être de provenance diverse : -<p>Maintenant que nous avons créé un contexte, nous allons utiliser les méthodes de ce contexte pour quasiment tout ce qui nous reste à faire. La première étape consiste à créer une source audio. Les sources peuvent être de provenance diverse :</p> +- générées en JavaScript par un noeud audio tel qu'un oscillateur. Pour créer un {{domxref("OscillatorNode")}} on utilise la méthode {{domxref("AudioContext.createOscillator")}}. +- créées à partir de données PCM brutes: le contexte audio a des méthodes pour décoder lesformats supportés; voir {{ domxref("AudioContext.createBuffer()") }}, {{domxref("AudioContext.createBufferSource()")}}, et {{domxref("AudioContext.decodeAudioData()")}}. +- récupérées dans des élements HTML tels que {{HTMLElement("video")}} ou {{HTMLElement("audio")}}: voir {{domxref("AudioContext.createMediaElementSource()")}}. +- prises dans un [WebRTC](/en-US/docs/WebRTC) {{domxref("MediaStream")}} comme une webcam ou un microphone. Voir {{ domxref("AudioContext.createMediaStreamSource()") }}. -<ul> - <li>générées en JavaScript par un noeud audio tel qu'un oscillateur. Pour créer un {{domxref("OscillatorNode")}} on utilise la méthode {{domxref("AudioContext.createOscillator")}}.</li> - <li>créées à partir de données PCM brutes: le contexte audio a des méthodes pour décoder lesformats supportés; voir {{ domxref("AudioContext.createBuffer()") }}, {{domxref("AudioContext.createBufferSource()")}}, et {{domxref("AudioContext.decodeAudioData()")}}.</li> - <li>récupérées dans des élements HTML tels que {{HTMLElement("video")}} ou {{HTMLElement("audio")}}: voir {{domxref("AudioContext.createMediaElementSource()")}}.</li> - <li>prises dans un <a href="/en-US/docs/WebRTC">WebRTC</a> {{domxref("MediaStream")}} comme une webcam ou un microphone. Voir {{ domxref("AudioContext.createMediaStreamSource()") }}.</li> -</ul> +Pour notre exemple nous nous contenterons de créer un oscillateur pour générer un son simple comme source, et un noeud de gain pour contrôler le volume: -<p>Pour notre exemple nous nous contenterons de créer un oscillateur pour générer un son simple comme source, et un noeud de gain pour contrôler le volume:</p> - -<pre class="brush: js">var oscillateur = contexteAudio.createOscillator(); +```js +var oscillateur = contexteAudio.createOscillator(); var noeudGain = contexteAudio.createGain(); -</pre> +``` -<div class="note"> -<p><strong>Note :</strong> Pour jouer un fichier audio directement, il faut charger le fichier en XHR, le décoder en mémoire tampon, puis associer le tampon à une source. Voir l'exemple <a href="https://github.com/mdn/voice-change-o-matic/blob/gh-pages/scripts/app.js#L48-L68">Voice-change-O-matic</a>.</p> -</div> +> **Note :** Pour jouer un fichier audio directement, il faut charger le fichier en XHR, le décoder en mémoire tampon, puis associer le tampon à une source. Voir l'exemple [Voice-change-O-matic](https://github.com/mdn/voice-change-o-matic/blob/gh-pages/scripts/app.js#L48-L68). -<div class="note"> -<p><strong>Note :</strong> Scott Michaud a écrit la librairie <a href="https://github.com/ScottMichaud/AudioSampleLoader">AudioSampleLoader</a>, très pratique pour charger et décoder un ou plusieurs extraits audio. Elle peut aider à simplifier le processus de chargement XHR / mémoire tampon décrit dans la note précédente.</p> -</div> +> **Note :** Scott Michaud a écrit la librairie [AudioSampleLoader](https://github.com/ScottMichaud/AudioSampleLoader), très pratique pour charger et décoder un ou plusieurs extraits audio. Elle peut aider à simplifier le processus de chargement XHR / mémoire tampon décrit dans la note précédente. -<h3 id="Lien_entre_les_noeuds_source_et_destination">Lien entre les noeuds source et destination</h3> +### Lien entre les noeuds source et destination -<p>Pour faire sortir le son dans vos enceintes, il faut relier la source et la destination. Pour cela on appelle la méthode <code>connect</code> sur le noeud source, le noeud de destination étant passé en argument. La méthode <code>connect</code> est disponible sur la plupart des types de noeuds.<code> </code></p> +Pour faire sortir le son dans vos enceintes, il faut relier la source et la destination. Pour cela on appelle la méthode `connect` sur le noeud source, le noeud de destination étant passé en argument. La méthode `connect` est disponible sur la plupart des types de noeuds.`` -<p>La sortie par défaut du matériel (en général les enceintes) est accessible via {{ domxref("AudioContext.destination") }}. Pour connecter l'oscillateur, le noeud de gain et la destination, on écrirait les lignes suivantes:</p> +La sortie par défaut du matériel (en général les enceintes) est accessible via {{ domxref("AudioContext.destination") }}. Pour connecter l'oscillateur, le noeud de gain et la destination, on écrirait les lignes suivantes: -<pre class="brush: js">oscillateur.connect(noeudGain); +```js +oscillateur.connect(noeudGain); noeudGain.connect(contexteAudio.destination); -</pre> +``` -<p>On peut connecter autant de noeuds qu'on le souhaite (cf. <a href="http://mdn.github.io/voice-change-o-matic/">Voice-change-O-matic</a>). Par exemple:</p> +On peut connecter autant de noeuds qu'on le souhaite (cf. [Voice-change-O-matic](http://mdn.github.io/voice-change-o-matic/)). Par exemple: -<pre class="brush: js">source = contexteAudio.createMediaStreamSource(stream); +```js +source = contexteAudio.createMediaStreamSource(stream); source.connect(analyser); analyser.connect(distortion); distortion.connect(biquadFilter); biquadFilter.connect(convolver); convolver.connect(noeudGain); noeudGain.connect(contexteAudio.destination); -</pre> +``` -<p>Ce code créerait le graphe audio suivant :</p> +Ce code créerait le graphe audio suivant : -<p><img alt="Un graphe audio avec un élément audio source connecté à la destination par défaut" src="graph1.jpg"></p> +![Un graphe audio avec un élément audio source connecté à la destination par défaut](graph1.jpg) -<p>Il est possible de connecter plusieurs noeuds à un seul noeud, par exemple pour mixer plusieurs sources ensemble, et les passer dans un seul noeud d'effet, tel qu'un noeud de gain.</p> +Il est possible de connecter plusieurs noeuds à un seul noeud, par exemple pour mixer plusieurs sources ensemble, et les passer dans un seul noeud d'effet, tel qu'un noeud de gain. -<div class="note"> -<p><strong>Note :</strong> Depuis Firefox 32, les outils de développement intégrés incluent un <a href="/en-US/docs/Tools/Web_Audio_Editor">éditeur audio</a>, très utile pour débugger les graphes audio.</p> -</div> +> **Note :** Depuis Firefox 32, les outils de développement intégrés incluent un [éditeur audio](/en-US/docs/Tools/Web_Audio_Editor), très utile pour débugger les graphes audio. -<h3 id="Lecture_du_son_et_définition_du_pitch">Lecture du son et définition du pitch</h3> +### Lecture du son et définition du pitch -<p>Maintenant que le graphe audio est en place, nous pouvons ajuster certains aspects du son en définissant la valeur de certaines propriétés ou en utilsant ses méthodes. L'exemple suivant spécifie un pitch en hertz pour un oscillateur, lui assigne un type, et demande à l'oscillateur de jouer le son.</p> +Maintenant que le graphe audio est en place, nous pouvons ajuster certains aspects du son en définissant la valeur de certaines propriétés ou en utilsant ses méthodes. L'exemple suivant spécifie un pitch en hertz pour un oscillateur, lui assigne un type, et demande à l'oscillateur de jouer le son. -<pre class="brush: js">oscillateur.type = 'sine'; // onde sinusoïdale — les autres valeurs possible sont : 'square', 'sawtooth', 'triangle' et 'custom' +```js +oscillateur.type = 'sine'; // onde sinusoïdale — les autres valeurs possible sont : 'square', 'sawtooth', 'triangle' et 'custom' oscillateur.frequency.value = 2500; // valeur en hertz oscillateur.start(); -</pre> +``` -<p>Le code suivant, qui vient de l'exemple <a href="http://mdn.github.io/violent-theremin/">Violent Theremin</a>, spécifie une valeur maximum pour le gain, et une valeur pour la fréquence:</p> +Le code suivant, qui vient de l'exemple [Violent Theremin](http://mdn.github.io/violent-theremin/), spécifie une valeur maximum pour le gain, et une valeur pour la fréquence: -<pre class="brush: js">var largeur = window.innerWidth; +```js +var largeur = window.innerWidth; var hauteur = window.innerHeight; var frequenceMax = 6000; @@ -141,11 +129,12 @@ oscillateur.frequency.value = frequenceInitiale; // valeur en hertz oscillateur.start(); noeudGain.gain.value = volumeInitial; -</pre> +``` -<p>On peut aussi réassigner les valeurs de fréquence et de pitch à chaque mouvement de la souris, en utilisant la position pour calculer un pourcentage des valeurs maximum de fréquence et de gain :</p> +On peut aussi réassigner les valeurs de fréquence et de pitch à chaque mouvement de la souris, en utilisant la position pour calculer un pourcentage des valeurs maximum de fréquence et de gain : -<pre class="brush: js">// coordonnées de la souris +```js +// coordonnées de la souris var positionX; var positionY; @@ -164,13 +153,14 @@ function updatePage(e) { canvasDraw(); } -</pre> +``` -<h3 id="Simple_visualisation_avec_canvas">Simple visualisation avec canvas</h3> +### Simple visualisation avec canvas -<p>On appelle une fonction <code>canvasDraw()</code> à chaque mouvement de la souris. Elle dessine une grappe de cercles à l'endroit où se trouve la souris, leur taille et couleur étant basées sur les valeurs de fréquence et de gain.</p> +On appelle une fonction `canvasDraw()` à chaque mouvement de la souris. Elle dessine une grappe de cercles à l'endroit où se trouve la souris, leur taille et couleur étant basées sur les valeurs de fréquence et de gain. -<pre class="brush: js">function aleatoire(number1, number2) { +```js +function aleatoire(number1, number2) { return number1 + (Math.floor(Math.random() * (number2 - number1)) + 1); } @@ -187,7 +177,7 @@ function canvasDraw() { canvasCtx.globalAlpha = 0.2; - for(i=1;i<=15;i=i+2) { + for(i=1;i<=15;i=i+2) { contexteCanvas.beginPath(); var chaineStyle = 'rgb(' + 100 + (i * 10) + ',' + Math.floor((noeudGain.gain.value / volumeMax) * 255); chaineStyle += ',' + Math.floor((oscillateur.frequency.value / frequenceMax) * 255) + ')'; @@ -196,13 +186,15 @@ function canvasDraw() { contexteCanvas.fill(); contexteCanvas.closePath(); } -}</pre> +} +``` -<h3 id="Couper_le_son_du_theremin">Couper le son du theremin</h3> +### Couper le son du theremin -<p>Quand on appuie sur le bouton pour couper le son, la fonction ci-dessous est appelée, qui déconnecte le noeud de gain du noeud de destination, cassant ainsi le graphe de façon à ce qu'aucun son ne soit produit. Appuyer de nouveau sur le bouton a l'effet inverse.</p> +Quand on appuie sur le bouton pour couper le son, la fonction ci-dessous est appelée, qui déconnecte le noeud de gain du noeud de destination, cassant ainsi le graphe de façon à ce qu'aucun son ne soit produit. Appuyer de nouveau sur le bouton a l'effet inverse. -<pre class="brush: js">var coupeSon = document.querySelector('.mute'); +```js +var coupeSon = document.querySelector('.mute'); coupeSon.onclick = function() { if(coupeSon.id == "") { @@ -215,63 +207,68 @@ coupeSon.onclick = function() { coupeSon.innerHTML = "Mute"; } } -</pre> +``` -<h2 id="Autres_options_des_noeuds">Autres options des noeuds</h2> +## Autres options des noeuds -<p>On peut créer un grand nombre d'autres noeuds avec la Web Audio API. De façon générale, ils fonctionnent de façon très similaire à ceux que nous venons de voir: on crée un noeud, le connecte avec d'autres noeuds, et on manipule ensuite ses propriétés et méthodes pour agir sur la source.</p> +On peut créer un grand nombre d'autres noeuds avec la Web Audio API. De façon générale, ils fonctionnent de façon très similaire à ceux que nous venons de voir: on crée un noeud, le connecte avec d'autres noeuds, et on manipule ensuite ses propriétés et méthodes pour agir sur la source. -<p>Ce document passe en revue quelques-uns des outils et effets disponibles; vous trouverez davantage de détails sur les pages de référence de la {{ domxref("Web_Audio_API") }}.</p> +Ce document passe en revue quelques-uns des outils et effets disponibles; vous trouverez davantage de détails sur les pages de référence de la {{ domxref("Web_Audio_API") }}. -<h3 id="Noeuds_modulateurs_d'onde">Noeuds modulateurs d'onde</h3> +### Noeuds modulateurs d'onde -<p>On peut créer un noeud modulatur d'onde avec la méthode {{ domxref("AudioContext.createWaveShaper") }} :</p> +On peut créer un noeud modulatur d'onde avec la méthode {{ domxref("AudioContext.createWaveShaper") }} : -<pre class="brush: js">var distortion = contexteAudio.createWaveShaper(); -</pre> +```js +var distortion = contexteAudio.createWaveShaper(); +``` -<p>On associe ensuite à cet objet une forme d'onde définie mathématiquement, qui est appliquée à l'onde de base pour créer un effet de distortion. Ecrire son propre algorithme n'est pas si simple, et pour commencer le mieux est encore d'en chercher un sur le Web. Par exemple, nous avons trouvé celui-ci sur <a href="http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion">Stack Overflow</a>:</p> +On associe ensuite à cet objet une forme d'onde définie mathématiquement, qui est appliquée à l'onde de base pour créer un effet de distortion. Ecrire son propre algorithme n'est pas si simple, et pour commencer le mieux est encore d'en chercher un sur le Web. Par exemple, nous avons trouvé celui-ci sur [Stack Overflow](http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion): -<pre class="brush: js">function genererCourbeDistortion(amount) { +```js +function genererCourbeDistortion(amount) { var k = typeof amount === 'number' ? amount : 50, n_samples = 44100, curve = new Float32Array(n_samples), deg = Math.PI / 180, i = 0, x; - for ( ; i < n_samples; ++i ) { + for ( ; i < n_samples; ++i ) { x = i * 2 / n_samples - 1; curve[i] = ( 3 + k ) * x * 20 * deg / ( Math.PI + k * Math.abs(x) ); } return curve; }; -</pre> +``` -<p>L'exemple suivant, qui vient de <a href="https://github.com/mdn/voice-change-o-matic">Voice-change-O-matic</a>, connecte un noeud de <code>distortion</code> à un graphe audio, puis applique l'algorithme de forme d'onde précédent au noeud de distortion :</p> +L'exemple suivant, qui vient de [Voice-change-O-matic](https://github.com/mdn/voice-change-o-matic), connecte un noeud de `distortion` à un graphe audio, puis applique l'algorithme de forme d'onde précédent au noeud de distortion : -<pre class="brush: js">source.connect(analyser); +```js +source.connect(analyser); analyser.connect(distortion); distortion.connect(biquadFilter); ... distortion.curve = genererCourbeDistortion(400); -</pre> +``` -<h3 id="Filtre_biquad">Filtre biquad</h3> +### Filtre biquad -<p>Les filtres biquad ont de nombreuses options. Nous montrons ici comment créer un filtre biquad avec la méthode {{domxref("AudioContext.createBiquadFilter")}}.</p> +Les filtres biquad ont de nombreuses options. Nous montrons ici comment créer un filtre biquad avec la méthode {{domxref("AudioContext.createBiquadFilter")}}. -<pre class="brush: js">var filtreBiquad = contexteAudio.createBiquadFilter(); -</pre> +```js +var filtreBiquad = contexteAudio.createBiquadFilter(); +``` -<p>Le filtre utilisé dans la démo Voice-change-o-matic est un filtre lowshelf, qui amplifie le son au niveau des basses. Ici on augmente de 25 décibels toutes les fréquences en dessous de 1000.</p> +Le filtre utilisé dans la démo Voice-change-o-matic est un filtre lowshelf, qui amplifie le son au niveau des basses. Ici on augmente de 25 décibels toutes les fréquences en dessous de 1000. -<pre class="brush: js">filtreBiquad.type = "lowshelf"; +```js +filtreBiquad.type = "lowshelf"; filtreBiquad.frequency.value = 1000; filtreBiquad.gain.value = 25; -</pre> +``` -<h2 id="Autres_usages_de_la_Web_Audio_API">Autres usages de la Web Audio API</h2> +## Autres usages de la Web Audio API -<p>La Web Audio API peut avoir bien d'autres applications que la visualisation ou la spatialisation audio (comme gérer la balance d'un son). Nous détaillerons d'autres options dans des articles séparés.</p> +La Web Audio API peut avoir bien d'autres applications que la visualisation ou la spatialisation audio (comme gérer la balance d'un son). Nous détaillerons d'autres options dans des articles séparés. diff --git a/files/fr/web/api/web_audio_api/visualizations_with_web_audio_api/index.md b/files/fr/web/api/web_audio_api/visualizations_with_web_audio_api/index.md index 8a128b4d81..c565d3c6b6 100644 --- a/files/fr/web/api/web_audio_api/visualizations_with_web_audio_api/index.md +++ b/files/fr/web/api/web_audio_api/visualizations_with_web_audio_api/index.md @@ -3,98 +3,117 @@ title: Visualisations avec la Web Audio API slug: Web/API/Web_Audio_API/Visualizations_with_Web_Audio_API translation_of: Web/API/Web_Audio_API/Visualizations_with_Web_Audio_API --- -<p>L'une des fonctionnalités les plus intéressantes de la Web Audio API est la possibilité d'extraire de la source audio la fréquence, la forme d'onde et d'autres données, qui permettent de créer des visualisations. Cet article explique comment, et fournit quelques exemples basiques.</p> +L'une des fonctionnalités les plus intéressantes de la Web Audio API est la possibilité d'extraire de la source audio la fréquence, la forme d'onde et d'autres données, qui permettent de créer des visualisations. Cet article explique comment, et fournit quelques exemples basiques. -<div class="note"> -<p><strong>Note :</strong> Vous pouvez trouver des exemples de tous les extraits de the code dans notre démo <a href="https://mdn.github.io/voice-change-o-matic/">Voice-change-O-matic</a>.</p> -</div> +> **Note :** Vous pouvez trouver des exemples de tous les extraits de the code dans notre démo [Voice-change-O-matic](https://mdn.github.io/voice-change-o-matic/). -<h2 id="Concepts_de_base">Concepts de base</h2> +## Concepts de base -<p>Pour extraire les données d'une source audio, il faut un {{ domxref("AnalyserNode") }}, que l'on peut créer à l'aide de la méthode {{ domxref("AudioContext.createAnalyser()") }}, par exemple:</p> +Pour extraire les données d'une source audio, il faut un {{ domxref("AnalyserNode") }}, que l'on peut créer à l'aide de la méthode {{ domxref("AudioContext.createAnalyser()") }}, par exemple: -<pre class="brush: js">var contexteAudio = new (window.AudioContext || window.webkitAudioContext)(); -var analyseur = contexteAudio.createAnalyser();</pre> +```js +var contexteAudio = new (window.AudioContext || window.webkitAudioContext)(); +var analyseur = contexteAudio.createAnalyser(); +``` -<p>Ce noeud est ensuite connecté à la source audio :</p> +Ce noeud est ensuite connecté à la source audio : -<pre class="brush: js">source = contexteAudio.createMediaStreamSource(stream); +```js +source = contexteAudio.createMediaStreamSource(stream); source.connect(analyseur); analyseur.connect(distortion); -// etc.</pre> +// etc. +``` -<div class="note"> -<p><strong>Note :</strong> il n'est pas nécessaire de connecter la sortie de l'analyseur à un noeud pour qu'il fonctionne, il suffit que l'entrée soit connectée à la source, directement ou via un autre noeud.</p> -</div> +> **Note :** il n'est pas nécessaire de connecter la sortie de l'analyseur à un noeud pour qu'il fonctionne, il suffit que l'entrée soit connectée à la source, directement ou via un autre noeud. -<p>L'analyseur va alors capturer les données audio en usant une Transformation de Fourier Rapide (fft) à une certaine fréquence, en fonction de ce qui est spécifié dans la propriété {{ domxref("AnalyserNode.fftSize") }} (la valeur par défaut est 2048).</p> +L'analyseur va alors capturer les données audio en usant une Transformation de Fourier Rapide (fft) à une certaine fréquence, en fonction de ce qui est spécifié dans la propriété {{ domxref("AnalyserNode.fftSize") }} (la valeur par défaut est 2048). -<div class="note"> -<p><strong>Note :</strong> Vous pouvez aussi spécifier des valeurs de puissance minimum et maximum pour la plage de mise à l'échelle fft, en utilisant {{ domxref("AnalyserNode.minDecibels") }} et {{ domxref("AnalyserNode.maxDecibels") }}, et plusieurs valeurs de transition en utilisant {{ domxref("AnalyserNode.smoothingTimeConstant") }}.</p> -</div> +> **Note :** Vous pouvez aussi spécifier des valeurs de puissance minimum et maximum pour la plage de mise à l'échelle fft, en utilisant {{ domxref("AnalyserNode.minDecibels") }} et {{ domxref("AnalyserNode.maxDecibels") }}, et plusieurs valeurs de transition en utilisant {{ domxref("AnalyserNode.smoothingTimeConstant") }}. -<p>Pour capturer des données, il faut utiliser les méthodes {{ domxref("AnalyserNode.getFloatFrequencyData()") }} et {{ domxref("AnalyserNode.getByteFrequencyData()") }} pour la fréquence, et {{ domxref("AnalyserNode.getByteTimeDomainData()") }} et {{ domxref("AnalyserNode.getFloatTimeDomainData()") }} pour la forme d'onde.</p> +Pour capturer des données, il faut utiliser les méthodes {{ domxref("AnalyserNode.getFloatFrequencyData()") }} et {{ domxref("AnalyserNode.getByteFrequencyData()") }} pour la fréquence, et {{ domxref("AnalyserNode.getByteTimeDomainData()") }} et {{ domxref("AnalyserNode.getFloatTimeDomainData()") }} pour la forme d'onde. -<p>Ces méthodes copient les données dans le tableau passé en paramètre, il faut donc créer un tableau avant de les invoquer. La première produit des nombres flottants à simple précision de 32 bits, qui ne peuvent être stockées dans un simple tableau javascript. Vous devez créer un domxref("Float32Array") }} ou un {{ domxref("Uint8Array") }}, en fonction du type de données que vous traitez.</p> +Ces méthodes copient les données dans le tableau passé en paramètre, il faut donc créer un tableau avant de les invoquer. La première produit des nombres flottants à simple précision de 32 bits, qui ne peuvent être stockées dans un simple tableau javascript. Vous devez créer un domxref("Float32Array") }} ou un {{ domxref("Uint8Array") }}, en fonction du type de données que vous traitez. -<p>Par exemple, disons que nous manipulons une fft de fréquence 2048. Nous retournons la valeur {{ domxref("AnalyserNode.frequencyBinCount") }}, qui correspond à la moitié de la fréquence, puis nous appelons la méthode Uint8Array() en passant frequencyBinCount comme argument pour la taille — c'est le nombre de points de données qui seront collectées pour cette fréquence.</p> +Par exemple, disons que nous manipulons une fft de fréquence 2048. Nous retournons la valeur {{ domxref("AnalyserNode.frequencyBinCount") }}, qui correspond à la moitié de la fréquence, puis nous appelons la méthode Uint8Array() en passant frequencyBinCount comme argument pour la taille — c'est le nombre de points de données qui seront collectées pour cette fréquence. -<pre class="brush: js">analyseur.fftSize = 2048; +```js +analyseur.fftSize = 2048; var tailleMemoireTampon = analyseur.frequencyBinCount; -var tableauDonnees = new Uint8Array(tailleMemoireTampon);</pre> +var tableauDonnees = new Uint8Array(tailleMemoireTampon); +``` -<p>Pour récupérer les données et les copier dans notre tableau, nous appelons ensuite la méthode de notre choix, en passant le tableau comme argument. Par exemple :</p> +Pour récupérer les données et les copier dans notre tableau, nous appelons ensuite la méthode de notre choix, en passant le tableau comme argument. Par exemple : -<pre class="brush: js">analyseur.getByteTimeDomainData(tableauDonnees);</pre> +```js +analyseur.getByteTimeDomainData(tableauDonnees); +``` -<p>Nous avons maintenant les données audio qui correspondent à ce laps de temps capturées dans notre tableau, et pouvons procéder à la visualisation, par exemple en les dessinant dans un élément HTML5 {{ htmlelement("canvas") }}.</p> +Nous avons maintenant les données audio qui correspondent à ce laps de temps capturées dans notre tableau, et pouvons procéder à la visualisation, par exemple en les dessinant dans un élément HTML5 {{ htmlelement("canvas") }}. -<p>Regardons quelques exemples précis.</p> +Regardons quelques exemples précis. -<h2 id="Création_d'une_forme_d'onde_oscilloscope">Création d'une forme d'onde / oscilloscope</h2> +## Création d'une forme d'onde / oscilloscope -<p>Pour visualiser un oscilloscope (chapeau à <a href="http://soledadpenades.com/">Soledad Penadés</a> pour le code original sur <a href="https://github.com/mdn/voice-change-o-matic/blob/gh-pages/scripts/app.js#L123-L167">Voice-change-O-matic</a>), nous commençons par suivre la procédure standard décrite dans le paragraphe précédent pour mettre en place le tampon :</p> +Pour visualiser un oscilloscope (chapeau à [Soledad Penadés](http://soledadpenades.com/) pour le code original sur [Voice-change-O-matic](https://github.com/mdn/voice-change-o-matic/blob/gh-pages/scripts/app.js#L123-L167)), nous commençons par suivre la procédure standard décrite dans le paragraphe précédent pour mettre en place le tampon : -<pre class="brush: js">analyseur.fftSize = 2048; +```js +analyseur.fftSize = 2048; var tailleMemoireTampon = analyseur.frequencyBinCount; -var tableauDonnees = new Uint8Array(tailleMemoireTampon);</pre> +var tableauDonnees = new Uint8Array(tailleMemoireTampon); +``` -<p>Ensuite nous effaçons ce qui est dessiné sur le canvas , avant le nouvel affichage :</p> +Ensuite nous effaçons ce qui est dessiné sur le canvas , avant le nouvel affichage : -<pre class="brush: js">contexteCanvas.clearRect(0, 0, LARGEUR, HAUTEUR);</pre> +```js +contexteCanvas.clearRect(0, 0, LARGEUR, HAUTEUR); +``` -<p>Puis nous définissons la fonction <code>dessiner()</code> :</p> +Puis nous définissons la fonction `dessiner()` : -<pre class="brush: js">function <code>dessiner</code>() {</pre> +```js +function dessiner() { +``` -<p>Dans cette fonction, nous utilisons <code>requestAnimationFrame()</code> pour faire boucler la fonction une fois qu'elle a été appelée :</p> +Dans cette fonction, nous utilisons `requestAnimationFrame()` pour faire boucler la fonction une fois qu'elle a été appelée : -<pre class="brush: js"> dessin = requestAnimationFrame(<code>dessiner</code>);</pre> +```js + dessin = requestAnimationFrame(dessiner); +``` -<p>Ensuite, nous récupérons les données et les passons dans notre tableau :</p> +Ensuite, nous récupérons les données et les passons dans notre tableau : -<pre class="brush: js"> analyseur.getByteTimeDomainData(tableauDonnees);</pre> +```js + analyseur.getByteTimeDomainData(tableauDonnees); +``` -<p>Nous remplissons le canvas avec une couleur de fond :</p> +Nous remplissons le canvas avec une couleur de fond : -<pre class="brush: js"> contexteCanvas.fillStyle = 'rgb(200, 200, 200)'; - contexteCanvas.fillRect(0, 0, LARGEUR, HAUTEUR);</pre> +```js + contexteCanvas.fillStyle = 'rgb(200, 200, 200)'; + contexteCanvas.fillRect(0, 0, LARGEUR, HAUTEUR); +``` -<p>Nous définissons l'épaisseur et la couleur du trait pour la forme d'onde que nous allons dessiner, et commençons le tracé :</p> +Nous définissons l'épaisseur et la couleur du trait pour la forme d'onde que nous allons dessiner, et commençons le tracé : -<pre class="brush: js"> contexteCanvas.lineWidth = 2; +```js + contexteCanvas.lineWidth = 2; contexteCanvas.strokeStyle = 'rgb(0, 0, 0)'; - contexteCanvas.beginPath();</pre> + contexteCanvas.beginPath(); +``` -<p>Pour déterminer la largeur de chacun des segments qui composent la ligne, nous divisons la largeur du canvas par la taille du tableau de données (laquelle est égale à FrequencyBinCount, comme nous l'avons dit plus haut), puis nous définissons une variable x pour stocker la position à laquelle il faut se déplacer pour chaque segment.</p> +Pour déterminer la largeur de chacun des segments qui composent la ligne, nous divisons la largeur du canvas par la taille du tableau de données (laquelle est égale à FrequencyBinCount, comme nous l'avons dit plus haut), puis nous définissons une variable x pour stocker la position à laquelle il faut se déplacer pour chaque segment. -<pre class="brush: js"> var largeurSegment = LARGEUR * 1.0 / tailleMemoireTampon; - var x = 0;</pre> +```js + var largeurSegment = LARGEUR * 1.0 / tailleMemoireTampon; + var x = 0; +``` -<p>Nous parcourons une boucle, qui définit la position du segment de l'onde pour chaque valeur du tableau: la hauteur (y) est basée sur cette valeur, tandis que la position en x correspond à une largeur de segment supplémentaire à chaque itération :</p> +Nous parcourons une boucle, qui définit la position du segment de l'onde pour chaque valeur du tableau: la hauteur (y) est basée sur cette valeur, tandis que la position en x correspond à une largeur de segment supplémentaire à chaque itération : -<pre class="brush: js"> for(var i = 0; i < tailleMemoireTampon; i++) { +```js + for(var i = 0; i < tailleMemoireTampon; i++) { var v = tableauDonnees[i] / 128.0; var y = v * HAUTEUR/2; @@ -106,58 +125,70 @@ var tableauDonnees = new Uint8Array(tailleMemoireTampon);</pre> } x += largeurSegment; - }</pre> + } +``` -<p>Finally, quand le tracé de la ligne a atteint le bord droit du canvas, nous l'affichons:</p> +Finally, quand le tracé de la ligne a atteint le bord droit du canvas, nous l'affichons: -<pre class="brush: js"> contexteCanvas.lineTo(canvas.width, canvas.height/2); +```js + contexteCanvas.lineTo(canvas.width, canvas.height/2); contexteCanvas.stroke(); - };</pre> + }; +``` -<p>Nous pouvons maintenant appeler la fonction <code>draw()</code> que nous venons de définir pour lancer le processus:</p> +Nous pouvons maintenant appeler la fonction `draw()` que nous venons de définir pour lancer le processus: -<pre class="brush: js"> <code>dessiner</code>();</pre> +```js + dessiner(); +``` -<p>Ce qui nous donne un affichage de forme d'onde, actualisé plusieurs fois par seconde :</p> +Ce qui nous donne un affichage de forme d'onde, actualisé plusieurs fois par seconde : -<p><img alt="Une ligne d'oscilloscope noire, illustrant la forme d'onde d'un signal audio" src="wave.png"></p> +![Une ligne d'oscilloscope noire, illustrant la forme d'onde d'un signal audio](wave.png) -<h2 id="Création_d'un_graphique_à_barres_représentant_la_fréquence">Création d'un graphique à barres représentant la fréquence</h2> +## Création d'un graphique à barres représentant la fréquence -<p>Un autre exemple de visualisation assez simple à créer est le graphique à barres dans le style de Winamp. Il y en a un dans la démo Voice-change-O-matic; regardons comment il est fait.</p> +Un autre exemple de visualisation assez simple à créer est le graphique à barres dans le style de Winamp. Il y en a un dans la démo Voice-change-O-matic; regardons comment il est fait. -<p>Tout d'abord, nous mettons de nouveau en place notre analyseur et notre tableau de données, et nous effaçons le contenu du canvas avec <code>clearRect()</code>. La seule différence est que la valeur de la propriété fftSize est beaucoup plus petite, de façon à ce que chaque barre soit assez grosse pour ressembler à une barre et non à un fil.</p> +Tout d'abord, nous mettons de nouveau en place notre analyseur et notre tableau de données, et nous effaçons le contenu du canvas avec `clearRect()`. La seule différence est que la valeur de la propriété fftSize est beaucoup plus petite, de façon à ce que chaque barre soit assez grosse pour ressembler à une barre et non à un fil. -<pre class="brush: js"> analyseur.fftSize = 256; +```js + analyseur.fftSize = 256; var tailleMemoireTampon = analyseur.frequencyBinCount; console.log(tailleMemoireTampon); var tableauDonnees = new Uint8Array(tailleMemoireTampon); - canvasCtx.clearRect(0, 0, LARGEUR, HAUTEUR);</pre> + canvasCtx.clearRect(0, 0, LARGEUR, HAUTEUR); +``` -<p>Ensuite, nous passons à la fonction <code>dessiner()</code>, là encore avec une boucle <code>requestAnimationFrame()</code> qui efface l'affichage et le met à jour.</p> +Ensuite, nous passons à la fonction `dessiner()`, là encore avec une boucle `requestAnimationFrame()` qui efface l'affichage et le met à jour. -<pre class="brush: js"> function <code>dessiner</code>() { - dessin = requestAnimationFrame(<code>dessiner</code>); +```js + function dessiner() { + dessin = requestAnimationFrame(dessiner); analyseur.getByteFrequencyData(tableauDonnees); contexteCanvas.fillStyle = 'rgb(0, 0, 0)'; - contexteCanvas.fillRect(0, 0, LARGEUR, HAUTEUR);</pre> + contexteCanvas.fillRect(0, 0, LARGEUR, HAUTEUR); +``` -<p>A présent nous calculons la largeur d'une barre, à savoir la largeur du canvas divisée par le nombre de barres (par la taille du buffer). Et nous multiplions cette valeur par 2.5, en prévision du fait que la plupart des fréquences ne contiendront pas de son, car les sons que nous entendons se situent dans un intervalle de fréquence plutôt bas. Nous ne voulons pas afficher des barres vides, nous ne gardons donc que celles qui ont une hauteur suffisante.</p> +A présent nous calculons la largeur d'une barre, à savoir la largeur du canvas divisée par le nombre de barres (par la taille du buffer). Et nous multiplions cette valeur par 2.5, en prévision du fait que la plupart des fréquences ne contiendront pas de son, car les sons que nous entendons se situent dans un intervalle de fréquence plutôt bas. Nous ne voulons pas afficher des barres vides, nous ne gardons donc que celles qui ont une hauteur suffisante. -<p>Nous déclarons une variable <code>hauteurBarre</code>, ainsi qu'une variable <code>x</code> pour mémoriser la posiiton à laquelle il faudra dessiner la barre.</p> +Nous déclarons une variable `hauteurBarre`, ainsi qu'une variable `x` pour mémoriser la posiiton à laquelle il faudra dessiner la barre. -<pre class="brush: js"> var largeurBarre = (LARGEUR / tailleMemoireTampon) * 2.5; +```js + var largeurBarre = (LARGEUR / tailleMemoireTampon) * 2.5; var hauteurBarre; - var x = 0;</pre> + var x = 0; +``` -<p>Nous créons maintenant une boucle et itérons sur chaque valeur de <code>tableauDonnees</code> : <code>hauteurBarre</code> correspond à la valeur du tableau, la couleur de fond est aussi basée sur cette valeur (plus elle est grande plus la barre est lumineuse), et la barre est placée à <code>x</code> pixels du bord gauche du canvas, sa largeur est <code>largeurBarre</code> et sa hauteur est <code>hauteurBarre/2</code> (nous avons finalement décidé de diviser cette valeur par deux pour que les barres rentrent mieux dans le canvas).</p> +Nous créons maintenant une boucle et itérons sur chaque valeur de `tableauDonnees` : `hauteurBarre` correspond à la valeur du tableau, la couleur de fond est aussi basée sur cette valeur (plus elle est grande plus la barre est lumineuse), et la barre est placée à `x` pixels du bord gauche du canvas, sa largeur est `largeurBarre` et sa hauteur est `hauteurBarre/2` (nous avons finalement décidé de diviser cette valeur par deux pour que les barres rentrent mieux dans le canvas). -<p>La position verticale de la barre est calculée comme tel : <code>HAUTEUR-hauteurBarre/2</code>, parce que nous voulons que les barres s'alignent en bas du canvas, et non pas en haut (auquel cas nous aurions positionné la barre à 0).</p> +La position verticale de la barre est calculée comme tel : `HAUTEUR-hauteurBarre/2`, parce que nous voulons que les barres s'alignent en bas du canvas, et non pas en haut (auquel cas nous aurions positionné la barre à 0). -<pre class="brush: js"> for(var i = 0; i < tailleMemoireTampon; i++) { +```js + for(var i = 0; i < tailleMemoireTampon; i++) { hauteurBarre = tableauDonnees[i]/2; contexteCanvas.fillStyle = 'rgb(' + (hauteurBarre+100) + ',50,50)'; @@ -165,16 +196,17 @@ var tableauDonnees = new Uint8Array(tailleMemoireTampon);</pre> x += largeurBarre + 1; } - };</pre> + }; +``` -<p>Là encore, nous invoquons la fonction <code>dessiner</code>() pour lancer le processus.</p> +Là encore, nous invoquons la fonction `dessiner`() pour lancer le processus. -<pre class="brush: js"> <code>dessiner</code>();</pre> +```js + dessiner(); +``` -<p>Ce code donne le résultat suivant:</p> +Ce code donne le résultat suivant: -<p><img alt="Une série de barres rouges dans un barre-graphe qui illustre l'intensité des différentes fréquences d'un signal audio" src="bar-graph.png"></p> +![Une série de barres rouges dans un barre-graphe qui illustre l'intensité des différentes fréquences d'un signal audio](bar-graph.png) -<div class="note"> -<p><strong>Note :</strong> Les examples de cet article montrent l'utilisation de {{ domxref("AnalyserNode.getByteFrequencyData()") }} et {{ domxref("AnalyserNode.getByteTimeDomainData()") }}. Pour des exemples montrant {{ domxref("AnalyserNode.getFloatFrequencyData()") }} et {{ domxref("AnalyserNode.getFloatTimeDomainData()") }}, voir notre démo <a href="http://mdn.github.io/voice-change-o-matic-float-data/">Voice-change-O-matic-float-data</a> (et son <a href="https://github.com/mdn/voice-change-o-matic-float-data">code source</a>) — elle est identique à la <a href="http://mdn.github.io/voice-change-o-matic/">Voice-change-O-matic </a>originale, à ceci près qu'elle utilise des données à virgule flottante, au lieu de données non signées.</p> -</div>
\ No newline at end of file +> **Note :** Les examples de cet article montrent l'utilisation de {{ domxref("AnalyserNode.getByteFrequencyData()") }} et {{ domxref("AnalyserNode.getByteTimeDomainData()") }}. Pour des exemples montrant {{ domxref("AnalyserNode.getFloatFrequencyData()") }} et {{ domxref("AnalyserNode.getFloatTimeDomainData()") }}, voir notre démo [Voice-change-O-matic-float-data](http://mdn.github.io/voice-change-o-matic-float-data/) (et son [code source](https://github.com/mdn/voice-change-o-matic-float-data)) — elle est identique à la [Voice-change-O-matic ](http://mdn.github.io/voice-change-o-matic/)originale, à ceci près qu'elle utilise des données à virgule flottante, au lieu de données non signées. diff --git a/files/fr/web/api/web_audio_api/web_audio_spatialization_basics/index.md b/files/fr/web/api/web_audio_api/web_audio_spatialization_basics/index.md index d0de8755ec..0946ffe4a5 100644 --- a/files/fr/web/api/web_audio_api/web_audio_spatialization_basics/index.md +++ b/files/fr/web/api/web_audio_api/web_audio_spatialization_basics/index.md @@ -3,73 +3,70 @@ title: Web audio spatialization basics slug: Web/API/Web_Audio_API/Web_audio_spatialization_basics translation_of: Web/API/Web_Audio_API/Web_audio_spatialization_basics --- -<p>En plus de sa grande variété de fonctionnalités et d'options, la Web Audio API permet aussi d'émuler la différence dans l'écoute d'un son lorsqu'un auditeur se déplace par rapport à une source, par exemple un panoramique lorsqu'il se déplace de gauche à droite de la source. On parle alors de spatialisation. Cet article expose les notions de base pour implémenter ce type de système.</p> +En plus de sa grande variété de fonctionnalités et d'options, la Web Audio API permet aussi d'émuler la différence dans l'écoute d'un son lorsqu'un auditeur se déplace par rapport à une source, par exemple un panoramique lorsqu'il se déplace de gauche à droite de la source. On parle alors de spatialisation. Cet article expose les notions de base pour implémenter ce type de système. -<p>Le cas d'utilisation le plus simple est la simulation des altérations d'un son de façon réaliste pour imaginer comment une source se comportera pour un personnage qui se déplace dans un environnement 3D.</p> +Le cas d'utilisation le plus simple est la simulation des altérations d'un son de façon réaliste pour imaginer comment une source se comportera pour un personnage qui se déplace dans un environnement 3D. -<h2 id="Concepts_de_base">Concepts de base</h2> +## Concepts de base -<p>Créer une spatialisation audio comporte deux principaux aspects :</p> +Créer une spatialisation audio comporte deux principaux aspects : -<ol> - <li>L'objet {{ domxref("AudioListener") }} représente la position dans l'espace 3D d'une personne qui écoute la source audio; on y accède avec la propriété {{ domxref("AudioContext.listener") }}. On peut paramétrer la position et l'orientation de l'auditeur, entre autres.</li> - <li>L'objet {{ domxref("PannerNode") }} représente la position dans l'espace 3D d'une source audio; on le crée avec la méthode {{ domxref("AudioContext.createPanner()") }}. On peut paramétrer un certain nombre d'options comme la position, l'orientation, la vitesse, et l'angle s'un cône qui indique dans quelle direction le son peut être entendu (s'il n'est pas omnidirectionnel).</li> -</ol> +1. L'objet {{ domxref("AudioListener") }} représente la position dans l'espace 3D d'une personne qui écoute la source audio; on y accède avec la propriété {{ domxref("AudioContext.listener") }}. On peut paramétrer la position et l'orientation de l'auditeur, entre autres. +2. L'objet {{ domxref("PannerNode") }} représente la position dans l'espace 3D d'une source audio; on le crée avec la méthode {{ domxref("AudioContext.createPanner()") }}. On peut paramétrer un certain nombre d'options comme la position, l'orientation, la vitesse, et l'angle s'un cône qui indique dans quelle direction le son peut être entendu (s'il n'est pas omnidirectionnel). -<p>Dans cet article nous allons nous concentrer sur la position de l'auditeur et du panoramique, tous deux paramétrés à l'aide de la méthode <code>setPosition(). </code>Celle-co accepte trois valeurs qui correspondent à X, Y, et Z dans un système de coordonnées cartésien.</p> +Dans cet article nous allons nous concentrer sur la position de l'auditeur et du panoramique, tous deux paramétrés à l'aide de la méthode `setPosition(). `Celle-co accepte trois valeurs qui correspondent à X, Y, et Z dans un système de coordonnées cartésien. -<div class="note"> -<p><strong>Note :</strong> Trouver les bonnes valeurs pour que le cas d'utilisation fonctionne bien et semble réaliste n'est pas toujours évident et peur prendre du temps, et il faut souvent continuer à modifier les valeurs par la suite. Nous discuterons ceci plus en détail en parcourant le code qui suit.</p> -</div> +> **Note :** Trouver les bonnes valeurs pour que le cas d'utilisation fonctionne bien et semble réaliste n'est pas toujours évident et peur prendre du temps, et il faut souvent continuer à modifier les valeurs par la suite. Nous discuterons ceci plus en détail en parcourant le code qui suit. -<p>Les autres options disponibles, que nous ne traiterons pas ici, sont :</p> +Les autres options disponibles, que nous ne traiterons pas ici, sont : -<ul> - <li><code>setOrientation()</code>: disponible à la fois pour l'auditeur et le panoramique for both the listener and panner, cette méthode paramètre l'orientation. Elle prend six valeurs: les trois premières représentent un vecteur frontal dans l'espace 3D (imaginez une personne et la direction dans laquelle pointe son nez) and les trois autre un vecteur de direction verticale dans l'espace 3D space (imaginez la même personne et la direction vers laquelle pointe le haut de sa tête)</li> - <li><code>setVelocity()</code>: disponible uniquement pour le panoramique; permet de paramétrer la vitesse à laquelle une source audio se déplace, à l'aide d'un vecteur de vitesse dans l'espace 3D (valeurs X, Y, et Z). When set, the browser will apply a doppler shift effect.</li> - <li><code>coneInnerAngle</code>, <code>coneOuterAngle</code>, and <code>coneOuterGain</code>: Available for the panner only, these allow you to set an angle inside/outside of which the volume will be reduced by the specified gain value. This is done to specify directional audio sources, but the default is 360/360/0, respectively, meaning that by default you get an omnidirectional sound source.</li> -</ul> +- `setOrientation()`: disponible à la fois pour l'auditeur et le panoramique for both the listener and panner, cette méthode paramètre l'orientation. Elle prend six valeurs: les trois premières représentent un vecteur frontal dans l'espace 3D (imaginez une personne et la direction dans laquelle pointe son nez) and les trois autre un vecteur de direction verticale dans l'espace 3D space (imaginez la même personne et la direction vers laquelle pointe le haut de sa tête) +- `setVelocity()`: disponible uniquement pour le panoramique; permet de paramétrer la vitesse à laquelle une source audio se déplace, à l'aide d'un vecteur de vitesse dans l'espace 3D (valeurs X, Y, et Z). When set, the browser will apply a doppler shift effect. +- `coneInnerAngle`, `coneOuterAngle`, and `coneOuterGain`: Available for the panner only, these allow you to set an angle inside/outside of which the volume will be reduced by the specified gain value. This is done to specify directional audio sources, but the default is 360/360/0, respectively, meaning that by default you get an omnidirectional sound source. -<h2 id="A_simple_demo_Room_of_metal">A simple demo: Room of metal</h2> +## A simple demo: Room of metal -<p>In our demo, you can move left and right past a 2.5D stereo that can be made to play a groovy tune, and you can also move towards the stereo. As you move left and right, the tune will pan to emulate how the tune will sound as you change your position proportional to the sound source. When you zoom in and out, the sound will get louder and quieter to suit.</p> +In our demo, you can move left and right past a 2.5D stereo that can be made to play a groovy tune, and you can also move towards the stereo. As you move left and right, the tune will pan to emulate how the tune will sound as you change your position proportional to the sound source. When you zoom in and out, the sound will get louder and quieter to suit. -<div class="note"> -<p><strong>Note :</strong> You can see this example <a href="https://mdn.github.io/webaudio-examples/panner-node/">running live</a>, and <a href="https://github.com/mdn/panner-node">view the source code</a>.</p> -</div> +> **Note :** You can see this example [running live](https://mdn.github.io/webaudio-examples/panner-node/), and [view the source code](https://github.com/mdn/panner-node). -<p>Let's walk through the code and see how this was actually done.</p> +Let's walk through the code and see how this was actually done. -<h3 id="Defining_basic_variables">Defining basic variables</h3> +### Defining basic variables -<p>First we define a new audio context, panner, listener, and source:</p> +First we define a new audio context, panner, listener, and source: -<pre class="brush: js">var AudioContext = window.AudioContext || window.webkitAudioContext; +```js +var AudioContext = window.AudioContext || window.webkitAudioContext; var audioCtx = new AudioContext(); var panner = audioCtx.createPanner(); var listener = audioCtx.listener; -var source;</pre> +var source; +``` -<p>Next we grab the objects on the page we are using for our demo. First the <code>play</code> and <code>stop</code> buttons to control the audio, then the <code>boomBox</code>, which is just the graphic of the stereo that we are moving around. After that, we grab a reference to two paragraphs that are used to output the position of the <code>listener</code> and <code>panner</code>, for debugging purposes.</p> +Next we grab the objects on the page we are using for our demo. First the `play` and `stop` buttons to control the audio, then the `boomBox`, which is just the graphic of the stereo that we are moving around. After that, we grab a reference to two paragraphs that are used to output the position of the `listener` and `panner`, for debugging purposes. -<pre class="brush: js">var play = document.querySelector('.play'); +```js +var play = document.querySelector('.play'); var stop = document.querySelector('.stop'); var boomBox = document.querySelector('.boom-box'); var listenerData = document.querySelector('.listener-data'); -var pannerData = document.querySelector('.panner-data');</pre> +var pannerData = document.querySelector('.panner-data'); +``` -<h3 id="Working_out_listener_and_panner_positions">Working out listener and panner positions</h3> +### Working out listener and panner positions -<p>Next comes a little bit of slightly fiddly maths. We want to make the <code>boomBox</code>, <code>listener</code>, and <code>panner</code> appear in the center of the screen initially, so we work out the width and height of the viewport, and divide both by two to get our X and Y values for those things. The <code>zPos</code> is only used on the panner, and is updated as the zoom controls are used (see later on); the initial value of 295 was decided on fairly arbitrarily — it sounded good. As long as you set the position of the panner appropriately in relation to the listener position, you will be ok.</p> +Next comes a little bit of slightly fiddly maths. We want to make the `boomBox`, `listener`, and `panner` appear in the center of the screen initially, so we work out the width and height of the viewport, and divide both by two to get our X and Y values for those things. The `zPos` is only used on the panner, and is updated as the zoom controls are used (see later on); the initial value of 295 was decided on fairly arbitrarily — it sounded good. As long as you set the position of the panner appropriately in relation to the listener position, you will be ok. -<p>Next for this section, we set a <code>leftBound</code> and <code>rightBound</code>, which is the furthest we want our stereo graph to travel left and right. For the layout, we are using <a href="/en-US/docs/Web/Guide/CSS/Flexible_boxes">Flexbox</a> to initially place the <code>boomBox</code> right in the center of the viewport, after which we then use iterative transforms and {{domxref("window.requestAnimationFrame()")}} to apply the <code>boomBox</code> movement. Therefore the "0" position is in the center of the viewport so the rightmost position is that position plus half the viewport, but minus 50 (pixels) so the <code>boomBox</code> can't shoot all the way off the right of the screen, and the leftmost position is that position minus half the viewport, but plus 50 (pixels), so the <code>boomBox</code> can't shoot all the way off the left of the screen.</p> +Next for this section, we set a `leftBound` and `rightBound`, which is the furthest we want our stereo graph to travel left and right. For the layout, we are using [Flexbox](/en-US/docs/Web/Guide/CSS/Flexible_boxes) to initially place the `boomBox` right in the center of the viewport, after which we then use iterative transforms and {{domxref("window.requestAnimationFrame()")}} to apply the `boomBox` movement. Therefore the "0" position is in the center of the viewport so the rightmost position is that position plus half the viewport, but minus 50 (pixels) so the `boomBox` can't shoot all the way off the right of the screen, and the leftmost position is that position minus half the viewport, but plus 50 (pixels), so the `boomBox` can't shoot all the way off the left of the screen. -<p>The last part of this code is the <code>xIterator</code> — we set this to a 150th of the screen width, and then move the <code>boomBox</code> left and right by this amount when the left and right controls are pressed. We use this rather than a constant so that the app is a little more responsive.</p> +The last part of this code is the `xIterator` — we set this to a 150th of the screen width, and then move the `boomBox` left and right by this amount when the left and right controls are pressed. We use this rather than a constant so that the app is a little more responsive. -<pre class="brush: js">var WIDTH = window.innerWidth; +```js +var WIDTH = window.innerWidth; var HEIGHT = window.innerHeight; var xPos = WIDTH/2; @@ -79,25 +76,31 @@ var zPos = 295; leftBound = (-xPos) + 50; rightBound = xPos - 50; -xIterator = WIDTH/150;</pre> +xIterator = WIDTH/150; +``` -<p>Next we set the position of the <code>listener</code> and output the coordinates to the <code>listenerData</code> paragraph. It is always going to be in the same place, in a good position relative to the panner.</p> +Next we set the position of the `listener` and output the coordinates to the `listenerData` paragraph. It is always going to be in the same place, in a good position relative to the panner. -<pre class="brush: js">listener.setPosition(xPos,yPos,300); -listenerData.innerHTML = 'Listener data: X ' + xPos + ' Y ' + yPos + ' Z ' + 300;</pre> +```js +listener.setPosition(xPos,yPos,300); +listenerData.innerHTML = 'Listener data: X ' + xPos + ' Y ' + yPos + ' Z ' + 300; +``` -<p>In the <code>positionPanner()</code> function, we set the position of the panner, and output the coordinates to the <code>pannerData</code> paragraph. This function is called with each animation frame as the <code>boomBox</code> is moved, so the panner position updates accordingly:</p> +In the `positionPanner()` function, we set the position of the panner, and output the coordinates to the `pannerData` paragraph. This function is called with each animation frame as the `boomBox` is moved, so the panner position updates accordingly: -<pre class="brush: js">function positionPanner() { +```js +function positionPanner() { panner.setPosition(xPos,yPos,zPos); pannerData.innerHTML = 'Panner data: X ' + xPos + ' Y ' + yPos + ' Z ' + zPos; -}</pre> +} +``` -<h3 id="Loading_and_playing_our_music">Loading and playing our music</h3> +### Loading and playing our music -<p>Next we use XHR to load an audio track, and <code>decodeAudioData()</code> to decode it and stick it in a buffer. Then we put the buffer into an {{domxref("AudioBufferSourceNode") }}:</p> +Next we use XHR to load an audio track, and `decodeAudioData()` to decode it and stick it in a buffer. Then we put the buffer into an {{domxref("AudioBufferSourceNode") }}: -<pre class="brush: js">function getData() { +```js +function getData() { source = audioCtx.createBufferSource(); request = new XMLHttpRequest(); @@ -124,11 +127,13 @@ listenerData.innerHTML = 'Listener data: X ' + xPos + ' Y ' + yPos + ' Z ' + 300 } request.send(); -}</pre> +} +``` -<p>The next stage is to wire up the buttons to stop and play the audio. The pulse wrapper is an extra wrapper {{ htmlelement("div") }} wrapped around the <code>boomBox</code>. We apply the pulsating (<code>scaleY</code>) animation to this element when the play button is clicked, not the <code>boomBox</code> itself, because the <code>boomBox</code> already has animations applied to it throughout the course of the app's running.</p> +The next stage is to wire up the buttons to stop and play the audio. The pulse wrapper is an extra wrapper {{ htmlelement("div") }} wrapped around the `boomBox`. We apply the pulsating (`scaleY`) animation to this element when the play button is clicked, not the `boomBox` itself, because the `boomBox` already has animations applied to it throughout the course of the app's running. -<pre class="brush: js">var pulseWrapper = document.querySelector('.pulse-wrapper'); +```js +var pulseWrapper = document.querySelector('.pulse-wrapper'); play.onclick = function() { getData(); @@ -141,38 +146,40 @@ stop.onclick = function() { source.stop(0); play.removeAttribute('disabled'); pulseWrapper.classList.remove('pulsate'); -}</pre> +} +``` -<h3 id="Moving_the_boom_box_and_the_panner">Moving the boom box and the panner</h3> +### Moving the boom box and the panner -<p>The next section of code grabs references to the left, right, zoom in, and zoom out buttons, and defines initial X, Y, and scale amounts for the <code>boomBox</code> to be positioned by when the transforms first start to be applied.</p> +The next section of code grabs references to the left, right, zoom in, and zoom out buttons, and defines initial X, Y, and scale amounts for the `boomBox` to be positioned by when the transforms first start to be applied. -<pre class="brush: js">var leftButton = document.querySelector('.left'); +```js +var leftButton = document.querySelector('.left'); var rightButton = document.querySelector('.right'); var zoomInButton = document.querySelector('.zoom-in'); var zoomOutButton = document.querySelector('.zoom-out'); var boomX = 0; var boomY = 0; -var boomZoom = 0.25;</pre> +var boomZoom = 0.25; +``` -<p>Now we get to the four functions that control the left, right, zoom in, and zoom out functionality: <code>moveRight()</code>, <code>moveLeft()</code>, <code>zoomIn()</code>, and <code>zoomOut()</code>. Each is a little different, but works in a similar way:</p> +Now we get to the four functions that control the left, right, zoom in, and zoom out functionality: `moveRight()`, `moveLeft()`, `zoomIn()`, and `zoomOut()`. Each is a little different, but works in a similar way: -<ol> - <li>The <code>boomX</code> or <code>boomZoom</code> variables are updated in order to change the <code>boomBox</code>'s position on the screen.</li> - <li>The <code>xPos</code> or <code>zPos</code> variables are updated in order to change the {{domxref("PannerNode") }}'s position in 3D space. The changes are quite small, but these are the values we found to work.</li> - <li>A check is done to see if the upper bounds of movement have been reached (a <code>boomX</code> equal or less than <code>leftBound</code> or greater than <code>rightBound</code>, or a <code>boomZoom</code> greater than 4 or equal or less than 0.25.) If so, the values are updated to force the <code>boomBox</code> to stay in certain constraints, and to force the <code>xPos</code> and <code>zPos</code> variables to also stay within certain constrants. These are, respectively, 5 greater or less than <code>WIDTH/2</code>, and a <code>zPos</code> between 295 and 299.9. These are the values we found produced a relatively realistic sounding panning and volume adjustment as the <code>boomBox</code> was moved around.</li> - <li><code>boomBox</code> is transformed (translated and scaled) by the new values of <code>boomX</code>, <code>boomY</code>, and <code>boomZoom</code> to move it around the screen.</li> - <li>The <code>positionPanner()</code> function is run to update the position of the panner.</li> - <li>A {{domxref("window.requestAnimationFrame") }} instance is called to keep running the function for as long as the mouse button is pressed down.</li> - <li>The <code>requestAnimationFrame</code> ID is returned out of the function so that it can be cancelled when the mouse button is released.</li> -</ol> +1. The `boomX` or `boomZoom` variables are updated in order to change the `boomBox`'s position on the screen. +2. The `xPos` or `zPos` variables are updated in order to change the {{domxref("PannerNode") }}'s position in 3D space. The changes are quite small, but these are the values we found to work. +3. A check is done to see if the upper bounds of movement have been reached (a `boomX` equal or less than `leftBound` or greater than `rightBound`, or a `boomZoom` greater than 4 or equal or less than 0.25.) If so, the values are updated to force the `boomBox` to stay in certain constraints, and to force the `xPos` and `zPos` variables to also stay within certain constrants. These are, respectively, 5 greater or less than `WIDTH/2`, and a `zPos` between 295 and 299.9. These are the values we found produced a relatively realistic sounding panning and volume adjustment as the `boomBox` was moved around. +4. `boomBox` is transformed (translated and scaled) by the new values of `boomX`, `boomY`, and `boomZoom` to move it around the screen. +5. The `positionPanner()` function is run to update the position of the panner. +6. A {{domxref("window.requestAnimationFrame") }} instance is called to keep running the function for as long as the mouse button is pressed down. +7. The `requestAnimationFrame` ID is returned out of the function so that it can be cancelled when the mouse button is released. -<pre class="brush: js">function moveRight() { +```js +function moveRight() { boomX += -xIterator; xPos += -0.066; - if(boomX <= leftBound) { + if(boomX <= leftBound) { boomX = leftBound; xPos = (WIDTH/2) - 5; } @@ -188,7 +195,7 @@ function moveLeft() { boomX += xIterator; xPos += 0.066; - if(boomX > rightBound) { + if(boomX > rightBound) { boomX = rightBound; xPos = (WIDTH/2) + 5; } @@ -204,7 +211,7 @@ function zoomIn() { boomZoom += 0.05; zPos += 0.066; - if(boomZoom > 4) { + if(boomZoom > 4) { boomZoom = 4; zPos = 299.9; } @@ -220,7 +227,7 @@ function zoomOut() { boomZoom += -0.05; zPos += -0.066; - if(boomZoom <= 0.25) { + if(boomZoom <= 0.25) { boomZoom = 0.25; zPos = 295; } @@ -230,11 +237,13 @@ function zoomOut() { boomBox.style.transform = "translate(" + boomX + "px , " + boomY + "px) scale(" + boomZoom + ")"; zoomOutLoop = requestAnimationFrame(zoomOut); return zoomOutLoop; -}</pre> +} +``` -<p>In the final block of code, we simply wire up event handlers to control the movement when the buttons are pressed. For each button, the relevant function is invoked <code>onmousedown</code>; then <code>onmouseup</code>, {{domxref("window.cancelAnimationFrame") }} is called along with the returned <code>requestAnimationFrame()</code> ID to stop the animation happening.</p> +In the final block of code, we simply wire up event handlers to control the movement when the buttons are pressed. For each button, the relevant function is invoked `onmousedown`; then `onmouseup`, {{domxref("window.cancelAnimationFrame") }} is called along with the returned `requestAnimationFrame()` ID to stop the animation happening. -<pre class="brush: js">leftButton.onmousedown = moveLeft; +```js +leftButton.onmousedown = moveLeft; leftButton.onmouseup = function () { window.cancelAnimationFrame(leftLoop); } @@ -252,10 +261,9 @@ zoomInButton.onmouseup = function () { zoomOutButton.onmousedown = zoomOut; zoomOutButton.onmouseup = function () { window.cancelAnimationFrame(zoomOutLoop); -}</pre> +} +``` -<p>As you can see, the actual panner code is pretty simple — specify the positions, and the browser takes care of the rest. It is working out the surrounding code, and the values to use for positioning, which takes a bit more time.</p> +As you can see, the actual panner code is pretty simple — specify the positions, and the browser takes care of the rest. It is working out the surrounding code, and the values to use for positioning, which takes a bit more time. -<div class="note"> -<p><strong>Note :</strong> You are probably thinking "why didn't you move the listener and keep the panner still instead: surely that is a bit more obvious?" Well, perhaps, but we felt that since the panner has more methods and properties available to it, moving it would allow more control in the long term.</p> -</div>
\ No newline at end of file +> **Note :** You are probably thinking "why didn't you move the listener and keep the panner still instead: surely that is a bit more obvious?" Well, perhaps, but we felt that since the panner has more methods and properties available to it, moving it would allow more control in the long term. |