v2.4 : choix du clavier azerty ou qwerty
This commit is contained in:
+120
@@ -0,0 +1,120 @@
|
||||
# Journal des versions — _chordlab
|
||||
|
||||
Historique des ajouts, modifications et corrections. Les versions les plus récentes figurent en haut.
|
||||
|
||||
Conventions :
|
||||
**Ajouté** (nouvelle fonctionnalité) · **Modifié** (comportement existant changé) · **Corrigé** (bug) · **Retiré** (fonctionnalité supprimée) · **Documentation**
|
||||
|
||||
---
|
||||
|
||||
## [2.4] — dispositions clavier QWERTY et AZERTY
|
||||
|
||||
### Ajouté
|
||||
- **Sélecteur de disposition clavier QWERTY / AZERTY**, placé sous le clavier de l'application. Jusqu'ici la correspondance des touches était figée en QWERTY : sur un clavier AZERTY, les deux touches concernées par la divergence sont précisément **A→Q (Do) et W→Z (Do dièse)**, ce qui rendait le jeu au clavier physique impraticable. Les dix autres touches (S E D F T G Y H U J) sont communes aux deux dispositions.
|
||||
- **Détection au démarrage** d'après la langue du navigateur : AZERTY si la langue commence par `fr`, QWERTY sinon. Il s'agit d'une heuristique, le sélecteur permet de la corriger en un clic.
|
||||
- La disposition retenue est **enregistrée dans les sessions `.json`** et restaurée au chargement.
|
||||
- La ligne d'aide sous le clavier affiche les lettres de la disposition active.
|
||||
|
||||
### Modifié
|
||||
- La table de correspondance unique est remplacée par deux tables commutables ; les gestionnaires d'événements clavier lisent la disposition courante à chaque frappe.
|
||||
|
||||
### Documentation
|
||||
- Manuels FR et EN : section « Raccourcis clavier » complétée, figure 12 montrant les deux dispositions côte à côte avec les touches divergentes mises en évidence.
|
||||
- Tutoriel Markdown et README mis à jour.
|
||||
|
||||
---
|
||||
|
||||
## [2.3] — correctif basse slash
|
||||
|
||||
### Corrigé
|
||||
- **Le sélecteur « basse / » restait sans effet en Key Mode.** La basse jouait systématiquement la fondamentale, quel que soit le choix (tierce, quinte, septième). Le calcul du renversement reconstruisait l'accord à partir du type et des tensions ; or en Key Mode l'accord provient de l'harmonisation diatonique et ne passe pas par ce chemin. Le bug était invisible hors Key Mode, ce qui le rendait intermittent selon la configuration.
|
||||
*Correction :* `slashInterval()` et `bassNoteFor()` remplacés par `slashIntervalFrom()` et `bassFromRaw()`, qui dérivent la note de basse des **notes réelles de l'accord** — valable dans les deux modes.
|
||||
- **Basse forcée sur la fondamentale dans les progressions générées.** Le chargement d'un preset et le bouton *✦ suggérer* écrivaient la basse en dur, ignorant le sélecteur ainsi que le nom slash (`C/E`) dans le libellé du slot.
|
||||
- Le nom d'accord slash s'affiche désormais correctement partout, y compris en Key Mode (`C/E`, `Dm/F`, `G7*/F`).
|
||||
|
||||
### Comportement à connaître
|
||||
- Demander la **septième** sur une triade (accord sans septième) fait retomber la basse sur la fondamentale plutôt que d'inventer une note. Activer la tension `m7` ou `M7` pour l'obtenir.
|
||||
|
||||
---
|
||||
|
||||
## [2.2] — simplification de la basse
|
||||
|
||||
### Retiré
|
||||
- **Les 10 rythmiques de basse** introduites en 2.1 (sélecteur *rythme B*, affichage LCD associé, moteur `renderBassEvents`, persistance en session). La basse revient à une **note tenue** sur toute la durée de l'accord.
|
||||
|
||||
### Conservé
|
||||
- Les durées libres de 1 à 16 temps par slot (voir 2.1). Les sessions `.json` enregistrées en 2.1 se rechargent sans erreur : le champ de rythme éventuel est ignoré.
|
||||
|
||||
---
|
||||
|
||||
## [2.1] — rythmiques de basse et durées libres
|
||||
|
||||
### Ajouté
|
||||
- **10 rythmiques de basse** : tenue, noires, croches, contretemps, octaves alternées, fondamentale–quinte, boogie, tresillo 3–3–2, pompe, aléatoire probabiliste. Rendues à l'identique en audition, MIDI live et export `.mid`, avec bornage de chaque frappe à la fin du slot.
|
||||
- **Durée de slot réglable de 1 à 16 temps** au pas de 1, via des boutons `−` / `+`. Rend possibles les accords de 3, 5 ou 7 temps et les mesures asymétriques.
|
||||
|
||||
### Modifié
|
||||
- Le badge de durée cyclique (4 → 8 → 2 → 1 temps) est remplacé par les boutons `−` / `+`.
|
||||
- Chargement de session : les durées sont bornées entre 1 et 16 pour garantir la compatibilité ascendante.
|
||||
|
||||
---
|
||||
|
||||
## [2.0] — refonte harmonique
|
||||
|
||||
### Ajouté
|
||||
- **Types d'accords portés de 4 à 8**, tous en boutons directs : Dim, Min, Maj, Aug, Sus2, Sus4, power chord (5), m♭6.
|
||||
- **Tensions étendues** : ♭9, ♯9, 11, ♯11, 13 s'ajoutent aux 6, m7, M7, 9.
|
||||
- **Altérations** : ♭5 et ♯5 (qui *remplacent* la quinte au lieu de s'y ajouter), et `no3` pour retirer la tierce.
|
||||
- **Drop voicings** appliqués après la rotation : close, drop 2, drop 3, drop 2+4, spread.
|
||||
- **Accords slash** : basse sur la fondamentale, la tierce, la quinte ou la septième, avec détection de l'intervalle correct selon le type d'accord et affichage `C/E` sur le LCD.
|
||||
- **Voice-leading** : `VL AUTO` re-voice chaque accord ajouté pour minimiser le déplacement des voix ; le bouton `⇄ voice-leading` optimise toute la progression d'un coup.
|
||||
- **Suggestion harmonique** (`✦ suggérer`) : propose l'accord suivant via une table d'harmonie fonctionnelle, dans la tonalité courante.
|
||||
- **Key Mode porté à 8 gammes** : majeur, mineur naturel, mineur harmonique, dorien, phrygien, lydien, mixolydien, locrien. Harmonisation diatonique jusqu'à la 13e.
|
||||
- **Modes de performance** : block, strum ↑/↓, harp, arpèges ↑/↓/↕/aléatoire, à 1/8, 1/16 ou 1/32. Rendus dans l'audio, le MIDI live **et** l'export `.mid` (rendu désactivable).
|
||||
- **Humanisation** optionnelle des vélocités (±10) et du timing (±15 ms).
|
||||
- **Durée individuelle par slot** et réordonnancement des slots (`‹` / `›`).
|
||||
- **Sauvegarde et chargement de session** en fichier `.json` (réglages complets + progression). Aucun stockage navigateur : le fichier est l'unique persistance.
|
||||
- Preset supplémentaire : cycle des quintes.
|
||||
|
||||
### Modifié
|
||||
- Les types d'accords passent de la sélection multiple avec combinaisons implicites à une **sélection unique** : Aug et Sus2 deviennent des boutons dédiés au lieu de résulter d'une combinaison.
|
||||
- Le moteur de rendu est unifié : une fonction `renderEvents()` unique alimente l'audio, le MIDI live et l'export, ce qui garantit que les trois sorties sont identiques.
|
||||
- Nommage des accords enrichi (`Cdim7`, `Cø7`, `C7(♭9)`, `Cadd9`, `Cmaj7(♯11)`…).
|
||||
|
||||
### Corrigé
|
||||
- Nommage des accords `add9`, `add11` et `add13` : ils s'écrivaient entre parenthèses comme des tensions alors qu'aucune septième n'était présente.
|
||||
|
||||
---
|
||||
|
||||
## [1.0] — version initiale
|
||||
|
||||
### Ajouté
|
||||
- Construction d'accords par description : clavier une octave pour la fondamentale, 4 types (Dim, Min, Maj, Sus) et 4 extensions empilables (6, m7, M7, 9).
|
||||
- Combinaisons implicites : `Dim + Maj` = augmenté, `Min + Sus` = sus2.
|
||||
- **Knob de voicing rotatif ±8** : chaque cran remonte la note la plus grave d'une octave (ou descend la plus aiguë).
|
||||
- **Key Mode** sur deux gammes (majeur, mineur naturel) avec grisage des touches hors tonalité.
|
||||
- Moteur de basse sur canal MIDI séparé (−1 / −2 octaves).
|
||||
- Rack de progression avec ajout (`ADD` / barre espace), lecture, boucle et BPM réglable.
|
||||
- 7 presets de cadences générés dans la tonalité choisie.
|
||||
- **Sortie Web MIDI live** avec canaux distincts pour les accords et la basse.
|
||||
- **Export `.mid`** : writer MIDI maison, format 1, PPQ 480, tempo intégré, une ou deux pistes.
|
||||
- Synthé de pré-écoute intégré (Web Audio : deux dents de scie désaccordées, filtre passe-bas ; onde triangle pour la basse).
|
||||
|
||||
---
|
||||
|
||||
## Documentation
|
||||
|
||||
| Version | Élément |
|
||||
|---|---|
|
||||
| 2.3 | Manuel visuel traduit en anglais (`tuto_en.html`), sélecteur de langue entre les deux manuels, liens vers les manuels ajoutés dans le pied de page de l'application |
|
||||
| 2.2 | Manuel visuel HTML (`tuto.html`) : 10 sections et 12 figures SVG (cartographie de l'interface, rotation du voicing, drop voicings, Key Mode, anatomie d'un slot, voice-leading, modes de performance en piano-roll, routage MIDI, flux d'export, raccourcis) |
|
||||
| 2.0 | `README.md`, tutoriel d'utilisation Markdown, tutoriel de déploiement Coolify (dépôt Git → build pack statique → Traefik, procédure de mise à jour et table de dépannage) |
|
||||
|
||||
---
|
||||
|
||||
## Notes techniques transversales
|
||||
|
||||
- **Aucune dépendance externe** depuis la version 1.0 : JavaScript natif, Web Audio API, Web MIDI API, FileReader. Un seul fichier HTML.
|
||||
- **Aucun stockage navigateur** (ni `localStorage`, ni `sessionStorage`) : l'état ne persiste que par les fichiers de session `.json` exportés.
|
||||
- **Web MIDI exige un contexte sécurisé** (`https://` ou `localhost`). En `file://`, l'audio et l'export fonctionnent mais la sortie MIDI live est bloquée par le navigateur. Safari ne supporte pas Web MIDI.
|
||||
- Canaux MIDI par défaut : accords sur le canal 3, basse sur le canal 5.
|
||||
@@ -1,6 +1,6 @@
|
||||
# _chordlab ORC·v2
|
||||
|
||||
Générateur d'accords et de progressions harmoniques dans le navigateur, inspiré de la logique du **Telepathic Instruments Orchid ORC-1** (implémentation indépendante, étendue). Un seul fichier HTML, zéro dépendance, zéro backend.
|
||||
Générateur d'accords et de progressions harmoniques dans le navigateur. Un seul fichier HTML, zéro dépendance, zéro backend.
|
||||
|
||||
> Construis un accord avec un doigt, façonne son voicing, chaîne une progression, envoie-la en MIDI live vers ton studio dawless ou exporte-la en `.mid` pour ton DAW.
|
||||
|
||||
@@ -9,7 +9,7 @@ Générateur d'accords et de progressions harmoniques dans le navigateur, inspir
|
||||
## Fonctionnalités
|
||||
|
||||
**Construction d'accords**
|
||||
- Clavier une octave pour la fondamentale (souris, tactile ou clavier PC)
|
||||
- Clavier une octave pour la fondamentale (souris, tactile ou clavier PC, dispositions **QWERTY et AZERTY**)
|
||||
- 8 types d'accords : Dim · Min · Maj · Aug · Sus2 · Sus4 · 5 (power chord) · m♭6
|
||||
- 12 modificateurs empilables : 6 · m7 · M7 · 9 · ♭9 · ♯9 · 11 · ♯11 · 13 · ♭5 · ♯5 · no3
|
||||
- Nommage automatique (Cm7, Cdim7, Cø7, C7(♭9)…) affiché sur le LCD
|
||||
@@ -65,8 +65,10 @@ Modifiables dans le panneau **MIDI out (live)**. L'export `.mid` reprend les mê
|
||||
```
|
||||
chordlab/
|
||||
├── index.html # l'application complète
|
||||
├── tuto.html # manuel visuel (accessible à /tuto.html)
|
||||
├── tuto.html # manuel visuel FR (accessible à /tuto.html)
|
||||
├── tuto_en.html # manuel visuel EN (accessible à /tuto_en.html)
|
||||
├── README.md
|
||||
├── CHANGELOG.md # journal des versions
|
||||
└── docs/
|
||||
├── TUTORIEL_UTILISATION.md # guide utilisateur complet
|
||||
└── TUTORIEL_DEPLOIEMENT_COOLIFY.md # mise en ligne + mises à jour
|
||||
@@ -86,12 +88,12 @@ chordlab/
|
||||
|
||||
## Notes de conception
|
||||
|
||||
- Le moteur de voicing reproduit le principe du dial de l'Orchid : chaque cran fait une **rotation** de l'accord (la note la plus grave remonte d'une octave, ou l'inverse), sur ±8 crans.
|
||||
- Le moteur de voicing procède par **rotation** : chaque cran remonte la note la plus grave d'une octave (ou descend la plus aiguë), sur ±8 crans.
|
||||
- Les combinaisons classiques tombent naturellement : `DIM + 6 = dim7`, `DIM + m7 = ø7` (demi-diminué), `MAJ + m7 + ♯9 = accord Hendrix`.
|
||||
- Empiler `m7 + M7` affiche `WTF?` sur le LCD — clin d'œil assumé à l'Orchid.
|
||||
- Empiler `m7 + M7` affiche `WTF?` sur le LCD : la combinaison est musicalement contradictoire, mais rien ne l'interdit.
|
||||
- Le voice-leading minimise la somme des déplacements de voix entre deux accords en testant les rotations de voicing candidates.
|
||||
- Aucune donnée n'est stockée dans le navigateur : la persistance passe exclusivement par les fichiers `.json` de session.
|
||||
|
||||
## Licence & crédit
|
||||
|
||||
Projet personnel underscorelab / leradiologue. La logique d'accords s'inspire du concept de l'Orchid ORC-1 de Telepathic Instruments, sans réutiliser ni code, ni sons, ni assets de l'instrument original.
|
||||
Projet personnel underscorelab / leradiologue. Code original, sans dépendance ni asset tiers.
|
||||
|
||||
@@ -28,7 +28,7 @@ Le **LCD** est votre référence permanente : il affiche le nom de l'accord cour
|
||||
|
||||
## 2. Jouer un accord
|
||||
|
||||
Le principe fondamental, hérité de l'Orchid : **vous ne jouez jamais les notes de l'accord, vous le décrivez**.
|
||||
Le principe fondamental : **vous ne jouez jamais les notes de l'accord, vous le décrivez**.
|
||||
|
||||
1. **Type** — un seul actif à la fois (LED allumée). MAJ est sélectionné au démarrage.
|
||||
2. **Fondamentale** — cliquez une touche du clavier, ou utilisez le clavier PC : `A W S E D F T G Y H U J` = C C# D D# E F F# G G# A A# B.
|
||||
@@ -210,9 +210,12 @@ L'application ne stocke rien dans le navigateur : le fichier `.json` est l'uniqu
|
||||
|
||||
## 11. Raccourcis clavier
|
||||
|
||||
Un sélecteur **QWERTY / AZERTY** se trouve sous le clavier de l'application. Seules deux touches diffèrent entre les deux dispositions, mais ce sont le Do et le Do dièse. La disposition est choisie au démarrage d'après la langue du navigateur, modifiable d'un clic, et conservée dans les sessions `.json`.
|
||||
|
||||
| Touche | Action |
|
||||
|---|---|
|
||||
| A W S E D F T G Y H U J | fondamentales C → B |
|
||||
| A W S E D F T G Y H U J | fondamentales C → B (QWERTY) |
|
||||
| Q Z S E D F T G Y H U J | fondamentales C → B (AZERTY) |
|
||||
| Espace | ADD (ajouter l'accord courant à la progression) |
|
||||
| ← / → | voicing −1 / +1 |
|
||||
| ↑ ↓ ← → (knob focalisé) | voicing fin |
|
||||
|
||||
+69
-9
@@ -136,7 +136,18 @@
|
||||
}
|
||||
.bkey:active,.bkey.pressed{background:#3A362C}
|
||||
.bkey.outkey{background:#4B4739}
|
||||
.kbd-hint{font-size:.55rem;color:var(--silk-light);opacity:.4;margin-top:.5rem;letter-spacing:.08em}
|
||||
.kbd-hint{font-size:.55rem;color:var(--silk-light);opacity:.4;letter-spacing:.08em}
|
||||
.kbd-foot{display:flex;align-items:center;justify-content:space-between;gap:.6rem;margin-top:.5rem;flex-wrap:wrap}
|
||||
.seg{display:inline-flex;border:1px solid #4A4436;border-radius:6px;overflow:hidden;flex:none}
|
||||
.segbtn{
|
||||
background:var(--module-2);border:none;
|
||||
color:var(--silk-light);font-family:var(--mono);
|
||||
font-size:.55rem;letter-spacing:.1em;
|
||||
padding:.28rem .5rem;cursor:pointer;opacity:.5;
|
||||
}
|
||||
.segbtn + .segbtn{border-left:1px solid #4A4436}
|
||||
.segbtn.on{background:#4A4436;color:var(--led-on);opacity:1}
|
||||
.segbtn:focus-visible{outline:2px solid var(--led-on);outline-offset:-2px}
|
||||
|
||||
/* ---------- Colonne voicing ---------- */
|
||||
.side{display:flex;flex-direction:column;gap:.65rem}
|
||||
@@ -220,6 +231,15 @@
|
||||
}
|
||||
|
||||
footer{margin-top:1rem;font-size:.55rem;opacity:.5;letter-spacing:.1em;text-align:right}
|
||||
footer .doclink{
|
||||
color:var(--silk);text-decoration:none;
|
||||
border-bottom:1px solid rgba(64,58,47,.45);
|
||||
padding-bottom:1px;
|
||||
}
|
||||
footer .doclink:hover,footer .doclink:focus-visible{
|
||||
color:var(--accent);border-bottom-color:var(--accent);outline:none;
|
||||
}
|
||||
footer .docsep{margin:0 .35rem;opacity:.5}
|
||||
|
||||
@media (max-width:900px){
|
||||
.deck{grid-template-columns:1fr}
|
||||
@@ -234,7 +254,7 @@
|
||||
<body>
|
||||
<div class="unit">
|
||||
<header>
|
||||
<h1><span>_chordlab.v2</span></h1>
|
||||
<h1>_chordlab <span>ORC·v2</span></h1>
|
||||
<div class="sub">chord ideas machine · underscorelab / leradiologue</div>
|
||||
</header>
|
||||
|
||||
@@ -291,7 +311,12 @@
|
||||
<div class="mod kbd-mod">
|
||||
<h2>Root</h2>
|
||||
<div class="kbd" id="kbd"></div>
|
||||
<div class="kbd-hint">clavier PC : A W S E D F T G Y H U J · ␣ = ADD · ← → = voicing</div>
|
||||
<div class="kbd-foot">
|
||||
<span class="kbd-hint" id="kbdHint">clavier PC : A W S E D F T G Y H U J · ␣ = ADD · ← → = voicing</span>
|
||||
<span class="seg" role="group" aria-label="Disposition du clavier">
|
||||
<button class="segbtn" id="layQwerty" aria-pressed="false">QWERTY</button><button class="segbtn on" id="layAzerty" aria-pressed="true">AZERTY</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Voicing / drop / slash / bass / key -->
|
||||
@@ -435,7 +460,13 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer>_chordlab v2.3 · logique d'accords</footer>
|
||||
<footer>
|
||||
<a href="tuto.html" class="doclink">Manuel (FR)</a>
|
||||
<span class="docsep">·</span>
|
||||
<a href="tuto_en.html" class="doclink">Manual (EN)</a>
|
||||
<span class="docsep">·</span>
|
||||
_chordlab v2.4 · underscorelab / leradiologue
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
@@ -466,6 +497,7 @@ const state = {
|
||||
vlAuto:false,
|
||||
perf:"block", rate:0.25,
|
||||
humanize:false,
|
||||
layout:(navigator.language||"").toLowerCase().startsWith("fr") ? "azerty" : "qwerty",
|
||||
};
|
||||
|
||||
/* ---------- Moteur d'accords ---------- */
|
||||
@@ -875,6 +907,7 @@ function saveSession(){
|
||||
drop:state.drop, slash:state.slash, bass:state.bass, bassOct:state.bassOct,
|
||||
keyMode:state.keyMode, keyRoot:state.keyRoot, keyScale:state.keyScale,
|
||||
perf:state.perf, rate:state.rate, humanize:state.humanize,
|
||||
layout:state.layout,
|
||||
bpm:getBpm(), vlAuto:state.vlAuto,
|
||||
},
|
||||
progression:state.progression,
|
||||
@@ -905,6 +938,7 @@ function loadSession(file){
|
||||
state.perf=s.perf||"block";
|
||||
state.rate=s.rate||0.25;
|
||||
state.humanize=!!s.humanize;
|
||||
state.layout=(s.layout==="qwerty")?"qwerty":(s.layout==="azerty"?"azerty":state.layout);
|
||||
state.vlAuto=!!s.vlAuto;
|
||||
state.progression=Array.isArray(d.progression)?d.progression:[];
|
||||
state.progression.forEach(c=>{ c.beats=Math.max(1,Math.min(16,c.beats||4)); });
|
||||
@@ -927,6 +961,7 @@ function syncUiFromState(){
|
||||
$("keyScaleSel").value=state.keyScale;
|
||||
$("perfSel").value=state.perf; $("rateSel").value=state.rate;
|
||||
$("humanBtn").classList.toggle("on", state.humanize);
|
||||
setLayout(state.layout);
|
||||
$("vlBtn").classList.toggle("on", state.vlAuto);
|
||||
$("lcdDrop").textContent=state.drop.toUpperCase();
|
||||
$("lcdPerf").textContent=$("perfSel").selectedOptions[0].textContent.toUpperCase();
|
||||
@@ -1006,21 +1041,45 @@ kbdEl.addEventListener("pointerdown",ev=>{
|
||||
kbdEl.addEventListener("pointerup",ev=>{
|
||||
ev.target.classList&&ev.target.classList.remove("pressed");
|
||||
});
|
||||
const PCKEYS={a:0,w:1,s:2,e:3,d:4,f:5,t:6,g:7,y:8,h:9,u:10,j:11};
|
||||
/* Dispositions clavier : mêmes touches physiques, lettres différentes.
|
||||
Sur AZERTY, A→Q et W→Z ; le reste de la rangée est identique. */
|
||||
const KEYMAPS = {
|
||||
qwerty:{a:0,w:1,s:2,e:3,d:4,f:5,t:6,g:7,y:8,h:9,u:10,j:11},
|
||||
azerty:{q:0,z:1,s:2,e:3,d:4,f:5,t:6,g:7,y:8,h:9,u:10,j:11},
|
||||
};
|
||||
const KEYHINT = {
|
||||
qwerty:"clavier PC : A W S E D F T G Y H U J · ␣ = ADD · ← → = voicing",
|
||||
azerty:"clavier PC : Q Z S E D F T G Y H U J · ␣ = ADD · ← → = voicing",
|
||||
};
|
||||
function pcKeys(){ return KEYMAPS[state.layout]; }
|
||||
function setLayout(l, silent){
|
||||
state.layout = (l==="qwerty") ? "qwerty" : "azerty";
|
||||
const isQ = state.layout==="qwerty";
|
||||
$("layQwerty").classList.toggle("on", isQ);
|
||||
$("layAzerty").classList.toggle("on", !isQ);
|
||||
$("layQwerty").setAttribute("aria-pressed", isQ);
|
||||
$("layAzerty").setAttribute("aria-pressed", !isQ);
|
||||
$("kbdHint").textContent = KEYHINT[state.layout];
|
||||
}
|
||||
|
||||
window.addEventListener("keydown",ev=>{
|
||||
if (ev.repeat||ev.target.tagName==="INPUT"||ev.target.tagName==="SELECT") return;
|
||||
const k=ev.key.toLowerCase();
|
||||
if (k in PCKEYS){
|
||||
keyEls[PCKEYS[k]].classList.add("pressed");
|
||||
triggerChord(PCKEYS[k]);
|
||||
const map=pcKeys();
|
||||
if (k in map){
|
||||
keyEls[map[k]].classList.add("pressed");
|
||||
triggerChord(map[k]);
|
||||
} else if (ev.code==="Space"){ ev.preventDefault(); addToProgression(); }
|
||||
else if (ev.key==="ArrowRight"){ setVoicing(state.voicing+1); }
|
||||
else if (ev.key==="ArrowLeft"){ setVoicing(state.voicing-1); }
|
||||
});
|
||||
window.addEventListener("keyup",ev=>{
|
||||
const k=ev.key.toLowerCase();
|
||||
if (k in PCKEYS) keyEls[PCKEYS[k]].classList.remove("pressed");
|
||||
const map=pcKeys();
|
||||
if (k in map) keyEls[map[k]].classList.remove("pressed");
|
||||
});
|
||||
$("layQwerty").addEventListener("click",()=>setLayout("qwerty"));
|
||||
$("layAzerty").addEventListener("click",()=>setLayout("azerty"));
|
||||
|
||||
/* knob voicing */
|
||||
const knob=$("voicingKnob");
|
||||
@@ -1270,6 +1329,7 @@ $("fileInput").addEventListener("change",function(){
|
||||
|
||||
/* init */
|
||||
buildKeyboard();
|
||||
setLayout(state.layout);
|
||||
renderProgression();
|
||||
refreshKeyDimming();
|
||||
setVoicing(0,true);
|
||||
|
||||
@@ -149,9 +149,9 @@
|
||||
<div class="sheet">
|
||||
|
||||
<div class="cover">
|
||||
<div class="kicker">manuel d'utilisation · rev. 2.2</div>
|
||||
<div class="kicker">manuel d'utilisation · rev. 2.4 · <a href="tuto_en.html" style="color:var(--accent);text-decoration:none;border-bottom:1px solid var(--accent)">English version</a></div>
|
||||
<h1>_chordlab <em>ORC</em></h1>
|
||||
<p>Machine à accords et à progressions, inspirée de la logique de l'Orchid ORC-1. Le principe tient en une phrase : <strong>vous ne jouez pas les notes d'un accord, vous le décrivez</strong> — une fondamentale, un type, des tensions — et la machine fait le reste, jusqu'à vos synthés ou votre DAW.</p>
|
||||
<p>Machine à accords et à progressions. Le principe tient en une phrase : <strong>vous ne jouez pas les notes d'un accord, vous le décrivez</strong> — une fondamentale, un type, des tensions — et la machine fait le reste, jusqu'à vos synthés ou votre DAW.</p>
|
||||
</div>
|
||||
|
||||
<nav aria-label="Sommaire">
|
||||
@@ -696,12 +696,18 @@
|
||||
<!-- ============ 10 RACCOURCIS ============ -->
|
||||
<section id="s10">
|
||||
<div class="shead"><span class="num">10</span><h2>Raccourcis clavier</h2></div>
|
||||
<p>Les lettres suivent la disposition d'un clavier de piano. Un sélecteur <strong>QWERTY / AZERTY</strong> se trouve sous le clavier de l'application : il n'y a que deux touches de différence, mais ce sont le Do et le Do dièse, donc le bon réglage change tout. L'application choisit une disposition au démarrage d'après la langue du navigateur — corrigez-la d'un clic si besoin, le choix est conservé dans les sessions <code>.json</code>.</p>
|
||||
|
||||
<figure>
|
||||
<div style="text-align:center;padding:.4rem 0 .2rem">
|
||||
<div style="margin-bottom:.7rem">
|
||||
<div style="margin-bottom:.5rem">
|
||||
<span style="font-size:.55rem;color:var(--silk-light);opacity:.5;letter-spacing:.16em;display:block;margin-bottom:.25rem">QWERTY</span>
|
||||
<span class="keycap">A</span><span class="keycap">W</span><span class="keycap">S</span><span class="keycap">E</span><span class="keycap">D</span><span class="keycap">F</span><span class="keycap">T</span><span class="keycap">G</span><span class="keycap">Y</span><span class="keycap">H</span><span class="keycap">U</span><span class="keycap">J</span>
|
||||
<span style="font-size:.68rem;color:var(--silk-light);margin-left:.6rem">= C → B (les lettres suivent le clavier de piano)</span>
|
||||
</div>
|
||||
<div style="margin-bottom:.7rem">
|
||||
<span style="font-size:.55rem;color:var(--silk-light);opacity:.5;letter-spacing:.16em;display:block;margin-bottom:.25rem">AZERTY</span>
|
||||
<span class="keycap" style="border-color:var(--accent)">Q</span><span class="keycap" style="border-color:var(--accent)">Z</span><span class="keycap">S</span><span class="keycap">E</span><span class="keycap">D</span><span class="keycap">F</span><span class="keycap">T</span><span class="keycap">G</span><span class="keycap">Y</span><span class="keycap">H</span><span class="keycap">U</span><span class="keycap">J</span>
|
||||
<span style="font-size:.68rem;color:var(--silk-light);margin-left:.6rem">= C → B</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="keycap" style="padding:.18rem 2.2rem">espace</span>
|
||||
@@ -710,7 +716,7 @@
|
||||
<span style="font-size:.68rem;color:var(--silk-light);margin-left:.4rem">voicing −1 / +1</span>
|
||||
</div>
|
||||
</div>
|
||||
<figcaption>fig. 12 — la main gauche joue, la droite reste sur la souris</figcaption>
|
||||
<figcaption>fig. 12 — seules les deux premières touches changent entre les dispositions</figcaption>
|
||||
</figure>
|
||||
|
||||
<h3>Deux workflows de référence</h3>
|
||||
@@ -723,7 +729,7 @@
|
||||
</table>
|
||||
</section>
|
||||
|
||||
<footer>_chordlab · manuel rev. 2.2 · underscorelab / leradiologue · logique d'accords inspirée de l'Orchid ORC-1 (implémentation indépendante)</footer>
|
||||
<footer>_chordlab · manuel rev. 2.4 · underscorelab / leradiologue</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+735
@@ -0,0 +1,735 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>_chordlab — user manual</title>
|
||||
<style>
|
||||
:root{
|
||||
--panel:#E0D6C3;
|
||||
--panel-2:#D6CBB5;
|
||||
--panel-edge:#C9BCA4;
|
||||
--module:#26231D;
|
||||
--module-2:#332F27;
|
||||
--silk:#403A2F;
|
||||
--silk-light:#D8CFBB;
|
||||
--lcd-bg:#141A12;
|
||||
--lcd-amber:#FFB454;
|
||||
--lcd-dim:#7A6A3F;
|
||||
--led-on:#FFAE33;
|
||||
--led-off:#4A4436;
|
||||
--accent:#E5482B;
|
||||
--key-w:#EFE9DB;
|
||||
--key-b:#1C1A16;
|
||||
--mono:ui-monospace,"SF Mono","Cascadia Mono","JetBrains Mono",Menlo,Consolas,monospace;
|
||||
}
|
||||
*{box-sizing:border-box;margin:0;padding:0}
|
||||
html{scroll-behavior:smooth;font-size:15px}
|
||||
@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
|
||||
body{
|
||||
font-family:var(--mono);
|
||||
background:#17150F;
|
||||
color:var(--silk);
|
||||
padding:1.4rem;
|
||||
display:flex;justify-content:center;
|
||||
}
|
||||
.sheet{
|
||||
width:100%;max-width:920px;
|
||||
background:linear-gradient(178deg,var(--panel) 0%,var(--panel-2) 100%);
|
||||
border:1px solid var(--panel-edge);
|
||||
border-radius:14px;
|
||||
box-shadow:0 18px 50px rgba(0,0,0,.55), inset 0 1px 0 rgba(255,255,255,.5);
|
||||
padding:2rem 2.2rem 2.4rem;
|
||||
}
|
||||
@media(max-width:640px){ body{padding:.6rem} .sheet{padding:1.2rem 1rem} }
|
||||
|
||||
/* ---------- en-tête ---------- */
|
||||
.cover{border-bottom:3px solid var(--silk);padding-bottom:1.1rem;margin-bottom:1.2rem}
|
||||
.cover .kicker{font-size:.62rem;letter-spacing:.3em;text-transform:uppercase;opacity:.6}
|
||||
.cover h1{font-size:2rem;font-weight:800;letter-spacing:.03em;margin:.3rem 0 .2rem}
|
||||
.cover h1 em{font-style:normal;color:var(--accent)}
|
||||
.cover p{font-size:.78rem;line-height:1.65;max-width:44rem;margin-top:.5rem}
|
||||
|
||||
/* ---------- sommaire ---------- */
|
||||
nav{
|
||||
display:flex;flex-wrap:wrap;gap:.4rem;
|
||||
margin-bottom:2rem;position:sticky;top:.6rem;z-index:5;
|
||||
background:var(--panel);padding:.5rem;border-radius:9px;
|
||||
border:1px solid var(--panel-edge);
|
||||
box-shadow:0 4px 14px rgba(0,0,0,.15);
|
||||
}
|
||||
nav a{
|
||||
font-size:.6rem;letter-spacing:.08em;text-decoration:none;
|
||||
color:var(--silk-light);background:var(--module-2);
|
||||
border:1px solid #4A4436;border-radius:5px;
|
||||
padding:.3rem .55rem;white-space:nowrap;
|
||||
}
|
||||
nav a:hover,nav a:focus-visible{border-color:var(--led-on);color:var(--led-on);outline:none}
|
||||
|
||||
/* ---------- sections ---------- */
|
||||
section{margin-bottom:3rem}
|
||||
.shead{display:flex;align-items:baseline;gap:.7rem;border-bottom:2px solid var(--silk);padding-bottom:.4rem;margin-bottom:1rem}
|
||||
.shead .num{
|
||||
font-size:.72rem;font-weight:800;color:#FFF3E4;background:var(--accent);
|
||||
border-radius:4px;padding:.15rem .45rem;letter-spacing:.05em;
|
||||
}
|
||||
.shead h2{font-size:1.05rem;font-weight:800;letter-spacing:.04em;text-transform:uppercase}
|
||||
h3{font-size:.8rem;font-weight:800;letter-spacing:.08em;text-transform:uppercase;margin:1.3rem 0 .5rem}
|
||||
p{font-size:.78rem;line-height:1.7;margin-bottom:.7rem;max-width:46rem}
|
||||
strong{font-weight:800}
|
||||
code{background:var(--module);color:var(--lcd-amber);border-radius:4px;padding:.06rem .3rem;font-size:.72rem}
|
||||
|
||||
/* ---------- figures (modules rendus + légendes) ---------- */
|
||||
figure{
|
||||
background:var(--module);
|
||||
border-radius:10px;
|
||||
padding:1.1rem;
|
||||
margin:1rem 0;
|
||||
box-shadow:inset 0 1px 0 rgba(255,255,255,.06), 0 2px 6px rgba(0,0,0,.25);
|
||||
position:relative;
|
||||
}
|
||||
figcaption{
|
||||
font-size:.6rem;color:var(--silk-light);opacity:.55;
|
||||
letter-spacing:.12em;text-transform:uppercase;margin-top:.8rem;
|
||||
}
|
||||
.legend{list-style:none;margin:.8rem 0 0;display:grid;gap:.35rem}
|
||||
.legend li{font-size:.72rem;line-height:1.55;color:var(--silk-light);display:flex;gap:.5rem;align-items:baseline}
|
||||
.legend li p, .legend li span.t{color:var(--silk-light)}
|
||||
.dot{
|
||||
flex:none;width:16px;height:16px;border-radius:50%;
|
||||
background:var(--led-on);color:#26231D;
|
||||
font-size:.62rem;font-weight:800;
|
||||
display:inline-flex;align-items:center;justify-content:center;
|
||||
box-shadow:0 0 8px rgba(255,174,51,.5);
|
||||
transform:translateY(2px);
|
||||
}
|
||||
.dot.inplace{position:absolute;z-index:3}
|
||||
|
||||
/* ---------- rendus hardware réutilisables ---------- */
|
||||
.hwbtn{
|
||||
background:var(--module-2);border:1px solid #4A4436;border-radius:7px;
|
||||
color:var(--silk-light);font-size:.68rem;font-weight:600;
|
||||
padding:.55rem .2rem .45rem;
|
||||
display:flex;flex-direction:column;align-items:center;gap:.32rem;
|
||||
min-width:56px;
|
||||
}
|
||||
.led{width:7px;height:7px;border-radius:50%;background:var(--led-off);box-shadow:inset 0 1px 2px rgba(0,0,0,.6)}
|
||||
.on .led{background:var(--led-on);box-shadow:0 0 8px var(--led-on)}
|
||||
.btnrow{display:flex;gap:.45rem;flex-wrap:wrap}
|
||||
.lcd{
|
||||
background:var(--lcd-bg);border:3px solid #0B0E0A;border-radius:8px;
|
||||
box-shadow:inset 0 0 24px rgba(0,0,0,.8);
|
||||
padding:.6rem .9rem;display:inline-block;min-width:220px;
|
||||
}
|
||||
.lcd .big{font-size:1.5rem;font-weight:700;color:var(--lcd-amber);text-shadow:0 0 12px rgba(255,180,84,.45)}
|
||||
.lcd .small{font-size:.62rem;color:var(--lcd-dim);letter-spacing:.1em;margin-top:.15rem}
|
||||
.keycap{
|
||||
display:inline-block;background:var(--panel);color:var(--silk);
|
||||
border:1px solid var(--panel-edge);border-bottom-width:3px;border-radius:5px;
|
||||
font-size:.66rem;font-weight:700;padding:.18rem .45rem;margin:0 .1rem;
|
||||
}
|
||||
.arrow{color:var(--led-on);font-weight:800}
|
||||
table{border-collapse:collapse;font-size:.72rem;margin:.6rem 0;width:100%;max-width:46rem}
|
||||
th,td{border:1px solid var(--panel-edge);padding:.4rem .55rem;text-align:left;line-height:1.5}
|
||||
th{background:var(--module);color:var(--silk-light);font-size:.62rem;letter-spacing:.1em;text-transform:uppercase}
|
||||
td b{font-weight:800}
|
||||
.tip{
|
||||
border-left:4px solid var(--led-on);
|
||||
background:rgba(255,174,51,.09);
|
||||
border-radius:0 7px 7px 0;
|
||||
padding:.6rem .8rem;font-size:.72rem;line-height:1.6;
|
||||
margin:.8rem 0;max-width:46rem;
|
||||
}
|
||||
.warn{border-left-color:var(--accent);background:rgba(229,72,43,.08)}
|
||||
svg text{font-family:var(--mono)}
|
||||
footer{border-top:2px solid var(--silk);padding-top:.8rem;font-size:.6rem;opacity:.55;letter-spacing:.1em;text-align:right}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="sheet">
|
||||
|
||||
<div class="cover">
|
||||
<div class="kicker">user manual · rev. 2.4 · <a href="tuto.html" style="color:var(--accent);text-decoration:none;border-bottom:1px solid var(--accent)">Version française</a></div>
|
||||
<h1>_chordlab <em>ORC</em></h1>
|
||||
<p>A chord and progression machine. The whole idea fits in one sentence: <strong>you don't play the notes of a chord, you describe it</strong> — a root, a type, some tensions — and the machine takes it from there, all the way to your synths or your DAW.</p>
|
||||
</div>
|
||||
|
||||
<nav aria-label="Contents">
|
||||
<a href="#s1">01 Interface</a>
|
||||
<a href="#s2">02 First chord</a>
|
||||
<a href="#s3">03 Tensions</a>
|
||||
<a href="#s4">04 Voicing</a>
|
||||
<a href="#s5">05 Key Mode</a>
|
||||
<a href="#s6">06 Progression</a>
|
||||
<a href="#s7">07 Performance</a>
|
||||
<a href="#s8">08 Live MIDI</a>
|
||||
<a href="#s9">09 Export & sessions</a>
|
||||
<a href="#s10">10 Shortcuts</a>
|
||||
</nav>
|
||||
|
||||
<!-- ============ 01 INTERFACE ============ -->
|
||||
<section id="s1">
|
||||
<div class="shead"><span class="num">01</span><h2>The front panel</h2></div>
|
||||
<p>The screen is laid out like a hardware front panel. Six zones, always in the same place:</p>
|
||||
|
||||
<figure>
|
||||
<div style="display:grid;grid-template-columns:1fr;gap:.5rem;position:relative">
|
||||
<div style="background:var(--lcd-bg);border-radius:6px;padding:.6rem .8rem;position:relative">
|
||||
<span style="color:var(--lcd-amber);font-weight:700;font-size:.95rem">Cm7</span>
|
||||
<span style="color:var(--lcd-dim);font-size:.58rem;margin-left:.8rem">C4 · D#4 · G4 · A#4</span>
|
||||
<span class="dot inplace" style="top:-8px;left:-8px">1</span>
|
||||
</div>
|
||||
<div style="display:grid;grid-template-columns:1.1fr 1.6fr .9fr;gap:.5rem">
|
||||
<div style="background:var(--module-2);border:1px solid #4A4436;border-radius:6px;padding:.55rem;font-size:.58rem;color:var(--silk-light);position:relative;line-height:1.9">
|
||||
CHORD TYPE<br>TENSIONS<br>ALTÉRATIONS
|
||||
<span class="dot inplace" style="top:-8px;left:-8px">2</span>
|
||||
</div>
|
||||
<div style="background:var(--module-2);border:1px solid #4A4436;border-radius:6px;padding:.55rem;font-size:.58rem;color:var(--silk-light);position:relative;display:flex;align-items:center;justify-content:center">
|
||||
ROOT — 1-octave keyboard
|
||||
<span class="dot inplace" style="top:-8px;left:-8px">3</span>
|
||||
</div>
|
||||
<div style="background:var(--module-2);border:1px solid #4A4436;border-radius:6px;padding:.55rem;font-size:.58rem;color:var(--silk-light);position:relative;line-height:1.9">
|
||||
VOICING<br>BASS · KEY
|
||||
<span class="dot inplace" style="top:-8px;left:-8px">4</span>
|
||||
</div>
|
||||
</div>
|
||||
<div style="background:var(--module-2);border:1px solid #4A4436;border-radius:6px;padding:.55rem;font-size:.58rem;color:var(--silk-light);position:relative">
|
||||
PROGRESSION — slots · ADD · PLAY · perf · BPM
|
||||
<span class="dot inplace" style="top:-8px;left:-8px">5</span>
|
||||
</div>
|
||||
<div style="background:var(--module-2);border:1px solid #4A4436;border-radius:6px;padding:.55rem;font-size:.58rem;color:var(--silk-light);position:relative">
|
||||
MIDI OUT · EXPORT .MID · SESSION
|
||||
<span class="dot inplace" style="top:-8px;left:-8px">6</span>
|
||||
</div>
|
||||
</div>
|
||||
<ul class="legend">
|
||||
<li><span class="dot">1</span><span class="t"><strong>LCD</strong> — your constant reference: chord name, actual notes, mode status.</span></li>
|
||||
<li><span class="dot">2</span><span class="t"><strong>Chord description</strong> — type (one active at a time) plus tensions and alterations (stackable).</span></li>
|
||||
<li><span class="dot">3</span><span class="t"><strong>Root</strong> — the only thing you actually “play”.</span></li>
|
||||
<li><span class="dot">4</span><span class="t"><strong>Shaping</strong> — voicing, drop, bass, key.</span></li>
|
||||
<li><span class="dot">5</span><span class="t"><strong>Sequence</strong> — the progression and its playback.</span></li>
|
||||
<li><span class="dot">6</span><span class="t"><strong>Ins and outs</strong> — the bridge to your studio.</span></li>
|
||||
</ul>
|
||||
<figcaption>fig. 1 — front panel map</figcaption>
|
||||
</figure>
|
||||
</section>
|
||||
|
||||
<!-- ============ 02 FIRST CHORD ============ -->
|
||||
<section id="s2">
|
||||
<div class="shead"><span class="num">02</span><h2>Your first chord</h2></div>
|
||||
<p>Three moves: pick a <strong>type</strong>, press a <strong>root</strong>, read the <strong>LCD</strong>. The chord sounds right away.</p>
|
||||
|
||||
<figure>
|
||||
<div style="display:flex;gap:1.4rem;flex-wrap:wrap;align-items:flex-start">
|
||||
<div style="position:relative">
|
||||
<div style="font-size:.55rem;color:var(--silk-light);opacity:.5;letter-spacing:.18em;margin-bottom:.4rem">CHORD TYPE</div>
|
||||
<div class="btnrow">
|
||||
<div class="hwbtn"><span class="led"></span>DIM</div>
|
||||
<div class="hwbtn on"><span class="led"></span>MIN</div>
|
||||
<div class="hwbtn"><span class="led"></span>MAJ</div>
|
||||
<div class="hwbtn"><span class="led"></span>SUS4</div>
|
||||
</div>
|
||||
<span class="dot inplace" style="top:14px;left:60px">1</span>
|
||||
</div>
|
||||
<div style="position:relative">
|
||||
<div style="font-size:.55rem;color:var(--silk-light);opacity:.5;letter-spacing:.18em;margin-bottom:.4rem">ROOT</div>
|
||||
<svg width="238" height="96" viewBox="0 0 238 96" role="img" aria-label="One-octave keyboard with C pressed">
|
||||
<!-- white keys -->
|
||||
<g stroke="#B9AE97" stroke-width="1">
|
||||
<rect x="1" y="1" width="33" height="94" fill="#D9CFBA"/>
|
||||
<rect x="34" y="1" width="33" height="94" fill="var(--key-w)"/>
|
||||
<rect x="67" y="1" width="33" height="94" fill="var(--key-w)"/>
|
||||
<rect x="100" y="1" width="33" height="94" fill="var(--key-w)"/>
|
||||
<rect x="133" y="1" width="33" height="94" fill="var(--key-w)"/>
|
||||
<rect x="166" y="1" width="33" height="94" fill="var(--key-w)"/>
|
||||
<rect x="199" y="1" width="33" height="94" fill="var(--key-w)"/>
|
||||
</g>
|
||||
<!-- touches noires -->
|
||||
<g fill="var(--key-b)">
|
||||
<rect x="24" y="1" width="20" height="56" rx="3"/>
|
||||
<rect x="57" y="1" width="20" height="56" rx="3"/>
|
||||
<rect x="123" y="1" width="20" height="56" rx="3"/>
|
||||
<rect x="156" y="1" width="20" height="56" rx="3"/>
|
||||
<rect x="189" y="1" width="20" height="56" rx="3"/>
|
||||
</g>
|
||||
<text x="17" y="88" font-size="9" fill="#8A8070" text-anchor="middle">C</text>
|
||||
</svg>
|
||||
<span class="dot inplace" style="top:52px;left:6px">2</span>
|
||||
</div>
|
||||
<div style="position:relative">
|
||||
<div style="font-size:.55rem;color:var(--silk-light);opacity:.5;letter-spacing:.18em;margin-bottom:.4rem">LCD</div>
|
||||
<div class="lcd">
|
||||
<div class="big">Cm</div>
|
||||
<div class="small">C4 · D#4 · G4</div>
|
||||
</div>
|
||||
<span class="dot inplace" style="top:14px;left:-8px">3</span>
|
||||
</div>
|
||||
</div>
|
||||
<ul class="legend">
|
||||
<li><span class="dot">1</span><span class="t">Select <strong>MIN</strong> — the LED lights up; only one type is active at a time.</span></li>
|
||||
<li><span class="dot">2</span><span class="t">Press <strong>C</strong> (mouse, touch, or the <span class="keycap">A</span> key on your computer keyboard).</span></li>
|
||||
<li><span class="dot">3</span><span class="t">The LCD confirms: <strong>Cm</strong>, with the actual notes and their octaves.</span></li>
|
||||
</ul>
|
||||
<figcaption>fig. 2 — the core move: type + root → chord</figcaption>
|
||||
</figure>
|
||||
|
||||
<h3>The eight types</h3>
|
||||
<table>
|
||||
<tr><th>Button</th><th>Chord</th><th>Intervals</th><th>Character</th></tr>
|
||||
<tr><td><b>DIM</b></td><td>diminished</td><td>1 · ♭3 · ♭5</td><td>tense, passing</td></tr>
|
||||
<tr><td><b>MIN</b></td><td>minor</td><td>1 · ♭3 · 5</td><td>dark, melancholic</td></tr>
|
||||
<tr><td><b>MAJ</b></td><td>major</td><td>1 · 3 · 5</td><td>stable, bright</td></tr>
|
||||
<tr><td><b>AUG</b></td><td>augmented</td><td>1 · 3 · ♯5</td><td>unsettled, strange</td></tr>
|
||||
<tr><td><b>SUS2</b></td><td>suspended 2nd</td><td>1 · 2 · 5</td><td>open, airy</td></tr>
|
||||
<tr><td><b>SUS4</b></td><td>suspended 4th</td><td>1 · 4 · 5</td><td>waiting to resolve</td></tr>
|
||||
<tr><td><b>5</b></td><td>power chord</td><td>1 · 5</td><td>neutral, heavy</td></tr>
|
||||
<tr><td><b>m♭6</b></td><td>minor flat 6th</td><td>1 · ♭3 · ♭6</td><td>dramatic, cinematic</td></tr>
|
||||
</table>
|
||||
</section>
|
||||
|
||||
<!-- ============ 03 TENSIONS ============ -->
|
||||
<section id="s3">
|
||||
<div class="shead"><span class="num">03</span><h2>Tensions & alterations</h2></div>
|
||||
<p>The two lower rows <strong>stack</strong> freely on top of the type: several LEDs on at once. <strong>Tensions</strong> add notes; <strong>alterations</strong> change or remove notes that are already there.</p>
|
||||
|
||||
<figure>
|
||||
<div style="font-size:.55rem;color:var(--silk-light);opacity:.5;letter-spacing:.18em;margin-bottom:.4rem">TENSIONS — add notes</div>
|
||||
<div class="btnrow" style="margin-bottom:.8rem">
|
||||
<div class="hwbtn"><span class="led"></span>6</div>
|
||||
<div class="hwbtn on"><span class="led"></span>m7</div>
|
||||
<div class="hwbtn"><span class="led"></span>M7</div>
|
||||
<div class="hwbtn on"><span class="led"></span>9</div>
|
||||
<div class="hwbtn"><span class="led"></span>♭9</div>
|
||||
<div class="hwbtn"><span class="led"></span>♯9</div>
|
||||
<div class="hwbtn"><span class="led"></span>11</div>
|
||||
<div class="hwbtn"><span class="led"></span>♯11</div>
|
||||
</div>
|
||||
<div style="font-size:.55rem;color:var(--silk-light);opacity:.5;letter-spacing:.18em;margin-bottom:.4rem">ALTERATIONS — change / remove</div>
|
||||
<div class="btnrow">
|
||||
<div class="hwbtn"><span class="led"></span>13</div>
|
||||
<div class="hwbtn"><span class="led"></span>♭5</div>
|
||||
<div class="hwbtn"><span class="led"></span>♯5</div>
|
||||
<div class="hwbtn"><span class="led"></span>no3</div>
|
||||
</div>
|
||||
<div style="margin-top:1rem;display:flex;align-items:center;gap:.8rem;flex-wrap:wrap">
|
||||
<span style="font-size:.68rem;color:var(--silk-light)">MIN + m7 + 9 pressed →</span>
|
||||
<div class="lcd"><div class="big">Cm7(9)</div><div class="small">C4 · D#4 · G4 · A#4 · D5</div></div>
|
||||
</div>
|
||||
<figcaption>fig. 3 — stacking: the deep-pad m9 chord in two LEDs</figcaption>
|
||||
</figure>
|
||||
|
||||
<h3>Combinations worth knowing</h3>
|
||||
<table>
|
||||
<tr><th>Combination</th><th>Result</th><th>Why</th></tr>
|
||||
<tr><td><b>DIM + 6</b></td><td>Cdim7</td><td>a 6th on a diminished triad <em>is</em> the diminished 7th</td></tr>
|
||||
<tr><td><b>DIM + m7</b></td><td>Cø7</td><td>the half-diminished, backbone of the minor ii–V</td></tr>
|
||||
<tr><td><b>MAJ + m7 + ♯9</b></td><td>C7(♯9)</td><td>the “Hendrix” chord</td></tr>
|
||||
<tr><td><b>type + no3</b></td><td>open chord</td><td>neither major nor minor — perfect for ambient</td></tr>
|
||||
<tr><td><b>m7 + M7</b></td><td>WTF?</td><td>the LCD warns you. You do you.</td></tr>
|
||||
</table>
|
||||
<div class="tip">♭5 and ♯5 <strong>replace</strong> the fifth rather than adding to it: C7♭5 contains F♯, not G plus F♯. That is what makes them usable straight away.</div>
|
||||
</section>
|
||||
|
||||
<!-- ============ 04 VOICING ============ -->
|
||||
<section id="s4">
|
||||
<div class="shead"><span class="num">04</span><h2>Voicing</h2></div>
|
||||
<p>The same chord can be tight, open, low or airy. Three independent tools stack up, in this order: <strong>rotation → drop → slash bass</strong>.</p>
|
||||
|
||||
<h3>4.1 · The rotation knob (±8)</h3>
|
||||
<p>Each step <strong>rotates</strong> the chord: at +1 the lowest note jumps up an octave; at −1 the highest note drops down. Here is Cmaj7:</p>
|
||||
|
||||
<figure>
|
||||
<svg width="100%" viewBox="0 0 640 220" role="img" aria-label="Voicing rotation: four positions of Cmaj7">
|
||||
<!-- axe hauteur -->
|
||||
<text x="10" y="16" font-size="10" fill="#7A6A3F">high ↑</text>
|
||||
<text x="10" y="208" font-size="10" fill="#7A6A3F">low ↓</text>
|
||||
<!-- colonnes : chaque note = bloc. y = 200 - (midi-55)*4 -->
|
||||
<!-- V0: C4 E4 G4 B4 = 60 64 67 71 -->
|
||||
<g>
|
||||
<text x="110" y="212" font-size="11" fill="#D8CFBB" text-anchor="middle">voicing 0</text>
|
||||
<rect x="80" y="176" width="60" height="14" rx="3" fill="#FFAE33"/><text x="110" y="187" font-size="10" fill="#26231D" text-anchor="middle" font-weight="700">C4</text>
|
||||
<rect x="80" y="160" width="60" height="14" rx="3" fill="#5C543F"/><text x="110" y="171" font-size="10" fill="#E0D6C3" text-anchor="middle">E4</text>
|
||||
<rect x="80" y="144" width="60" height="14" rx="3" fill="#5C543F"/><text x="110" y="155" font-size="10" fill="#E0D6C3" text-anchor="middle">G4</text>
|
||||
<rect x="80" y="128" width="60" height="14" rx="3" fill="#5C543F"/><text x="110" y="139" font-size="10" fill="#E0D6C3" text-anchor="middle">B4</text>
|
||||
</g>
|
||||
<!-- flèche : C4 saute en C5 -->
|
||||
<path d="M 143 183 C 190 183 190 78 232 78" stroke="#E5482B" stroke-width="2.5" fill="none" marker-end="url(#arr)"/>
|
||||
<text x="188" y="128" font-size="10" fill="#E5482B" text-anchor="middle">+12</text>
|
||||
<defs><marker id="arr" markerWidth="8" markerHeight="8" refX="6" refY="3" orient="auto"><path d="M0,0 L6,3 L0,6 Z" fill="#E5482B"/></marker></defs>
|
||||
<!-- V+1: E4 G4 B4 C5 -->
|
||||
<g>
|
||||
<text x="270" y="212" font-size="11" fill="#D8CFBB" text-anchor="middle">voicing +1</text>
|
||||
<rect x="240" y="160" width="60" height="14" rx="3" fill="#5C543F"/><text x="270" y="171" font-size="10" fill="#E0D6C3" text-anchor="middle">E4</text>
|
||||
<rect x="240" y="144" width="60" height="14" rx="3" fill="#5C543F"/><text x="270" y="155" font-size="10" fill="#E0D6C3" text-anchor="middle">G4</text>
|
||||
<rect x="240" y="128" width="60" height="14" rx="3" fill="#5C543F"/><text x="270" y="139" font-size="10" fill="#E0D6C3" text-anchor="middle">B4</text>
|
||||
<rect x="240" y="72" width="60" height="14" rx="3" fill="#FFAE33"/><text x="270" y="83" font-size="10" fill="#26231D" text-anchor="middle" font-weight="700">C5</text>
|
||||
</g>
|
||||
<!-- flèche E4 -> E5 -->
|
||||
<path d="M 303 167 C 350 167 350 44 392 44" stroke="#E5482B" stroke-width="2.5" fill="none" marker-end="url(#arr)"/>
|
||||
<text x="348" y="102" font-size="10" fill="#E5482B" text-anchor="middle">+12</text>
|
||||
<!-- V+2: G4 B4 C5 E5 -->
|
||||
<g>
|
||||
<text x="430" y="212" font-size="11" fill="#D8CFBB" text-anchor="middle">voicing +2</text>
|
||||
<rect x="400" y="144" width="60" height="14" rx="3" fill="#5C543F"/><text x="430" y="155" font-size="10" fill="#E0D6C3" text-anchor="middle">G4</text>
|
||||
<rect x="400" y="128" width="60" height="14" rx="3" fill="#5C543F"/><text x="430" y="139" font-size="10" fill="#E0D6C3" text-anchor="middle">B4</text>
|
||||
<rect x="400" y="72" width="60" height="14" rx="3" fill="#5C543F"/><text x="430" y="83" font-size="10" fill="#E0D6C3" text-anchor="middle">C5</text>
|
||||
<rect x="400" y="38" width="60" height="14" rx="3" fill="#FFAE33"/><text x="430" y="49" font-size="10" fill="#26231D" text-anchor="middle" font-weight="700">E5</text>
|
||||
</g>
|
||||
<!-- V-1: B3 C4 E4 G4 -->
|
||||
<g>
|
||||
<text x="590" y="212" font-size="11" fill="#D8CFBB" text-anchor="middle">voicing −1</text>
|
||||
<rect x="560" y="192" width="60" height="14" rx="3" fill="#FFAE33"/><text x="590" y="203" font-size="10" fill="#26231D" text-anchor="middle" font-weight="700">B3</text>
|
||||
<rect x="560" y="176" width="60" height="14" rx="3" fill="#5C543F"/><text x="590" y="187" font-size="10" fill="#E0D6C3" text-anchor="middle">C4</text>
|
||||
<rect x="560" y="160" width="60" height="14" rx="3" fill="#5C543F"/><text x="590" y="171" font-size="10" fill="#E0D6C3" text-anchor="middle">E4</text>
|
||||
<rect x="560" y="144" width="60" height="14" rx="3" fill="#5C543F"/><text x="590" y="155" font-size="10" fill="#E0D6C3" text-anchor="middle">G4</text>
|
||||
</g>
|
||||
</svg>
|
||||
<figcaption>fig. 4 — rotation: the amber note is the one that just moved by an octave</figcaption>
|
||||
</figure>
|
||||
<p>How to drive it: drag vertically on the knob, use the <code>−</code> <code>0</code> <code>+</code> buttons or the <span class="keycap">←</span><span class="keycap">→</span> arrows, double-click to return to 0. The same chord at +3 and at −2 tells two different stories.</p>
|
||||
|
||||
<h3>4.2 · Drop voicings</h3>
|
||||
<p>Applied <strong>after</strong> the rotation, these spread the voices the way an arranger would:</p>
|
||||
<figure>
|
||||
<svg width="100%" viewBox="0 0 640 200" role="img" aria-label="Drop voicings compared on Cmaj7">
|
||||
<text x="10" y="16" font-size="10" fill="#7A6A3F">high ↑</text>
|
||||
<text x="10" y="192" font-size="10" fill="#7A6A3F">low ↓</text>
|
||||
<!-- close: 60 64 67 71 → y=180-(m-48)*5 -->
|
||||
<g>
|
||||
<text x="140" y="196" font-size="11" fill="#D8CFBB" text-anchor="middle">close</text>
|
||||
<circle cx="140" cy="120" r="7" fill="#FFAE33"/><text x="158" y="124" font-size="10" fill="#D8CFBB">C4</text>
|
||||
<circle cx="140" cy="100" r="7" fill="#FFAE33"/><text x="158" y="104" font-size="10" fill="#D8CFBB">E4</text>
|
||||
<circle cx="140" cy="85" r="7" fill="#FFAE33"/><text x="158" y="89" font-size="10" fill="#D8CFBB">G4</text>
|
||||
<circle cx="140" cy="65" r="7" fill="#FFAE33"/><text x="158" y="69" font-size="10" fill="#D8CFBB">B4</text>
|
||||
</g>
|
||||
<!-- drop2: 55 60 64 71 -->
|
||||
<g>
|
||||
<text x="330" y="196" font-size="11" fill="#D8CFBB" text-anchor="middle">drop 2</text>
|
||||
<circle cx="330" cy="145" r="7" fill="#E5482B"/><text x="348" y="149" font-size="10" fill="#D8CFBB">G3 ↓</text>
|
||||
<circle cx="330" cy="120" r="7" fill="#FFAE33"/><text x="348" y="124" font-size="10" fill="#D8CFBB">C4</text>
|
||||
<circle cx="330" cy="100" r="7" fill="#FFAE33"/><text x="348" y="104" font-size="10" fill="#D8CFBB">E4</text>
|
||||
<circle cx="330" cy="65" r="7" fill="#FFAE33"/><text x="348" y="69" font-size="10" fill="#D8CFBB">B4</text>
|
||||
</g>
|
||||
<!-- spread: 60 76 67(+? ) spread on triad 60 64 67 → 60 67 76 -->
|
||||
<g>
|
||||
<text x="520" y="196" font-size="11" fill="#D8CFBB" text-anchor="middle">spread</text>
|
||||
<circle cx="520" cy="120" r="7" fill="#FFAE33"/><text x="538" y="124" font-size="10" fill="#D8CFBB">C4</text>
|
||||
<circle cx="520" cy="85" r="7" fill="#FFAE33"/><text x="538" y="89" font-size="10" fill="#D8CFBB">G4</text>
|
||||
<circle cx="520" cy="40" r="7" fill="#E5482B"/><text x="538" y="44" font-size="10" fill="#D8CFBB">E5 ↑</text>
|
||||
</g>
|
||||
</svg>
|
||||
<ul class="legend">
|
||||
<li><span class="dot" style="background:#E5482B;box-shadow:none;color:#FFF3E4">↕</span><span class="t">The red notes are the ones moved by an octave by the drop mode.</span></li>
|
||||
</ul>
|
||||
<figcaption>fig. 5 — close · drop 2 (the jazz voicing) · spread (wide pad)</figcaption>
|
||||
</figure>
|
||||
<table>
|
||||
<tr><th>Mode</th><th>Effect</th><th>Use</th></tr>
|
||||
<tr><td><b>close</b></td><td>close position (no change)</td><td>default</td></tr>
|
||||
<tr><td><b>drop 2</b></td><td>2nd voice from the top → −1 oct</td><td>the jazz standard</td></tr>
|
||||
<tr><td><b>drop 3</b></td><td>3rd voice from the top → −1 oct</td><td>wide gaps, guitar-like</td></tr>
|
||||
<tr><td><b>drop 2+4</b></td><td>two voices dropped</td><td>very open, cinematic</td></tr>
|
||||
<tr><td><b>spread</b></td><td>every other voice → +1 oct</td><td>wide pads, ambient</td></tr>
|
||||
</table>
|
||||
|
||||
<h3>4.3 · Bass and slash chords</h3>
|
||||
<p>The <strong>BASS</strong> button adds a held note (−1 or −2 octaves) on its <strong>own MIDI channel</strong>. The <strong>bass /</strong> selector picks which chord tone it plays: root, third, fifth or seventh — the LCD then reads <code>C/E</code>. Detection follows the chord: minor third on a minor chord, diminished fifth on a ♭5. If the chord has no seventh, asking for one falls back to the root.</p>
|
||||
</section>
|
||||
|
||||
<!-- ============ 05 KEY MODE ============ -->
|
||||
<section id="s5">
|
||||
<div class="shead"><span class="num">05</span><h2>Key Mode — one-finger diatonic chords</h2></div>
|
||||
<p>Turn on <strong>KEY</strong>, choose a tonic and one of the eight scales. Every key then produces <strong>the diatonic chord for its degree</strong> — you cannot fall out of the key.</p>
|
||||
|
||||
<figure>
|
||||
<svg width="100%" viewBox="0 0 480 150" role="img" aria-label="Key Mode in C major: black keys dimmed, diatonic chords under each white key">
|
||||
<g stroke="#B9AE97" stroke-width="1">
|
||||
<rect x="1" y="1" width="66" height="110" fill="var(--key-w)"/>
|
||||
<rect x="69" y="1" width="66" height="110" fill="var(--key-w)"/>
|
||||
<rect x="137" y="1" width="66" height="110" fill="var(--key-w)"/>
|
||||
<rect x="205" y="1" width="66" height="110" fill="var(--key-w)"/>
|
||||
<rect x="273" y="1" width="66" height="110" fill="var(--key-w)"/>
|
||||
<rect x="341" y="1" width="66" height="110" fill="var(--key-w)"/>
|
||||
<rect x="409" y="1" width="66" height="110" fill="var(--key-w)"/>
|
||||
</g>
|
||||
<!-- black keys dimmed (out of key in C major) -->
|
||||
<g fill="#4B4739" opacity=".55">
|
||||
<rect x="46" y="1" width="42" height="64" rx="4"/>
|
||||
<rect x="114" y="1" width="42" height="64" rx="4"/>
|
||||
<rect x="250" y="1" width="42" height="64" rx="4"/>
|
||||
<rect x="318" y="1" width="42" height="64" rx="4"/>
|
||||
<rect x="386" y="1" width="42" height="64" rx="4"/>
|
||||
</g>
|
||||
<!-- resulting chords -->
|
||||
<g font-size="13" fill="#403A2F" text-anchor="middle" font-weight="700">
|
||||
<text x="34" y="100">C</text>
|
||||
<text x="102" y="100">Dm</text>
|
||||
<text x="170" y="100">Em</text>
|
||||
<text x="238" y="100">F</text>
|
||||
<text x="306" y="100">G</text>
|
||||
<text x="374" y="100">Am</text>
|
||||
<text x="442" y="100">Bdim</text>
|
||||
</g>
|
||||
<g font-size="10" fill="#7A6A3F" text-anchor="middle">
|
||||
<text x="34" y="138">I</text>
|
||||
<text x="102" y="138">ii</text>
|
||||
<text x="170" y="138">iii</text>
|
||||
<text x="238" y="138">IV</text>
|
||||
<text x="306" y="138">V</text>
|
||||
<text x="374" y="138">vi</text>
|
||||
<text x="442" y="138">vii°</text>
|
||||
</g>
|
||||
</svg>
|
||||
<figcaption>fig. 6 — Key Mode in C major: each key gives its degree’s chord; out-of-key notes are dimmed and silent</figcaption>
|
||||
</figure>
|
||||
|
||||
<p>The <code>6</code> <code>m7</code> <code>M7</code> <code>9</code> <code>11</code> <code>13</code> tensions stay active and are harmonised <strong>within the scale</strong>: the 7th on G in C major gives a real G7 (with a natural F). The asterisk in the name (<code>G7*</code>) marks that diatonic harmonisation.</p>
|
||||
<div class="tip"><strong>Harmonic minor</strong> is worth a try: its V degree becomes a genuine dominant chord with a leading tone — the classic minor cadence, with one finger.</div>
|
||||
</section>
|
||||
|
||||
<!-- ============ 06 PROGRESSION ============ -->
|
||||
<section id="s6">
|
||||
<div class="shead"><span class="num">06</span><h2>Building a progression</h2></div>
|
||||
<p>Play a chord, then hit <strong>ADD</strong> (or <span class="keycap">space</span>): it becomes a slot in the sequence. Anatomy of a slot:</p>
|
||||
|
||||
<figure>
|
||||
<div style="display:flex;justify-content:center;padding:1.4rem 0 .6rem">
|
||||
<div style="position:relative;background:var(--module-2);border:1px solid #4A4436;border-radius:7px;padding:.5rem .7rem .4rem;min-width:150px;color:var(--silk-light);font-size:.72rem">
|
||||
<span style="position:absolute;top:2px;right:6px;opacity:.5">×</span>
|
||||
<div style="font-weight:700;color:var(--lcd-amber);font-size:.9rem">Fm7</div>
|
||||
<div style="opacity:.55;font-size:.56rem;margin-top:.15rem">F G# C D# +B</div>
|
||||
<div style="display:flex;gap:.35rem;margin-top:.35rem;align-items:center">
|
||||
<span style="opacity:.5">‹</span>
|
||||
<span style="opacity:.7">−</span>
|
||||
<span style="background:#1E1B15;border:1px solid #4A4436;border-radius:4px;font-size:.55rem;padding:.1rem .3rem">3♩</span>
|
||||
<span style="opacity:.7">+</span>
|
||||
<span style="opacity:.5">›</span>
|
||||
</div>
|
||||
<span class="dot inplace" style="top:-10px;right:-4px;left:auto">1</span>
|
||||
<span class="dot inplace" style="top:16px;left:-10px">2</span>
|
||||
<span class="dot inplace" style="bottom:26px;left:-10px;top:auto">3</span>
|
||||
<span class="dot inplace" style="bottom:-6px;left:64px;top:auto">4</span>
|
||||
<span class="dot inplace" style="bottom:-6px;right:-4px;left:auto;top:auto">5</span>
|
||||
</div>
|
||||
</div>
|
||||
<ul class="legend">
|
||||
<li><span class="dot">1</span><span class="t"><strong>×</strong> — delete the slot.</span></li>
|
||||
<li><span class="dot">2</span><span class="t">Name, notes, and <code>+B</code> when the bass is on.</span></li>
|
||||
<li><span class="dot">3</span><span class="t"><strong>Click the slot</strong> — audition it on its own.</span></li>
|
||||
<li><span class="dot">4</span><span class="t"><strong>− / +</strong> — length from <strong>1 to 16 beats</strong>, one beat at a time. A 3-, 5- or 7-beat chord fits in a single slot.</span></li>
|
||||
<li><span class="dot">5</span><span class="t"><strong>‹ ›</strong> — move the slot along the sequence.</span></li>
|
||||
</ul>
|
||||
<figcaption>fig. 7 — anatomy of a progression slot</figcaption>
|
||||
</figure>
|
||||
|
||||
<h3>Three ways to fill the sequence</h3>
|
||||
<table>
|
||||
<tr><th>Method</th><th>Action</th><th>When</th></tr>
|
||||
<tr><td><b>By hand</b></td><td>play + ADD</td><td>you know where you are going</td></tr>
|
||||
<tr><td><b>Presets</b></td><td>pick a progression + load</td><td>instant starting point in your key (I–V–vi–IV, ii–V–I, circle of fifths…)</td></tr>
|
||||
<tr><td><b>✦ suggest</b></td><td>one click = one proposed chord</td><td>let the machine drift using functional harmony, take over when it gets interesting</td></tr>
|
||||
</table>
|
||||
|
||||
<h3>Voice leading</h3>
|
||||
<p>The same progression, voiced two ways:</p>
|
||||
<figure>
|
||||
<svg width="100%" viewBox="0 0 640 170" role="img" aria-label="With and without voice leading">
|
||||
<text x="150" y="16" font-size="11" fill="#D8CFBB" text-anchor="middle">without VL — voices jump</text>
|
||||
<g stroke="#E5482B" stroke-width="2" opacity=".85">
|
||||
<line x1="70" y1="120" x2="150" y2="60"/><line x1="150" y1="60" x2="230" y2="130"/>
|
||||
<line x1="70" y1="100" x2="150" y2="40"/><line x1="150" y1="40" x2="230" y2="110"/>
|
||||
<line x1="70" y1="85" x2="150" y2="25"/><line x1="150" y1="25" x2="230" y2="90"/>
|
||||
</g>
|
||||
<g fill="#FFAE33">
|
||||
<circle cx="70" cy="120" r="6"/><circle cx="70" cy="100" r="6"/><circle cx="70" cy="85" r="6"/>
|
||||
<circle cx="150" cy="60" r="6"/><circle cx="150" cy="40" r="6"/><circle cx="150" cy="25" r="6"/>
|
||||
<circle cx="230" cy="130" r="6"/><circle cx="230" cy="110" r="6"/><circle cx="230" cy="90" r="6"/>
|
||||
</g>
|
||||
<g font-size="10" fill="#7A6A3F" text-anchor="middle">
|
||||
<text x="70" y="155">C</text><text x="150" y="155">F</text><text x="230" y="155">G</text>
|
||||
</g>
|
||||
<text x="490" y="16" font-size="11" fill="#D8CFBB" text-anchor="middle">with VL — voices glide</text>
|
||||
<g stroke="#8BC34A" stroke-width="2" opacity=".9">
|
||||
<line x1="410" y1="120" x2="490" y2="112"/><line x1="490" y1="112" x2="570" y2="118"/>
|
||||
<line x1="410" y1="100" x2="490" y2="95"/><line x1="490" y1="95" x2="570" y2="102"/>
|
||||
<line x1="410" y1="85" x2="490" y2="78"/><line x1="490" y1="78" x2="570" y2="84"/>
|
||||
</g>
|
||||
<g fill="#FFAE33">
|
||||
<circle cx="410" cy="120" r="6"/><circle cx="410" cy="100" r="6"/><circle cx="410" cy="85" r="6"/>
|
||||
<circle cx="490" cy="112" r="6"/><circle cx="490" cy="95" r="6"/><circle cx="490" cy="78" r="6"/>
|
||||
<circle cx="570" cy="118" r="6"/><circle cx="570" cy="102" r="6"/><circle cx="570" cy="84" r="6"/>
|
||||
</g>
|
||||
<g font-size="10" fill="#7A6A3F" text-anchor="middle">
|
||||
<text x="410" y="155">C</text><text x="490" y="155">F</text><text x="570" y="155">G</text>
|
||||
</g>
|
||||
</svg>
|
||||
<figcaption>fig. 8 — voice leading picks the voicing that keeps the voices moving as little as possible</figcaption>
|
||||
</figure>
|
||||
<p><strong>VL AUTO</strong> (in the transport) applies this on every ADD; <strong>⇄ voice-leading</strong> re-voices the whole existing progression in one go. Try it right after loading a preset — you hear the difference immediately.</p>
|
||||
</section>
|
||||
|
||||
<!-- ============ 07 PERFORMANCE ============ -->
|
||||
<section id="s7">
|
||||
<div class="shead"><span class="num">07</span><h2>Playback & performance modes</h2></div>
|
||||
<p><strong>PLAY</strong> runs the progression at the displayed BPM, <strong>LOOP</strong> repeats it. The <strong>perf</strong> selector changes how each chord is delivered — everywhere: auditioning, live MIDI and <code>.mid</code> export.</p>
|
||||
|
||||
<figure>
|
||||
<svg width="100%" viewBox="0 0 640 240" role="img" aria-label="Three performance modes as piano roll: block, strum, arpeggio">
|
||||
<!-- BLOCK -->
|
||||
<text x="60" y="22" font-size="11" fill="#D8CFBB">block</text>
|
||||
<g fill="#FFAE33">
|
||||
<rect x="120" y="10" width="440" height="10" rx="2"/>
|
||||
<rect x="120" y="26" width="440" height="10" rx="2"/>
|
||||
<rect x="120" y="42" width="440" height="10" rx="2"/>
|
||||
</g>
|
||||
<!-- STRUM -->
|
||||
<text x="60" y="102" font-size="11" fill="#D8CFBB">strum ↑</text>
|
||||
<g fill="#FFAE33">
|
||||
<rect x="120" y="106" width="440" height="10" rx="2"/>
|
||||
<rect x="150" y="90" width="410" height="10" rx="2"/>
|
||||
<rect x="180" y="74" width="380" height="10" rx="2"/>
|
||||
</g>
|
||||
<!-- ARP -->
|
||||
<text x="60" y="182" font-size="11" fill="#D8CFBB">arp ↑ 1/16</text>
|
||||
<g fill="#FFAE33">
|
||||
<rect x="120" y="200" width="42" height="10" rx="2"/>
|
||||
<rect x="175" y="184" width="42" height="10" rx="2"/>
|
||||
<rect x="230" y="168" width="42" height="10" rx="2"/>
|
||||
<rect x="285" y="200" width="42" height="10" rx="2"/>
|
||||
<rect x="340" y="184" width="42" height="10" rx="2"/>
|
||||
<rect x="395" y="168" width="42" height="10" rx="2"/>
|
||||
<rect x="450" y="200" width="42" height="10" rx="2"/>
|
||||
<rect x="505" y="184" width="42" height="10" rx="2"/>
|
||||
</g>
|
||||
<line x1="120" y1="228" x2="560" y2="228" stroke="#4A4436" stroke-width="1"/>
|
||||
<text x="120" y="240" font-size="9" fill="#7A6A3F">t = 0</text>
|
||||
<text x="560" y="240" font-size="9" fill="#7A6A3F" text-anchor="end">slot length →</text>
|
||||
</svg>
|
||||
<figcaption>fig. 9 — the same triad as block, strum and arpeggio</figcaption>
|
||||
</figure>
|
||||
|
||||
<table>
|
||||
<tr><th>Mode</th><th>Output</th></tr>
|
||||
<tr><td><b>block</b></td><td>chord played as a block</td></tr>
|
||||
<tr><td><b>strum ↑ / ↓</b></td><td>notes rolled upwards / downwards, guitar style</td></tr>
|
||||
<tr><td><b>harp</b></td><td>fast sweep (glissando)</td></tr>
|
||||
<tr><td><b>arp ↑ / ↓ / ↕ / rnd</b></td><td>arpeggio at the speed set by <b>rate</b> (1/8 · 1/16 · 1/32)</td></tr>
|
||||
</table>
|
||||
<p><strong>HUM</strong> humanises velocity (±10) and timing (±15 ms) — strums and arpeggios breathe.</p>
|
||||
</section>
|
||||
|
||||
<!-- ============ 08 MIDI LIVE ============ -->
|
||||
<section id="s8">
|
||||
<div class="shead"><span class="num">08</span><h2>Live MIDI to your studio</h2></div>
|
||||
<p>Every chord you click, every slot you audition and the full playback go out over MIDI on <strong>two separate channels</strong> — chords and bass drive two different machines at once.</p>
|
||||
|
||||
<figure>
|
||||
<svg width="100%" viewBox="0 0 640 190" role="img" aria-label="MIDI routing: chordlab to USB interface, then Pro-800 on channel 3 and TD-3 on channel 5">
|
||||
<rect x="20" y="65" width="140" height="60" rx="8" fill="#332F27" stroke="#4A4436"/>
|
||||
<text x="90" y="92" font-size="12" fill="#FFB454" text-anchor="middle" font-weight="700">_chordlab</text>
|
||||
<text x="90" y="110" font-size="9" fill="#7A6A3F" text-anchor="middle">browser (https)</text>
|
||||
|
||||
<line x1="160" y1="95" x2="240" y2="95" stroke="#FFAE33" stroke-width="2.5" marker-end="url(#arr2)"/>
|
||||
<text x="200" y="86" font-size="9" fill="#D8CFBB" text-anchor="middle">Web MIDI</text>
|
||||
|
||||
<rect x="240" y="65" width="130" height="60" rx="8" fill="#332F27" stroke="#4A4436"/>
|
||||
<text x="305" y="92" font-size="11" fill="#D8CFBB" text-anchor="middle" font-weight="700">interface</text>
|
||||
<text x="305" y="108" font-size="9" fill="#7A6A3F" text-anchor="middle">USB-MIDI</text>
|
||||
|
||||
<path d="M 370 82 C 420 82 420 40 468 40" stroke="#FFAE33" stroke-width="2.5" fill="none" marker-end="url(#arr2)"/>
|
||||
<text x="418" y="48" font-size="10" fill="#FFAE33" text-anchor="middle" font-weight="700">ch 3</text>
|
||||
<path d="M 370 108 C 420 108 420 150 468 150" stroke="#E5482B" stroke-width="2.5" fill="none" marker-end="url(#arr3)"/>
|
||||
<text x="418" y="142" font-size="10" fill="#E5482B" text-anchor="middle" font-weight="700">ch 5</text>
|
||||
|
||||
<rect x="470" y="14" width="150" height="52" rx="8" fill="#332F27" stroke="#4A4436"/>
|
||||
<text x="545" y="36" font-size="11" fill="#D8CFBB" text-anchor="middle" font-weight="700">Pro-800</text>
|
||||
<text x="545" y="52" font-size="9" fill="#7A6A3F" text-anchor="middle">chords / pads</text>
|
||||
|
||||
<rect x="470" y="124" width="150" height="52" rx="8" fill="#332F27" stroke="#4A4436"/>
|
||||
<text x="545" y="146" font-size="11" fill="#D8CFBB" text-anchor="middle" font-weight="700">TD-3 + K-2</text>
|
||||
<text x="545" y="162" font-size="9" fill="#7A6A3F" text-anchor="middle">bass (unison)</text>
|
||||
|
||||
<defs>
|
||||
<marker id="arr2" markerWidth="8" markerHeight="8" refX="6" refY="3" orient="auto"><path d="M0,0 L6,3 L0,6 Z" fill="#FFAE33"/></marker>
|
||||
<marker id="arr3" markerWidth="8" markerHeight="8" refX="6" refY="3" orient="auto"><path d="M0,0 L6,3 L0,6 Z" fill="#E5482B"/></marker>
|
||||
</defs>
|
||||
</svg>
|
||||
<figcaption>fig. 10 — default routing: chords on ch3, bass on ch5 (both editable in the MIDI panel)</figcaption>
|
||||
</figure>
|
||||
|
||||
<p>Getting going: <strong>①</strong> plug the interface in before opening the page (or reload), <strong>②</strong> allow the MIDI access the browser asks for, <strong>③</strong> select the device in the <strong>MIDI out (live)</strong> panel. The LCD reads <code>MIDI ON</code>.</p>
|
||||
<div class="tip warn"><strong>Web MIDI needs HTTPS</strong> (or localhost). Over <code>file://</code>, audio and export still work but live MIDI output does not — which is why the app is hosted at <code>chordlab.ghostinthemachine.fr</code>. Safari does not support Web MIDI: use Chrome, Edge or Firefox. Stuck note on a machine? <strong>STOP</strong> sends All Notes Off across all 16 channels.</div>
|
||||
</section>
|
||||
|
||||
<!-- ============ 09 EXPORT ============ -->
|
||||
<section id="s9">
|
||||
<div class="shead"><span class="num">09</span><h2>Export & sessions</h2></div>
|
||||
|
||||
<figure>
|
||||
<svg width="100%" viewBox="0 0 640 120" role="img" aria-label="Export flow: progression to .mid file to DAW or tracker">
|
||||
<rect x="20" y="35" width="150" height="50" rx="8" fill="#332F27" stroke="#4A4436"/>
|
||||
<text x="95" y="57" font-size="11" fill="#D8CFBB" text-anchor="middle" font-weight="700">progression</text>
|
||||
<text x="95" y="72" font-size="9" fill="#7A6A3F" text-anchor="middle">slots + lengths</text>
|
||||
<line x1="170" y1="60" x2="240" y2="60" stroke="#FFAE33" stroke-width="2.5" marker-end="url(#arr4)"/>
|
||||
<rect x="242" y="35" width="130" height="50" rx="8" fill="#332F27" stroke="#4A4436"/>
|
||||
<text x="307" y="57" font-size="11" fill="#FFB454" text-anchor="middle" font-weight="700">.mid</text>
|
||||
<text x="307" y="72" font-size="9" fill="#7A6A3F" text-anchor="middle">format 1 · PPQ 480 · tempo</text>
|
||||
<path d="M 372 50 C 410 50 410 30 448 30" stroke="#FFAE33" stroke-width="2" fill="none" marker-end="url(#arr4)"/>
|
||||
<path d="M 372 70 C 410 70 410 92 448 92" stroke="#FFAE33" stroke-width="2" fill="none" marker-end="url(#arr4)"/>
|
||||
<text x="530" y="34" font-size="11" fill="#D8CFBB" font-weight="700">DAW (drag and drop)</text>
|
||||
<text x="530" y="96" font-size="11" fill="#D8CFBB" font-weight="700">Tracker Mini (SD card)</text>
|
||||
<defs><marker id="arr4" markerWidth="8" markerHeight="8" refX="6" refY="3" orient="auto"><path d="M0,0 L6,3 L0,6 Z" fill="#FFAE33"/></marker></defs>
|
||||
</svg>
|
||||
<figcaption>fig. 11 — one file, two destinations</figcaption>
|
||||
</figure>
|
||||
|
||||
<table>
|
||||
<tr><th>Export option</th><th>Choice</th></tr>
|
||||
<tr><td><b>tracks</b></td><td>chords + bass (2 tracks, each on its own channel) · or chords only</td></tr>
|
||||
<tr><td><b>render perf</b></td><td><b>yes</b>: strums and arpeggios are written note by note into the file · <b>no</b>: block chords (better if you plan to arpeggiate later in the DAW or tracker)</td></tr>
|
||||
</table>
|
||||
|
||||
<h3>Sessions</h3>
|
||||
<p><strong>↓ save session</strong> writes a <code>.json</code> holding every setting and the full progression; <strong>↑ load</strong> restores all of it. Nothing is kept in the browser: the file is the only persistence — version your sessions in Git like any other project file.</p>
|
||||
</section>
|
||||
|
||||
<!-- ============ 10 RACCOURCIS ============ -->
|
||||
<section id="s10">
|
||||
<div class="shead"><span class="num">10</span><h2>Keyboard shortcuts</h2></div>
|
||||
<p>The letters follow a piano layout. A <strong>QWERTY / AZERTY</strong> switch sits under the on-screen keyboard: only two keys differ between the two layouts, but they are C and C sharp, so the right setting makes all the difference. The app picks a layout at startup based on your browser language — change it with one click if needed, and the choice is stored in <code>.json</code> sessions.</p>
|
||||
|
||||
<figure>
|
||||
<div style="text-align:center;padding:.4rem 0 .2rem">
|
||||
<div style="margin-bottom:.5rem">
|
||||
<span style="font-size:.55rem;color:var(--silk-light);opacity:.5;letter-spacing:.16em;display:block;margin-bottom:.25rem">QWERTY</span>
|
||||
<span class="keycap">A</span><span class="keycap">W</span><span class="keycap">S</span><span class="keycap">E</span><span class="keycap">D</span><span class="keycap">F</span><span class="keycap">T</span><span class="keycap">G</span><span class="keycap">Y</span><span class="keycap">H</span><span class="keycap">U</span><span class="keycap">J</span>
|
||||
</div>
|
||||
<div style="margin-bottom:.7rem">
|
||||
<span style="font-size:.55rem;color:var(--silk-light);opacity:.5;letter-spacing:.16em;display:block;margin-bottom:.25rem">AZERTY</span>
|
||||
<span class="keycap" style="border-color:var(--accent)">Q</span><span class="keycap" style="border-color:var(--accent)">Z</span><span class="keycap">S</span><span class="keycap">E</span><span class="keycap">D</span><span class="keycap">F</span><span class="keycap">T</span><span class="keycap">G</span><span class="keycap">Y</span><span class="keycap">H</span><span class="keycap">U</span><span class="keycap">J</span>
|
||||
<span style="font-size:.68rem;color:var(--silk-light);margin-left:.6rem">= C → B</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="keycap" style="padding:.18rem 2.2rem">espace</span>
|
||||
<span style="font-size:.68rem;color:var(--silk-light);margin:0 1rem 0 .4rem">ADD</span>
|
||||
<span class="keycap">←</span><span class="keycap">→</span>
|
||||
<span style="font-size:.68rem;color:var(--silk-light);margin-left:.4rem">voicing −1 / +1</span>
|
||||
</div>
|
||||
</div>
|
||||
<figcaption>fig. 12 — only the first two keys differ between layouts</figcaption>
|
||||
</figure>
|
||||
|
||||
<h3>Two reference workflows</h3>
|
||||
<table>
|
||||
<tr><th>Dawless (hardware session)</th><th>DAW / tracker (writing)</th></tr>
|
||||
<tr>
|
||||
<td>KEY ON → preset or ✦ suggest → ⇄ voice-leading → live MIDI (Pro-800 + TD-3) → LOOP while you shape the sounds and record to the mixer → save a .json session</td>
|
||||
<td>KEY OFF, free exploration of colours (types + tensions + drops) → VL AUTO → export .mid with <b>render perf: no</b> → import into the DAW or Tracker Mini → arpeggiation and sound design in the target machine</td>
|
||||
</tr>
|
||||
</table>
|
||||
</section>
|
||||
|
||||
<footer>_chordlab · manual rev. 2.4 · underscorelab / leradiologue</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user