Un oscilloscope1 est un instrument de mesure destiné à visualiser un signal électrique, le plus souvent variable au cours du temps.
Il est utilisé par de nombreux scientifiques afin de visualiser soit des tensions électriques, soit diverses autres grandeurs physiques préalablement transformées en tension au moyen d'un convertisseur adapté ou de capteurs. La courbe de rendu d'un oscilloscope est appelée oscillogramme.Il existe deux sorte d'oscilloscope: Analogique et celle que nous verrons Numérique.
- L'analogique : utilise directement un multiple de la tension d'entrée pour produire la déviation du spot.
- Le Numérique: quand à lui transforme préalablement pour un traitement futur, la tension d'entrée en nombre. L'affichage est reconstruit après coup. Ici nous récupérons le spectre du signal pour générer l'oscillogramme.
L'API est paru en 2010, son principe est assez simple : il prends des objets audioNode de façon arbitraire. Chaque noeud possède une entrée et/ou une sortie. Le noeud d'entrée ne possède qu'une sortie alors qu'un noeud de sortie ne possède qu'une entrée (== destination). On peut placer différents noeuds entre le noeud Source et le noeud de Destination. Ce principe est appelé 'routage' et cela se produit dans un 'audioContext'.
Un son est constitué d'une série d'ondes, vibrations d'air très fines, qui oscillent selon des fréquences généralement irrégulières, variables dans le temps. L'oreille humaine détecte des variations de fréquences sonores entre 20Hz et 20Khz.
Le spectre correspond la longueur > [intervalle] à analyser (temps d'une piste par exemple).
L'analyseur de spectre sonore va donc re-découper la composition spectrale du signal audio produit en tranches de fréquences, de 20Hz à 20KHz, mais au lieu de modifier le volume sur ces tranches, il va finement restituer une courbe graphique tracée à partir du volume effectivement détecté sur chacune des plages analysées.
Les résultats se cantonnent toujours à la plage dynamique de l'audition humaine de 20Hz à 20KHz. Cela peut être utile dans l'analyse du caractère de la musique et en notant si certaines fréquences sont dominante ou manquantes au sein d'un mix. spectre == styles de spectrogrammes proposés sont variables
SHEMAS
ENTRÉE NOEUDS SORTIE/RENDER
--------------- ---------------- --------------------------------
| MP3 / MIC | × ===> × | ANALYSER/GAIN | × ===> × | HAUT-PARLEUR / OSCILLO RENDU |
--------------- ---------------- --------------------------------
La doc du W3C a subit plusieurs moutures depuis ça publication du 15 Décembre 2011, 5 précisément.
Le temps a pousser à sécurser le web. Les éléments audios étaient une failles à gérer. Les HTMLMediaElement permettent d'accéder à des sources d'origine différentes en les analysant. Parfois cela crée une perte d'information si un script d'une origine inspect celle d'une autre origine. C'est pour ces conditions que nous utilisons un server (local ici:lite-server) afin de ne pas lever les panneaux d'alertes de Chrome par exemple avec les autorisations CORs-ross-origine qui ne permettent pas de lire un fichier contenant des audioELements.
Pour créer l'oscilloscope et pour son bon fonctionnement il est nécesaire de préparer plusieur outils:
$ lite-server je vous épargne ça: téléchargez le script Shell suivant ("enregistrer-sous"): telecharger le script
une fois téléchargé lancez le terminal et aller dans le répertoire dans lequel vous avez enregistré le fichier.sh et lancz la commande suivante :
$ ./screatoscillo.sh il vous créera dans votre répertoire ./Documents un dossier /createOscillo/
en premier lieu on construit la structure du html: ouvrez le fichier $atom index.html, il se présentera comme le suivant :
var audio = new Audio();
audio.src = PlayList[0].src; // './mp3/jpetelesplombs.mp3'
audio.controls = true;
audio.loop = false;
window.addEventListener("load", initMP3, true);
var canvas,
ctx,
source,
context,
analyser,
fbc_array,
bars,
bar_x,
bar_width,
bar_height;
function initMp3(){
document.getElementById('audio_box').appendChild(audio).setAttribute('id', 'audioOscilo');
window.AudioContext = window.AudioContext ||
window.webkitAudioContext;
context = new AudioContext();
analyser = context.createAnalyser()
canvas = document.getElementById('analyser_render');
ctx = canvas.getContext('2d');
source = context.createMediaElementSource(audio);
source.connect(analyser);
analyser.connect(context.destination);
La méthode window.requestAnimationFrame() notifie le navigateur que l'on souhaite exécuter une animation et demande que celui-ci exécute une fonction spécifique de mise à jour de l'animation, avant le prochain rafraîchissement du navigateur. Cette méthode prend comme argument un callback qui sera appelé avant le rafraîchissement du navigateur.
Note pour appeler l'animation suivant: Si l'on veut animer une nouvelle animation lors du prochain rafraichissement on rappele la méthode requestAnimFrame(). IL faut paramétrer le callback à 60/s, cela est dû au paramètre de rafraîssement de l'écran LCD de référence qui est en général égal à 60Hz
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60); // rappel
};
})();
window.requestAnimationFrame(frameLooper);
La propriété frequencyBinCount de l'objet AnalyserNode est un nombre entier non signé équivalent à la moitié la taille de la FFT. Il correspond en général au nombre de valeurs que l'on aurat à manipuler pour la visualisation.
fbc_array = new Uint8Array(analyser.frequencyBinCount);
La méthode getByteFrequencyData() de l'objet AnalyserNode copie les données de fréquence dans le Uint8Array (tableau d'entiers non-signés) passé en argument. Si le tableau a moins d'éléments que AnalyserNode.frequencyBinCount, les excédants sont supprimés; s'il en a davantage, les excédants sont ignorés.
analyser.getByteFrequencyData(fbc_array);
// tableau des données piste
var PlayList = [
{track: 1, artist: "Rihanna", album: "Anti", title:"Needed Me", src: "./mp3/neededme.mp3", imgsrc: "./img/neededme.jpg" }, // 0
{track: 2, artist: "Young Money", album: "Rise Of An Empire", title:"Senile", src: "./mp3/senile.mp3", imgsrc: "./img/senile.jpg" } , // 1
{track: 3, artist: "Disiz la peste", album: "Le Poisson Rouge", title:"J'pète Les Plombs", src: "./mp3/jpetelesplombs.mp3", imgsrc: "./img/jpetelesplombs.jpg" }, // 2
{track: 4, artist: "Bjork", album: "Homogenic", title:"Joga", src: "./mp3/joga.mp3", imgsrc: "./img/joga.jpg" }, // 4
{track: 5, artist: "Yemi Alade", album: "King of Queens", title:"Johnny", src: "./mp3/johnny.mp3", imgsrc: "./img/johnny.jpg" },// 5
//{track: 6, artist: "Midnite", album: "Unpolished", title:"Don't Move", src: "./mp3/dontmove.mp3", imgsrc: "./img/dontmove.jpg" }, // 6 NE PAS DECOMMENTER
{track: 7, artist: "Le Peuple De L'Herbe", album: "P.H Test/Two", title:"No Escape", src: "./mp3/noescape.mp3", imgsrc: "./img/noescape.jpg" },// 7
{track: 8, artist: "Vanessa Da Mata", album: "Good Luck ft Ben Harper", title:"Boa Sorte", src: "./mp3/boasorte.mp3", imgsrc: "./img/boasorte.jpg" }, // 8
{track: 9, artist: "Rihanna", album: "Good Girl Gone Bad", title:"Rehab", src: "./mp3/rehab.mp3", imgsrc: "./img/rehab.jpg" },// 9
{track: 10, artist: "Oscar Chavez", album: "Desde Mexico Para Siempre Che", title:"Hasta Siempre Comandante Che Guevara", src: "./mp3/hastasiemprecomandantecheguevara.mp3", imgsrc: "./img/hastasiemprecomandantecheguevara.jpg" }, // 10
];
console.log(PlayList);
/*---------------- AUDIO API----------------*/
//Access-Control-Allow-Credentials: true; TOFIXED
var audio = new Audio();
audio.src = PlayList[0].src; // on cré la source en récupérant la proprité 'src' >> source.mp3 dans le tableau de propriété.
audio.controls = true; // on paramètre le controls du médias pour pouvoir le récupérer et le designer sois-même
audio.loop = false; // DÉSACTIVER LE LOOP car c'est par défaut
//audio.crossorigin = "anonymous";
// DECLARATION DES VARIABLES QUI VONT ETRE UTILISÉS
var canvas, ctx, source, context, analyser, fbc_array, bars, bar_x, bar_width, bar_height;
// APPELLE DE LA FONCTION INIALISATRICE DU MP3
window.addEventListener("load", initMP3, true);
function initMP3(){
// on récupère de l'id de l'audio_box
document.getElementById('audio_box').appendChild(audio).setAttribute('id', 'audioOscilo');
// CREATION DE L'AUDIOCONTEXT
window.AudioContext = window.AudioContext ||
window.webkitAudioContext;
context = new AudioContext();
analyser = context.createAnalyser();
canvas = document.getElementById('analyser_render');
ctx = canvas.getContext('2d');
// CONNEXION DE DE LA SOURCE VERS L'ANALYSEUR
source = context.createMediaElementSource(audio);
source.connect(analyser);
// on connect l'analyseur à la destination
analyser.connect(context.destination);
playRandom(); // intègre les options de lecture
frameLooper();
};
// APPELER FRAME
function frameLooper(){
// ON REQUETE SUR LE CADRE DE L'ANIMATION.
// webkit pour l'adaption des diff browsers
//
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60); // rappel
};
})();
window.requestAnimationFrame(frameLooper);
fbc_array = new Uint8Array(analyser.frequencyBinCount);
analyser.getByteFrequencyData(fbc_array);
ctx.clearRect(0, 0, canvas.width, canvas.height);
// création du style
ctx.fillStyle = "#ff6666";
// création du diagramme en bars.
bars = 50; // nombre de bars sur l'abscisse
for (var i = 0; i < bars; i++){
bar_x = i * 10;
bar_width = 8; // largeur des bars
bar_height = -(fbc_array[i]/2);
ctx.fillRect(bar_x, canvas.height, bar_width, bar_height);
};
};
/*---------------- PLAYRANDOM---------- */