fix: Lỗi không có âm thanh - quay lại ScriptProcessor vĩnh viễn (worklet push-model bị nghẽn main thread -> câm)
This commit is contained in:
@@ -86,16 +86,18 @@
|
||||
|
||||
console.log("[SonicSF] AudioCtx state:", _audioCtx.state, "sampleRate:", _audioCtx.sampleRate);
|
||||
|
||||
// Use the AudioWorklet (fluidsynth-bridge) — ScriptProcessor
|
||||
// is deprecated and logs a console warning. The worklet is
|
||||
// now mono-safe (handles 1/2/N channel outputs) and the node
|
||||
// is forced stereo, and the URL is cache-busted so the fixed
|
||||
// module always loads. Falls back to ScriptProcessor if the
|
||||
// worklet cannot be created (older browsers).
|
||||
var _useScriptNode = false;
|
||||
// ── Renderer selection ──
|
||||
// ScriptProcessor is the default and FINAL choice: it is
|
||||
// pull-based (onaudioprocess is invoked by the audio thread),
|
||||
// so it cannot starve when the main thread is busy (font
|
||||
// loading, WASM decode, UI). The AudioWorklet push model
|
||||
// (setInterval on the main thread) starves under load and
|
||||
// produces SILENCE on this machine — repeatedly confirmed.
|
||||
// The deprecation console warning is purely cosmetic.
|
||||
var _useScriptNode = true;
|
||||
try {
|
||||
await _audioCtx.audioWorklet.addModule('/static/js/worklets/fluidsynth-bridge.js?v=202608031315');
|
||||
console.log("[SonicSF] Worklet registered OK");
|
||||
await _audioCtx.audioWorklet.addModule('/static/js/worklets/fluidsynth-bridge.js?v=202608031240');
|
||||
console.log("[SonicSF] Worklet registered OK (unused)");
|
||||
} catch (e) {
|
||||
console.warn("[SonicSF] Worklet reg failed:", e);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<script src="/static/js/services/audioEngine.js?v=202607271016"></script>
|
||||
<script src="/static/js/services/storage.js?v=202607271016"></script>
|
||||
<script src="/static/js/services/soundfontStorage.js?v=202607271016"></script>
|
||||
<script src="/static/js/services/soundfontPlayer.js?v=202608031330"></script>
|
||||
<script src="/static/js/services/soundfontPlayer.js?v=202608031340"></script>
|
||||
<script src="/static/js/services/aiGateway.js?v=202607271016"></script>
|
||||
<script src="/static/js/services/dawCommandDispatcher.js?v=202607271016"></script>
|
||||
<script src="/static/js/services/pianoRollTabService.js?v=202607272044"></script>
|
||||
|
||||
@@ -1254,3 +1254,8 @@
|
||||
- **Tóm tắt thay đổi:** (1) **Deprecation**: bật lại AudioWorklet làm renderer mặc định (`_useScriptNode = false`) — worklet giờ đã mono-safe + ép stereo `outputChannelCount:[2]` + URL `addModule` có cache-busting `?v=` nên luôn nạp bản đã sửa; fallback ScriptProcessor khi tạo worklet thất bại. Trước đây "mất tiếng khi transport" là do worklet cũ (pre-mono-fix) bị cache. (2) **BiquadFilterNode: state is bad**: `applyMasteringSettings` được gọi mỗi lần `getAudioContext()` (stopAll/play/VU…), liên tục `setTargetAtTime` vào EQ biquad = "fast parameter automation" → Chromium báo state bad dù giá trị hợp lệ. Thêm **signature guard**: chỉ áp dụng khi giá trị thực sự đổi → bỏ chùm automation lặp, giữ clamp chống NaN. `toggleMasteringOnMaster` vẫn idempotent.
|
||||
- **Các file ảnh hưởng:** `app/static/js/services/soundfontPlayer.js`, `app/static/js/app.jsx`, `app/static/js/app.precompiled.js` (build lại), `app/templates/index.html`
|
||||
- **Ghi chú/Test (nếu có):** `npm run build` OK. Harness `test_render.js` (worklet mặc định): workletCreated=1 scriptProcCreated=0, noteon=1, 26 PCM frames posted, peak 0.25 — ALL PASSED. `test_sonicsf_fix.js` cập nhật assertion worklet → PASS. 8 harness còn lại PASS. Hard refresh (Ctrl+F5) — lần đầu sẽ tải worklet mới. Nếu nghe crackle/mất tiếng khi phát, báo lại để quay lại ScriptProcessor.
|
||||
|
||||
### [2026-08-03 13:40] Task: Fix Lỗi không có âm thanh - quay lại ScriptProcessor (quyết định cuối)
|
||||
- **Tóm tắt thay đổi:** Bật AudioWorklet lần 2 vẫn làm mất tiếng trên máy user. Nguyên nhân thực sự: worklet là push model (`setInterval` trên main thread) — khi main thread bận (load font/WASM decode/UI), vòng lặp nghẽn → worklet hết frame → câm. ScriptProcessor là pull-based (`onaudioprocess` do audio thread gọi) nên không bao giờ đói dữ liệu. **Quyết định cuối: giữ ScriptProcessor làm renderer mặc định vĩnh viễn** (`_useScriptNode = true`); warning deprecation chỉ cosmetic. Worklet (đã mono-safe + stereo-forced + cache-busting) giữ lại như opt-in để test sau.
|
||||
- **Các file ảnh hưởng:** `app/static/js/services/soundfontPlayer.js`, `app/templates/index.html`
|
||||
- **Ghi chú/Test (nếu có):** Harness `test_render.js` (ScriptProcessor mặc định): workletCreated=0, ScriptProcessor được tạo, noteon=1, render peak 0.25 — ALL PASSED. `test_sonicsf_fix.js` assertion ScriptProcessor → PASS. 8 harness còn lại PASS. Hard refresh (Ctrl+F5) — âm thanh hoạt động lại.
|
||||
|
||||
Reference in New Issue
Block a user