fix: piano roll recording - playhead, realtime notes, recording display

This commit is contained in:
2026-07-25 18:30:16 +07:00
parent 9498a0d4b0
commit dffb8562df
2 changed files with 53 additions and 4 deletions
+49 -1
View File
@@ -4810,6 +4810,23 @@ const PianoRollTabEditor = ({ st, zoom, bpm, viewportWidth, onClose, onUpdateNot
ctx.fillRect(x + 1, y + 1, velW, NoteHeight - 2);
});
// Draw real-time recording notes
if (recordingState === 'RECORDING' && recTempMidiNotes && recTempMidiNotes.length > 0) {
recTempMidiNotes.forEach(note => {
const x = note.start_beat * pixelsPerBeat;
const y = (127 - note.pitch) * NoteHeight;
const w = (note.duration_beats || 0.25) * pixelsPerBeat;
ctx.fillStyle = 'rgba(255, 100, 100, 0.35)';
ctx.strokeStyle = '#ff6464';
ctx.lineWidth = 1;
ctx.fillRect(x + 1, y + 1, Math.max(2, w - 2), NoteHeight - 2);
ctx.strokeRect(x + 1, y + 1, Math.max(2, w - 2), NoteHeight - 2);
const vel = Math.min(1, note.velocity || 0.8);
ctx.fillStyle = '#ff6464';
ctx.fillRect(x + 1, y + 1, Math.max(2, (w - 2) * vel), NoteHeight - 2);
});
}
// Draw selection marquee if active
if (selectionMarquee) {
const minBeat = Math.min(selectionMarquee.startBeat, selectionMarquee.currentBeat);
@@ -4844,7 +4861,7 @@ const PianoRollTabEditor = ({ st, zoom, bpm, viewportWidth, onClose, onUpdateNot
ctx.stroke();
}
}
}, [notes, snapVal, rollZoom, selectedNoteIds, selectionMarquee, st.currentTime, bpm, viewWidth, viewBeats]);
}, [notes, snapVal, rollZoom, selectedNoteIds, selectionMarquee, st.currentTime, bpm, viewWidth, viewBeats, recordingState, recTempMidiNotes]);
React.useEffect(() => {
const canvas = ccCanvasRef.current;
@@ -9825,10 +9842,41 @@ const App = () => {
pianoRollRecorderRef.current = midiRec;
activeMIDIRecordersRef.current['piano_roll'] = midiRec;
if (selectedMidiInputId) midiRec.setSelectedMidiInputId(selectedMidiInputId);
setRecStartTimelineTime(startTime);
recordingStartTimeRef.current = startTime;
setRecordingState('RECORDING');
setRecTempMidiNotes([]);
startTrackPlayback(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));
setSubTabs(prev => prev.map(s => {
if (s.id !== tab.id) return s;
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);
return { ...s, currentTime: startTime + sec, isDirty: true };
}));
};
showToast('Recording MIDI to Piano Roll...', 'info');
};
File diff suppressed because one or more lines are too long