melhorando a leitura de projetos no mmpCreator
Deploy / Deploy (push) Successful in 3m12s
Details
Deploy / Deploy (push) Successful in 3m12s
Details
This commit is contained in:
parent
9cf3c585fe
commit
a6291ef60a
755813
_data/all.yml
755813
_data/all.yml
File diff suppressed because it is too large
Load Diff
|
|
@ -86,6 +86,7 @@
|
||||||
- remixtrap-n.wav
|
- remixtrap-n.wav
|
||||||
- screams.wav
|
- screams.wav
|
||||||
- sect02.wav
|
- sect02.wav
|
||||||
|
- sipaus2.wav
|
||||||
- synthpop-xcalibur-retrospect.wav
|
- synthpop-xcalibur-retrospect.wav
|
||||||
- the-riddle-amandyte.wav
|
- the-riddle-amandyte.wav
|
||||||
- titulo-incorreto-1.wav
|
- titulo-incorreto-1.wav
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
BIN
_data/users.db
BIN
_data/users.db
Binary file not shown.
|
|
@ -267,61 +267,67 @@ export async function parseMmpContent(xmlString) {
|
||||||
// 3. EXTRAÇÃO DAS TRILHAS DE BASSLINE E SEUS FILHOS
|
// 3. EXTRAÇÃO DAS TRILHAS DE BASSLINE E SEUS FILHOS
|
||||||
// -------------------------------------------------------------
|
// -------------------------------------------------------------
|
||||||
|
|
||||||
let allBasslineInstruments = [];
|
// -------------------------------------------------------------
|
||||||
|
// 3. EXTRAÇÃO DAS TRILHAS DE BASSLINE E DO RACK COMPARTILHADO
|
||||||
|
// -------------------------------------------------------------
|
||||||
|
|
||||||
|
// 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"]')
|
||||||
|
);
|
||||||
|
|
||||||
|
bbRackInstruments = internalInstrumentNodes
|
||||||
|
.map((node) => parseInstrumentNode(node, sortedBBTrackNameNodes, pathMap, rackId))
|
||||||
|
.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
|
const basslineContainers = bbTrackNodes
|
||||||
.map((trackNode) => {
|
.map((trackNode, idx) => {
|
||||||
const trackName = trackNode.getAttribute("name") || "Beat/Bassline";
|
const trackName = trackNode.getAttribute("name") || "Beat/Bassline";
|
||||||
const containerId = `bassline_${Date.now()}_${Math.random()
|
|
||||||
.toString(36)
|
|
||||||
.substr(2, 9)}`;
|
|
||||||
|
|
||||||
// A. Extrai os clipes da timeline (blocos azuis)
|
|
||||||
const playlistClips = Array.from(
|
const playlistClips = Array.from(
|
||||||
trackNode.querySelectorAll(":scope > bbtco")
|
trackNode.querySelectorAll(":scope > bbtco")
|
||||||
).map((bbtco) => {
|
).map((bbtco) => ({
|
||||||
return {
|
|
||||||
pos: parseInt(bbtco.getAttribute("pos"), 10) || 0,
|
pos: parseInt(bbtco.getAttribute("pos"), 10) || 0,
|
||||||
len: parseInt(bbtco.getAttribute("len"), 10) || 192,
|
len: parseInt(bbtco.getAttribute("len"), 10) || 192,
|
||||||
name: trackName,
|
name: trackName,
|
||||||
};
|
}));
|
||||||
});
|
|
||||||
|
|
||||||
// Se não tiver clipes, geralmente é container vazio, mas vamos criar mesmo assim
|
|
||||||
if (playlistClips.length === 0) return null;
|
if (playlistClips.length === 0) return null;
|
||||||
|
|
||||||
// B. Extrai os instrumentos INTERNOS desta Bassline
|
|
||||||
const internalInstrumentNodes = Array.from(
|
|
||||||
trackNode.querySelectorAll('bbtrack > trackcontainer > track[type="0"]')
|
|
||||||
);
|
|
||||||
|
|
||||||
const internalInstruments = internalInstrumentNodes
|
|
||||||
.map((node) =>
|
|
||||||
parseInstrumentNode(
|
|
||||||
node,
|
|
||||||
sortedBBTrackNameNodes,
|
|
||||||
pathMap,
|
|
||||||
containerId
|
|
||||||
)
|
|
||||||
) // Passa ID do Pai
|
|
||||||
.filter((t) => t !== null);
|
|
||||||
|
|
||||||
// Acumula na lista geral de instrumentos
|
|
||||||
allBasslineInstruments.push(...internalInstruments);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: containerId,
|
id: `bassline_${Date.now()}_${Math.random().toString(36).slice(2)}`,
|
||||||
name: trackName,
|
name: trackName,
|
||||||
type: "bassline", // Tipo especial para o audio_ui.js
|
type: "bassline",
|
||||||
playlist_clips: playlistClips,
|
playlist_clips: playlistClips,
|
||||||
instruments: internalInstruments, // Mantém referência
|
|
||||||
|
// qual "pattern/coluna" este BBTrack representa
|
||||||
|
patternIndex: idx,
|
||||||
|
|
||||||
|
// aponta pro rack real (se não achou rack, cai nele mesmo)
|
||||||
|
instrumentSourceId: rackId,
|
||||||
|
|
||||||
volume: 1,
|
volume: 1,
|
||||||
pan: 0,
|
pan: 0,
|
||||||
patterns: [],
|
patterns: [],
|
||||||
isMuted: trackNode.getAttribute("muted") === "1",
|
isMuted: trackNode.getAttribute("muted") === "1",
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
.filter((t) => t !== null);
|
.filter(Boolean);
|
||||||
|
|
||||||
// -------------------------------------------------------------
|
// -------------------------------------------------------------
|
||||||
// 4. COMBINAÇÃO E FINALIZAÇÃO
|
// 4. COMBINAÇÃO E FINALIZAÇÃO
|
||||||
|
|
|
||||||
|
|
@ -633,15 +633,23 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
|
||||||
window.openPatternEditor = function (basslineTrack) {
|
window.openPatternEditor = function (basslineTrack) {
|
||||||
console.log("Focando na Bassline:", basslineTrack.name);
|
console.log("Focando na Bassline:", basslineTrack.name);
|
||||||
// Define o ID da bassline como foco
|
|
||||||
appState.pattern.focusedBasslineId = basslineTrack.id;
|
|
||||||
// Renderiza o editor, que agora vai filtrar e mostrar só o conteúdo dela
|
|
||||||
renderAll();
|
|
||||||
|
|
||||||
// Feedback visual opcional
|
appState.pattern.focusedBasslineId = basslineTrack.id;
|
||||||
showToast(`Editando: ${basslineTrack.name}`, "info");
|
|
||||||
|
// 🔥 chave: sincroniza a coluna/pattern com o BBTrack escolhido
|
||||||
|
if (Number.isInteger(basslineTrack.patternIndex)) {
|
||||||
|
appState.pattern.activePatternIndex = basslineTrack.patternIndex;
|
||||||
|
|
||||||
|
// opcional: manter o selector UI consistente (se existir)
|
||||||
|
const sel = document.getElementById("global-pattern-selector");
|
||||||
|
if (sel) sel.value = String(basslineTrack.patternIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderAll();
|
||||||
|
showToast(`Editando: ${basslineTrack.name}`, "info");
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
window.exitPatternFocus = function() {
|
window.exitPatternFocus = function() {
|
||||||
console.log("Saindo do foco da Bassline");
|
console.log("Saindo do foco da Bassline");
|
||||||
appState.pattern.focusedBasslineId = null;
|
appState.pattern.focusedBasslineId = null;
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,21 @@ export function renderPatternEditor() {
|
||||||
|
|
||||||
if (appState.pattern.focusedBasslineId) {
|
if (appState.pattern.focusedBasslineId) {
|
||||||
isFocusedMode = true;
|
isFocusedMode = true;
|
||||||
// Mostra apenas os filhos da Bassline selecionada
|
|
||||||
tracksToRender = appState.pattern.tracks.filter(t => t.parentBasslineId === appState.pattern.focusedBasslineId);
|
|
||||||
|
|
||||||
// Busca o nome para exibir no título
|
// 1) acha o container (Caixa/Kick/...) focado
|
||||||
const basslineTrack = appState.pattern.tracks.find(t => t.id === appState.pattern.focusedBasslineId);
|
const basslineTrack = appState.pattern.tracks.find(
|
||||||
|
t => t.id === appState.pattern.focusedBasslineId && t.type === "bassline"
|
||||||
|
);
|
||||||
|
|
||||||
|
// 2) usa o rack real como "pai" (fallback: id do próprio container)
|
||||||
|
const srcId = basslineTrack?.instrumentSourceId || appState.pattern.focusedBasslineId;
|
||||||
|
|
||||||
|
// 3) mostra somente instrumentos pertencentes ao rack
|
||||||
|
tracksToRender = appState.pattern.tracks.filter(
|
||||||
|
t => t.type !== "bassline" && t.parentBasslineId === srcId
|
||||||
|
);
|
||||||
|
|
||||||
|
// Nome no header
|
||||||
if (basslineTrack) contextName = basslineTrack.name;
|
if (basslineTrack) contextName = basslineTrack.name;
|
||||||
} else {
|
} else {
|
||||||
// Modo Padrão: Mostra trilhas da raiz (sem pai) e que NÃO são containers de bassline
|
// Modo Padrão: Mostra trilhas da raiz (sem pai) e que NÃO são containers de bassline
|
||||||
|
|
@ -170,7 +180,11 @@ export function redrawSequencer() {
|
||||||
|
|
||||||
if (!trackData || !trackData.patterns || trackData.patterns.length === 0) return;
|
if (!trackData || !trackData.patterns || trackData.patterns.length === 0) return;
|
||||||
|
|
||||||
const activePatternIndex = trackData.activePatternIndex || 0;
|
const isFocused = !!appState.pattern.focusedBasslineId;
|
||||||
|
const activePatternIndex = isFocused
|
||||||
|
? (appState.pattern.activePatternIndex || 0)
|
||||||
|
: (trackData.activePatternIndex || 0);
|
||||||
|
|
||||||
const activePattern = trackData.patterns[activePatternIndex];
|
const activePattern = trackData.patterns[activePatternIndex];
|
||||||
if (!activePattern) return;
|
if (!activePattern) return;
|
||||||
|
|
||||||
|
|
@ -299,7 +313,10 @@ export function updateGlobalPatternSelector() {
|
||||||
const activeTrack = appState.pattern.tracks.find(t => t.id === activeTrackId);
|
const activeTrack = appState.pattern.tracks.find(t => t.id === activeTrackId);
|
||||||
|
|
||||||
// Tenta pegar a track ativa ou a primeira visível como referência de patterns
|
// Tenta pegar a track ativa ou a primeira visível como referência de patterns
|
||||||
const referenceTrack = activeTrack || appState.pattern.tracks.find(t => !t.isMuted && t.type !== 'bassline');
|
const isFocused = !!appState.pattern.focusedBasslineId;
|
||||||
|
const referenceTrack = isFocused
|
||||||
|
? appState.pattern.tracks.find(t => t.type !== "bassline" && t.parentBasslineId !== null)
|
||||||
|
: (activeTrack || appState.pattern.tracks.find(t => !t.isMuted && t.type !== "bassline"));
|
||||||
|
|
||||||
globalPatternSelector.innerHTML = '';
|
globalPatternSelector.innerHTML = '';
|
||||||
|
|
||||||
|
|
@ -311,7 +328,9 @@ export function updateGlobalPatternSelector() {
|
||||||
globalPatternSelector.appendChild(option);
|
globalPatternSelector.appendChild(option);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (activeTrack) {
|
if (isFocused) {
|
||||||
|
globalPatternSelector.value = appState.pattern.activePatternIndex || 0;
|
||||||
|
} else if (activeTrack) {
|
||||||
globalPatternSelector.value = activeTrack.activePatternIndex || 0;
|
globalPatternSelector.value = activeTrack.activePatternIndex || 0;
|
||||||
} else {
|
} else {
|
||||||
globalPatternSelector.value = 0;
|
globalPatternSelector.value = 0;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue