diff --git a/assets/js/creations/pattern/pattern_audio.js b/assets/js/creations/pattern/pattern_audio.js index e1de1fde..cfccf789 100755 --- a/assets/js/creations/pattern/pattern_audio.js +++ b/assets/js/creations/pattern/pattern_audio.js @@ -34,6 +34,15 @@ const timerDisplay = document.getElementById("timer-display"); // Variável para armazenar as "Parts" (sequências melódicas) do Tone.js let activeParts = []; +let currentStep = 0; + +function updateStepHighlight(step) { + // usa a função já existente do seu pattern_ui + highlightStep(step, true); + setTimeout(() => highlightStep(step, false), 60); +} + + function formatTime(milliseconds) { const totalSeconds = Math.floor(milliseconds / 1000); const minutes = Math.floor(totalSeconds / 60) @@ -277,10 +286,17 @@ export function schedulePianoRoll() { part.loop = true; part.loopEnd = `${barsNeeded}m`; - scheduledParts.push(part); + activeParts.push(part); }); } +function stopScheduledPianoRoll() { + activeParts.forEach((p) => { + try { p.stop(); } catch {} + try { p.dispose(); } catch {} + }); + activeParts = []; +} // ========================================================================= // Renderizar o Pattern atual para um Blob de Áudio @@ -594,6 +610,33 @@ export function startSongPatternPlaybackOnTransport() { continue; // 👈 importante: não cair na lógica de steps abaixo } + // ✅ 1b) SAMPLER com piano roll (notes) — respeita oitava/pitch via playbackRate + if ( + track.type === "sampler" && + track.buffer && + Array.isArray(patt.notes) && + patt.notes.length > 0 + ) { + const stepStartTick = hit.localStep * LMMS_TICKS_PER_STEP; + const stepEndTick = stepStartTick + LMMS_TICKS_PER_STEP; + + for (const n of patt.notes) { + const nPos = Number(n.pos) || 0; + if (nPos < stepStartTick || nPos >= stepEndTick) continue; + + const offsetTicks = nPos - stepStartTick; + const t2 = time + ticksToSec(offsetTicks, stepIntervalSec); + + const lenTicks = Math.max(1, Number(n.len) || LMMS_TICKS_PER_STEP); + const durSec = Math.max(0.01, ticksToSec(lenTicks, stepIntervalSec)); + + playSamplerNoteAtTime(track, n.key, t2, durSec); + } + + continue; // 👈 importante: não cair na lógica de steps + } + + // ✅ 2) Lógica antiga de STEP (sampler / plugin sem notes) if (!patt.steps) continue;