Un instrument à deux mains avec roues d’accords et clavier mélodique, activés du bout des doigts devant la webcam.
Vue d’ensemble
Touch music propose deux modes de jeu à la webcam. En mode « Accords à deux mains », chaque main pointe une roue superposée à l’image : la roue gauche choisit la fondamentale (sept lettres, ou les douze degrés chromatiques en mode avancé, centre = silence), la roue droite choisit la qualité de l’accord (majeur, majeur 7, dominante, sus4, mineur, mineur 7, diminué, augmenté), le tout désigné du bout de l’index. En mode « Mélodie + accords », la main droite joue un clavier horizontal mélodique en pinçant pouce et index pour déclencher chaque note, pendant que la main gauche pilote une roue d’accords dont la distance au centre règle le volume et le pincement bascule majeur/mineur.
C’est une réplique fidèle, en vanilla JS, du fonctionnement d’un instrument gestuel de référence trouvé en ligne — jusqu’aux mêmes seuils de détection — mais entièrement recomposée sur un unique canvas (vidéo, roues, mains et grande note centrale) pour que l’enregistrement vidéo capture exactement ce qui est affiché à l’écran.
Fonctionnalités
- Mode Accords à deux mains — roue gauche pour la fondamentale, roue droite pour la qualité de l’accord, visées à l’index.
- Mode Mélodie + accords — clavier mélodique horizontal joué au pincement pouce-index (main droite), roue d’accords en volume/majeur-mineur (main gauche).
- Attribution des mains par position à l’écran — la main la plus à gauche joue toujours les accords, plus robuste qu’une détection de latéralité.
- Mode « Simple » — bascule entre sept lettres diatoniques ou les douze degrés chromatiques sur la roue de fondamentale.
- Enregistrement vidéo — capture du canvas et du son joué, exportés en vidéo téléchargeable.
- Mode performance — masque HUD et contrôles pour ne garder que l’instrument à l’écran, plein écran et wake-lock pour empêcher la mise en veille en jouant.
Sous le capot
Le suivi des mains repose sur MediaPipe Hands ; plutôt que de se fier à la latéralité détectée par le modèle (peu fiable selon l’orientation), l’application assigne les rôles simplement selon la position horizontale des mains à l’écran. Les repères de chaque main passent par la même transformation de recadrage « cover » que la vidéo miroir, pour que le pointage à l’index reste précis jusqu’aux bords de l’image — un détail que la référence originale ne traite qu’approximativement.
La synthèse audio est entièrement réécrite en Web Audio natif (la référence utilisait Tone.js) : la voix mélodique passe par un oscillateur unique suivi d’un filtre passe-bas, les accords par quatre oscillateurs en onde triangle sommés avant leur propre filtre — avec un lissage continu des paramètres à chaque frame pour éviter les sauts de volume ou de hauteur. La détection de pincement compare la distance pouce-index à la taille de la paume pour rester stable quelle que soit la distance à la caméra, avec une hystérésis sur les roues pour éviter que le geste hésite entre deux secteurs adjacents.
Contrôles
| Touche / geste | Action |
|---|---|
| F | Plein écran |
| H | Mode performance (masque HUD/contrôles/aide, les roues restent affichées) |
| R | Démarre / arrête l’enregistrement vidéo |
| Pincement pouce-index | Déclenche une note (clavier mélodique) ou bascule majeur/mineur (roue d’accords) |
| Pointage à l’index | Vise un secteur de roue en mode Accords à deux mains |
Stack technique
- Vanilla JS (modules ES6), zéro framework
- MediaPipe Hands — suivi des deux mains en temps réel
- Web Audio API native — synthèse mélodique et d’accords, sans librairie tierce
- Canvas 2D — composition unique de la vidéo, des roues, des mains et de la note affichée
- canvas.captureStream + MediaRecorder — enregistrement vidéo avec le son du synthé
Cas d’usage
Un instrument gestuel à deux mains pour improviser des accords et des mélodies sans contrôleur physique, une démo portfolio de suivi de mains double, ou un jouet musical à filmer en mode performance.
Deux mains, deux roues, un instrument entier tenu dans le vide devant l’écran.



