fix: add try-catch + nextMetronomeBeatRef init to startPianoRollRecording

This commit is contained in:
2026-07-25 19:56:19 +07:00
parent d858628a8f
commit 97855f47d1
2 changed files with 59 additions and 48 deletions
+58 -47
View File
@@ -9850,53 +9850,64 @@ const App = () => {
}; };
const startPianoRollRecording = (tab) => { const startPianoRollRecording = (tab) => {
const context = getAudioContext(); try {
const secondsPerBeat = 60.0 / (parseInt(bpm) || 120); const context = getAudioContext();
const startTime = currentTime; const secondsPerBeat = 60.0 / (parseInt(bpm) || 120);
const midiRec = new ClientMIDIRecorder(context, parseInt(bpm) || 120, 4); const startTime = currentTime;
midiRec.tempTabId = tab.id; const startBeat = startTime / secondsPerBeat;
midiRec.selectedMidiInputId = selectedMidiInputId || 'ALL'; nextMetronomeBeatRef.current = Math.ceil(startBeat);
midiRec.start(startTime / secondsPerBeat, midiRec.selectedMidiInputId); const midiRec = new ClientMIDIRecorder(context, parseInt(bpm) || 120, 4);
pianoRollRecorderRef.current = midiRec; midiRec.tempTabId = tab.id;
activeMIDIRecordersRef.current['piano_roll'] = midiRec; midiRec.selectedMidiInputId = selectedMidiInputId || 'ALL';
setRecStartTimelineTime(startTime); midiRec.start(startTime / secondsPerBeat, midiRec.selectedMidiInputId);
recordingStartTimeRef.current = startTime; pianoRollRecorderRef.current = midiRec;
setRecordingState('RECORDING'); activeMIDIRecordersRef.current['piano_roll'] = midiRec;
setRecTempMidiNotes([]); setRecStartTimelineTime(startTime);
const ctx = getAudioContext(); recordingStartTimeRef.current = startTime;
const silentBuf = ctx.createBuffer(1, 128, ctx.sampleRate); setRecordingState('RECORDING');
setSubTabs(prev => prev.map(s => s.id === tab.id ? { ...s, buffer: silentBuf, isPlaying: true } : s)); setRecTempMidiNotes([]);
startSubTabPlayback({ ...tab, buffer: silentBuf }, startTime); const ctx = getAudioContext();
startOffsetTimeRef.current = startTime; const silentBuf = ctx.createBuffer(1, 128, ctx.sampleRate);
startAudioTimeRef.current = context.currentTime; setSubTabs(prev => prev.map(s => s.id === tab.id ? { ...s, buffer: silentBuf, isPlaying: true } : s));
setIsPlaying(true); startSubTabPlayback({ ...tab, buffer: silentBuf }, startTime);
midiRec.onNoteOn = (pitch, currentBeat) => { startOffsetTimeRef.current = startTime;
const elapsedBeats = Math.max(0, currentBeat); startAudioTimeRef.current = context.currentTime;
const sec = elapsedBeats * (60.0 / (parseInt(bpm) || 120)); setIsPlaying(true);
const activeNotes = Array.from(midiRec.activeNotes.values()).map(n => ({ midiRec.onNoteOn = (pitch, currentBeat) => {
id: 'rec_' + n.pitch + '_' + currentBeat, const elapsedBeats = Math.max(0, currentBeat);
pitch: n.pitch, const sec = elapsedBeats * (60.0 / (parseInt(bpm) || 120));
start_beat: n.start_beat, const activeNotes = Array.from(midiRec.activeNotes.values()).map(n => ({
duration_beats: Math.max(0.125, currentBeat - n.start_beat), id: 'rec_' + n.pitch + '_' + currentBeat,
velocity: Math.min(1, (n.velocity || 0.8)), pitch: n.pitch,
pan: 0.0 start_beat: n.start_beat,
})); duration_beats: Math.max(0.125, currentBeat - n.start_beat),
const rec = midiRec.recordedNotes.map((n, i) => ({ velocity: Math.min(1, (n.velocity || 0.8)),
id: 'rec_' + Date.now() + '_' + i, pan: 0.0
pitch: n.pitch, }));
start_beat: n.start_beat, const rec = midiRec.recordedNotes.map((n, i) => ({
duration_beats: n.duration_beats, id: 'rec_' + Date.now() + '_' + i,
velocity: Math.min(1, (n.velocity || 0.8)), pitch: n.pitch,
pan: 0.0 start_beat: n.start_beat,
})); duration_beats: n.duration_beats,
const allNotes = [...rec, ...activeNotes]; velocity: Math.min(1, (n.velocity || 0.8)),
setRecTempMidiNotes(allNotes); pan: 0.0
setCanvasRedrawCount(n => n + 1); }));
setSubTabs(prev => prev.map(s => const allNotes = [...rec, ...activeNotes];
s.id === tab.id ? { ...s, currentTime: startTime + sec, isDirty: true } : s setRecTempMidiNotes(allNotes);
)); setCanvasRedrawCount(n => n + 1);
}; setSubTabs(prev => prev.map(s =>
showToast('Recording MIDI to Piano Roll...', 'info'); s.id === tab.id ? { ...s, currentTime: startTime + sec, isDirty: true } : s
));
};
if (!tab._recordingStarted) {
tab._recordingStarted = true;
}
showToast('Recording MIDI to Piano Roll...', 'info');
} catch (err) {
console.error('startPianoRollRecording error:', err);
showToast('Lỗi khi bắt đầu ghi âm Piano Roll: ' + err.message, 'warning');
setRecordingState('IDLE');
}
}; };
const startRecordingTake = async (armedTracks) => { const startRecordingTake = async (armedTracks) => {
File diff suppressed because one or more lines are too long