fix: piano roll recording - playhead, realtime notes, recording display
This commit is contained in:
+49
-1
@@ -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
Reference in New Issue
Block a user