diff --git a/src/plugin.rs b/src/plugin.rs index 385ed30e..ed8e6696 100644 --- a/src/plugin.rs +++ b/src/plugin.rs @@ -358,12 +358,77 @@ pub enum NoteEvent { 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. + /// The note's pressure, from 0 to 1. pressure: f32, }, - // TODO: Add the other non-CC expressions supported by Bitwig and CLAP, register VST3 note - // expressions for hosts that support those + /// A volume expression event, available on [`MidiConfig::Basic`] and up. Not all hosts may + /// support these expressions. + Volume { + 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 voltage gain ratio, where 1.0 is unity gain. + gain: f32, + }, + /// A panning expression event, available on [`MidiConfig::Basic`] and up. Not all hosts may + /// support these expressions. + Pan { + 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 panning from, from -1 to 1, with -1 being panned hard left, and 1 being + /// panned hard right. + pan: f32, + }, + /// A tuning expression event, available on [`MidiConfig::Basic`] and up. Not all hosts may support + /// these expressions. + Tuning { + 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 tuning in semitones, from -120 to 120. + tuning: f32, + }, + /// A vibrato expression event, available on [`MidiConfig::Basic`] and up. Not all hosts may support + /// these expressions. + Vibrato { + 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 vibrato amount, from 0 to 1. + vibrato: f32, + }, + /// A expression expression (yes, expression expression) event, available on + /// [`MidiConfig::Basic`] and up. Not all hosts may support these expressions. + Expression { + 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 expression amount, from 0 to 1. + expression: f32, + }, + /// A brightness expression event, available on [`MidiConfig::Basic`] and up. Not all hosts may support + /// these expressions. + Brightness { + 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 brightness amount, from 0 to 1. + brightness: f32, + }, + // TODO: Add MIDI channel pressure, pitchbend, and CCs } impl NoteEvent { @@ -373,6 +438,12 @@ impl NoteEvent { NoteEvent::NoteOn { timing, .. } => *timing, NoteEvent::NoteOff { timing, .. } => *timing, NoteEvent::PolyPressure { timing, .. } => *timing, + NoteEvent::Volume { timing, .. } => *timing, + NoteEvent::Pan { timing, .. } => *timing, + NoteEvent::Tuning { timing, .. } => *timing, + NoteEvent::Vibrato { timing, .. } => *timing, + NoteEvent::Expression { timing, .. } => *timing, + NoteEvent::Brightness { timing, .. } => *timing, } } } diff --git a/src/wrapper/clap/wrapper.rs b/src/wrapper/clap/wrapper.rs index 0d5df6d6..7348a9a4 100644 --- a/src/wrapper/clap/wrapper.rs +++ b/src/wrapper/clap/wrapper.rs @@ -9,7 +9,9 @@ use clap_sys::events::{ 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_EVENT_PARAM_GESTURE_END, CLAP_EVENT_PARAM_VALUE, CLAP_NOTE_EXPRESSION_BRIGHTNESS, + CLAP_NOTE_EXPRESSION_EXPRESSION, CLAP_NOTE_EXPRESSION_PAN, CLAP_NOTE_EXPRESSION_PRESSURE, + CLAP_NOTE_EXPRESSION_TUNING, CLAP_NOTE_EXPRESSION_VIBRATO, CLAP_NOTE_EXPRESSION_VOLUME, 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, @@ -909,7 +911,55 @@ impl Wrapper

{ note: event.key as u8, pressure: event.value as f32, }); - dbg!(event.value); + } + CLAP_NOTE_EXPRESSION_VOLUME => { + input_events.push_back(NoteEvent::Volume { + timing: raw_event.time - current_sample_idx as u32, + channel: event.channel as u8, + note: event.key as u8, + gain: event.value as f32, + }); + } + CLAP_NOTE_EXPRESSION_PAN => { + input_events.push_back(NoteEvent::Pan { + timing: raw_event.time - current_sample_idx as u32, + channel: event.channel as u8, + note: event.key as u8, + // In CLAP this value goes from [0, 1] instead of [-1, 1] + pan: (event.value as f32 * 2.0) - 1.0, + }); + } + CLAP_NOTE_EXPRESSION_TUNING => { + input_events.push_back(NoteEvent::Tuning { + timing: raw_event.time - current_sample_idx as u32, + channel: event.channel as u8, + note: event.key as u8, + tuning: event.value as f32, + }); + } + CLAP_NOTE_EXPRESSION_VIBRATO => { + input_events.push_back(NoteEvent::Vibrato { + timing: raw_event.time - current_sample_idx as u32, + channel: event.channel as u8, + note: event.key as u8, + vibrato: event.value as f32, + }); + } + CLAP_NOTE_EXPRESSION_EXPRESSION => { + input_events.push_back(NoteEvent::Expression { + timing: raw_event.time - current_sample_idx as u32, + channel: event.channel as u8, + note: event.key as u8, + expression: event.value as f32, + }); + } + CLAP_NOTE_EXPRESSION_BRIGHTNESS => { + input_events.push_back(NoteEvent::Brightness { + timing: raw_event.time - current_sample_idx as u32, + channel: event.channel as u8, + note: event.key as u8, + brightness: event.value as f32, + }); } n => nih_debug_assert_failure!("Unhandled note expression ID {}", n), } diff --git a/src/wrapper/vst3/wrapper.rs b/src/wrapper/vst3/wrapper.rs index c9650ded..a5330fd6 100644 --- a/src/wrapper/vst3/wrapper.rs +++ b/src/wrapper/vst3/wrapper.rs @@ -792,6 +792,9 @@ impl IAudioProcessor for Wrapper

{ pressure: event.pressure, }); } + + // TODO: Add note event controllers to support the same expression types + // we're supporting for CLAP } } }