playlist funcional. inserindo loops de uma mesma faixa de pattern
Deploy / Deploy (push) Successful in 2m5s Details

This commit is contained in:
JotaChina 2025-12-25 17:20:28 -03:00
parent 37c7fa006f
commit a4b4157f7e
1 changed files with 54 additions and 0 deletions

View File

@ -377,6 +377,60 @@ export async function parseMmpContent(xmlString) {
const pathMap = getSamplePathMap();
// -------------------------------------------------------------
// 2.1) EXTRAÇÃO DE SAMPLETRACKS DO SONG EDITOR (track[type="2"])
// -------------------------------------------------------------
const secondsPerStep = getSecondsPerStep(); // já é usado no JSON parser :contentReference[oaicite:3]{index=3}
const sampleTrackNodes = Array.from(
xmlDoc.querySelectorAll('song > trackcontainer > track[type="2"]')
);
sampleTrackNodes.forEach((node, idx) => {
const trackName = node.getAttribute("name") || `Áudio ${idx + 1}`;
// cria lane de áudio
const trackId = `sample_lane_${Date.now()}_${idx}`;
appState.audio.tracks.push({ id: trackId, name: trackName });
// pan/vol defaults do <sampletrack>
const st = node.querySelector("sampletrack");
const laneVol = st ? Number(st.getAttribute("vol") ?? 100) / 100 : 1;
const lanePan = st ? Number(st.getAttribute("pan") ?? 0) / 100 : 0;
// cada <sampletco> é um clip
const clips = Array.from(node.querySelectorAll(":scope > sampletco"));
clips.forEach((c, cidx) => {
const src = c.getAttribute("src") || "";
const fileName = src.split(/[\\/]/).pop(); // "#2.wav"
// resolve caminho via manifest; fallback para /samples
const resolvedUrl =
(fileName && pathMap[fileName]) ||
(fileName ? `${SAMPLE_SRC}/${fileName}` : null);
if (!resolvedUrl) return;
const posTicks = Number(c.getAttribute("pos") || 0);
const lenTicks = Number(c.getAttribute("len") || 0);
const startSec = ((posTicks / 12) * secondsPerStep);
const durSec = ((lenTicks / 12) * secondsPerStep);
const clipId = `clip_${trackId}_${cidx}`;
addAudioClipToTimeline(resolvedUrl, trackId, startSec, clipId, fileName);
const muted = String(c.getAttribute("muted") ?? "0") === "1";
updateAudioClipProperties(clipId, {
durationInSeconds: durSec || 0,
volume: muted ? 0 : laneVol,
pan: isNaN(lanePan) ? 0 : lanePan,
});
});
});
// 1. Identifica colunas de beat/patterns (usado para mapear steps)
// Normalmente ficam dentro do primeiro container de Bassline
const bbTrackNodes = Array.from(xmlDoc.querySelectorAll('track[type="1"]'));