melhorando a leitura de projetos no mmpCreator
Deploy / Deploy (push) Successful in 2m12s
Details
Deploy / Deploy (push) Successful in 2m12s
Details
This commit is contained in:
parent
c384a4a92f
commit
3727ac7b13
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
BIN
_data/users.db
BIN
_data/users.db
Binary file not shown.
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue