fix(piano-roll): seek-to-start restarts playback
- Add seekPlaybackTo(time) that stops, updates refs, reschedules MIDI, and restarts playback for both sub-tab and main timeline - 'Quay lại đầu' and 'Đầu vùng chọn' buttons use seekPlaybackTo
This commit is contained in:
+46
-20
@@ -10118,6 +10118,46 @@ const App = () => {
|
||||
isPlaying: false
|
||||
})));
|
||||
};
|
||||
const seekPlaybackTo = (time) => {
|
||||
const isSubTab = subTabs.some(sub => sub.id === activeTab);
|
||||
if (isSubTab) {
|
||||
const st = subTabs.find(s => s.id === activeTab);
|
||||
if (!st) return;
|
||||
if (st.isPlaying) {
|
||||
stopAllPlayback();
|
||||
window.SonicSF.stopAll();
|
||||
setSubTabs(prev => prev.map(s => s.id === activeTab ? {
|
||||
...s,
|
||||
currentTime: time,
|
||||
isPlaying: true
|
||||
} : s));
|
||||
const ctx = getAudioContext();
|
||||
startOffsetTimeRef.current = time;
|
||||
startAudioTimeRef.current = ctx.currentTime;
|
||||
startBufferOffsetRef.current = time * (st.speed || 1.0);
|
||||
if (st.type === 'PIANO_ROLL') {
|
||||
schedulePianoRollMidi(st, time);
|
||||
}
|
||||
startSubTabPlayback(st, time);
|
||||
} else {
|
||||
setSubTabs(prev => prev.map(s => s.id === activeTab ? {
|
||||
...s,
|
||||
currentTime: time
|
||||
} : s));
|
||||
}
|
||||
} else {
|
||||
if (isPlaying) {
|
||||
stopAllPlayback();
|
||||
setCurrentTime(time);
|
||||
startOffsetTimeRef.current = time;
|
||||
startAudioTimeRef.current = getAudioContext().currentTime;
|
||||
startTrackPlayback(time);
|
||||
setIsPlaying(true);
|
||||
} else {
|
||||
setCurrentTime(time);
|
||||
}
|
||||
}
|
||||
};
|
||||
const handleStop = () => {
|
||||
if (recordingStateRef.current === 'RECORDING' || recordingStateRef.current === 'COUNT_IN') {
|
||||
stopRecordingTake();
|
||||
@@ -14488,17 +14528,7 @@ const App = () => {
|
||||
})))), /*#__PURE__*/React.createElement("div", {
|
||||
className: "w-[1px] h-5 bg-zinc-800 mx-0.5"
|
||||
}), /*#__PURE__*/React.createElement("button", {
|
||||
onClick: () => {
|
||||
const isSubTab = subTabs.some(sub => sub.id === activeTab);
|
||||
if (isSubTab) {
|
||||
setSubTabs(prev => prev.map(s => s.id === activeTab ? {
|
||||
...s,
|
||||
currentTime: 0
|
||||
} : s));
|
||||
} else {
|
||||
setCurrentTime(0);
|
||||
}
|
||||
},
|
||||
onClick: () => seekPlaybackTo(0),
|
||||
className: "w-7 h-7 flex items-center justify-center bg-zinc-800 hover:bg-zinc-700 text-zinc-200 rounded border border-zinc-700 transition",
|
||||
title: "Quay lại đầu"
|
||||
}, /*#__PURE__*/React.createElement("span", {
|
||||
@@ -14510,16 +14540,12 @@ const App = () => {
|
||||
onClick: () => {
|
||||
const isSubTab = subTabs.some(sub => sub.id === activeTab);
|
||||
if (isSubTab) {
|
||||
setSubTabs(prev => prev.map(s => {
|
||||
if (s.id !== activeTab) return s;
|
||||
const left = s.selectionStart !== null && s.selectionEnd !== null ? Math.min(s.selectionStart, s.selectionEnd) : null;
|
||||
return left !== null ? {
|
||||
...s,
|
||||
currentTime: left
|
||||
} : s;
|
||||
}));
|
||||
const st = subTabs.find(s => s.id === activeTab);
|
||||
if (!st) return;
|
||||
const left = st.selectionStart !== null && st.selectionEnd !== null ? Math.min(st.selectionStart, st.selectionEnd) : null;
|
||||
if (left !== null) seekPlaybackTo(left);
|
||||
} else {
|
||||
if (selLeft !== null) setCurrentTime(selLeft);
|
||||
if (selLeft !== null) seekPlaybackTo(selLeft);
|
||||
}
|
||||
},
|
||||
className: "w-7 h-7 flex items-center justify-center bg-zinc-800 hover:bg-zinc-700 text-zinc-200 rounded border border-zinc-700 transition",
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -261,6 +261,11 @@
|
||||
- **Các file ảnh hưởng:** `app/static/js/app.jsx`, `app/static/js/services/soundfontPlayer.js`, `app/static/js/app.precompiled.js`
|
||||
- **Ghi chú/Test (nếu có):** `npm run build` pass.
|
||||
|
||||
### [2026-07-26 12:20] Task: Fix Piano Roll seek-to-start during playback
|
||||
- **Tóm tắt thay đổi:** Thêm hàm `seekPlaybackTo(time)` xử lý seek khi đang play cho cả sub-tab và main timeline. Nút "Quay lại đầu" (`skip-back`) và "Đầu vùng chọn" (`step-back`) giờ restart playback từ vị trí mới: stop → update refs → reschedule MIDI → restart.
|
||||
- **Các file ảnh hưởng:** `app/static/js/app.jsx`, `app/static/js/app.precompiled.js`
|
||||
- **Ghi chú/Test (nếu có):** `npm run build` pass.
|
||||
|
||||
### [2026-07-26 12:13] Task: Fix Piano Roll loop/stop behavior
|
||||
- **Tóm tắt thay đổi:** (1) Sub-tab loop selection chỉ active khi nút Loop (st.isLooping) bật — không còn bị ảnh hưởng bởi global isLoopingSelection. (2) Stop dừng ngay lập tức: `SonicSF.stopAll()` set gain 0 và stop oscillator tại ctx.currentTime, không ramp.
|
||||
- **Các file ảnh hưởng:** `app/static/js/app.jsx`, `app/static/js/services/soundfontPlayer.js`, `app/static/js/app.precompiled.js`
|
||||
|
||||
Reference in New Issue
Block a user