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 context = getAudioContext();
const secondsPerBeat = 60.0 / (parseInt(bpm) || 120);
const startTime = currentTime;
const midiRec = new ClientMIDIRecorder(context, parseInt(bpm) || 120, 4);
midiRec.tempTabId = tab.id;
midiRec.selectedMidiInputId = selectedMidiInputId || 'ALL';
midiRec.start(startTime / secondsPerBeat, midiRec.selectedMidiInputId);
pianoRollRecorderRef.current = midiRec;
activeMIDIRecordersRef.current['piano_roll'] = midiRec;
setRecStartTimelineTime(startTime);
recordingStartTimeRef.current = startTime;
setRecordingState('RECORDING');
setRecTempMidiNotes([]);
const ctx = getAudioContext();
const silentBuf = ctx.createBuffer(1, 128, ctx.sampleRate);
setSubTabs(prev => prev.map(s => s.id === tab.id ? { ...s, buffer: silentBuf, isPlaying: true } : s));
startSubTabPlayback({ ...tab, buffer: silentBuf }, startTime);
startOffsetTimeRef.current = startTime;
startAudioTimeRef.current = context.currentTime;
setIsPlaying(true);
midiRec.onNoteOn = (pitch, currentBeat) => {
const elapsedBeats = Math.max(0, currentBeat);
const sec = elapsedBeats * (60.0 / (parseInt(bpm) || 120));
const activeNotes = Array.from(midiRec.activeNotes.values()).map(n => ({
id: 'rec_' + n.pitch + '_' + currentBeat,
pitch: n.pitch,
start_beat: n.start_beat,
duration_beats: Math.max(0.125, currentBeat - n.start_beat),
velocity: Math.min(1, (n.velocity || 0.8)),
pan: 0.0
}));
const rec = midiRec.recordedNotes.map((n, i) => ({
id: 'rec_' + Date.now() + '_' + i,
pitch: n.pitch,
start_beat: n.start_beat,
duration_beats: n.duration_beats,
velocity: Math.min(1, (n.velocity || 0.8)),
pan: 0.0
}));
const allNotes = [...rec, ...activeNotes];
setRecTempMidiNotes(allNotes);
setCanvasRedrawCount(n => n + 1);
setSubTabs(prev => prev.map(s =>
s.id === tab.id ? { ...s, currentTime: startTime + sec, isDirty: true } : s
));
};
showToast('Recording MIDI to Piano Roll...', 'info');
try {
const context = getAudioContext();
const secondsPerBeat = 60.0 / (parseInt(bpm) || 120);
const startTime = currentTime;
const startBeat = startTime / secondsPerBeat;
nextMetronomeBeatRef.current = Math.ceil(startBeat);
const midiRec = new ClientMIDIRecorder(context, parseInt(bpm) || 120, 4);
midiRec.tempTabId = tab.id;
midiRec.selectedMidiInputId = selectedMidiInputId || 'ALL';
midiRec.start(startTime / secondsPerBeat, midiRec.selectedMidiInputId);
pianoRollRecorderRef.current = midiRec;
activeMIDIRecordersRef.current['piano_roll'] = midiRec;
setRecStartTimelineTime(startTime);
recordingStartTimeRef.current = startTime;
setRecordingState('RECORDING');
setRecTempMidiNotes([]);
const ctx = getAudioContext();
const silentBuf = ctx.createBuffer(1, 128, ctx.sampleRate);
setSubTabs(prev => prev.map(s => s.id === tab.id ? { ...s, buffer: silentBuf, isPlaying: true } : s));
startSubTabPlayback({ ...tab, buffer: silentBuf }, startTime);
startOffsetTimeRef.current = startTime;
startAudioTimeRef.current = context.currentTime;
setIsPlaying(true);
midiRec.onNoteOn = (pitch, currentBeat) => {
const elapsedBeats = Math.max(0, currentBeat);
const sec = elapsedBeats * (60.0 / (parseInt(bpm) || 120));
const activeNotes = Array.from(midiRec.activeNotes.values()).map(n => ({
id: 'rec_' + n.pitch + '_' + currentBeat,
pitch: n.pitch,
start_beat: n.start_beat,
duration_beats: Math.max(0.125, currentBeat - n.start_beat),
velocity: Math.min(1, (n.velocity || 0.8)),
pan: 0.0
}));
const rec = midiRec.recordedNotes.map((n, i) => ({
id: 'rec_' + Date.now() + '_' + i,
pitch: n.pitch,
start_beat: n.start_beat,
duration_beats: n.duration_beats,
velocity: Math.min(1, (n.velocity || 0.8)),
pan: 0.0
}));
const allNotes = [...rec, ...activeNotes];
setRecTempMidiNotes(allNotes);
setCanvasRedrawCount(n => n + 1);
setSubTabs(prev => prev.map(s =>
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) => {
File diff suppressed because one or more lines are too long