feat(export): stop transport khi export offline + check file export khong cam (peak < -60dB -> canh bao)

This commit is contained in:
2026-08-24 18:26:52 +07:00
parent edbb477657
commit fefe95d0a9
3 changed files with 12 additions and 3 deletions
+8
View File
@@ -27935,6 +27935,9 @@ const App = () => {
// ── Server-side Export ──
const triggerWavExport = async () => {
// Stop transport ngay khi bắt đầu export offline → tắt âm thanh đang phát.
try { if (typeof stopAllPlayback === 'function') stopAllPlayback(); } catch (e) { }
try { if (window.SonicSF && window.SonicSF.stopAllNotes) window.SonicSF.stopAllNotes(); } catch (e) { }
// Realtime UNCHECKED → export OFFLINE thuần (server-side nếu connected, fallback client).
// MIDI không render được trong OfflineAudioContext: nếu project có MIDI items mà
// cache preview chưa đủ → file xuất có thể thiếu âm MIDI. Cảnh báo, vẫn xuất offline.
@@ -28669,11 +28672,13 @@ const App = () => {
writeString(36, 'data');
view.setUint32(40, exportLength * bytesPerSample * numExportCh, true);
let offset = 44;
let peak = 0;
for (let i = 0; i < exportLength; i++) {
if ((i & 0x3FFF) === 0) setExportProgress(60 + Math.round((i / Math.max(1, exportLength)) * 32));
for (let ch = 0; ch < numExportCh; ch++) {
const chData = renderedBuffer.getChannelData(ch);
const sample = Math.max(-1, Math.min(1, chData[i]));
if (Math.abs(sample) > peak) peak = Math.abs(sample);
if (bitDepth === 8) {
view.setUint8(offset, Math.floor((sample + 1.0) * 127.5));
} else if (bitDepth === 16) {
@@ -28689,6 +28694,9 @@ const App = () => {
offset += bytesPerSample;
}
}
if (peak < 0.001) {
showToast("Cảnh báo: file export gần như CÂM (không có tín hiệu âm) — kiểm tra nguồn track / MIDI cache preview.", "warning");
}
const blob = new Blob([view], {
type: 'audio/wav'
});
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -51,7 +51,7 @@
<script src="/static/js/services/promptTemplateManager.js?v=202607281039"></script>
<script src="/static/js/services/undoRedoEngine.js?v=202607290941"></script>
<script src="/static/js/services/chordTheory.js?v=202608211300"></script>
<script src="/static/js/app.precompiled.js?v=202608232345" defer></script>
<script src="/static/js/app.precompiled.js?v=202608240010" defer></script>
<link rel="stylesheet" href="/static/css/styles.css?v=202607271016">
<style>
:root {