Move MIDI parsing from CLAP wrapper to NoteEvent
This commit is contained in:
parent
4e021dd0bb
commit
66f5a0e7de
48
src/midi.rs
48
src/midi.rs
|
@ -1,5 +1,7 @@
|
|||
//! Constants and definitions surrounding MIDI support.
|
||||
|
||||
use midi_consts::channel_event as midi;
|
||||
|
||||
pub use midi_consts::channel_event::control_change;
|
||||
|
||||
/// Determines which note events a plugin receives.
|
||||
|
@ -184,6 +186,52 @@ impl NoteEvent {
|
|||
}
|
||||
}
|
||||
|
||||
/// Parse MIDI into a [`NoteEvent`]. Will return `Err(event_type)` if the parsing failed.
|
||||
pub fn from_midi(timing: u32, midi_data: [u8; 3]) -> Result<Self, u8> {
|
||||
// TODO: Maybe add special handling for 14-bit CCs and RPN messages at some
|
||||
// point, right now the plugin has to figure it out for itself
|
||||
let event_type = midi_data[0] & midi::EVENT_TYPE_MASK;
|
||||
let channel = midi_data[0] & midi::MIDI_CHANNEL_MASK;
|
||||
match event_type {
|
||||
midi::NOTE_ON => Ok(NoteEvent::NoteOn {
|
||||
timing,
|
||||
channel,
|
||||
note: midi_data[1],
|
||||
velocity: midi_data[2] as f32 / 127.0,
|
||||
}),
|
||||
midi::NOTE_OFF => Ok(NoteEvent::NoteOff {
|
||||
timing,
|
||||
channel,
|
||||
note: midi_data[1],
|
||||
velocity: midi_data[2] as f32 / 127.0,
|
||||
}),
|
||||
midi::POLYPHONIC_KEY_PRESSURE => Ok(NoteEvent::PolyPressure {
|
||||
timing,
|
||||
channel,
|
||||
note: midi_data[1],
|
||||
pressure: midi_data[2] as f32 / 127.0,
|
||||
}),
|
||||
midi::CHANNEL_KEY_PRESSURE => Ok(NoteEvent::MidiChannelPressure {
|
||||
timing,
|
||||
channel,
|
||||
pressure: midi_data[1] as f32 / 127.0,
|
||||
}),
|
||||
midi::PITCH_BEND_CHANGE => Ok(NoteEvent::MidiPitchBend {
|
||||
timing,
|
||||
channel,
|
||||
value: (midi_data[1] as u16 + ((midi_data[2] as u16) << 7)) as f32
|
||||
/ ((1 << 14) - 1) as f32,
|
||||
}),
|
||||
midi::CONTROL_CHANGE => Ok(NoteEvent::MidiCC {
|
||||
timing,
|
||||
channel,
|
||||
cc: midi_data[1],
|
||||
value: midi_data[2] as f32 / 127.0,
|
||||
}),
|
||||
n => Err(n),
|
||||
}
|
||||
}
|
||||
|
||||
/// Subtract a sample offset from this event's timing, needed to compensate for the block
|
||||
/// splitting in the VST3 wrapper implementation because all events have to be read upfront.
|
||||
pub(crate) fn subtract_timing(&mut self, samples: u32) {
|
||||
|
|
|
@ -1360,63 +1360,14 @@ impl<P: ClapPlugin> Wrapper<P> {
|
|||
if P::MIDI_INPUT >= MidiConfig::MidiCCs {
|
||||
let event = &*(event as *const clap_event_midi);
|
||||
|
||||
// TODO: Maybe add special handling for 14-bit CCs and RPN messages at some
|
||||
// point, right now the plugin has to figure it out for itself
|
||||
let event_type = event.data[0] & midi::EVENT_TYPE_MASK;
|
||||
let channel = event.data[0] & midi::MIDI_CHANNEL_MASK;
|
||||
match event_type {
|
||||
// Hosts shouldn't be sending this, bu twe'll handle it just in case
|
||||
midi::NOTE_ON => {
|
||||
input_events.push_back(NoteEvent::NoteOn {
|
||||
timing: raw_event.time - current_sample_idx as u32,
|
||||
channel,
|
||||
note: event.data[1],
|
||||
velocity: event.data[2] as f32 / 127.0,
|
||||
});
|
||||
match NoteEvent::from_midi(
|
||||
raw_event.time - current_sample_idx as u32,
|
||||
event.data,
|
||||
) {
|
||||
Ok(note_event) => {
|
||||
input_events.push_back(note_event);
|
||||
}
|
||||
// Hosts shouldn't be sending this, bu twe'll handle it just in case
|
||||
midi::NOTE_OFF => {
|
||||
input_events.push_back(NoteEvent::NoteOff {
|
||||
timing: raw_event.time - current_sample_idx as u32,
|
||||
channel,
|
||||
note: event.data[1],
|
||||
velocity: event.data[2] as f32 / 127.0,
|
||||
});
|
||||
}
|
||||
// Hosts shouldn't be sending this, bu twe'll handle it just in case
|
||||
midi::POLYPHONIC_KEY_PRESSURE => {
|
||||
input_events.push_back(NoteEvent::PolyPressure {
|
||||
timing: raw_event.time - current_sample_idx as u32,
|
||||
channel,
|
||||
note: event.data[1],
|
||||
pressure: event.data[2] as f32 / 127.0,
|
||||
});
|
||||
}
|
||||
midi::CHANNEL_KEY_PRESSURE => {
|
||||
input_events.push_back(NoteEvent::MidiChannelPressure {
|
||||
timing: raw_event.time - current_sample_idx as u32,
|
||||
channel,
|
||||
pressure: event.data[1] as f32 / 127.0,
|
||||
});
|
||||
}
|
||||
midi::PITCH_BEND_CHANGE => {
|
||||
input_events.push_back(NoteEvent::MidiPitchBend {
|
||||
timing: raw_event.time - current_sample_idx as u32,
|
||||
channel,
|
||||
value: (event.data[1] as u16 + ((event.data[2] as u16) << 7))
|
||||
as f32
|
||||
/ ((1 << 14) - 1) as f32,
|
||||
});
|
||||
}
|
||||
midi::CONTROL_CHANGE => {
|
||||
input_events.push_back(NoteEvent::MidiCC {
|
||||
timing: raw_event.time - current_sample_idx as u32,
|
||||
channel,
|
||||
cc: event.data[1],
|
||||
value: event.data[2] as f32 / 127.0,
|
||||
});
|
||||
}
|
||||
n => nih_debug_assert_failure!("Unhandled MIDI message type {}", n),
|
||||
Err(n) => nih_debug_assert_failure!("Unhandled MIDI message type {}", n),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue