melhorando a leitura de projetos no mmpCreator
This commit is contained in:
1 parent
6dd0aa9fb4
commit
7f329db1b3
4 files changed
+38
-137
No files matched your search
+38
-47
@@ -45,6 +45,13 @@ function resolveSamplePath(sampleName, pathMap) {
|
||||
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) {
|
||||
resetProjectState();
|
||||
initializeAudioContext();
|
||||
@@ -88,64 +95,48 @@ export async function parseBeatIndexJson(data) {
|
||||
appState.pattern.tracks = newPatternTracks;
|
||||
|
||||
// 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) {
|
||||
const laneId = st.id || safeId("audioTrack");
|
||||
const laneName = st.track_name || "Áudio";
|
||||
for (let i = 0; i < sampleTracks.length; i++) {
|
||||
const t = sampleTracks[i];
|
||||
|
||||
// lane (pista)
|
||||
addAudioTrackLane({
|
||||
id: laneId,
|
||||
name: laneName,
|
||||
volume: Number(st.sample_info?.vol ?? 100) / 100,
|
||||
pan: Number(st.sample_info?.pan ?? 0) / 100,
|
||||
// 1) cria lane de áudio
|
||||
const trackId = `sample_lane_${Date.now()}_${i}`;
|
||||
appState.audio.tracks.push({
|
||||
id: trackId,
|
||||
name: t.track_name || "Áudio",
|
||||
});
|
||||
|
||||
// arquivo
|
||||
const sampleName =
|
||||
st.sample_name ||
|
||||
basename(st.sample_info?.src) || // só pra extrair "#2.wav"
|
||||
null;
|
||||
// 2) resolve URL do arquivo
|
||||
const fileName = t.sample_name || basename(t.sample_info?.src) || `${sample_info.src}.wav`;
|
||||
|
||||
const filePath = resolveSamplePath(sampleName, pathMap);
|
||||
if (!filePath) continue;
|
||||
// tenta achar pelo filename no manifest do browser
|
||||
// (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
|
||||
const clipDefs =
|
||||
Array.isArray(st.playlist_clips) && st.playlist_clips.length
|
||||
? st.playlist_clips
|
||||
: [
|
||||
{
|
||||
pos: Number(st.sample_info?.pos ?? 0),
|
||||
len: Number(st.sample_info?.len ?? 0),
|
||||
name: sampleName,
|
||||
},
|
||||
];
|
||||
// 3) converte pos/len (ticks) -> seconds
|
||||
const startSec = ticksToSeconds(t.sample_info?.pos, bpm);
|
||||
const durSec = ticksToSeconds(t.sample_info?.len, bpm);
|
||||
|
||||
for (const c of clipDefs) {
|
||||
const startTimeInSeconds = (Number(c.pos || 0) / TICKS_PER_STEP) * secondsPerStep;
|
||||
const durationInSeconds = (Number(c.len || 0) / TICKS_PER_STEP) * secondsPerStep;
|
||||
// 4) cria clip
|
||||
const clipId = `clip_${trackId}_0`;
|
||||
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}
|
||||
await addAudioClipToTimeline(filePath, laneId, startTimeInSeconds, clipId, c.name || sampleName);
|
||||
|
||||
// garante que o “tamanho na playlist” respeita seu len do beat-index
|
||||
if (durationInSeconds > 0) {
|
||||
updateAudioClipProperties(clipId, { durationInSeconds, offset: 0, pitch: 0 });
|
||||
}
|
||||
}
|
||||
updateAudioClipProperties(clipId, {
|
||||
durationInSeconds: durSec || 0,
|
||||
volume: muted ? 0 : vol,
|
||||
pan: isNaN(pan) ? 0 : pan,
|
||||
});
|
||||
}
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user