atualizações em tempo real para as patterns na playlist
Deploy / Deploy (push) Successful in 2m22s
Details
Deploy / Deploy (push) Successful in 2m22s
Details
This commit is contained in:
parent
46105a8fb2
commit
d003c2ccd6
|
|
@ -511,6 +511,39 @@ socket.on("action_broadcast", (payload) => {
|
|||
const LMMS_BAR_TICKS = 192;
|
||||
const STEPS_PER_BAR = 16;
|
||||
|
||||
// ticks por step (1/16) no LMMS: 192/16 = 12
|
||||
const TICKS_PER_STEP = LMMS_BAR_TICKS / STEPS_PER_BAR;
|
||||
|
||||
function _syncNotesWithStepToggle(pattern, stepIndex, isActive) {
|
||||
if (!pattern) return;
|
||||
if (!Array.isArray(pattern.notes)) pattern.notes = [];
|
||||
|
||||
const pos = Math.round(stepIndex * TICKS_PER_STEP);
|
||||
|
||||
const samePos = (n) => Number(n?.pos) === pos;
|
||||
|
||||
if (isActive) {
|
||||
// se já existe nota nesse step, não duplica
|
||||
if (pattern.notes.some(samePos)) return;
|
||||
|
||||
// tenta reaproveitar "template" de nota pra manter key/vol/pan coerentes
|
||||
const tpl = pattern.notes[0] || { vol: 100, len: TICKS_PER_STEP, pan: 0, key: 57 };
|
||||
|
||||
pattern.notes.push({
|
||||
vol: tpl.vol ?? 100,
|
||||
len: tpl.len ?? TICKS_PER_STEP,
|
||||
pan: tpl.pan ?? 0,
|
||||
key: tpl.key ?? 57,
|
||||
pos,
|
||||
});
|
||||
|
||||
pattern.notes.sort((a, b) => Number(a.pos) - Number(b.pos));
|
||||
} else {
|
||||
// remove todas as notas nesse step (útil inclusive pra "steps compostos")
|
||||
pattern.notes = pattern.notes.filter((n) => !samePos(n));
|
||||
}
|
||||
}
|
||||
|
||||
function _makeEmptyPattern(idx) {
|
||||
// tenta respeitar bars-input atual, mas nunca menos que 1 bar
|
||||
const bars = parseInt(document.getElementById("bars-input")?.value, 10) || 1;
|
||||
|
|
@ -1039,6 +1072,11 @@ async function handleActionBroadcast(action) {
|
|||
|
||||
t.patterns[pi].steps[si] = isActive;
|
||||
|
||||
_syncNotesWithStepToggle(t.patterns[pi], si, isActive);
|
||||
|
||||
// importante: se o Audio Editor estiver tocando, precisa re-schedulear
|
||||
restartAudioEditorIfPlaying();
|
||||
|
||||
try { updateStepUI(ti, pi, si, isActive); } catch {}
|
||||
if (!isFromSelf) schedulePatternRerender();
|
||||
}
|
||||
|
|
@ -1098,6 +1136,8 @@ async function handleActionBroadcast(action) {
|
|||
// 5) Salva no sessionStorage
|
||||
saveStateToSession();
|
||||
|
||||
restartAudioEditorIfPlaying();
|
||||
|
||||
break;
|
||||
}
|
||||
// Samples
|
||||
|
|
|
|||
Loading…
Reference in New Issue