diff --git a/assets/js/creations/pattern/pattern_audio.js b/assets/js/creations/pattern/pattern_audio.js index 12904b50..d33cd257 100755 --- a/assets/js/creations/pattern/pattern_audio.js +++ b/assets/js/creations/pattern/pattern_audio.js @@ -313,24 +313,34 @@ function schedulePianoRoll() { } }, events).start(0); - // calcula até onde vai a última nota do pianoroll + // Loop deve cobrir toda a extensão do pianoroll (última nota) + const barsInput = + parseInt(document.getElementById("bars-input")?.value || 1, 10) || 1; + let maxEndTick = 0; + for (const n of pattern.notes) { const pos = Number(n.pos) || 0; const rawLen = Number(n.len) || 0; - const len = rawLen < 0 ? TICKS_PER_STEP : rawLen; - maxEndTick = Math.max(maxEndTick, pos + Math.max(len, TICKS_PER_STEP)); + + // len negativo acontece em alguns casos (one-shot/edge do LMMS) + const lenTicks = rawLen < 0 ? TICKS_PER_STEP : rawLen; + + // garante no mínimo 1 step + const endTick = pos + Math.max(lenTicks, TICKS_PER_STEP); + if (endTick > maxEndTick) maxEndTick = endTick; } - const totalStepsNeeded = Math.max(1, Math.ceil(maxEndTick / TICKS_PER_STEP)); - const barsNeeded = Math.max(1, Math.ceil(totalStepsNeeded / STEPS_PER_BAR)); + const stepsNeeded = Math.max(1, Math.ceil(maxEndTick / TICKS_PER_STEP)); + const barsNeeded = Math.max(1, Math.ceil(stepsNeeded / STEPS_PER_BAR)); + + // respeita o bars-input se o usuário colocar maior, mas nunca menor que o necessário + const loopBars = Math.max(barsInput, barsNeeded); part.loop = true; - part.loopEnd = `${barsNeeded}m`; + part.loopEnd = `${loopBars}m`; - - activeParts.push(part); - } + } }); }