adicionando instrumentos no editor de patterns
Deploy / Deploy (push) Successful in 1m59s Details

This commit is contained in:
JotaChina 2025-12-27 20:17:51 -03:00
parent 96a7bd3f3c
commit cca7ddd398
2 changed files with 53 additions and 53 deletions

View File

@ -203,61 +203,60 @@ export async function loadAudioForTrack(track) {
export function addTrackToState() { export function addTrackToState() {
const totalSteps = getTotalSteps(); const totalSteps = getTotalSteps();
// ✅ define o "pai" correto pra UI conseguir renderizar const all = appState.pattern.tracks || [];
const focusedId = appState.pattern.focusedBasslineId || null; const nonBass = all.filter(t => t.type !== "bassline");
let parentBasslineId = null; // Prefere usar como referência um instrumento do rack raiz que já tenha patterns
if (focusedId) {
const basslineTrack = appState.pattern.tracks.find(
(t) => t.type === "bassline" && t.id === focusedId
);
// mesmo critério do pattern_ui: srcId = instrumentSourceId || focusedId
parentBasslineId = basslineTrack?.instrumentSourceId || focusedId;
} else {
parentBasslineId = null; // IMPORTANTÍSSIMO: não deixar undefined
}
// ✅ pega referência do mesmo pai (pra clonar patterns compatíveis)
const referenceTrack = const referenceTrack =
appState.pattern.tracks.find( nonBass.find(t => t.parentBasslineId == null && Array.isArray(t.patterns) && t.patterns.length) ||
(t) => nonBass.find(t => Array.isArray(t.patterns) && t.patterns.length) ||
t.type !== "bassline" &&
(t.parentBasslineId ?? null) === parentBasslineId &&
Array.isArray(t.patterns) &&
t.patterns.length > 0
) ||
appState.pattern.tracks.find(
(t) => t.type !== "bassline" && Array.isArray(t.patterns) && t.patterns.length > 0
) ||
null; null;
const newId = Date.now() + Math.random(); // Quantos patterns existem no projeto? (pega o máximo entre instrumentos)
const patternCount = Math.max(
1,
...nonBass.map(t => Array.isArray(t.patterns) ? t.patterns.length : 0)
);
const patterns = Array.from({ length: patternCount }, (_, i) => {
const ref = referenceTrack?.patterns?.[i];
const refStepsLen = Array.isArray(ref?.steps) ? ref.steps.length : totalSteps;
const name = String(ref?.name || `Pattern ${i + 1}`);
const pos = Number.isFinite(Number(ref?.pos)) ? Number(ref.pos) : i * 192; // 1 bar = 192 ticks no LMMS
return {
name,
steps: new Array(refStepsLen).fill(false),
notes: [],
pos
};
});
const rootCount = nonBass.filter(t => t.parentBasslineId == null).length;
const newId = Date.now() + Math.random();
const newTrack = { const newTrack = {
id: newId, id: newId,
name: `Novo Instrumento ${appState.pattern.tracks.filter(t => t.type !== "bassline").length + 1}`, name: `Novo Instrumento ${rootCount + 1}`,
samplePath: null, samplePath: null,
type: "plugin", type: "plugin",
// ✅ AQUI a chave: agora a track entra no lugar certo (rack ou root) // ✅ Rack raiz
parentBasslineId, parentBasslineId: null,
// instrumento default
instrumentName: "kicker", instrumentName: "kicker",
instrumentXml: DEFAULT_KICKER_XML, instrumentXml: DEFAULT_KICKER_XML,
player: null, player: null,
buffer: null, buffer: null,
instrument: null,
previewPlayer: null,
patterns: referenceTrack patterns,
? referenceTrack.patterns.map((p) => ({ activePatternIndex: appState.pattern.activePatternIndex ?? 0,
name: p.name,
steps: new Array((p.steps?.length || totalSteps)).fill(false),
notes: [],
pos: p.pos,
}))
: [{ name: "Pattern 1", steps: new Array(totalSteps).fill(false), notes: [], pos: 0 }],
activePatternIndex: 0,
volume: DEFAULT_VOLUME, volume: DEFAULT_VOLUME,
pan: DEFAULT_PAN, pan: DEFAULT_PAN,
volumeNode: new Tone.Volume(Tone.gainToDb(DEFAULT_VOLUME)), volumeNode: new Tone.Volume(Tone.gainToDb(DEFAULT_VOLUME)),
@ -272,10 +271,9 @@ export function addTrackToState() {
appState.pattern.tracks.push(newTrack); appState.pattern.tracks.push(newTrack);
appState.pattern.activeTrackId = newTrack.id; appState.pattern.activeTrackId = newTrack.id;
console.log("Faixa adicionada ao estado com Kicker padrão."); console.log("✅ Instrumento adicionado no rack raiz:", newTrack.name);
} }
export function removeTrackById(trackId) { export function removeTrackById(trackId) {
const index = appState.pattern.tracks.findIndex(t => t.id === trackId); const index = appState.pattern.tracks.findIndex(t => t.id === trackId);

View File

@ -19,26 +19,28 @@ export function renderPatternEditor() {
let contextName = "Song Editor"; // Nome da visualização atual let contextName = "Song Editor"; // Nome da visualização atual
if (appState.pattern.focusedBasslineId) { if (appState.pattern.focusedBasslineId) {
isFocusedMode = true; isFocusedMode = true;
// 1) acha o container (Caixa/Kick/...) focado // 1) acha o container (Caixa/Kick/...) focado
const basslineTrack = appState.pattern.tracks.find( const basslineTrack = appState.pattern.tracks.find(
t => t.id === appState.pattern.focusedBasslineId && t.type === "bassline" t => t.id === appState.pattern.focusedBasslineId && t.type === "bassline"
); );
// 2) usa o rack real como "pai" (fallback: id do próprio container) // 2) usa o rack real como "pai" (fallback: id do próprio container)
const srcId = basslineTrack?.instrumentSourceId || appState.pattern.focusedBasslineId; const srcId = basslineTrack?.instrumentSourceId || appState.pattern.focusedBasslineId;
// 3) mostra somente instrumentos pertencentes ao rack // 3) mostra somente instrumentos pertencentes ao rack
tracksToRender = appState.pattern.tracks.filter( tracksToRender = appState.pattern.tracks.filter(
t => t.type !== "bassline" && t.parentBasslineId === srcId t => t.type !== "bassline" && (t.parentBasslineId === srcId || t.parentBasslineId == null)
); );
// Nome no header // 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
tracksToRender = appState.pattern.tracks.filter(t => t.type !== 'bassline' && t.parentBasslineId === null); tracksToRender = appState.pattern.tracks.filter(
t => t.type !== "bassline" && t.parentBasslineId == null
);
// Fallback: Se a lista ficar vazia (projeto antigo ou mal formatado), mostra tudo que não é container // Fallback: Se a lista ficar vazia (projeto antigo ou mal formatado), mostra tudo que não é container
if (tracksToRender.length === 0) { if (tracksToRender.length === 0) {