renderizando projetos com sample tracks. basslines ok
This commit is contained in:
1 parent
be5b12e845
commit
43a9aff447
3 files changed
+130
-32
No files matched your search
@@ -912,6 +912,40 @@ async function generateAndDownloadMmpz(baseName) {
|
||||
|
||||
}
|
||||
|
||||
export async function buildRenderPackageBlob(baseName = "projeto") {
|
||||
initializeAudioContext();
|
||||
|
||||
const baseXmlString = generateXmlFromState(); // patterns
|
||||
const xmlDoc = new DOMParser().parseFromString(baseXmlString, "application/xml");
|
||||
|
||||
const zip = new JSZip();
|
||||
await applySampleTracksToXmlAndZip(xmlDoc, zip); // ✅ coloca sampletco + samples/*.wav
|
||||
|
||||
const finalXml = new XMLSerializer().serializeToString(xmlDoc);
|
||||
zip.file(`${baseName}.mmp`, finalXml);
|
||||
|
||||
const blob = await zip.generateAsync({ type: "blob", compression: "DEFLATE" });
|
||||
|
||||
// pode ser .mmpz (LMMS costuma aceitar) ou .zip (você já usa)
|
||||
return { blob, fileName: `${baseName}.mmpz` };
|
||||
}
|
||||
|
||||
export async function buildRenderPackageBase64(baseName = "projeto") {
|
||||
const { blob, fileName } = await buildRenderPackageBlob(baseName);
|
||||
const base64 = await blobToBase64(blob);
|
||||
return { mmpzBase64: base64, mmpzName: fileName };
|
||||
}
|
||||
|
||||
|
||||
function blobToBase64(blob) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const r = new FileReader();
|
||||
r.onload = () => resolve(String(r.result).split(",")[1]); // remove data:...
|
||||
r.onerror = reject;
|
||||
r.readAsDataURL(blob);
|
||||
});
|
||||
}
|
||||
|
||||
function downloadBlob(blob, fileName) {
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement("a");
|
||||
@@ -1085,6 +1119,10 @@ async function _decodeAudioBufferCached(url) {
|
||||
return decoded;
|
||||
}
|
||||
|
||||
function _isProbablyWavUrl(url) {
|
||||
return /\.wav(\?|#|$)/i.test(String(url || ""));
|
||||
}
|
||||
|
||||
// -------------------- XML: SampleTracks + zip --------------------
|
||||
|
||||
async function applySampleTracksToXmlAndZip(xmlDoc, zip) {
|
||||
@@ -1179,17 +1217,17 @@ async function applySampleTracksToXmlAndZip(xmlDoc, zip) {
|
||||
// ✅ OTIMIZAÇÃO 2: sem offset + sem bake mix
|
||||
// -> usa arquivo original no zip (sem decode/encode)
|
||||
// -----------------------------------------
|
||||
const needsOffset = Math.abs(offsetSec) > 1e-6;
|
||||
const needsBake = Math.abs((vol ?? 1) - 1) > 1e-6 || Math.abs((pan ?? 0) - 0) > 1e-6;
|
||||
const isWav = _isProbablyWavUrl(srcUrl);
|
||||
|
||||
if (!needsOffset && !needsBake) {
|
||||
if (!needsOffset && !needsBake && isWav) {
|
||||
const raw = await _fetchArrayBufferCached(srcUrl);
|
||||
|
||||
const name =
|
||||
`${_sanitizeFileName(laneName)}__${_sanitizeFileName(clip.name || "clip")}` +
|
||||
`__raw__${_sanitizeFileName(clip.id || String(cidx))}.wav`;
|
||||
|
||||
const zipPath = `samples/${name}`;
|
||||
|
||||
// evita regravar o mesmo raw várias vezes
|
||||
if (!zip.file(zipPath)) zip.file(zipPath, raw);
|
||||
|
||||
const tco = xmlDoc.createElement("sampletco");
|
||||
@@ -1201,6 +1239,8 @@ async function applySampleTracksToXmlAndZip(xmlDoc, zip) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// se NÃO for wav, cai no “bake” (decode+encode wav) abaixo ✅
|
||||
|
||||
// -----------------------------------------
|
||||
// ✅ OTIMIZAÇÃO 3: cache de slice idêntico
|
||||
// -----------------------------------------
|
||||
|
||||
Reference in new issue
Block a user