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);
}
}
_ => (),
},
_ => break 'midi_events,
}

View file

@ -313,7 +313,8 @@ pub enum MidiConfig {
Basic,
// // TODO:
// /// 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,
}
@ -325,6 +326,7 @@ pub enum MidiConfig {
///
/// TODO: Add more events as needed
#[derive(Debug, Clone, Copy, PartialEq)]
#[non_exhaustive]
pub enum NoteEvent {
/// A note on event, available on [`MidiConfig::Basic`] and up.
NoteOn {
@ -348,6 +350,20 @@ pub enum NoteEvent {
/// 127 levels available in MIDI.
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 {
@ -356,6 +372,7 @@ impl NoteEvent {
match &self {
NoteEvent::NoteOn { timing, .. } => *timing,
NoteEvent::NoteOff { timing, .. } => *timing,
NoteEvent::PolyPressure { timing, .. } => *timing,
}
}
}

View file

@ -5,11 +5,12 @@
use atomic_float::AtomicF32;
use atomic_refcell::{AtomicRefCell, AtomicRefMut};
use clap_sys::events::{
clap_event_header, clap_event_note, clap_event_param_gesture, clap_event_param_value,
clap_event_type, clap_input_events, clap_output_events, CLAP_CORE_EVENT_SPACE_ID,
CLAP_EVENT_IS_LIVE, CLAP_EVENT_MIDI, CLAP_EVENT_NOTE_EXPRESSION, CLAP_EVENT_NOTE_OFF,
CLAP_EVENT_NOTE_ON, CLAP_EVENT_PARAM_GESTURE_BEGIN, CLAP_EVENT_PARAM_GESTURE_END,
CLAP_EVENT_PARAM_VALUE, CLAP_TRANSPORT_HAS_BEATS_TIMELINE, CLAP_TRANSPORT_HAS_SECONDS_TIMELINE,
clap_event_header, clap_event_note, clap_event_note_expression, clap_event_param_gesture,
clap_event_param_value, clap_event_type, clap_input_events, clap_output_events,
CLAP_CORE_EVENT_SPACE_ID, CLAP_EVENT_IS_LIVE, CLAP_EVENT_MIDI, CLAP_EVENT_NOTE_EXPRESSION,
CLAP_EVENT_NOTE_OFF, CLAP_EVENT_NOTE_ON, CLAP_EVENT_PARAM_GESTURE_BEGIN,
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_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) => {
if P::MIDI_INPUT >= MidiConfig::Basic {
// We currently don't report supporting this at all in the event filter, add that once
// we support MIDI CCs
// TODO: Implement pressure and other expressions along with MIDI CCs
// TODO: Add support for the other expression types
let event = &*(event as *const clap_event_note_expression);
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
@ -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_NOTE_ON)
| (CLAP_CORE_EVENT_SPACE_ID, CLAP_EVENT_NOTE_OFF)
| (CLAP_CORE_EVENT_SPACE_ID, CLAP_EVENT_NOTE_EXPRESSION)
// TODO: Implement midi CC handling
// | (CLAP_CORE_EVENT_SPACE_ID, CLAP_EVENT_NOTE_EXPRESSION)
// | (CLAP_CORE_EVENT_SPACE_ID, CLAP_EVENT_MIDI)
if P::MIDI_INPUT >= MidiConfig::Basic =>
{

View file

@ -781,6 +781,16 @@ impl<P: Vst3Plugin> IAudioProcessor for Wrapper<P> {
note: event.pitch as u8,
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,
});
}
}
}