v2.3 : correction bug ligne de basse

This commit is contained in:
lrdlg
2026-07-21 06:16:46 +02:00
parent 0e19ac59e9
commit 166ec447d5
12 changed files with 26 additions and 4516 deletions
+26 -19
View File
@@ -230,12 +230,11 @@
*{transition:none !important}
}
</style>
<script defer src="https://umami.ghostinthemachine.fr/script.js" data-website-id="0e5510f0-0521-4e70-b43e-6cc7d97df7a3"></script>
</head>
<body>
<div class="unit">
<header>
<h1>_chordlab <span>ORC·v2</span></h1>
<h1><span>_chordlab.v2</span></h1>
<div class="sub">chord ideas machine · underscorelab / leradiologue</div>
</header>
@@ -436,7 +435,7 @@
</div>
</div>
<footer>_chordlab v2.2 · logique d'accords inspirée de l'Orchid ORC-1 (implémentation indépendante étendue)</footer>
<footer>_chordlab v2.3 · logique d'accords</footer>
</div>
<script>
@@ -536,17 +535,20 @@ function applyDrop(notes, mode){
return n.sort((a,b)=>a-b);
}
/* Slash bass : choisit la note de basse parmi les tons de l'accord */
function slashInterval(rootPc, type, exts, which){
const rel = buildChord(rootPc, type, exts).map(n=>n-(BASE+rootPc));
/* Slash bass : choisit la note de basse parmi les notes réelles de l'accord.
Travaille sur les notes construites (avant voicing), donc valable
aussi bien en mode libre qu'en Key Mode. */
function slashIntervalFrom(rawNotes, which){
const root = rawNotes[0];
const rel = rawNotes.map(n => (n - root) % 12).map(i => i<0 ? i+12 : i);
const pickFrom = arr => arr.find(i=>rel.includes(i));
if (which==="third") return pickFrom([4,3,5,2]) ?? 0;
if (which==="fifth") return pickFrom([7,6,8]) ?? 0;
if (which==="seventh") return pickFrom([10,11,9]) ?? 0;
return 0;
}
function bassNoteFor(rootPc, type, exts){
const iv = slashInterval(rootPc, type, exts, state.slash);
function bassFromRaw(rawNotes, rootPc){
const iv = slashIntervalFrom(rawNotes, state.slash);
return {midi: BASE + rootPc + iv + state.bassOct, iv};
}
@@ -604,9 +606,7 @@ function currentChord(rootPc){
// slash dans le nom
let bass = null;
if (state.bass){
const b = state.keyMode
? {midi: BASE + rootPc + state.bassOct, iv:0}
: bassNoteFor(rootPc, state.type, state.exts);
const b = bassFromRaw(raw, rootPc);
bass = b.midi;
if (b.iv !== 0) name += "/" + NOTE_NAMES[(rootPc + b.iv) % 12];
}
@@ -651,10 +651,15 @@ function suggestNext(){
let notes = applyDrop(applyVoicing(d.notes, state.voicing), state.drop);
if (state.vlAuto && state.progression.length)
notes = bestVoicingAgainst(notes, state.progression[state.progression.length-1].notes);
let label = d.name;
let bass = null;
if (state.bass){
const b = bassFromRaw(d.notes, pc);
bass = b.midi;
if (b.iv !== 0) label += "/" + NOTE_NAMES[(pc + b.iv) % 12];
}
state.progression.push({
label: d.name, notes,
bass: state.bass ? BASE + pc + state.bassOct : null,
rootPc: pc, beats: 4,
label, notes, bass, rootPc: pc, beats: 4,
});
renderProgression();
}
@@ -1191,11 +1196,13 @@ $("presetLoad").addEventListener("click",()=>{
let notes=applyDrop(applyVoicing(dc.notes,state.voicing),state.drop);
if (state.vlAuto && prev) notes=bestVoicingAgainst(notes,prev);
prev=notes;
state.progression.push({
label:dc.name,notes,
bass:state.bass?BASE+pc+state.bassOct:null,
rootPc:pc,beats:4,
});
let label=dc.name, bass=null;
if (state.bass){
const b=bassFromRaw(dc.notes,pc);
bass=b.midi;
if (b.iv!==0) label+="/"+NOTE_NAMES[(pc+b.iv)%12];
}
state.progression.push({label,notes,bass,rootPc:pc,beats:4});
});
renderProgression();
});