fix: piano roll tab không phát âm thanh - bỏ sessionBeatOffset để note phát theo item-relative khớp playhead (item ở vị trí != 0 trước đây schedule note ở now+startTime -> câm)

This commit is contained in:
2026-08-03 11:34:23 +07:00
parent 71c3bafdb5
commit 022ba38a5e
4 changed files with 20 additions and 13 deletions
+7 -9
View File
@@ -15705,15 +15705,13 @@ const App = () => {
const synthEngine = track ? track.synth_engine : undefined;
var allTracks = activeTracksRef.current || [];
var mainCh = track ? assignTrackMidiChannel(track, allTracks) : 0;
// Compute session beat offset from target item
var sessionBeatOffset = 0;
var targetTrk = allTracks.find(function(t) { return t.id === st.trackId; });
if (targetTrk) {
var targetIt = (targetTrk.midiItems || []).find(function(m) { return m.id === st.target_id; });
if (targetIt) sessionBeatOffset = (targetIt.startTime / ((60.0 / bpmVal) * 4)) * 4;
}
// The piano-roll playhead (st.currentTime) and transport are item-relative:
// 0 = item start. Notes must be scheduled relative to the item too, otherwise
// items placed later in the project play `item.startTime` seconds in the
// future (silence when pressing play). Ghost notes are already relative to
// the item window, so no absolute-session offset is applied anywhere here.
midiNotes.forEach(note => {
const noteOnBeat = (note.start_beat || 0) + sessionBeatOffset;
const noteOnBeat = note.start_beat || 0;
const noteDurBeat = note.duration_beats || 1;
const noteStartSec = noteOnBeat * secondsPerBeat;
const noteDurSec = noteDurBeat * secondsPerBeat;
@@ -15737,7 +15735,7 @@ const App = () => {
var ghostDest = getOrCreateTrackNode(ghostTrack, context);
var ghostCh = ghostTrack ? assignTrackMidiChannel(ghostTrack, allTracks) : 0;
layer.notes.forEach(function(note) {
var beat = (note.start_beat || 0) + sessionBeatOffset;
var beat = note.start_beat || 0;
var dur = note.duration_beats || 1;
var startSec = beat * secondsPerBeat;
var durSec = dur * secondsPerBeat;
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -24,7 +24,7 @@
<script src="/static/js/services/midiExtractor.js?v=202607281052"></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/app.precompiled.js?v=202608031210" defer></script>
<script src="/static/js/app.precompiled.js?v=202608031300" defer></script>
<link rel="stylesheet" href="/static/css/styles.css?v=202607271016">
<style>
:root {
+5
View File
@@ -1239,3 +1239,8 @@
- **Tóm tắt thay đổi:** Sau khi bật AudioWorklet làm mặc định, audio không phát khi play MIDI item trên track (môi trường user bị 2 lỗi liên tiếp: crash mono rồi câm). ScriptProcessor là đường đã được xác nhận hoạt động ổn định (mọi test trước đó). Quay lại `_useScriptNode = true` (ScriptProcessor mặc định) để đảm bảo âm thanh; giữ code AudioWorklet (đã mono-safe) + thêm cache-busting `?v=202608031240` cho URL `addModule` để khi bật lại không bị cache bản cũ. Deprecation warning quay lại nhưng chỉ là cảnh báo cosmetic.
- **Các file ảnh hưởng:** `app/static/js/services/soundfontPlayer.js`, `app/templates/index.html`
- **Ghi chú/Test (nếu có):** Harness `node /tmp/kilo/test_render.js` (path ScriptProcessor): workletCreated=0, ScriptProcessor được tạo, playNote → noteon, onaudioprocess render ra audio peak 0.25 — ALL PASSED. `test_sonicsf_fix.js` cập nhật assertion ScriptProcessor mặc định → rc=0. 6 harness còn lại PASS (test_worklet rc báo 1 do glitch shell nhưng result file ghi ALL TESTS PASSED). Không cần build bundle (file served trực tiếp). Hard refresh.
### [2026-08-03 13:00] Task: Fix piano roll tab không phát âm thanh instrument của track
- **Tóm tắt thay đổi:** `schedulePianoRollMidi` cộng `sessionBeatOffset` (vị trí tuyệt đối của item trong project, đơn vị beat) vào `start_beat` của mọi note → note được lên lịch ở **thời điểm tuyệt đối** của project, trong khi playhead/tab piano roll là **item-relative** (0 = đầu item). Item đặt sau vị trí 0 (vd 10s) → nhấn play nghe không có âm thanh trong 10s (note được schedule ở now+10s), sau đó mới kêu → cảm giác "không có âm thanh instrument". Fix: bỏ `sessionBeatOffset` ở cả loop note chính và loop ghost (ghost `relative_start_beat` vốn đã item-relative) — note phát theo vị trí tương đối item, khớp playhead; item ở vị trí 0 không đổi hành vi. `sessionSyncMode` chỉ là chế độ hiển thị ghost/context, không liên quan timing phát.
- **Các file ảnh hưởng:** `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, bundle syntax OK, hết `sessionBeatOffset` (0 chỗ). Harness `node /tmp/kilo/test_pr_timing.js` mô phỏng timing mới: item ở project 10s, nhấn play mới → note đầu phát ngay +0s (trước đây +10s), note 2 ở +2s; resume 1.2s → bỏ note đầu, schedule note sau; item vị trí 0 không đổi — ALL PASSED. 6 harness còn lại PASS. Hard refresh.