Etape 8

Exercice d'application : Un instrument de musique sur une page web

Le principe utilisé ici est très simple voire rudimentaire. J'ai enregistré une gamme chromatique (métronome à 60 et toutes les valeurs en blanches). En cliquant sur une zone de l'image le programme déclenche la lecture à une position correspondante (currentTime) du fichier son.

Pour ne pas me casser la tête j'ai utilisé un son de piano, mais j'aurais pu en choisir un autre. Pour l'image j'ai pris mon piano en photo.
(Il est beau, non ? Il date de l'époque où les éléphants n'avaient qu'un désir, se faire massacrer pour les doigts sensibles de nos immenses pianistes.)
Vous pourriez procéder de même avec un xylophone, un accordéon à boutons, un manche de guitare, voire utiliser une image distincte par note (doigté d'un instrument à vent) etc.
Les possibilités d'exploitation sont très grandes. Vous n'êtes limité que par votre imagination.

Rechargez le fichier page5a.html et enregistrez le sous page8.html. Comme vu dans l'étape précédente, la balise img permet d'insérer des images. Les formats d'image compatibles les plus utilisés sont :

le format gif pour les images avec un nombre limité de couleurs,
le format jpeg pour les photos.

Faisons un peu le ménage et transformons la deuxième balise input en balise img. Il s'agit d'obtenir ceci :

<!doctype html>
<html lang="fr">
<head>
<meta charset="UTF-8">
</head>
<body>
<audio src="gamme.wav" Id="lecteur1"></audio>
<p style="text-align:center;">
<input type="button" value="0.0" Id="compteur" style="width:50px;"/><br/>
<img src= "clavier.gif" />
</p>
<script type="text/javascript">
var pos;
var lecteur=document.getElementById("lecteur1");
function lecture()
{
lecteur.play();
}
</script>
</body>
</html>

Sur l'image du clavier nous allons déterminer des zones sensibles au clic de souris. A chaque zone va correspondre une note.
Pour cela nous utilisons une balise appelée map (carte) et pour chaque zone délimitée une balise area (aire) :
shape désigne la forme de la zone (ici un rectangle) ; coords sont les coordonnées horizontales et verticales des coins en haut à gauche et en bas à droite du rectangle.
On retrouve le comportement onClick qui déclenche la lecture de la note. Cette fois-ci nous allons passer un paramètre (le nombre entre parenthèse) à la fonction lecture. Il s'agit tout simplement de la position de la note en secondes (currentTime) dans le fichier son.
Copiez-collez le code qui suit à la place de la balise img.

<br/>
<img src="clavier.gif" usemap="#clavier"/>
<map name="clavier">
<area shape="rect" coords="5,190,49,290" onClick="lecture(0);">
<area shape="rect" coords="50,190,94,290" onClick="lecture(2);">
<area shape="rect" coords="95,190,139,290" onClick="lecture(4);">
<area shape="rect" coords="140,190,184,290" onClick="lecture(5);">
<area shape="rect" coords="185,190,229,290" onClick="lecture(7);">
<area shape="rect" coords="230,190,274,290" onClick="lecture(9);">
<area shape="rect" coords="275,190,319,290" onClick="lecture(11);">
<area shape="rect" coords="320,190,364,290" onClick="lecture(12);">
<area shape="rect" coords="365,190,409,290" onClick="lecture(14);">
<area shape="rect" coords="410,190,454,290" onClick="lecture(16);">
<area shape="rect" coords="455,190,499,290" onClick="lecture(17);">
<area shape="rect" coords="500,190,544,290" onClick="lecture(19);">
<area shape="rect" coords="25,5,60,189" onClick="lecture(1);">
<area shape="rect" coords="79,5,114,189" onClick="lecture(3);">
<area shape="rect" coords="158,5,193,189" onClick="lecture(6);">
<area shape="rect" coords="212,5,247,189" onClick="lecture(8);">
<area shape="rect" coords="266,5,301,189" onClick="lecture(10);">
<area shape="rect" coords="345,5,380,189" onClick="lecture(13);">
<area shape="rect" coords="399,5,434,189" onClick="lecture(15);">
<area shape="rect" coords="478,5,513,189" onClick="lecture(18);">
</map>

Il s'agit également de modifier la fonction lecture c'est-à-dire :

La variable idTemp permet d'interrompre une temporisation en cours pour éviter de couper la ou les notes suivantes.
Nous plaçons la ligne clearTimeout(idTemp); en début de fonction.

Allez, un dernier effort. Ça serait sympa si le bouton au-dessus de l'image affichait le nom des notes cliqués.
Comme le navigateur ne connaît pas le solfège il faut commencer par le lui apprendre. Pour cela nous allons créer un tableau de valeurs de notes à placer immédiatement après la balise <script>. Ne vous en faites pas s'il se produit un passage à la ligne mais n'insérez pas vous-même de retour chariot !

var nom_notes=new Array("do3","do#3","ré3","mib3","mi3","fa3","fa#3","sol3","sol#3","la3","sib3","si3","do4","do#4","ré4","mib4","mi4","fa4","fa#4","sol4");

Les différentes notes correspondent chacune à un indice [entre crochets] différent :
nom_notes[0] retourne do3
nom_notes[1] retourne do#3
etc. On rajoute la ligne suivante dans la fonction lecture(pos):
document.getElementById('compteur').value=nom_notes[pos];
Ça devrait le faire
...
Ah, ben non ! Ça marche partout sauf sous Firefox Android !"


C'est currentTime qui coince lorsque le lecteur n'a pas démarré une première fois.
On rajoute donc encore 2 lignes avant la fonction lecture :
lecteur.play();
idTemp=setTimeout("lecteur.pause();", 50);

Au chargement de la page le lecteur va démarrer et s'arrêter 50ms après.

Voici le code complet du script :

var nom_notes=new Array("do3","do#3","ré3","mib3","mi3","fa3","fa#3","sol3","sol#3","la3","sib3","si3","do4","do#4","ré4","mib4","mi4","fa4","fa#4","sol4");
var pos;
var lecteur=document.getElementById("lecteur1");
var idTemp;
lecteur.play();
idTemp=setTimeout("lecteur.pause();", 50);

function lecture(pos)
    {
    clearTimeout(idTemp);
    lecteur.currentTime=pos*2;
    lecteur.play();
    idTemp=setTimeout("lecteur.pause();",1920);
    document.getElementById("compteur").value=nom_notes[pos];
    }

A vous de jouer !
Pour voir le résultat cliquez sur l'image :       (Pour le code complet voir la source de l'exemple 8 fourni)