1
0
Fork 0

Move MIDI parsing from CLAP wrapper to NoteEvent

This commit is contained in:
Robbert van der Helm 2022-06-14 22:59:32 +02:00
parent 4e021dd0bb
commit 66f5a0e7de
2 changed files with 55 additions and 56 deletions

View file

@ -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) {

View file

@ -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),
};
}