1
0
Fork 0

Add polyphonic aftertouch support

This commit is contained in:
Robbert van der Helm 2022-04-07 20:54:37 +02:00
parent 1141616466
commit b9a10455bb
4 changed files with 50 additions and 10 deletions

View file

@ -153,6 +153,7 @@ impl Plugin for Sine {
self.midi_note_gain.set_target(self.sample_rate, 0.0); self.midi_note_gain.set_target(self.sample_rate, 0.0);
} }
} }
_ => (),
}, },
_ => break 'midi_events, _ => break 'midi_events,
} }

View file

@ -313,7 +313,8 @@ pub enum MidiConfig {
Basic, Basic,
// // TODO: // // TODO:
// /// The plugin receives full MIDI CCs as well as pitch bend information. For VST3 plugins this // /// The plugin receives full MIDI CCs as well as pitch bend information. For VST3 plugins this
// /// involves adding // /// involves adding 130*16 parameters to bind to the the 128 MIDI CCs, pitch bend, and channel
// /// pressure.
// MidiCCs, // MidiCCs,
} }
@ -325,6 +326,7 @@ pub enum MidiConfig {
/// ///
/// TODO: Add more events as needed /// TODO: Add more events as needed
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
#[non_exhaustive]
pub enum NoteEvent { pub enum NoteEvent {
/// A note on event, available on [`MidiConfig::Basic`] and up. /// A note on event, available on [`MidiConfig::Basic`] and up.
NoteOn { NoteOn {
@ -348,6 +350,20 @@ pub enum NoteEvent {
/// 127 levels available in MIDI. /// 127 levels available in MIDI.
velocity: f32, velocity: f32,
}, },
/// A polyphonic note pressure/aftertouch event, available on [`MidiConfig::Basic`] and up. Not
/// all hosts may support polyphonic aftertouch.
PolyPressure {
timing: u32,
/// The note's channel, from 0 to 16.
channel: u8,
/// The note's MIDI key number, from 0 to 127.
note: u8,
/// The note's velocity, from 0 to 1. Some plugin APIs may allow higher precision than the
/// 127 levels available in MIDI.
pressure: f32,
},
// TODO: Add the other non-CC expressions supported by Bitwig and CLAP, register VST3 note
// expressions for hosts that support those
} }
impl NoteEvent { impl NoteEvent {
@ -356,6 +372,7 @@ impl NoteEvent {
match &self { match &self {
NoteEvent::NoteOn { timing, .. } => *timing, NoteEvent::NoteOn { timing, .. } => *timing,
NoteEvent::NoteOff { timing, .. } => *timing, NoteEvent::NoteOff { timing, .. } => *timing,
NoteEvent::PolyPressure { timing, .. } => *timing,
} }
} }
} }

View file

@ -5,11 +5,12 @@
use atomic_float::AtomicF32; use atomic_float::AtomicF32;
use atomic_refcell::{AtomicRefCell, AtomicRefMut}; use atomic_refcell::{AtomicRefCell, AtomicRefMut};
use clap_sys::events::{ use clap_sys::events::{
clap_event_header, clap_event_note, clap_event_param_gesture, clap_event_param_value, clap_event_header, clap_event_note, clap_event_note_expression, clap_event_param_gesture,
clap_event_type, clap_input_events, clap_output_events, CLAP_CORE_EVENT_SPACE_ID, clap_event_param_value, clap_event_type, clap_input_events, clap_output_events,
CLAP_EVENT_IS_LIVE, CLAP_EVENT_MIDI, CLAP_EVENT_NOTE_EXPRESSION, CLAP_EVENT_NOTE_OFF, CLAP_CORE_EVENT_SPACE_ID, CLAP_EVENT_IS_LIVE, CLAP_EVENT_MIDI, CLAP_EVENT_NOTE_EXPRESSION,
CLAP_EVENT_NOTE_ON, CLAP_EVENT_PARAM_GESTURE_BEGIN, CLAP_EVENT_PARAM_GESTURE_END, CLAP_EVENT_NOTE_OFF, CLAP_EVENT_NOTE_ON, CLAP_EVENT_PARAM_GESTURE_BEGIN,
CLAP_EVENT_PARAM_VALUE, CLAP_TRANSPORT_HAS_BEATS_TIMELINE, CLAP_TRANSPORT_HAS_SECONDS_TIMELINE, CLAP_EVENT_PARAM_GESTURE_END, CLAP_EVENT_PARAM_VALUE, CLAP_NOTE_EXPRESSION_PRESSURE,
CLAP_TRANSPORT_HAS_BEATS_TIMELINE, CLAP_TRANSPORT_HAS_SECONDS_TIMELINE,
CLAP_TRANSPORT_HAS_TEMPO, CLAP_TRANSPORT_HAS_TIME_SIGNATURE, CLAP_TRANSPORT_IS_LOOP_ACTIVE, CLAP_TRANSPORT_HAS_TEMPO, CLAP_TRANSPORT_HAS_TIME_SIGNATURE, CLAP_TRANSPORT_IS_LOOP_ACTIVE,
CLAP_TRANSPORT_IS_PLAYING, CLAP_TRANSPORT_IS_RECORDING, CLAP_TRANSPORT_IS_WITHIN_PRE_ROLL, CLAP_TRANSPORT_IS_PLAYING, CLAP_TRANSPORT_IS_RECORDING, CLAP_TRANSPORT_IS_WITHIN_PRE_ROLL,
}; };
@ -898,9 +899,20 @@ impl<P: ClapPlugin> Wrapper<P> {
} }
(CLAP_CORE_EVENT_SPACE_ID, CLAP_EVENT_NOTE_EXPRESSION) => { (CLAP_CORE_EVENT_SPACE_ID, CLAP_EVENT_NOTE_EXPRESSION) => {
if P::MIDI_INPUT >= MidiConfig::Basic { if P::MIDI_INPUT >= MidiConfig::Basic {
// We currently don't report supporting this at all in the event filter, add that once // TODO: Add support for the other expression types
// we support MIDI CCs let event = &*(event as *const clap_event_note_expression);
// TODO: Implement pressure and other expressions along with MIDI CCs match event.expression_id {
CLAP_NOTE_EXPRESSION_PRESSURE => {
input_events.push_back(NoteEvent::PolyPressure {
timing: raw_event.time - current_sample_idx as u32,
channel: event.channel as u8,
note: event.key as u8,
pressure: event.value as f32,
});
dbg!(event.value);
}
n => nih_debug_assert_failure!("Unhandled note expression ID {}", n),
}
} }
false false
@ -1617,8 +1629,8 @@ impl<P: ClapPlugin> Wrapper<P> {
(CLAP_CORE_EVENT_SPACE_ID, CLAP_EVENT_PARAM_VALUE) => true, (CLAP_CORE_EVENT_SPACE_ID, CLAP_EVENT_PARAM_VALUE) => true,
(CLAP_CORE_EVENT_SPACE_ID, CLAP_EVENT_NOTE_ON) (CLAP_CORE_EVENT_SPACE_ID, CLAP_EVENT_NOTE_ON)
| (CLAP_CORE_EVENT_SPACE_ID, CLAP_EVENT_NOTE_OFF) | (CLAP_CORE_EVENT_SPACE_ID, CLAP_EVENT_NOTE_OFF)
| (CLAP_CORE_EVENT_SPACE_ID, CLAP_EVENT_NOTE_EXPRESSION)
// TODO: Implement midi CC handling // TODO: Implement midi CC handling
// | (CLAP_CORE_EVENT_SPACE_ID, CLAP_EVENT_NOTE_EXPRESSION)
// | (CLAP_CORE_EVENT_SPACE_ID, CLAP_EVENT_MIDI) // | (CLAP_CORE_EVENT_SPACE_ID, CLAP_EVENT_MIDI)
if P::MIDI_INPUT >= MidiConfig::Basic => if P::MIDI_INPUT >= MidiConfig::Basic =>
{ {

View file

@ -781,6 +781,16 @@ impl<P: Vst3Plugin> IAudioProcessor for Wrapper<P> {
note: event.pitch as u8, note: event.pitch as u8,
velocity: event.velocity, velocity: event.velocity,
}); });
} else if event.type_
== vst3_sys::vst::EventTypes::kPolyPressureEvent as u16
{
let event = event.event.poly_pressure;
input_events.push_back(NoteEvent::PolyPressure {
timing,
channel: event.channel as u8,
note: event.pitch as u8,
pressure: event.pressure,
});
} }
} }
} }