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:
@@ -15705,15 +15705,13 @@ const App = () => {
|
|||||||
const synthEngine = track ? track.synth_engine : undefined;
|
const synthEngine = track ? track.synth_engine : undefined;
|
||||||
var allTracks = activeTracksRef.current || [];
|
var allTracks = activeTracksRef.current || [];
|
||||||
var mainCh = track ? assignTrackMidiChannel(track, allTracks) : 0;
|
var mainCh = track ? assignTrackMidiChannel(track, allTracks) : 0;
|
||||||
// Compute session beat offset from target item
|
// The piano-roll playhead (st.currentTime) and transport are item-relative:
|
||||||
var sessionBeatOffset = 0;
|
// 0 = item start. Notes must be scheduled relative to the item too, otherwise
|
||||||
var targetTrk = allTracks.find(function(t) { return t.id === st.trackId; });
|
// items placed later in the project play `item.startTime` seconds in the
|
||||||
if (targetTrk) {
|
// future (silence when pressing play). Ghost notes are already relative to
|
||||||
var targetIt = (targetTrk.midiItems || []).find(function(m) { return m.id === st.target_id; });
|
// the item window, so no absolute-session offset is applied anywhere here.
|
||||||
if (targetIt) sessionBeatOffset = (targetIt.startTime / ((60.0 / bpmVal) * 4)) * 4;
|
|
||||||
}
|
|
||||||
midiNotes.forEach(note => {
|
midiNotes.forEach(note => {
|
||||||
const noteOnBeat = (note.start_beat || 0) + sessionBeatOffset;
|
const noteOnBeat = note.start_beat || 0;
|
||||||
const noteDurBeat = note.duration_beats || 1;
|
const noteDurBeat = note.duration_beats || 1;
|
||||||
const noteStartSec = noteOnBeat * secondsPerBeat;
|
const noteStartSec = noteOnBeat * secondsPerBeat;
|
||||||
const noteDurSec = noteDurBeat * secondsPerBeat;
|
const noteDurSec = noteDurBeat * secondsPerBeat;
|
||||||
@@ -15737,7 +15735,7 @@ const App = () => {
|
|||||||
var ghostDest = getOrCreateTrackNode(ghostTrack, context);
|
var ghostDest = getOrCreateTrackNode(ghostTrack, context);
|
||||||
var ghostCh = ghostTrack ? assignTrackMidiChannel(ghostTrack, allTracks) : 0;
|
var ghostCh = ghostTrack ? assignTrackMidiChannel(ghostTrack, allTracks) : 0;
|
||||||
layer.notes.forEach(function(note) {
|
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 dur = note.duration_beats || 1;
|
||||||
var startSec = beat * secondsPerBeat;
|
var startSec = beat * secondsPerBeat;
|
||||||
var durSec = dur * secondsPerBeat;
|
var durSec = dur * secondsPerBeat;
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -24,7 +24,7 @@
|
|||||||
<script src="/static/js/services/midiExtractor.js?v=202607281052"></script>
|
<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/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/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">
|
<link rel="stylesheet" href="/static/css/styles.css?v=202607271016">
|
||||||
<style>
|
<style>
|
||||||
:root {
|
:root {
|
||||||
|
|||||||
@@ -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.
|
- **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`
|
- **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.
|
- **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.
|
||||||
|
|||||||
Reference in New Issue
Block a user