chordlab v2.2
This commit is contained in:
+3
-55
@@ -246,7 +246,7 @@
|
||||
</div>
|
||||
<div class="lcd-right">
|
||||
<div>VOICING <b id="lcdVoicing">0</b> · <b id="lcdDrop">CLOSE</b></div>
|
||||
<div>KEY <b id="lcdKey">OFF</b> · PERF <b id="lcdPerf">BLOCK</b> · B <b id="lcdBassPerf">TENUE</b></div>
|
||||
<div>KEY <b id="lcdKey">OFF</b> · PERF <b id="lcdPerf">BLOCK</b></div>
|
||||
<div>MIDI <b id="lcdMidi">—</b> · VL <b id="lcdVl">OFF</b></div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -333,20 +333,6 @@
|
||||
<option value="-12" selected>−1 oct</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="field"><label>rythme B</label>
|
||||
<select id="bassPerfSel">
|
||||
<option value="held">tenue</option>
|
||||
<option value="quarter">noires</option>
|
||||
<option value="eighth">croches</option>
|
||||
<option value="offbeat">contretemps</option>
|
||||
<option value="octave">octaves</option>
|
||||
<option value="root5">fond.–quinte</option>
|
||||
<option value="walk">boogie</option>
|
||||
<option value="tresillo">3–3–2</option>
|
||||
<option value="pump">pompe</option>
|
||||
<option value="rnd">aléatoire</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="toggle-line">
|
||||
<button class="hwbtn" id="keyBtn"><span class="led"></span>KEY</button>
|
||||
<select id="keyRoot"></select>
|
||||
@@ -449,7 +435,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer>_chordlab v2.1 · logique d'accords inspirée de l'Orchid ORC-1 (implémentation indépendante étendue)</footer>
|
||||
<footer>_chordlab v2.2 · logique d'accords inspirée de l'Orchid ORC-1 (implémentation indépendante étendue)</footer>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
@@ -479,7 +465,6 @@ const state = {
|
||||
playing:false, loop:false, playIdx:-1, playTimer:null,
|
||||
vlAuto:false,
|
||||
perf:"block", rate:0.25,
|
||||
bassPerf:"held",
|
||||
humanize:false,
|
||||
};
|
||||
|
||||
@@ -677,35 +662,6 @@ function suggestNext(){
|
||||
RENDU D'ÉVÉNEMENTS — partagé audio / MIDI live / export
|
||||
events: [{n, at (beats), dur (beats), vel, isBass}]
|
||||
========================================================= */
|
||||
function renderBassEvents(bassMidi, beats, hV, hT){
|
||||
const p = state.bassPerf, ev = [];
|
||||
const push = (n, at, dur, vel=110)=>{
|
||||
at = Math.max(0, at + hT());
|
||||
dur = Math.min(dur, Math.max(0.1, beats - at - 0.02));
|
||||
ev.push({n, at, dur, vel:vel+hV(), isBass:true});
|
||||
};
|
||||
if (p==="held"){ push(bassMidi, 0, beats*0.97); }
|
||||
else if (p==="quarter"){ for(let t=0;t<beats;t+=1) push(bassMidi,t,0.9); }
|
||||
else if (p==="eighth"){ for(let t=0;t<beats;t+=0.5) push(bassMidi,t,0.42); }
|
||||
else if (p==="offbeat"){ for(let t=0.5;t<beats;t+=1) push(bassMidi,t,0.42); }
|
||||
else if (p==="octave"){ let i=0; for(let t=0;t<beats;t+=0.5) push(i++%2?bassMidi+12:bassMidi,t,0.42); }
|
||||
else if (p==="root5"){ let i=0; for(let t=0;t<beats;t+=1) push(i++%2?bassMidi+7:bassMidi,t,0.9); }
|
||||
else if (p==="walk"){ const seq=[0,7,12,7]; let i=0; for(let t=0;t<beats;t+=1) push(bassMidi+seq[i++%4],t,0.9); }
|
||||
else if (p==="tresillo"){
|
||||
for(let c=0;c<beats;c+=4)
|
||||
[0,1.5,3].forEach(o=>{ if(c+o<beats) push(bassMidi,c+o,1.2,114); });
|
||||
}
|
||||
else if (p==="pump"){ for(let t=0;t<beats;t+=1) push(bassMidi,t,0.38,114); }
|
||||
else if (p==="rnd"){
|
||||
const opts=[0,0,7,12];
|
||||
for(let t=0;t<beats;t+=0.5)
|
||||
if (Math.random()<0.65) push(bassMidi+opts[Math.floor(Math.random()*opts.length)],t,0.42);
|
||||
if (!ev.length) push(bassMidi,0,0.9); // jamais de silence total
|
||||
}
|
||||
else { push(bassMidi, 0, beats*0.97); }
|
||||
return ev;
|
||||
}
|
||||
|
||||
function renderEvents(chord, beats, perfOverride){
|
||||
const perf = perfOverride || state.perf;
|
||||
const rate = state.rate;
|
||||
@@ -714,7 +670,7 @@ function renderEvents(chord, beats, perfOverride){
|
||||
const hV = ()=> hum ? Math.round((Math.random()-0.5)*20) : 0;
|
||||
const hT = ()=> hum ? (Math.random()-0.5)*0.03 : 0;
|
||||
if (chord.bass !== null && chord.bass !== undefined)
|
||||
ev.push(...renderBassEvents(chord.bass, beats, hV, hT));
|
||||
ev.push({n:chord.bass, at:0, dur:beats*0.97, vel:110+hV(), isBass:true});
|
||||
const notes = chord.notes;
|
||||
if (perf==="block"){
|
||||
notes.forEach(n=>ev.push({n, at:Math.max(0,hT()), dur:beats*0.95, vel:100+hV(), isBass:false}));
|
||||
@@ -913,7 +869,6 @@ 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,
|
||||
bassPerf:state.bassPerf,
|
||||
bpm:getBpm(), vlAuto:state.vlAuto,
|
||||
},
|
||||
progression:state.progression,
|
||||
@@ -943,7 +898,6 @@ function loadSession(file){
|
||||
state.keyScale=s.keyScale||"major";
|
||||
state.perf=s.perf||"block";
|
||||
state.rate=s.rate||0.25;
|
||||
state.bassPerf=s.bassPerf||"held";
|
||||
state.humanize=!!s.humanize;
|
||||
state.vlAuto=!!s.vlAuto;
|
||||
state.progression=Array.isArray(d.progression)?d.progression:[];
|
||||
@@ -966,8 +920,6 @@ function syncUiFromState(){
|
||||
$("keyRoot").value=state.keyRoot;
|
||||
$("keyScaleSel").value=state.keyScale;
|
||||
$("perfSel").value=state.perf; $("rateSel").value=state.rate;
|
||||
$("bassPerfSel").value=state.bassPerf;
|
||||
$("lcdBassPerf").textContent=$("bassPerfSel").selectedOptions[0].textContent.toUpperCase();
|
||||
$("humanBtn").classList.toggle("on", state.humanize);
|
||||
$("vlBtn").classList.toggle("on", state.vlAuto);
|
||||
$("lcdDrop").textContent=state.drop.toUpperCase();
|
||||
@@ -1134,10 +1086,6 @@ $("perfSel").addEventListener("change",function(){
|
||||
$("lcdPerf").textContent=this.selectedOptions[0].textContent.toUpperCase();
|
||||
});
|
||||
$("rateSel").addEventListener("change",function(){state.rate=parseFloat(this.value);});
|
||||
$("bassPerfSel").addEventListener("change",function(){
|
||||
state.bassPerf=this.value;
|
||||
$("lcdBassPerf").textContent=this.selectedOptions[0].textContent.toUpperCase();
|
||||
});
|
||||
$("humanBtn").addEventListener("click",function(){
|
||||
state.humanize=!state.humanize;
|
||||
this.classList.toggle("on",state.humanize);
|
||||
|
||||
Reference in New Issue
Block a user