fix(export): MIDI project WAV export qua server offline render thay vi bounce realtime

Bounce REALTIME race (note-on drop sau STOP / channel reload / watchdog
recovery) ra file chi 1 note roi cam hoac cam han. Offline render server
deterministic da xac nhan ra nhac day du (42.67s RMS ~0.24 moi giay).

triggerWavExport: project co MIDI + source=project + format=wav -> goi
renderMasteringExport (server /api/v1/plugins/render) thay vi bounce.
Bounce chi la fallback khi server disconnected va cache MIDI khong du.
This commit is contained in:
2026-08-24 20:32:15 +07:00
parent 141fa4a141
commit 1061a36626
3 changed files with 20 additions and 12 deletions
+14 -7
View File
@@ -27995,13 +27995,20 @@ const App = () => {
});
// MIDI chỉ render offline qua preview cache (tap sfEntry lúc play). Cache
// câm/thiếu khi routing bridge vào masterBus.input hoặc sub-node thay vì
// sfEntry → file offline đủ duration nhưng KHÔNG CÓ ÂM THANH. Khi cache
// không đủ → TỰ chuyển sang bounce REALTIME (capture masterBus.output =
// đúng âm đang nghe) thay vì xuất file câm. Áp dụng Export Project (mix).
if (midiTracks.length > 0 && !cacheOK && exportSettings.source === 'project' && exportSettings.format === 'wav') {
showToast("Cache MIDI chưa đủ — tự chuyển sang bounce REALTIME để giữ nguyên âm thanh...", "info");
await triggerBounceExport();
return;
// sfEntry → file offline đủ duration nhưng KHÔNG CÓ ÂM THANH. DAW-standard:
// project có MIDI → render OFFLINE deterministic qua server (đầy đủ MIDI +
// FX + mastering, đúng như DAW). Bounce REALTIME race không đáng tin (từng
// xuất file 1 note rồi câm / câm hẳn) → chỉ dùng làm fallback khi server lỗi.
if (midiTracks.length > 0 && exportSettings.source === 'project' && exportSettings.format === 'wav') {
if (serverStatus === 'connected') {
await renderMasteringExport();
return;
}
if (!cacheOK) {
showToast("Cache MIDI chưa đủ và server chưa kết nối — tự chuyển sang bounce REALTIME...", "info");
await triggerBounceExport();
return;
}
}
if (midiTracks.length > 0 && !cacheOK) {
showToast("Project có MIDI items chưa đủ cache preview — file offline có thể thiếu âm MIDI. Bật Realtime để bounce trung thực.", "warning");