feat(export): stop transport khi export offline + check file export khong cam (peak < -60dB -> canh bao)
This commit is contained in:
@@ -27935,6 +27935,9 @@ const App = () => {
|
|||||||
|
|
||||||
// ── Server-side Export ──
|
// ── Server-side Export ──
|
||||||
const triggerWavExport = async () => {
|
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).
|
// 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à
|
// 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.
|
// 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');
|
writeString(36, 'data');
|
||||||
view.setUint32(40, exportLength * bytesPerSample * numExportCh, true);
|
view.setUint32(40, exportLength * bytesPerSample * numExportCh, true);
|
||||||
let offset = 44;
|
let offset = 44;
|
||||||
|
let peak = 0;
|
||||||
for (let i = 0; i < exportLength; i++) {
|
for (let i = 0; i < exportLength; i++) {
|
||||||
if ((i & 0x3FFF) === 0) setExportProgress(60 + Math.round((i / Math.max(1, exportLength)) * 32));
|
if ((i & 0x3FFF) === 0) setExportProgress(60 + Math.round((i / Math.max(1, exportLength)) * 32));
|
||||||
for (let ch = 0; ch < numExportCh; ch++) {
|
for (let ch = 0; ch < numExportCh; ch++) {
|
||||||
const chData = renderedBuffer.getChannelData(ch);
|
const chData = renderedBuffer.getChannelData(ch);
|
||||||
const sample = Math.max(-1, Math.min(1, chData[i]));
|
const sample = Math.max(-1, Math.min(1, chData[i]));
|
||||||
|
if (Math.abs(sample) > peak) peak = Math.abs(sample);
|
||||||
if (bitDepth === 8) {
|
if (bitDepth === 8) {
|
||||||
view.setUint8(offset, Math.floor((sample + 1.0) * 127.5));
|
view.setUint8(offset, Math.floor((sample + 1.0) * 127.5));
|
||||||
} else if (bitDepth === 16) {
|
} else if (bitDepth === 16) {
|
||||||
@@ -28689,6 +28694,9 @@ const App = () => {
|
|||||||
offset += bytesPerSample;
|
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], {
|
const blob = new Blob([view], {
|
||||||
type: 'audio/wav'
|
type: 'audio/wav'
|
||||||
});
|
});
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -51,7 +51,7 @@
|
|||||||
<script src="/static/js/services/promptTemplateManager.js?v=202607281039"></script>
|
<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/undoRedoEngine.js?v=202607290941"></script>
|
||||||
<script src="/static/js/services/chordTheory.js?v=202608211300"></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">
|
<link rel="stylesheet" href="/static/css/styles.css?v=202607271016">
|
||||||
<style>
|
<style>
|
||||||
:root {
|
:root {
|
||||||
|
|||||||
Reference in New Issue
Block a user