playlist funcional. inserindo loops de uma mesma faixa de pattern
Deploy / Deploy (push) Successful in 2m6s
Details
Deploy / Deploy (push) Successful in 2m6s
Details
This commit is contained in:
parent
f9ae0d92a8
commit
37c7fa006f
|
|
@ -277,6 +277,47 @@ export function renderAudioEditor() {
|
|||
});
|
||||
}
|
||||
|
||||
function getLoopStepsForBasslineLane(basslineTrack) {
|
||||
const patternIndex = basslineTrack.patternIndex ?? 0;
|
||||
|
||||
// pega os instrumentos que pertencem a esse rack (mesma lógica do pattern_ui) :contentReference[oaicite:1]{index=1}
|
||||
const srcId = basslineTrack.instrumentSourceId || basslineTrack.id;
|
||||
const children = (appState.pattern.tracks || []).filter(
|
||||
(t) => t.type !== "bassline" && t.parentBasslineId === srcId && !t.muted
|
||||
);
|
||||
|
||||
let maxSteps = 0;
|
||||
|
||||
for (const t of children) {
|
||||
const p = t.patterns?.[patternIndex];
|
||||
if (!p) continue;
|
||||
|
||||
if (Array.isArray(p.steps) && p.steps.length > 0) {
|
||||
maxSteps = Math.max(maxSteps, p.steps.length);
|
||||
continue;
|
||||
}
|
||||
|
||||
// fallback pra patterns que só têm notes
|
||||
if (Array.isArray(p.notes) && p.notes.length > 0) {
|
||||
let endTick = 0;
|
||||
for (const n of p.notes) {
|
||||
const pos = Number(n.pos) || 0;
|
||||
const len = Math.max(0, Number(n.len) || 0);
|
||||
endTick = Math.max(endTick, pos + len);
|
||||
}
|
||||
const steps = Math.ceil(endTick / TICKS_PER_STEP);
|
||||
maxSteps = Math.max(maxSteps, steps);
|
||||
}
|
||||
}
|
||||
|
||||
if (maxSteps <= 0) maxSteps = 16; // default
|
||||
// arredonda pra múltiplo de 16 (bem “LMMS feel”)
|
||||
maxSteps = Math.ceil(maxSteps / 16) * 16;
|
||||
|
||||
return maxSteps;
|
||||
}
|
||||
|
||||
|
||||
tracksToRender.forEach((trackData) => {
|
||||
const audioTrackLane = document.createElement("div");
|
||||
audioTrackLane.className = "audio-track-lane";
|
||||
|
|
@ -369,6 +410,29 @@ export function renderAudioEditor() {
|
|||
clipDiv.style.left = `${leftPos}px`;
|
||||
clipDiv.style.width = `${widthDim}px`;
|
||||
clipDiv.style.height = "100%";
|
||||
// ✅ overlay de “marquinhas pretas” (loop do pattern)
|
||||
const loopSteps = getLoopStepsForBasslineLane(trackData);
|
||||
const loopPx = loopSteps * stepWidthPx;
|
||||
|
||||
if (loopPx > 0) {
|
||||
clipDiv.style.position = "absolute"; // garante
|
||||
const markers = document.createElement("div");
|
||||
markers.style.position = "absolute";
|
||||
markers.style.inset = "0";
|
||||
markers.style.pointerEvents = "none";
|
||||
markers.style.opacity = "0.9";
|
||||
markers.style.backgroundImage = `repeating-linear-gradient(
|
||||
to right,
|
||||
rgba(0,0,0,0.75) 0px,
|
||||
rgba(0,0,0,0.75) 2px,
|
||||
transparent 2px,
|
||||
transparent ${loopPx}px
|
||||
)`;
|
||||
// deixa o texto por cima
|
||||
markers.style.zIndex = "6";
|
||||
clipDiv.appendChild(markers);
|
||||
}
|
||||
|
||||
const gridStyle = getComputedStyle(grid);
|
||||
clipDiv.style.backgroundImage = gridStyle.backgroundImage;
|
||||
clipDiv.style.backgroundSize = gridStyle.backgroundSize;
|
||||
|
|
@ -391,6 +455,8 @@ export function renderAudioEditor() {
|
|||
label.style.pointerEvents = "none";
|
||||
label.style.whiteSpace = "nowrap";
|
||||
label.style.overflow = "hidden";
|
||||
label.style.position = "relative";
|
||||
label.style.zIndex = "7";
|
||||
clipDiv.appendChild(label);
|
||||
|
||||
clipDiv.addEventListener("dblclick", (e) => {
|
||||
|
|
|
|||
|
|
@ -586,7 +586,11 @@ export function startSongPatternPlaybackOnTransport() {
|
|||
|
||||
for (const hit of activePatternHits) {
|
||||
const patt = track.patterns?.[hit.patternIndex];
|
||||
if (!patt) continue;
|
||||
if (!patt?.steps) continue;
|
||||
|
||||
// 👇 ADD
|
||||
const pattLen = patt.steps.length;
|
||||
const stepInPattern = pattLen > 0 ? (hit.localStep % pattLen) : hit.localStep;
|
||||
|
||||
// ✅ 1) PLUGIN com piano roll (notes)
|
||||
if (
|
||||
|
|
@ -626,7 +630,7 @@ export function startSongPatternPlaybackOnTransport() {
|
|||
// ✅ 2) Lógica antiga de STEP (sampler / plugin sem notes)
|
||||
if (!patt.steps) continue;
|
||||
|
||||
if (patt.steps[hit.localStep]) {
|
||||
if (patt.steps[stepInPattern]) {
|
||||
if (track.type === "sampler" && track.player) {
|
||||
track.player.restart = true;
|
||||
try { track.player.start(time); } catch {}
|
||||
|
|
|
|||
Loading…
Reference in New Issue