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);
|
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
|
// Draw selection marquee if active
|
||||||
if (selectionMarquee) {
|
if (selectionMarquee) {
|
||||||
const minBeat = Math.min(selectionMarquee.startBeat, selectionMarquee.currentBeat);
|
const minBeat = Math.min(selectionMarquee.startBeat, selectionMarquee.currentBeat);
|
||||||
@@ -4844,7 +4861,7 @@ const PianoRollTabEditor = ({ st, zoom, bpm, viewportWidth, onClose, onUpdateNot
|
|||||||
ctx.stroke();
|
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(() => {
|
React.useEffect(() => {
|
||||||
const canvas = ccCanvasRef.current;
|
const canvas = ccCanvasRef.current;
|
||||||
@@ -9825,10 +9842,41 @@ const App = () => {
|
|||||||
pianoRollRecorderRef.current = midiRec;
|
pianoRollRecorderRef.current = midiRec;
|
||||||
activeMIDIRecordersRef.current['piano_roll'] = midiRec;
|
activeMIDIRecordersRef.current['piano_roll'] = midiRec;
|
||||||
if (selectedMidiInputId) midiRec.setSelectedMidiInputId(selectedMidiInputId);
|
if (selectedMidiInputId) midiRec.setSelectedMidiInputId(selectedMidiInputId);
|
||||||
|
setRecStartTimelineTime(startTime);
|
||||||
|
recordingStartTimeRef.current = startTime;
|
||||||
setRecordingState('RECORDING');
|
setRecordingState('RECORDING');
|
||||||
setRecTempMidiNotes([]);
|
setRecTempMidiNotes([]);
|
||||||
startTrackPlayback(startTime);
|
startTrackPlayback(startTime);
|
||||||
|
startOffsetTimeRef.current = startTime;
|
||||||
|
startAudioTimeRef.current = context.currentTime;
|
||||||
setIsPlaying(true);
|
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');
|
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