melhorando a leitura de projetos no mmpCreator

This commit is contained in:
JotaChina committed 2025-12-23 19:30:19 -03:00
1 parent 55e9aa868d
commit d87b5ea07a
7 files changed
+386967 -370721

No files matched your search

+54 -48
View File
@@ -267,61 +267,67 @@ export async function parseMmpContent(xmlString) {
// 3. EXTRAÇÃO DAS TRILHAS DE BASSLINE E SEUS FILHOS
// -------------------------------------------------------------
let allBasslineInstruments = [];
// -------------------------------------------------------------
// 3. EXTRAÇÃO DAS TRILHAS DE BASSLINE E DO RACK COMPARTILHADO
// -------------------------------------------------------------
const basslineContainers = bbTrackNodes
.map((trackNode) => {
const trackName = trackNode.getAttribute("name") || "Beat/Bassline";
const containerId = `bassline_${Date.now()}_${Math.random()
.toString(36)
.substr(2, 9)}`;
// 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"]')
);
// A. Extrai os clipes da timeline (blocos azuis)
const playlistClips = Array.from(
trackNode.querySelectorAll(":scope > bbtco")
).map((bbtco) => {
return {
pos: parseInt(bbtco.getAttribute("pos"), 10) || 0,
len: parseInt(bbtco.getAttribute("len"), 10) || 192,
name: trackName,
};
});
// Cria um ID único para o rack
const rackId = bbRackNode
? `bbRack_${Date.now()}_${Math.random().toString(36).slice(2)}`
: null;
// Se não tiver clipes, geralmente é container vazio, mas vamos criar mesmo assim
if (playlistClips.length === 0) return 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"]')
);
// B. Extrai os instrumentos INTERNOS desta Bassline
const internalInstrumentNodes = Array.from(
trackNode.querySelectorAll('bbtrack > trackcontainer > track[type="0"]')
);
bbRackInstruments = internalInstrumentNodes
.map((node) => parseInstrumentNode(node, sortedBBTrackNameNodes, pathMap, rackId))
.filter(Boolean);
}
const internalInstruments = internalInstrumentNodes
.map((node) =>
parseInstrumentNode(
node,
sortedBBTrackNameNodes,
pathMap,
containerId
)
) // Passa ID do Pai
.filter((t) => t !== null);
// 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";
// Acumula na lista geral de instrumentos
allBasslineInstruments.push(...internalInstruments);
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,
}));
return {
id: containerId,
name: trackName,
type: "bassline", // Tipo especial para o audio_ui.js
playlist_clips: playlistClips,
instruments: internalInstruments, // Mantém referência
volume: 1,
pan: 0,
patterns: [],
isMuted: trackNode.getAttribute("muted") === "1",
};
})
.filter((t) => t !== null);
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