[ Web Proxy ]
URL:
Viewing: https://developer.mozilla.org/fr/docs/Web/API/Web_Audio_API/Visualizations_with_Web_Audio_API [Back]  [Original]

Visualisations avec la Web Audio API - Les API Web | MDN

Cette page a t traduite partir de l'anglais par la communaut. Vous pouvez contribuer en rejoignant la communaut francophone sur MDN Web Docs.

View in English Always switch to English

Visualisations avec la Web Audio API

L'une des fonctionnalits les plus intressantes de la Web Audio API est la possibilit d'extraire de la source audio la frquence, la forme d'onde et d'autres donnes, qui permettent de crer des visualisations. Cet article explique comment, et fournit quelques exemples basiques.

Note : Vous pouvez trouver des exemples de tous les extraits de the code dans notre dmo Voice-change-O-matic.

Dans cet article

Concepts de base

Pour extraire les donnes d'une source audio, il faut un AnalyserNode, que l'on peut crer l'aide de la mthode AudioContext.createAnalyser(), par exemple:

js
var contexteAudio = new (window.AudioContext || window.webkitAudioContext)();
var analyseur = contexteAudio.createAnalyser();

Ce noeud est ensuite connect la source audio :

js
source = contexteAudio.createMediaStreamSource(stream);
source.connect(analyseur);
analyseur.connect(distortion);
// etc.

Note : Il n'est pas ncessaire de connecter la sortie de l'analyseur un noeud pour qu'il fonctionne, il suffit que l'entre soit connecte la source, directement ou via un autre noeud.

L'analyseur va alors capturer les donnes audio en usant une Transformation de Fourier Rapide (fft) une certaine frquence, en fonction de ce qui est spcifi dans la proprit AnalyserNode.fftSize (la valeur par dfaut est 2048).

Note : Vous pouvez aussi spcifier des valeurs de puissance minimum et maximum pour la plage de mise l'chelle fft, en utilisant AnalyserNode.minDecibels et AnalyserNode.maxDecibels, et plusieurs valeurs de transition en utilisant AnalyserNode.smoothingTimeConstant.

Pour capturer des donnes, il faut utiliser les mthodes AnalyserNode.getFloatFrequencyData() et AnalyserNode.getByteFrequencyData() pour la frquence, et AnalyserNode.getByteTimeDomainData() et AnalyserNode.getFloatTimeDomainData() pour la forme d'onde.

Ces mthodes copient les donnes dans le tableau pass en paramtre, il faut donc crer un tableau avant de les invoquer. La premire produit des nombres flottants simple prcision de 32 bits, qui ne peuvent tre stockes dans un simple tableau javascript. Vous devez crer un Float32Array ou un Uint8Array, en fonction du type de donnes que vous traitez.

Par exemple, disons que nous manipulons une fft de frquence 2048. Nous retournons la valeur AnalyserNode.frequencyBinCount, qui correspond la moiti de la frquence, puis nous appelons la mthode Uint8Array() en passant frequencyBinCount comme argument pour la taille c'est le nombre de points de donnes qui seront collectes pour cette frquence.

js
analyseur.fftSize = 2048;
var tailleMemoireTampon = analyseur.frequencyBinCount;
var tableauDonnees = new Uint8Array(tailleMemoireTampon);

Pour rcuprer les donnes et les copier dans notre tableau, nous appelons ensuite la mthode de notre choix, en passant le tableau comme argument. Par exemple :

js
analyseur.getByteTimeDomainData(tableauDonnees);

Nous avons maintenant les donnes audio qui correspondent ce laps de temps captures dans notre tableau, et pouvons procder la visualisation, par exemple en les dessinant dans un lment HTML5 <canvas>.

Regardons quelques exemples prcis.

Cration d'une forme d'onde / oscilloscope

Pour visualiser un oscilloscope (chapeau Soledad Penads pour le code original sur Voice-change-O-matic), nous commenons par suivre la procdure standard dcrite dans le paragraphe prcdent pour mettre en place le tampon :

js
analyseur.fftSize = 2048;
var tailleMemoireTampon = analyseur.frequencyBinCount;
var tableauDonnees = new Uint8Array(tailleMemoireTampon);

Ensuite nous effaons ce qui est dessin sur le canvas , avant le nouvel affichage :

js
contexteCanvas.clearRect(0, 0, LARGEUR, HAUTEUR);

Puis nous dfinissons la fonction dessiner() :

js
function dessiner() {

Dans cette fonction, nous utilisons requestAnimationFrame() pour faire boucler la fonction une fois qu'elle a t appele :

js
dessin = requestAnimationFrame(dessiner);

Ensuite, nous rcuprons les donnes et les passons dans notre tableau :

js
analyseur.getByteTimeDomainData(tableauDonnees);

Nous remplissons le canvas avec une couleur de fond :

js
contexteCanvas.fillStyle = "rgb(200, 200, 200)";
contexteCanvas.fillRect(0, 0, LARGEUR, HAUTEUR);

Nous dfinissons l'paisseur et la couleur du trait pour la forme d'onde que nous allons dessiner, et commenons le trac :

js
contexteCanvas.lineWidth = 2;
contexteCanvas.strokeStyle = "rgb(0, 0, 0)";

contexteCanvas.beginPath();

Pour dterminer la largeur de chacun des segments qui composent la ligne, nous divisons la largeur du canvas par la taille du tableau de donnes (laquelle est gale FrequencyBinCount, comme nous l'avons dit plus haut), puis nous dfinissons une variable x pour stocker la position laquelle il faut se dplacer pour chaque segment.

js
var largeurSegment = (LARGEUR * 1.0) / tailleMemoireTampon;
var x = 0;

Nous parcourons une boucle, qui dfinit la position du segment de l'onde pour chaque valeur du tableau: la hauteur (y) est base sur cette valeur, tandis que la position en x correspond une largeur de segment supplmentaire chaque itration :

js
for (var i = 0; i < tailleMemoireTampon; i++) {
  var v = tableauDonnees[i] / 128.0;
  var y = (v * HAUTEUR) / 2;

  if (i === 0) {
    contexteCanvas.moveTo(x, y);
  } else {
    contexteCanvas.lineTo(x, y);
  }

  x += largeurSegment;
}

Finally, quand le trac de la ligne a atteint le bord droit du canvas, nous l'affichons:

js
      contexteCanvas.lineTo(canvas.width, canvas.height/2);
      contexteCanvas.stroke();
    };

Nous pouvons maintenant appeler la fonction draw() que nous venons de dfinir pour lancer le processus:

js
dessiner();

Ce qui nous donne un affichage de forme d'onde, actualis plusieurs fois par seconde :

Une ligne d'oscilloscope noire, illustrant la forme d'onde d'un signal audio [Une ligne d'oscilloscope noire, illustrant la forme d'onde d'un signal audio]

Cration d'un graphique barres reprsentant la frquence

Un autre exemple de visualisation assez simple crer est le graphique barres dans le style de Winamp. Il y en a un dans la dmo Voice-change-O-matic; regardons comment il est fait.

Tout d'abord, nous mettons de nouveau en place notre analyseur et notre tableau de donnes, et nous effaons le contenu du canvas avec clearRect(). La seule diffrence est que la valeur de la proprit fftSize est beaucoup plus petite, de faon ce que chaque barre soit assez grosse pour ressembler une barre et non un fil.

js
analyseur.fftSize = 256;
var tailleMemoireTampon = analyseur.frequencyBinCount;
console.log(tailleMemoireTampon);
var tableauDonnees = new Uint8Array(tailleMemoireTampon);

canvasCtx.clearRect(0, 0, LARGEUR, HAUTEUR);

Ensuite, nous passons la fonction dessiner(), l encore avec une boucle requestAnimationFrame() qui efface l'affichage et le met jour.

js
    function dessiner() {
      dessin = requestAnimationFrame(dessiner);

      analyseur.getByteFrequencyData(tableauDonnees);

      contexteCanvas.fillStyle = 'rgb(0, 0, 0)';
      contexteCanvas.fillRect(0, 0, LARGEUR, HAUTEUR);

A prsent nous calculons la largeur d'une barre, savoir la largeur du canvas divise par le nombre de barres (par la taille du buffer). Et nous multiplions cette valeur par 2.5, en prvision du fait que la plupart des frquences ne contiendront pas de son, car les sons que nous entendons se situent dans un intervalle de frquence plutt bas. Nous ne voulons pas afficher des barres vides, nous ne gardons donc que celles qui ont une hauteur suffisante.

Nous dclarons une variable hauteurBarre, ainsi qu'une variable x pour mmoriser la posiiton laquelle il faudra dessiner la barre.

js
var largeurBarre = (LARGEUR / tailleMemoireTampon) * 2.5;
var hauteurBarre;
var x = 0;

Nous crons maintenant une boucle et itrons sur chaque valeur de tableauDonnees : hauteurBarre correspond la valeur du tableau, la couleur de fond est aussi base sur cette valeur (plus elle est grande plus la barre est lumineuse), et la barre est place x pixels du bord gauche du canvas, sa largeur est largeurBarre et sa hauteur est hauteurBarre/2 (nous avons finalement dcid de diviser cette valeur par deux pour que les barres rentrent mieux dans le canvas).

La position verticale de la barre est calcule 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).

js
      for(var i = 0; i < tailleMemoireTampon; i++) {
        hauteurBarre = tableauDonnees[i]/2;

        contexteCanvas.fillStyle = 'rgb(' + (hauteurBarre+100) + ',50,50)';
        contexteCanvas.fillRect(x,HAUTEUR-hauteurBarre/2,largeurBarre,hauteurBarre);

        x += largeurBarre + 1;
      }
    };

L encore, nous invoquons la fonction dessiner() pour lancer le processus.

js
dessiner();

Ce code donne le rsultat suivant:

Une srie de barres rouges dans un barre-graphe qui illustre l'intensit des diffrentes frquences d'un signal audio [Une srie de barres rouges dans un barre-graphe qui illustre l'intensit des diffrentes frquences d'un signal audio]

Note : Les exemples de cet article montrent l'utilisation de AnalyserNode.getByteFrequencyData() et AnalyserNode.getByteTimeDomainData(). Pour des exemples montrant AnalyserNode.getFloatFrequencyData() et AnalyserNode.getFloatTimeDomainData(), voir notre dmo Voice-change-O-matic-float-data (et son code source) elle est identique la Voice-change-O-matic originale, ceci prs qu'elle utilise des donnes virgule flottante, au lieu de donnes non signes.


Web Proxy Viewer  |  New URL  |  Original Page