fix: MIDI record + key highlight on MIDI key press
This commit is contained in:
+25
-14
@@ -4543,7 +4543,7 @@ const AIPresetModal = ({ isOpen, onClose }) => {
|
|||||||
}, "Đóng"))));
|
}, "Đóng"))));
|
||||||
};
|
};
|
||||||
|
|
||||||
const PianoRollTabEditor = ({ st, zoom, bpm, viewportWidth, onClose, onUpdateNotes, onSaveNotes, setSubTabs, onPlayPause, onStop, isPlaying, playPreviewNote, showToast, midiDevices, recordingState, recTempMidiNotes, onRecord, selectedMidiInputId, onMidiInputSelect }) => {
|
const PianoRollTabEditor = ({ st, zoom, bpm, viewportWidth, onClose, onUpdateNotes, onSaveNotes, setSubTabs, onPlayPause, onStop, isPlaying, playPreviewNote, showToast, midiDevices, recordingState, recTempMidiNotes, onRecord, selectedMidiInputId, onMidiInputSelect, activeMidiPitches }) => {
|
||||||
const [activeRollTool, setActiveRollTool] = React.useState('select');
|
const [activeRollTool, setActiveRollTool] = React.useState('select');
|
||||||
const [snapVal, setSnapVal] = React.useState('1/16');
|
const [snapVal, setSnapVal] = React.useState('1/16');
|
||||||
const [ccMode, setCcMode] = React.useState('velocity');
|
const [ccMode, setCcMode] = React.useState('velocity');
|
||||||
@@ -5381,7 +5381,7 @@ const PianoRollTabEditor = ({ st, zoom, bpm, viewportWidth, onClose, onUpdateNot
|
|||||||
/*#__PURE__*/React.createElement("div", {
|
/*#__PURE__*/React.createElement("div", {
|
||||||
key: pitch,
|
key: pitch,
|
||||||
style: { height: `${NoteHeight}px` },
|
style: { height: `${NoteHeight}px` },
|
||||||
className: `w-[60px] shrink-0 border-b border-zinc-800 text-[9px] font-bold flex items-center justify-end pr-2 transition cursor-pointer ${isBlack ? 'bg-zinc-950 text-slate-500 border-zinc-900 hover:bg-zinc-800' : 'bg-white text-zinc-800 border-r border-zinc-400 hover:bg-amber-100'}`,
|
className: `w-[60px] shrink-0 border-b border-zinc-800 text-[9px] font-bold flex items-center justify-end pr-2 transition cursor-pointer ${activeMidiPitches && activeMidiPitches.has(pitch) ? 'bg-emerald-500 text-white border-emerald-400' : isBlack ? 'bg-zinc-950 text-slate-500 border-zinc-900 hover:bg-zinc-800' : 'bg-white text-zinc-800 border-r border-zinc-400 hover:bg-amber-100'}`,
|
||||||
onMouseDown: (e) => {
|
onMouseDown: (e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
keybedMouseDownRef.current = true;
|
keybedMouseDownRef.current = true;
|
||||||
@@ -6279,13 +6279,21 @@ const App = () => {
|
|||||||
input.onmidimessage = msg => {
|
input.onmidimessage = msg => {
|
||||||
console.log(`[DevLog] [Raw MIDI] Received from "${input.name}" (ID: ${input.id}) - Data:`, Array.from(msg.data));
|
console.log(`[DevLog] [Raw MIDI] Received from "${input.name}" (ID: ${input.id}) - Data:`, Array.from(msg.data));
|
||||||
if (msg.data.length < 3) return;
|
if (msg.data.length < 3) return;
|
||||||
const cmd = msg.data[0] >> 4;
|
const cmd = msg.data[0] >> 4;
|
||||||
const pitch = msg.data[1];
|
const pitch = msg.data[1];
|
||||||
const velocity = msg.data[2];
|
const velocity = msg.data[2];
|
||||||
if (cmd === 0x9 && velocity > 0) {
|
if (cmd === 0x9 && velocity > 0) {
|
||||||
lastMidiNoteRef.current = { pitch, velocity, startTime: performance.now(), length: 0 };
|
lastMidiNoteRef.current = { pitch, velocity, startTime: performance.now(), length: 0 };
|
||||||
setLastMidiNote({ pitch, velocity, length: 0, time: Date.now() });
|
setLastMidiNote({ pitch, velocity, length: 0, time: Date.now() });
|
||||||
} else if (cmd === 0x8 || (cmd === 0x9 && velocity === 0)) {
|
activeMidiPitchesRef.current.add(pitch);
|
||||||
|
setActiveMidiPitches(new Set(activeMidiPitchesRef.current));
|
||||||
|
const activeTabInfo = subTabs.find(s => s.id === activeTab && s.type === 'PIANO_ROLL' && s.isArmed);
|
||||||
|
if (activeTabInfo && window.SonicSF) {
|
||||||
|
try { window.SonicSF.playNote(pitch, velocity, 500, undefined, activeTabInfo.instrumentProgram, null); } catch (e) {}
|
||||||
|
}
|
||||||
|
} else if (cmd === 0x8 || (cmd === 0x9 && velocity === 0)) {
|
||||||
|
activeMidiPitchesRef.current.delete(pitch);
|
||||||
|
setActiveMidiPitches(new Set(activeMidiPitchesRef.current));
|
||||||
const current = lastMidiNoteRef.current;
|
const current = lastMidiNoteRef.current;
|
||||||
if (current && current.pitch === pitch) {
|
if (current && current.pitch === pitch) {
|
||||||
const lenSec = (performance.now() - current.startTime) / 1000;
|
const lenSec = (performance.now() - current.startTime) / 1000;
|
||||||
@@ -6329,6 +6337,8 @@ const App = () => {
|
|||||||
const activeMIDIRecordersRef = useRef({});
|
const activeMIDIRecordersRef = useRef({});
|
||||||
const activeAudioRecordersRef = useRef({});
|
const activeAudioRecordersRef = useRef({});
|
||||||
const pianoRollRecorderRef = useRef(null);
|
const pianoRollRecorderRef = useRef(null);
|
||||||
|
const activeMidiPitchesRef = useRef(new Set());
|
||||||
|
const [activeMidiPitches, setActiveMidiPitches] = useState(new Set());
|
||||||
const recordingPCMDataRef = useRef({});
|
const recordingPCMDataRef = useRef({});
|
||||||
const recordingStartTimeRef = useRef(0);
|
const recordingStartTimeRef = useRef(0);
|
||||||
const recordingSyncRef = useRef(null);
|
const recordingSyncRef = useRef(null);
|
||||||
@@ -15420,11 +15430,12 @@ const App = () => {
|
|||||||
playPreviewNote: playMidiPreviewNote,
|
playPreviewNote: playMidiPreviewNote,
|
||||||
showToast: showToast,
|
showToast: showToast,
|
||||||
midiDevices: midiDevices,
|
midiDevices: midiDevices,
|
||||||
recordingState: recordingState,
|
recordingState: recordingState,
|
||||||
onRecord: handleRecordClick,
|
onRecord: handleRecordClick,
|
||||||
selectedMidiInputId: selectedMidiInputId,
|
selectedMidiInputId: selectedMidiInputId,
|
||||||
onMidiInputSelect: handleMidiInputSelect
|
onMidiInputSelect: handleMidiInputSelect,
|
||||||
});
|
activeMidiPitches: activeMidiPitches
|
||||||
|
});
|
||||||
}
|
}
|
||||||
const subTrack = tracks.find(t => t.id === st.trackId);
|
const subTrack = tracks.find(t => t.id === st.trackId);
|
||||||
const vTrack = subTrack ? {
|
const vTrack = subTrack ? {
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user