diff --git a/assets/js/creations/file.js b/assets/js/creations/file.js index ce15097f..ca13d6ac 100755 --- a/assets/js/creations/file.js +++ b/assets/js/creations/file.js @@ -264,82 +264,81 @@ export async function parseMmpContent(xmlString) { .filter((t) => t !== null); // ------------------------------------------------------------- - // 3. EXTRAÇÃO DAS TRILHAS DE BASSLINE E SEUS FILHOS + // 3. EXTRAÇÃO DAS TRILHAS DE BASSLINE (BBTracks) E RACK COMPARTILHADO // ------------------------------------------------------------- - // ------------------------------------------------------------- -// 3. EXTRAÇÃO DAS TRILHAS DE BASSLINE E DO RACK COMPARTILHADO -// ------------------------------------------------------------- + // 3.1) Acha um node que realmente contém o rack de instrumentos do BBE + const bbTrackNodes = Array.from(xmlDoc.querySelectorAll('track[type="1"]')); -// 3.1) Acha o "rack" que realmente contém os instrumentos do Beat/Bassline Editor -const bbRackNode = bbTrackNodes.find((n) => - n.querySelector('bbtrack > trackcontainer > track[type="0"]') -); - -// Cria um ID único para o rack -const rackId = bbRackNode - ? `bbRack_${Date.now()}_${Math.random().toString(36).slice(2)}` - : null; - -// 3.2) Parseia instrumentos UMA vez (do rack) -let bbRackInstruments = []; -if (bbRackNode && rackId) { - const internalInstrumentNodes = Array.from( - bbRackNode.querySelectorAll('bbtrack > trackcontainer > track[type="0"]') + const bbRackNode = bbTrackNodes.find((n) => + n.querySelector('bbtrack > trackcontainer > track[type="0"]') ); - bbRackInstruments = internalInstrumentNodes - .map((node) => parseInstrumentNode(node, sortedBBTrackNameNodes, pathMap, rackId)) + // ID do rack compartilhado + const rackId = bbRackNode + ? `bbRack_${Date.now()}_${Math.random().toString(36).slice(2)}` + : null; + + // 3.2) Parseia instrumentos UMA vez (do rack) + let bbRackInstruments = []; + if (bbRackNode && rackId) { + const internalInstrumentNodes = Array.from( + bbRackNode.querySelectorAll('bbtrack > trackcontainer > track[type="0"]') + ); + + bbRackInstruments = internalInstrumentNodes + .map((node) => + parseInstrumentNode(node, sortedBBTrackNameNodes, pathMap, rackId) + ) + .filter((t) => t !== null); + } + + // 3.3) Cria os containers “Caixa/Kick/…” como patterns (sem instrumentos próprios) + const basslineContainers = bbTrackNodes + .map((trackNode, idx) => { + const trackName = trackNode.getAttribute("name") || "Beat/Bassline"; + + const playlistClips = Array.from( + trackNode.querySelectorAll(":scope > bbtco") + ).map((bbtco) => ({ + pos: parseInt(bbtco.getAttribute("pos"), 10) || 0, + len: parseInt(bbtco.getAttribute("len"), 10) || 192, + name: trackName, + })); + + if (playlistClips.length === 0) return null; + + return { + id: `bassline_${Date.now()}_${Math.random().toString(36).slice(2)}`, + name: trackName, + type: "bassline", + playlist_clips: playlistClips, + + // 🔥 importante: qual “coluna/pattern” este BBTrack representa + patternIndex: idx, + + // 🔥 importante: de onde vêm os instrumentos + instrumentSourceId: rackId, + + volume: 1, + pan: 0, + patterns: [], + isMuted: trackNode.getAttribute("muted") === "1", + }; + }) .filter(Boolean); -} - -// 3.3) Agora cria os BBTracks (Caixa, Kick, etc) como "containers/patterns" -// Eles não carregam instrumentos próprios: só apontam para o rack. -const basslineContainers = bbTrackNodes - .map((trackNode, idx) => { - const trackName = trackNode.getAttribute("name") || "Beat/Bassline"; - - const playlistClips = Array.from( - trackNode.querySelectorAll(":scope > bbtco") - ).map((bbtco) => ({ - pos: parseInt(bbtco.getAttribute("pos"), 10) || 0, - len: parseInt(bbtco.getAttribute("len"), 10) || 192, - name: trackName, - })); - - if (playlistClips.length === 0) return null; - - return { - id: `bassline_${Date.now()}_${Math.random().toString(36).slice(2)}`, - name: trackName, - type: "bassline", - playlist_clips: playlistClips, - - // qual "pattern/coluna" este BBTrack representa - patternIndex: idx, - - // aponta pro rack real (se não achou rack, cai nele mesmo) - instrumentSourceId: rackId, - - volume: 1, - pan: 0, - patterns: [], - isMuted: trackNode.getAttribute("muted") === "1", - }; - }) - .filter(Boolean); // ------------------------------------------------------------- // 4. COMBINAÇÃO E FINALIZAÇÃO // ------------------------------------------------------------- - // A lista final plana contém TODOS: - // 1. Instrumentos da Raiz - // 2. Instrumentos dentro de Basslines - // 3. As próprias Basslines (Containers) + // A lista final plana contém: + // 1) Instrumentos do Song Editor + // 2) Instrumentos do rack compartilhado do Beat/Bassline Editor + // 3) Containers (Caixa/Kick/...) que só referenciam o rack const newTracks = [ ...songTracks, - ...allBasslineInstruments, + ...bbRackInstruments, ...basslineContainers, ];