melhorando a leitura de projetos no mmpCreator
Deploy / Deploy (push) Successful in 1m56s
Details
Deploy / Deploy (push) Successful in 1m56s
Details
This commit is contained in:
parent
3bd714e29d
commit
6beebe7ea2
|
|
@ -104,7 +104,7 @@ function parseInstrumentNode(
|
||||||
const trackName = trackNode.getAttribute("name");
|
const trackName = trackNode.getAttribute("name");
|
||||||
const instrumentName = instrumentNode.getAttribute("name");
|
const instrumentName = instrumentNode.getAttribute("name");
|
||||||
|
|
||||||
// 1. Coleta TODOS os patterns reais dentro do XML do instrumento
|
// Lógica de Patterns
|
||||||
const allPatternsNodeList = trackNode.querySelectorAll("pattern");
|
const allPatternsNodeList = trackNode.querySelectorAll("pattern");
|
||||||
const allPatternsArray = Array.from(allPatternsNodeList).sort((a, b) => {
|
const allPatternsArray = Array.from(allPatternsNodeList).sort((a, b) => {
|
||||||
return (
|
return (
|
||||||
|
|
@ -113,18 +113,14 @@ function parseInstrumentNode(
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 2. CORREÇÃO PRINCIPAL:
|
const patternsToCreate =
|
||||||
// O loop deve ser baseado nos patterns existentes no XML, não nos blocos da timeline (bbtco).
|
sortedBBTrackNameNodes.length > 0
|
||||||
// Se não houver patterns no XML (instrumento vazio), criamos um array com 1 item para gerar o pattern default.
|
? sortedBBTrackNameNodes
|
||||||
const loopSource = allPatternsArray.length > 0 ? allPatternsArray : [null];
|
: [{ getAttribute: () => "Pattern 1" }];
|
||||||
|
|
||||||
const patterns = loopSource.map((patternNode, index) => {
|
const patterns = patternsToCreate.map((bbTrack, index) => {
|
||||||
// Tenta pegar o nome do bloco correspondente na timeline, se existir, senão gera um genérico
|
const patternNode = allPatternsArray[index];
|
||||||
const bbTrackName =
|
const bbTrackName = bbTrack.getAttribute("name") || `Pattern ${index + 1}`;
|
||||||
sortedBBTrackNameNodes[index] &&
|
|
||||||
sortedBBTrackNameNodes[index].getAttribute("name")
|
|
||||||
? sortedBBTrackNameNodes[index].getAttribute("name")
|
|
||||||
: `Pattern ${index + 1}`;
|
|
||||||
|
|
||||||
if (!patternNode) {
|
if (!patternNode) {
|
||||||
return {
|
return {
|
||||||
|
|
@ -139,7 +135,10 @@ function parseInstrumentNode(
|
||||||
const steps = new Array(patternSteps).fill(false);
|
const steps = new Array(patternSteps).fill(false);
|
||||||
const notes = [];
|
const notes = [];
|
||||||
|
|
||||||
const ticksPerStep = 48; // 192 / 4
|
// === CORREÇÃO MATEMÁTICA ===
|
||||||
|
// No LMMS, 1 semínima (beat) = 192 ticks.
|
||||||
|
// 1 semicolcheia (1/16 step) = 192 / 4 = 48 ticks.
|
||||||
|
const ticksPerStep = 48;
|
||||||
|
|
||||||
patternNode.querySelectorAll("note").forEach((noteNode) => {
|
patternNode.querySelectorAll("note").forEach((noteNode) => {
|
||||||
const pos = parseInt(noteNode.getAttribute("pos"), 10);
|
const pos = parseInt(noteNode.getAttribute("pos"), 10);
|
||||||
|
|
@ -151,12 +150,8 @@ function parseInstrumentNode(
|
||||||
pan: parseInt(noteNode.getAttribute("pan"), 10),
|
pan: parseInt(noteNode.getAttribute("pan"), 10),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Calcula o step visual (para o beat editor)
|
// Calcula qual quadradinho acender
|
||||||
// Se o pos for > patternSteps * 48 (ex: compasso 2), precisamos normalizar se quisermos mostrar tudo junto
|
const stepIndex = Math.round(pos / ticksPerStep);
|
||||||
// Mas para manter simples, pegamos o relativo:
|
|
||||||
const relativePos = pos % (patternSteps * ticksPerStep);
|
|
||||||
const stepIndex = Math.round(relativePos / ticksPerStep);
|
|
||||||
|
|
||||||
if (stepIndex < patternSteps) steps[stepIndex] = true;
|
if (stepIndex < patternSteps) steps[stepIndex] = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -168,7 +163,7 @@ function parseInstrumentNode(
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
// Lógica de Sample vs Plugin (mantida igual)
|
// Lógica de Sample vs Plugin
|
||||||
let finalSamplePath = null;
|
let finalSamplePath = null;
|
||||||
let trackType = "plugin";
|
let trackType = "plugin";
|
||||||
|
|
||||||
|
|
@ -197,13 +192,13 @@ function parseInstrumentNode(
|
||||||
name: trackName,
|
name: trackName,
|
||||||
type: trackType,
|
type: trackType,
|
||||||
samplePath: finalSamplePath,
|
samplePath: finalSamplePath,
|
||||||
patterns: patterns, // Agora contém TODAS as patterns (pos 0, 192, etc)
|
patterns: patterns,
|
||||||
activePatternIndex: 0,
|
activePatternIndex: 0,
|
||||||
volume: !isNaN(volFromFile) ? volFromFile / 100 : DEFAULT_VOLUME,
|
volume: !isNaN(volFromFile) ? volFromFile / 100 : DEFAULT_VOLUME,
|
||||||
pan: !isNaN(panFromFile) ? panFromFile / 100 : DEFAULT_PAN,
|
pan: !isNaN(panFromFile) ? panFromFile / 100 : DEFAULT_PAN,
|
||||||
instrumentName: instrumentName,
|
instrumentName: instrumentName,
|
||||||
instrumentXml: instrumentNode.innerHTML,
|
instrumentXml: instrumentNode.innerHTML,
|
||||||
parentBasslineId: parentBasslineId,
|
parentBasslineId: parentBasslineId, // Guarda o ID do pai para filtragem na UI
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -657,21 +657,19 @@
|
||||||
// --- B. Steps (Correção Aqui) ---
|
// --- B. Steps (Correção Aqui) ---
|
||||||
let stepData = [];
|
let stepData = [];
|
||||||
|
|
||||||
// LÓGICA ATUALIZADA DE VISUALIZAÇÃO
|
|
||||||
// Se houver múltiplos patterns (loop longo), combinamos os steps ativos
|
|
||||||
// ou pegamos o pattern que realmente tem notas.
|
|
||||||
if (inst.patterns && inst.patterns.length > 0) {
|
if (inst.patterns && inst.patterns.length > 0) {
|
||||||
// Cria um array base de 16 steps (ou maior se quiser suportar 32/64)
|
// Tenta encontrar um pattern que tenha pelo menos uma nota 'true'
|
||||||
stepData = new Array(16).fill(false);
|
const activePattern = inst.patterns.find((p) =>
|
||||||
|
p.steps.some((s) => s === true)
|
||||||
|
);
|
||||||
|
|
||||||
inst.patterns.forEach((p) => {
|
if (activePattern) {
|
||||||
// Mescla os steps desse pattern no array principal visual
|
// Se achou um com notas, usa ele
|
||||||
if (p.steps) {
|
stepData = activePattern.steps;
|
||||||
p.steps.forEach((isActive, idx) => {
|
} else {
|
||||||
if (isActive && idx < 16) stepData[idx] = true;
|
// Se todos estão vazios, usa o primeiro mesmo
|
||||||
});
|
stepData = inst.patterns[0].steps;
|
||||||
}
|
}
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
stepData = Array(16).fill(false);
|
stepData = Array(16).fill(false);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue