melhorando a leitura de projetos no mmpCreator
Deploy / Deploy (push) Successful in 2m12s Details

This commit is contained in:
JotaChina 2025-12-23 22:41:48 -03:00
parent c384a4a92f
commit 3727ac7b13
4 changed files with 38 additions and 137 deletions

View File

@ -1059,58 +1059,13 @@ tracks:
plugin_name: audiofileprocessor plugin_name: audiofileprocessor
usemasterpitch: '1' usemasterpitch: '1'
vol: '100' vol: '100'
playlist_clips:
- len: 768
name: Caixa
pos: 0
- len: 768
name: Caixa
pos: 768
- len: 768
name: Caixa
pos: 1536
- len: 768
name: Caixa
pos: 2304
- len: 768
name: Caixa
pos: 3072
- len: 768
name: Caixa
pos: 3840
tags: audiofileprocessor tags: audiofileprocessor
track_name: Caixa
type: bassline type: bassline
- bassline_name: Kick - bassline_name: Kick
instruments: [] instruments: []
playlist_clips:
- len: 768
name: Kick
pos: 0
- len: 768
name: Kick
pos: 768
- len: 768
name: Kick
pos: 1536
- len: 768
name: Kick
pos: 2304
- len: 768
name: Kick
pos: 3072
- len: 768
name: Kick
pos: 3840
tags: '' tags: ''
track_name: Kick
type: bassline type: bassline
- bassline_name: Batida/Linha de Baixo 2 - bassline_name: Batida/Linha de Baixo 2
instruments: [] instruments: []
playlist_clips:
- len: 4608
name: Batida/Linha de Baixo 2
pos: 0
tags: '' tags: ''
track_name: Batida/Linha de Baixo 2
type: bassline type: bassline

View File

@ -514151,60 +514151,15 @@
plugin_name: audiofileprocessor plugin_name: audiofileprocessor
usemasterpitch: '1' usemasterpitch: '1'
vol: '100' vol: '100'
playlist_clips:
- len: 768
name: Caixa
pos: 0
- len: 768
name: Caixa
pos: 768
- len: 768
name: Caixa
pos: 1536
- len: 768
name: Caixa
pos: 2304
- len: 768
name: Caixa
pos: 3072
- len: 768
name: Caixa
pos: 3840
tags: audiofileprocessor tags: audiofileprocessor
track_name: Caixa
type: bassline type: bassline
- bassline_name: Kick - bassline_name: Kick
instruments: [] instruments: []
playlist_clips:
- len: 768
name: Kick
pos: 0
- len: 768
name: Kick
pos: 768
- len: 768
name: Kick
pos: 1536
- len: 768
name: Kick
pos: 2304
- len: 768
name: Kick
pos: 3072
- len: 768
name: Kick
pos: 3840
tags: '' tags: ''
track_name: Kick
type: bassline type: bassline
- bassline_name: Batida/Linha de Baixo 2 - bassline_name: Batida/Linha de Baixo 2
instruments: [] instruments: []
playlist_clips:
- len: 4608
name: Batida/Linha de Baixo 2
pos: 0
tags: '' tags: ''
track_name: Batida/Linha de Baixo 2
type: bassline type: bassline
- bpm: '150' - bpm: '150'
file: hybrid-trap-vespertine-fck-you file: hybrid-trap-vespertine-fck-you

Binary file not shown.

View File

@ -45,6 +45,13 @@ function resolveSamplePath(sampleName, pathMap) {
return null; return null;
} }
// helper: LMMS ticks -> seconds (1 beat = 192 ticks)
function ticksToSeconds(ticks, bpm) {
const t = Number(ticks || 0);
const b = Number(bpm || 120);
return (t * 60) / (b * 192);
}
export async function parseBeatIndexJson(data) { export async function parseBeatIndexJson(data) {
resetProjectState(); resetProjectState();
initializeAudioContext(); initializeAudioContext();
@ -88,64 +95,48 @@ export async function parseBeatIndexJson(data) {
appState.pattern.tracks = newPatternTracks; appState.pattern.tracks = newPatternTracks;
// 2) cria lanes/clips de áudio a partir dos sample-tracks // 2) cria lanes/clips de áudio a partir dos sample-tracks
const sampleTracks = (data.tracks || []).filter((t) => t.type === "sample"); const sampleTracks = (project?.tracks || []).filter((t) => t?.type === "sample");
for (const st of sampleTracks) { for (let i = 0; i < sampleTracks.length; i++) {
const laneId = st.id || safeId("audioTrack"); const t = sampleTracks[i];
const laneName = st.track_name || "Áudio";
// lane (pista) // 1) cria lane de áudio
addAudioTrackLane({ const trackId = `sample_lane_${Date.now()}_${i}`;
id: laneId, appState.audio.tracks.push({
name: laneName, id: trackId,
volume: Number(st.sample_info?.vol ?? 100) / 100, name: t.track_name || "Áudio",
pan: Number(st.sample_info?.pan ?? 0) / 100,
}); });
// arquivo // 2) resolve URL do arquivo
const sampleName = const fileName = t.sample_name || basename(t.sample_info?.src) || `${sample_info.src}.wav`;
st.sample_name ||
basename(st.sample_info?.src) || // só pra extrair "#2.wav"
null;
const filePath = resolveSamplePath(sampleName, pathMap); // tenta achar pelo filename no manifest do browser
if (!filePath) continue; // (se o seu manifest tiver duplicados com mesmo nome, aqui pode colidir)
const resolvedUrl =
pathMap[fileName] ||
// fallback bem simples (ajuste pro seu servidor)
`/src_mmpSearch/samples/samples/${project?.file || project?.original_title || ""}/${fileName}`;
// seus dados podem vir num único sample_info, OU você pode evoluir pra playlist_clips também // 3) converte pos/len (ticks) -> seconds
const clipDefs = const startSec = ticksToSeconds(t.sample_info?.pos, bpm);
Array.isArray(st.playlist_clips) && st.playlist_clips.length const durSec = ticksToSeconds(t.sample_info?.len, bpm);
? st.playlist_clips
: [
{
pos: Number(st.sample_info?.pos ?? 0),
len: Number(st.sample_info?.len ?? 0),
name: sampleName,
},
];
for (const c of clipDefs) { // 4) cria clip
const startTimeInSeconds = (Number(c.pos || 0) / TICKS_PER_STEP) * secondsPerStep; const clipId = `clip_${trackId}_0`;
const durationInSeconds = (Number(c.len || 0) / TICKS_PER_STEP) * secondsPerStep; addAudioClipToTimeline(resolvedUrl, trackId, startSec, clipId, fileName);
const clipId = safeId("clip"); // 5) aplica propriedades (duração/vol/pan) pra largura não ficar 0
const vol = Number(t.sample_info?.vol ?? 100) / 100;
const pan = Number(t.sample_info?.pan ?? 0) / 100;
const muted = String(t.sample_info?.muted ?? "0") === "1";
// isso decodifica e já deixa pronto pra desenhar waveform (clip.buffer) :contentReference[oaicite:7]{index=7} updateAudioClipProperties(clipId, {
await addAudioClipToTimeline(filePath, laneId, startTimeInSeconds, clipId, c.name || sampleName); durationInSeconds: durSec || 0,
volume: muted ? 0 : vol,
// garante que o “tamanho na playlist” respeita seu len do beat-index pan: isNaN(pan) ? 0 : pan,
if (durationInSeconds > 0) { });
updateAudioClipProperties(clipId, { durationInSeconds, offset: 0, pitch: 0 });
}
}
} }
// escolha de track ativa no pattern editor
const firstInst = newPatternTracks.find((t) => t.type !== "bassline");
appState.pattern.activeTrackId = firstInst ? firstInst.id : null;
appState.pattern.activePatternIndex = 0;
// mantém seu comportamento atual
await loadStateFromSession(); // se existir snapshot local, aplica
renderAll(); renderAll();
} }