• contact@spgoo.org

Dans le cadre des projets PASSY-DPFV et FRAPéOR nous avons dû trouver une solution pour afficher de façon dynamique les enregistrements sonores. Pour ce faire, après exploration de l’existant en passant par p5.js, nous nous sommes arrêtés sur cette librairie qui a priori correspond à nos besoins.

Sources : https://github.com/hvianna/audioMotion-analyzer/releases

Fenêtre de démonstration de cette librairie :

Mise en oeuvre et retour d’expérience :

Mise en oeuvre dans un contexte plus simple : voir

Insertion de cette librairie dans nos contextes WordPress par l’import de module. Page de démonstration qui illustre l’intégration de ce module dans nos développements.

 <script>
        // définition de l'espace de nom par defaut attache au module 
        const soundYS={};
    </script>
    <script type="module">
      // on accroche à cet espace de nom les traitements de sonores definis dans le module
      import { AudioMotionAnalyzer } from "./personnalisation/audioMotion-analyzer-4.5.2/src/audioMotion-analyzer.js";
      soundYS.AudioMotionAnalyzer = AudioMotionAnalyzer;
    </script> 

Instanciation de l’objet

   document.addEventListener("DOMContentLoaded", function(event) {
        
        // Initialisation de l'analyseur une fois la librairie et le module chargés 
        audioMotion = new soundYS.AudioMotionAnalyzer(
            document.getElementById('containerYS'),
            {
                mode: 10,
                gradient: 'prism',
                showScaleX: true,
                showScaleY: true,
                showPeaks: true,
                smoothing: 0.5,
                height: 300,
                fftSize: 8192,
                minDecibels: -85,
                maxDecibels: -25,
                showBgColor: true,
                bgAlpha: 0.7,
                overlay: true,
                lineWidth: 2,
                fillAlpha: 0.6,
                barSpace: 0.1,
                reflexRatio: 0,
                reflexAlpha: 0.15,
                reflexBright: 1,
                reflexFit: true,
                minFreq: 20,
                maxFreq: 22000,
                radius: 0.3,
                spinSpeed: 0,
                alphaBars: false,
                lumiBars: false,
                trueLeds: false,
                mirror: 0,
                splitGradient: false,
                roundBars: false,
                channelLayout: 'single',
                frequencyScale: 'log',
                noteLabels: false,
                ansiBands: false,
                weightingFilter: '',
            }
        );
        });

Chargement du fichier audio et association avec l’objet

        // Gestion du fichier audio
        document.getElementById('fileInput').addEventListener('change', function(e) {
            const file = e.target.files[0];
            if (file) {
                if (audioElement) {
                    audioElement.pause();
                    audioElement = null;
                }               
                audioElement = new Audio();
                audioElement.src = URL.createObjectURL(file);     
                if (!sourceNode) {
                    sourceNode = audioMotion.audioCtx.createMediaElementSource(audioElement);
                    sourceNode.connect(audioMotion._analyzer[0]);
                    audioMotion._analyzer[0].connect(audioMotion.audioCtx.destination);
                }
                // on active les boutons de controle de l'interface
                document.getElementById('fileName').textContent = `Fichier: ${file.name}`;
                document.getElementById('playBtn').disabled = false;
                document.getElementById('pauseBtn').disabled = false;
                document.getElementById('stopBtn').disabled = false;
            }
        });

Pour écouter l’enregistrement, il faut s’appuyer sur la variable audioElement de la façon suivante :

  document.getElementById('playBtn').addEventListener('click', () => audioElement && audioElement.play());

Autre exemple : examinons l’exemple de démonstration qui lui a plusieurs zones graphiques dans lesquelles des représentations complémentaires s’affichent : container1, container2 et container3

Comment se fait le lien entre le fichier sonore que l’on charge et les trois graphiques à afficher ?

try {
   for ( let i = 0; i < 3; i++ ) {
	const isFirst = ( i == 0 );
	audioMotion[ i ] = new AudioMotionAnalyzer(document.getElementById( `container${i}` ), {
	   source: isFirst ? document.getElementById('audio') : audioMotion[0].connectedSources[0],
  	   connectSpeakers: isFirst,height: isFirst ? 340 : 160,
	   onCanvasResize: ( reason, instance ) => {
   	      const instNo = instance.canvas.parentElement.id.slice(-1);
                if ( reason != 'create' )updateUI();
	  }
	});
   }
}
catch( err ) {
  document.getElementById('container0').innerHTML = `<p>audioMotion-analyzer failed with error: ${ err.code ? '<strong>' + err.code + '</strong>' : '' } <em>${ err.code ? err.message : err }</em></p>`;
}

Cette partie peut s’interpréter de la manière suivante c’est le premier objet AudioMotionAnalyzer qui est attaché à la source audio, les autres se rattachent au premier via la propriété connectedSource[0]

Réf sur les API audio : https://webaudio.github.io/web-audio-api/