Add voice ID fields for all non-MIDI note events
This will be useful when adding polyphonic modulation.
This commit is contained in:
parent
f11b3c1a03
commit
a2f8a9bebf
|
@ -11,6 +11,7 @@ code then it will not be listed here.
|
||||||
- The `CLAP_DESCRIPTION`, `CLAP_MANUAL_URL`, and `CLAP_SUPPORT_URL` associated
|
- The `CLAP_DESCRIPTION`, `CLAP_MANUAL_URL`, and `CLAP_SUPPORT_URL` associated
|
||||||
constants from the `ClapPlugin` are now optional and have the type
|
constants from the `ClapPlugin` are now optional and have the type
|
||||||
`Option<&'static str>` instead of `&'static str`.
|
`Option<&'static str>` instead of `&'static str`.
|
||||||
|
- Most `NoteEvent` variants now have an additional `voice_id` field.
|
||||||
|
|
||||||
## [2022-07-02]
|
## [2022-07-02]
|
||||||
|
|
||||||
|
|
|
@ -49,99 +49,117 @@ impl Plugin for MidiInverter {
|
||||||
match event {
|
match event {
|
||||||
NoteEvent::NoteOn {
|
NoteEvent::NoteOn {
|
||||||
timing,
|
timing,
|
||||||
|
voice_id,
|
||||||
channel,
|
channel,
|
||||||
note,
|
note,
|
||||||
velocity,
|
velocity,
|
||||||
} => context.send_event(NoteEvent::NoteOn {
|
} => context.send_event(NoteEvent::NoteOn {
|
||||||
timing,
|
timing,
|
||||||
|
voice_id,
|
||||||
channel: 15 - channel,
|
channel: 15 - channel,
|
||||||
note: 127 - note,
|
note: 127 - note,
|
||||||
velocity: 1.0 - velocity,
|
velocity: 1.0 - velocity,
|
||||||
}),
|
}),
|
||||||
NoteEvent::NoteOff {
|
NoteEvent::NoteOff {
|
||||||
timing,
|
timing,
|
||||||
|
voice_id,
|
||||||
channel,
|
channel,
|
||||||
note,
|
note,
|
||||||
velocity,
|
velocity,
|
||||||
} => context.send_event(NoteEvent::NoteOff {
|
} => context.send_event(NoteEvent::NoteOff {
|
||||||
timing,
|
timing,
|
||||||
|
voice_id,
|
||||||
channel: 15 - channel,
|
channel: 15 - channel,
|
||||||
note: 127 - note,
|
note: 127 - note,
|
||||||
velocity: 1.0 - velocity,
|
velocity: 1.0 - velocity,
|
||||||
}),
|
}),
|
||||||
NoteEvent::PolyPressure {
|
NoteEvent::PolyPressure {
|
||||||
timing,
|
timing,
|
||||||
|
voice_id,
|
||||||
channel,
|
channel,
|
||||||
note,
|
note,
|
||||||
pressure,
|
pressure,
|
||||||
} => context.send_event(NoteEvent::PolyPressure {
|
} => context.send_event(NoteEvent::PolyPressure {
|
||||||
timing,
|
timing,
|
||||||
|
voice_id,
|
||||||
channel: 15 - channel,
|
channel: 15 - channel,
|
||||||
note: 127 - note,
|
note: 127 - note,
|
||||||
pressure: 1.0 - pressure,
|
pressure: 1.0 - pressure,
|
||||||
}),
|
}),
|
||||||
NoteEvent::PolyVolume {
|
NoteEvent::PolyVolume {
|
||||||
timing,
|
timing,
|
||||||
|
voice_id,
|
||||||
channel,
|
channel,
|
||||||
note,
|
note,
|
||||||
gain,
|
gain,
|
||||||
} => context.send_event(NoteEvent::PolyVolume {
|
} => context.send_event(NoteEvent::PolyVolume {
|
||||||
timing,
|
timing,
|
||||||
|
voice_id,
|
||||||
channel: 15 - channel,
|
channel: 15 - channel,
|
||||||
note: 127 - note,
|
note: 127 - note,
|
||||||
gain: 1.0 - gain,
|
gain: 1.0 - gain,
|
||||||
}),
|
}),
|
||||||
NoteEvent::PolyPan {
|
NoteEvent::PolyPan {
|
||||||
timing,
|
timing,
|
||||||
|
voice_id,
|
||||||
channel,
|
channel,
|
||||||
note,
|
note,
|
||||||
pan,
|
pan,
|
||||||
} => context.send_event(NoteEvent::PolyPan {
|
} => context.send_event(NoteEvent::PolyPan {
|
||||||
timing,
|
timing,
|
||||||
|
voice_id,
|
||||||
channel: 15 - channel,
|
channel: 15 - channel,
|
||||||
note: 127 - note,
|
note: 127 - note,
|
||||||
pan: 1.0 - pan,
|
pan: 1.0 - pan,
|
||||||
}),
|
}),
|
||||||
NoteEvent::PolyTuning {
|
NoteEvent::PolyTuning {
|
||||||
timing,
|
timing,
|
||||||
|
voice_id,
|
||||||
channel,
|
channel,
|
||||||
note,
|
note,
|
||||||
tuning,
|
tuning,
|
||||||
} => context.send_event(NoteEvent::PolyTuning {
|
} => context.send_event(NoteEvent::PolyTuning {
|
||||||
timing,
|
timing,
|
||||||
|
voice_id,
|
||||||
channel: 15 - channel,
|
channel: 15 - channel,
|
||||||
note: 127 - note,
|
note: 127 - note,
|
||||||
tuning: 1.0 - tuning,
|
tuning: 1.0 - tuning,
|
||||||
}),
|
}),
|
||||||
NoteEvent::PolyVibrato {
|
NoteEvent::PolyVibrato {
|
||||||
timing,
|
timing,
|
||||||
|
voice_id,
|
||||||
channel,
|
channel,
|
||||||
note,
|
note,
|
||||||
vibrato,
|
vibrato,
|
||||||
} => context.send_event(NoteEvent::PolyVibrato {
|
} => context.send_event(NoteEvent::PolyVibrato {
|
||||||
timing,
|
timing,
|
||||||
|
voice_id,
|
||||||
channel: 15 - channel,
|
channel: 15 - channel,
|
||||||
note: 127 - note,
|
note: 127 - note,
|
||||||
vibrato: 1.0 - vibrato,
|
vibrato: 1.0 - vibrato,
|
||||||
}),
|
}),
|
||||||
NoteEvent::PolyExpression {
|
NoteEvent::PolyExpression {
|
||||||
timing,
|
timing,
|
||||||
|
voice_id,
|
||||||
channel,
|
channel,
|
||||||
note,
|
note,
|
||||||
expression,
|
expression,
|
||||||
} => context.send_event(NoteEvent::PolyExpression {
|
} => context.send_event(NoteEvent::PolyExpression {
|
||||||
timing,
|
timing,
|
||||||
|
voice_id,
|
||||||
channel: 15 - channel,
|
channel: 15 - channel,
|
||||||
note: 127 - note,
|
note: 127 - note,
|
||||||
expression: 1.0 - expression,
|
expression: 1.0 - expression,
|
||||||
}),
|
}),
|
||||||
NoteEvent::PolyBrightness {
|
NoteEvent::PolyBrightness {
|
||||||
timing,
|
timing,
|
||||||
|
voice_id,
|
||||||
channel,
|
channel,
|
||||||
note,
|
note,
|
||||||
brightness,
|
brightness,
|
||||||
} => context.send_event(NoteEvent::PolyBrightness {
|
} => context.send_event(NoteEvent::PolyBrightness {
|
||||||
timing,
|
timing,
|
||||||
|
voice_id,
|
||||||
channel: 15 - channel,
|
channel: 15 - channel,
|
||||||
note: 127 - note,
|
note: 127 - note,
|
||||||
brightness: 1.0 - brightness,
|
brightness: 1.0 - brightness,
|
||||||
|
|
54
src/midi.rs
54
src/midi.rs
|
@ -30,6 +30,9 @@ 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 {
|
||||||
timing: u32,
|
timing: u32,
|
||||||
|
/// A unique identifier for this note, if available. Using this to refer to a note is
|
||||||
|
/// required when allowing overlapping voices for CLAP plugins.
|
||||||
|
voice_id: Option<i32>,
|
||||||
/// The note's channel, from 0 to 16.
|
/// The note's channel, from 0 to 16.
|
||||||
channel: u8,
|
channel: u8,
|
||||||
/// The note's MIDI key number, from 0 to 127.
|
/// The note's MIDI key number, from 0 to 127.
|
||||||
|
@ -41,6 +44,9 @@ pub enum NoteEvent {
|
||||||
/// A note off event, available on [`MidiConfig::Basic`] and up.
|
/// A note off event, available on [`MidiConfig::Basic`] and up.
|
||||||
NoteOff {
|
NoteOff {
|
||||||
timing: u32,
|
timing: u32,
|
||||||
|
/// A unique identifier for this note, if available. Using this to refer to a note is
|
||||||
|
/// required when allowing overlapping voices for CLAP plugins.
|
||||||
|
voice_id: Option<i32>,
|
||||||
/// The note's channel, from 0 to 16.
|
/// The note's channel, from 0 to 16.
|
||||||
channel: u8,
|
channel: u8,
|
||||||
/// The note's MIDI key number, from 0 to 127.
|
/// The note's MIDI key number, from 0 to 127.
|
||||||
|
@ -59,6 +65,9 @@ pub enum NoteEvent {
|
||||||
/// you may manually combine the polyphonic key pressure and MPE channel pressure.
|
/// you may manually combine the polyphonic key pressure and MPE channel pressure.
|
||||||
PolyPressure {
|
PolyPressure {
|
||||||
timing: u32,
|
timing: u32,
|
||||||
|
/// A unique identifier for this note, if available. Using this to refer to a note is
|
||||||
|
/// required when allowing overlapping voices for CLAP plugins.
|
||||||
|
voice_id: Option<i32>,
|
||||||
/// The note's channel, from 0 to 16.
|
/// The note's channel, from 0 to 16.
|
||||||
channel: u8,
|
channel: u8,
|
||||||
/// The note's MIDI key number, from 0 to 127.
|
/// The note's MIDI key number, from 0 to 127.
|
||||||
|
@ -70,6 +79,9 @@ pub enum NoteEvent {
|
||||||
/// support these expressions.
|
/// support these expressions.
|
||||||
PolyVolume {
|
PolyVolume {
|
||||||
timing: u32,
|
timing: u32,
|
||||||
|
/// A unique identifier for this note, if available. Using this to refer to a note is
|
||||||
|
/// required when allowing overlapping voices for CLAP plugins.
|
||||||
|
voice_id: Option<i32>,
|
||||||
/// The note's channel, from 0 to 16.
|
/// The note's channel, from 0 to 16.
|
||||||
channel: u8,
|
channel: u8,
|
||||||
/// The note's MIDI key number, from 0 to 127.
|
/// The note's MIDI key number, from 0 to 127.
|
||||||
|
@ -81,6 +93,9 @@ pub enum NoteEvent {
|
||||||
/// support these expressions.
|
/// support these expressions.
|
||||||
PolyPan {
|
PolyPan {
|
||||||
timing: u32,
|
timing: u32,
|
||||||
|
/// A unique identifier for this note, if available. Using this to refer to a note is
|
||||||
|
/// required when allowing overlapping voices for CLAP plugins.
|
||||||
|
voice_id: Option<i32>,
|
||||||
/// The note's channel, from 0 to 16.
|
/// The note's channel, from 0 to 16.
|
||||||
channel: u8,
|
channel: u8,
|
||||||
/// The note's MIDI key number, from 0 to 127.
|
/// The note's MIDI key number, from 0 to 127.
|
||||||
|
@ -93,6 +108,9 @@ pub enum NoteEvent {
|
||||||
/// these expressions.
|
/// these expressions.
|
||||||
PolyTuning {
|
PolyTuning {
|
||||||
timing: u32,
|
timing: u32,
|
||||||
|
/// A unique identifier for this note, if available. Using this to refer to a note is
|
||||||
|
/// required when allowing overlapping voices for CLAP plugins.
|
||||||
|
voice_id: Option<i32>,
|
||||||
/// The note's channel, from 0 to 16.
|
/// The note's channel, from 0 to 16.
|
||||||
channel: u8,
|
channel: u8,
|
||||||
/// The note's MIDI key number, from 0 to 127.
|
/// The note's MIDI key number, from 0 to 127.
|
||||||
|
@ -104,6 +122,9 @@ pub enum NoteEvent {
|
||||||
/// these expressions.
|
/// these expressions.
|
||||||
PolyVibrato {
|
PolyVibrato {
|
||||||
timing: u32,
|
timing: u32,
|
||||||
|
/// A unique identifier for this note, if available. Using this to refer to a note is
|
||||||
|
/// required when allowing overlapping voices for CLAP plugins.
|
||||||
|
voice_id: Option<i32>,
|
||||||
/// The note's channel, from 0 to 16.
|
/// The note's channel, from 0 to 16.
|
||||||
channel: u8,
|
channel: u8,
|
||||||
/// The note's MIDI key number, from 0 to 127.
|
/// The note's MIDI key number, from 0 to 127.
|
||||||
|
@ -115,6 +136,9 @@ pub enum NoteEvent {
|
||||||
/// [`MidiConfig::Basic`] and up. Not all hosts may support these expressions.
|
/// [`MidiConfig::Basic`] and up. Not all hosts may support these expressions.
|
||||||
PolyExpression {
|
PolyExpression {
|
||||||
timing: u32,
|
timing: u32,
|
||||||
|
/// A unique identifier for this note, if available. Using this to refer to a note is
|
||||||
|
/// required when allowing overlapping voices for CLAP plugins.
|
||||||
|
voice_id: Option<i32>,
|
||||||
/// The note's channel, from 0 to 16.
|
/// The note's channel, from 0 to 16.
|
||||||
channel: u8,
|
channel: u8,
|
||||||
/// The note's MIDI key number, from 0 to 127.
|
/// The note's MIDI key number, from 0 to 127.
|
||||||
|
@ -126,6 +150,9 @@ pub enum NoteEvent {
|
||||||
/// these expressions.
|
/// these expressions.
|
||||||
PolyBrightness {
|
PolyBrightness {
|
||||||
timing: u32,
|
timing: u32,
|
||||||
|
/// A unique identifier for this note, if available. Using this to refer to a note is
|
||||||
|
/// required when allowing overlapping voices for CLAP plugins.
|
||||||
|
voice_id: Option<i32>,
|
||||||
/// The note's channel, from 0 to 16.
|
/// The note's channel, from 0 to 16.
|
||||||
channel: u8,
|
channel: u8,
|
||||||
/// The note's MIDI key number, from 0 to 127.
|
/// The note's MIDI key number, from 0 to 127.
|
||||||
|
@ -186,6 +213,24 @@ impl NoteEvent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the event's voice ID, if it has any.
|
||||||
|
pub fn voice_id(&self) -> Option<i32> {
|
||||||
|
match &self {
|
||||||
|
NoteEvent::NoteOn { voice_id, .. } => *voice_id,
|
||||||
|
NoteEvent::NoteOff { voice_id, .. } => *voice_id,
|
||||||
|
NoteEvent::PolyPressure { voice_id, .. } => *voice_id,
|
||||||
|
NoteEvent::PolyVolume { voice_id, .. } => *voice_id,
|
||||||
|
NoteEvent::PolyPan { voice_id, .. } => *voice_id,
|
||||||
|
NoteEvent::PolyTuning { voice_id, .. } => *voice_id,
|
||||||
|
NoteEvent::PolyVibrato { voice_id, .. } => *voice_id,
|
||||||
|
NoteEvent::PolyExpression { voice_id, .. } => *voice_id,
|
||||||
|
NoteEvent::PolyBrightness { voice_id, .. } => *voice_id,
|
||||||
|
NoteEvent::MidiChannelPressure { .. } => None,
|
||||||
|
NoteEvent::MidiPitchBend { .. } => None,
|
||||||
|
NoteEvent::MidiCC { .. } => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Parse MIDI into a [`NoteEvent`]. Will return `Err(event_type)` if the parsing failed.
|
/// 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> {
|
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
|
// TODO: Maybe add special handling for 14-bit CCs and RPN messages at some
|
||||||
|
@ -195,18 +240,21 @@ impl NoteEvent {
|
||||||
match event_type {
|
match event_type {
|
||||||
midi::NOTE_ON => Ok(NoteEvent::NoteOn {
|
midi::NOTE_ON => Ok(NoteEvent::NoteOn {
|
||||||
timing,
|
timing,
|
||||||
|
voice_id: None,
|
||||||
channel,
|
channel,
|
||||||
note: midi_data[1],
|
note: midi_data[1],
|
||||||
velocity: midi_data[2] as f32 / 127.0,
|
velocity: midi_data[2] as f32 / 127.0,
|
||||||
}),
|
}),
|
||||||
midi::NOTE_OFF => Ok(NoteEvent::NoteOff {
|
midi::NOTE_OFF => Ok(NoteEvent::NoteOff {
|
||||||
timing,
|
timing,
|
||||||
|
voice_id: None,
|
||||||
channel,
|
channel,
|
||||||
note: midi_data[1],
|
note: midi_data[1],
|
||||||
velocity: midi_data[2] as f32 / 127.0,
|
velocity: midi_data[2] as f32 / 127.0,
|
||||||
}),
|
}),
|
||||||
midi::POLYPHONIC_KEY_PRESSURE => Ok(NoteEvent::PolyPressure {
|
midi::POLYPHONIC_KEY_PRESSURE => Ok(NoteEvent::PolyPressure {
|
||||||
timing,
|
timing,
|
||||||
|
voice_id: None,
|
||||||
channel,
|
channel,
|
||||||
note: midi_data[1],
|
note: midi_data[1],
|
||||||
pressure: midi_data[2] as f32 / 127.0,
|
pressure: midi_data[2] as f32 / 127.0,
|
||||||
|
@ -239,6 +287,7 @@ impl NoteEvent {
|
||||||
match self {
|
match self {
|
||||||
NoteEvent::NoteOn {
|
NoteEvent::NoteOn {
|
||||||
timing: _,
|
timing: _,
|
||||||
|
voice_id: _,
|
||||||
channel,
|
channel,
|
||||||
note,
|
note,
|
||||||
velocity,
|
velocity,
|
||||||
|
@ -249,6 +298,7 @@ impl NoteEvent {
|
||||||
]),
|
]),
|
||||||
NoteEvent::NoteOff {
|
NoteEvent::NoteOff {
|
||||||
timing: _,
|
timing: _,
|
||||||
|
voice_id: _,
|
||||||
channel,
|
channel,
|
||||||
note,
|
note,
|
||||||
velocity,
|
velocity,
|
||||||
|
@ -259,6 +309,7 @@ impl NoteEvent {
|
||||||
]),
|
]),
|
||||||
NoteEvent::PolyPressure {
|
NoteEvent::PolyPressure {
|
||||||
timing: _,
|
timing: _,
|
||||||
|
voice_id: _,
|
||||||
channel,
|
channel,
|
||||||
note,
|
note,
|
||||||
pressure,
|
pressure,
|
||||||
|
@ -341,6 +392,7 @@ mod tests {
|
||||||
fn test_note_on_midi_conversion() {
|
fn test_note_on_midi_conversion() {
|
||||||
let event = NoteEvent::NoteOn {
|
let event = NoteEvent::NoteOn {
|
||||||
timing: TIMING,
|
timing: TIMING,
|
||||||
|
voice_id: None,
|
||||||
channel: 1,
|
channel: 1,
|
||||||
note: 2,
|
note: 2,
|
||||||
// The value will be rounded in the conversion to MIDI, hence this overly specific value
|
// The value will be rounded in the conversion to MIDI, hence this overly specific value
|
||||||
|
@ -357,6 +409,7 @@ mod tests {
|
||||||
fn test_note_off_midi_conversion() {
|
fn test_note_off_midi_conversion() {
|
||||||
let event = NoteEvent::NoteOff {
|
let event = NoteEvent::NoteOff {
|
||||||
timing: TIMING,
|
timing: TIMING,
|
||||||
|
voice_id: None,
|
||||||
channel: 1,
|
channel: 1,
|
||||||
note: 2,
|
note: 2,
|
||||||
velocity: 0.6929134,
|
velocity: 0.6929134,
|
||||||
|
@ -372,6 +425,7 @@ mod tests {
|
||||||
fn test_poly_pressure_midi_conversion() {
|
fn test_poly_pressure_midi_conversion() {
|
||||||
let event = NoteEvent::PolyPressure {
|
let event = NoteEvent::PolyPressure {
|
||||||
timing: TIMING,
|
timing: TIMING,
|
||||||
|
voice_id: None,
|
||||||
channel: 1,
|
channel: 1,
|
||||||
note: 2,
|
note: 2,
|
||||||
pressure: 0.6929134,
|
pressure: 0.6929134,
|
||||||
|
|
|
@ -909,6 +909,7 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
let push_successful = match event {
|
let push_successful = match event {
|
||||||
NoteEvent::NoteOn {
|
NoteEvent::NoteOn {
|
||||||
timing: _,
|
timing: _,
|
||||||
|
voice_id,
|
||||||
channel,
|
channel,
|
||||||
note,
|
note,
|
||||||
velocity,
|
velocity,
|
||||||
|
@ -922,7 +923,7 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
// We don't have a way to denote live events
|
// We don't have a way to denote live events
|
||||||
flags: 0,
|
flags: 0,
|
||||||
},
|
},
|
||||||
note_id: -1,
|
note_id: voice_id.unwrap_or(-1),
|
||||||
port_index: 0,
|
port_index: 0,
|
||||||
channel: channel as i16,
|
channel: channel as i16,
|
||||||
key: note as i16,
|
key: note as i16,
|
||||||
|
@ -933,6 +934,7 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
}
|
}
|
||||||
NoteEvent::NoteOff {
|
NoteEvent::NoteOff {
|
||||||
timing: _,
|
timing: _,
|
||||||
|
voice_id,
|
||||||
channel,
|
channel,
|
||||||
note,
|
note,
|
||||||
velocity,
|
velocity,
|
||||||
|
@ -945,7 +947,7 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
type_: CLAP_EVENT_NOTE_OFF,
|
type_: CLAP_EVENT_NOTE_OFF,
|
||||||
flags: 0,
|
flags: 0,
|
||||||
},
|
},
|
||||||
note_id: -1,
|
note_id: voice_id.unwrap_or(-1),
|
||||||
port_index: 0,
|
port_index: 0,
|
||||||
channel: channel as i16,
|
channel: channel as i16,
|
||||||
key: note as i16,
|
key: note as i16,
|
||||||
|
@ -956,6 +958,7 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
}
|
}
|
||||||
NoteEvent::PolyPressure {
|
NoteEvent::PolyPressure {
|
||||||
timing: _,
|
timing: _,
|
||||||
|
voice_id,
|
||||||
channel,
|
channel,
|
||||||
note,
|
note,
|
||||||
pressure,
|
pressure,
|
||||||
|
@ -969,7 +972,7 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
flags: 0,
|
flags: 0,
|
||||||
},
|
},
|
||||||
expression_id: CLAP_NOTE_EXPRESSION_PRESSURE,
|
expression_id: CLAP_NOTE_EXPRESSION_PRESSURE,
|
||||||
note_id: -1,
|
note_id: voice_id.unwrap_or(-1),
|
||||||
port_index: 0,
|
port_index: 0,
|
||||||
channel: channel as i16,
|
channel: channel as i16,
|
||||||
key: note as i16,
|
key: note as i16,
|
||||||
|
@ -980,6 +983,7 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
}
|
}
|
||||||
NoteEvent::PolyVolume {
|
NoteEvent::PolyVolume {
|
||||||
timing: _,
|
timing: _,
|
||||||
|
voice_id,
|
||||||
channel,
|
channel,
|
||||||
note,
|
note,
|
||||||
gain,
|
gain,
|
||||||
|
@ -993,7 +997,7 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
flags: 0,
|
flags: 0,
|
||||||
},
|
},
|
||||||
expression_id: CLAP_NOTE_EXPRESSION_VOLUME,
|
expression_id: CLAP_NOTE_EXPRESSION_VOLUME,
|
||||||
note_id: -1,
|
note_id: voice_id.unwrap_or(-1),
|
||||||
port_index: 0,
|
port_index: 0,
|
||||||
channel: channel as i16,
|
channel: channel as i16,
|
||||||
key: note as i16,
|
key: note as i16,
|
||||||
|
@ -1004,6 +1008,7 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
}
|
}
|
||||||
NoteEvent::PolyPan {
|
NoteEvent::PolyPan {
|
||||||
timing: _,
|
timing: _,
|
||||||
|
voice_id,
|
||||||
channel,
|
channel,
|
||||||
note,
|
note,
|
||||||
pan,
|
pan,
|
||||||
|
@ -1017,7 +1022,7 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
flags: 0,
|
flags: 0,
|
||||||
},
|
},
|
||||||
expression_id: CLAP_NOTE_EXPRESSION_PAN,
|
expression_id: CLAP_NOTE_EXPRESSION_PAN,
|
||||||
note_id: -1,
|
note_id: voice_id.unwrap_or(-1),
|
||||||
port_index: 0,
|
port_index: 0,
|
||||||
channel: channel as i16,
|
channel: channel as i16,
|
||||||
key: note as i16,
|
key: note as i16,
|
||||||
|
@ -1028,6 +1033,7 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
}
|
}
|
||||||
NoteEvent::PolyTuning {
|
NoteEvent::PolyTuning {
|
||||||
timing: _,
|
timing: _,
|
||||||
|
voice_id,
|
||||||
channel,
|
channel,
|
||||||
note,
|
note,
|
||||||
tuning,
|
tuning,
|
||||||
|
@ -1041,7 +1047,7 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
flags: 0,
|
flags: 0,
|
||||||
},
|
},
|
||||||
expression_id: CLAP_NOTE_EXPRESSION_TUNING,
|
expression_id: CLAP_NOTE_EXPRESSION_TUNING,
|
||||||
note_id: -1,
|
note_id: voice_id.unwrap_or(-1),
|
||||||
port_index: 0,
|
port_index: 0,
|
||||||
channel: channel as i16,
|
channel: channel as i16,
|
||||||
key: note as i16,
|
key: note as i16,
|
||||||
|
@ -1052,6 +1058,7 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
}
|
}
|
||||||
NoteEvent::PolyVibrato {
|
NoteEvent::PolyVibrato {
|
||||||
timing: _,
|
timing: _,
|
||||||
|
voice_id,
|
||||||
channel,
|
channel,
|
||||||
note,
|
note,
|
||||||
vibrato,
|
vibrato,
|
||||||
|
@ -1065,7 +1072,7 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
flags: 0,
|
flags: 0,
|
||||||
},
|
},
|
||||||
expression_id: CLAP_NOTE_EXPRESSION_VIBRATO,
|
expression_id: CLAP_NOTE_EXPRESSION_VIBRATO,
|
||||||
note_id: -1,
|
note_id: voice_id.unwrap_or(-1),
|
||||||
port_index: 0,
|
port_index: 0,
|
||||||
channel: channel as i16,
|
channel: channel as i16,
|
||||||
key: note as i16,
|
key: note as i16,
|
||||||
|
@ -1076,6 +1083,7 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
}
|
}
|
||||||
NoteEvent::PolyExpression {
|
NoteEvent::PolyExpression {
|
||||||
timing: _,
|
timing: _,
|
||||||
|
voice_id,
|
||||||
channel,
|
channel,
|
||||||
note,
|
note,
|
||||||
expression,
|
expression,
|
||||||
|
@ -1089,7 +1097,7 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
flags: 0,
|
flags: 0,
|
||||||
},
|
},
|
||||||
expression_id: CLAP_NOTE_EXPRESSION_EXPRESSION,
|
expression_id: CLAP_NOTE_EXPRESSION_EXPRESSION,
|
||||||
note_id: -1,
|
note_id: voice_id.unwrap_or(-1),
|
||||||
port_index: 0,
|
port_index: 0,
|
||||||
channel: channel as i16,
|
channel: channel as i16,
|
||||||
key: note as i16,
|
key: note as i16,
|
||||||
|
@ -1100,6 +1108,7 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
}
|
}
|
||||||
NoteEvent::PolyBrightness {
|
NoteEvent::PolyBrightness {
|
||||||
timing: _,
|
timing: _,
|
||||||
|
voice_id,
|
||||||
channel,
|
channel,
|
||||||
note,
|
note,
|
||||||
brightness,
|
brightness,
|
||||||
|
@ -1113,7 +1122,7 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
flags: 0,
|
flags: 0,
|
||||||
},
|
},
|
||||||
expression_id: CLAP_NOTE_EXPRESSION_BRIGHTNESS,
|
expression_id: CLAP_NOTE_EXPRESSION_BRIGHTNESS,
|
||||||
note_id: -1,
|
note_id: voice_id.unwrap_or(-1),
|
||||||
port_index: 0,
|
port_index: 0,
|
||||||
channel: channel as i16,
|
channel: channel as i16,
|
||||||
key: note as i16,
|
key: note as i16,
|
||||||
|
@ -1264,6 +1273,11 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
// When splitting up the buffer for sample accurate automation all events
|
// When splitting up the buffer for sample accurate automation all events
|
||||||
// should be relative to the block
|
// should be relative to the block
|
||||||
timing: raw_event.time - current_sample_idx as u32,
|
timing: raw_event.time - current_sample_idx as u32,
|
||||||
|
voice_id: if event.note_id != -1 {
|
||||||
|
Some(event.note_id)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
channel: event.channel as u8,
|
channel: event.channel as u8,
|
||||||
note: event.key as u8,
|
note: event.key as u8,
|
||||||
velocity: event.velocity as f32,
|
velocity: event.velocity as f32,
|
||||||
|
@ -1277,6 +1291,11 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
let event = &*(event as *const clap_event_note);
|
let event = &*(event as *const clap_event_note);
|
||||||
input_events.push_back(NoteEvent::NoteOff {
|
input_events.push_back(NoteEvent::NoteOff {
|
||||||
timing: raw_event.time - current_sample_idx as u32,
|
timing: raw_event.time - current_sample_idx as u32,
|
||||||
|
voice_id: if event.note_id != -1 {
|
||||||
|
Some(event.note_id)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
channel: event.channel as u8,
|
channel: event.channel as u8,
|
||||||
note: event.key as u8,
|
note: event.key as u8,
|
||||||
velocity: event.velocity as f32,
|
velocity: event.velocity as f32,
|
||||||
|
@ -1293,6 +1312,11 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
CLAP_NOTE_EXPRESSION_PRESSURE => {
|
CLAP_NOTE_EXPRESSION_PRESSURE => {
|
||||||
input_events.push_back(NoteEvent::PolyPressure {
|
input_events.push_back(NoteEvent::PolyPressure {
|
||||||
timing: raw_event.time - current_sample_idx as u32,
|
timing: raw_event.time - current_sample_idx as u32,
|
||||||
|
voice_id: if event.note_id != -1 {
|
||||||
|
Some(event.note_id)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
channel: event.channel as u8,
|
channel: event.channel as u8,
|
||||||
note: event.key as u8,
|
note: event.key as u8,
|
||||||
pressure: event.value as f32,
|
pressure: event.value as f32,
|
||||||
|
@ -1301,6 +1325,11 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
CLAP_NOTE_EXPRESSION_VOLUME => {
|
CLAP_NOTE_EXPRESSION_VOLUME => {
|
||||||
input_events.push_back(NoteEvent::PolyVolume {
|
input_events.push_back(NoteEvent::PolyVolume {
|
||||||
timing: raw_event.time - current_sample_idx as u32,
|
timing: raw_event.time - current_sample_idx as u32,
|
||||||
|
voice_id: if event.note_id != -1 {
|
||||||
|
Some(event.note_id)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
channel: event.channel as u8,
|
channel: event.channel as u8,
|
||||||
note: event.key as u8,
|
note: event.key as u8,
|
||||||
gain: event.value as f32,
|
gain: event.value as f32,
|
||||||
|
@ -1309,6 +1338,11 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
CLAP_NOTE_EXPRESSION_PAN => {
|
CLAP_NOTE_EXPRESSION_PAN => {
|
||||||
input_events.push_back(NoteEvent::PolyPan {
|
input_events.push_back(NoteEvent::PolyPan {
|
||||||
timing: raw_event.time - current_sample_idx as u32,
|
timing: raw_event.time - current_sample_idx as u32,
|
||||||
|
voice_id: if event.note_id != -1 {
|
||||||
|
Some(event.note_id)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
channel: event.channel as u8,
|
channel: event.channel as u8,
|
||||||
note: event.key as u8,
|
note: event.key as u8,
|
||||||
// In CLAP this value goes from [0, 1] instead of [-1, 1]
|
// In CLAP this value goes from [0, 1] instead of [-1, 1]
|
||||||
|
@ -1318,6 +1352,11 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
CLAP_NOTE_EXPRESSION_TUNING => {
|
CLAP_NOTE_EXPRESSION_TUNING => {
|
||||||
input_events.push_back(NoteEvent::PolyTuning {
|
input_events.push_back(NoteEvent::PolyTuning {
|
||||||
timing: raw_event.time - current_sample_idx as u32,
|
timing: raw_event.time - current_sample_idx as u32,
|
||||||
|
voice_id: if event.note_id != -1 {
|
||||||
|
Some(event.note_id)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
channel: event.channel as u8,
|
channel: event.channel as u8,
|
||||||
note: event.key as u8,
|
note: event.key as u8,
|
||||||
tuning: event.value as f32,
|
tuning: event.value as f32,
|
||||||
|
@ -1326,6 +1365,11 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
CLAP_NOTE_EXPRESSION_VIBRATO => {
|
CLAP_NOTE_EXPRESSION_VIBRATO => {
|
||||||
input_events.push_back(NoteEvent::PolyVibrato {
|
input_events.push_back(NoteEvent::PolyVibrato {
|
||||||
timing: raw_event.time - current_sample_idx as u32,
|
timing: raw_event.time - current_sample_idx as u32,
|
||||||
|
voice_id: if event.note_id != -1 {
|
||||||
|
Some(event.note_id)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
channel: event.channel as u8,
|
channel: event.channel as u8,
|
||||||
note: event.key as u8,
|
note: event.key as u8,
|
||||||
vibrato: event.value as f32,
|
vibrato: event.value as f32,
|
||||||
|
@ -1334,6 +1378,11 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
CLAP_NOTE_EXPRESSION_EXPRESSION => {
|
CLAP_NOTE_EXPRESSION_EXPRESSION => {
|
||||||
input_events.push_back(NoteEvent::PolyExpression {
|
input_events.push_back(NoteEvent::PolyExpression {
|
||||||
timing: raw_event.time - current_sample_idx as u32,
|
timing: raw_event.time - current_sample_idx as u32,
|
||||||
|
voice_id: if event.note_id != -1 {
|
||||||
|
Some(event.note_id)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
channel: event.channel as u8,
|
channel: event.channel as u8,
|
||||||
note: event.key as u8,
|
note: event.key as u8,
|
||||||
expression: event.value as f32,
|
expression: event.value as f32,
|
||||||
|
@ -1342,6 +1391,11 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
CLAP_NOTE_EXPRESSION_BRIGHTNESS => {
|
CLAP_NOTE_EXPRESSION_BRIGHTNESS => {
|
||||||
input_events.push_back(NoteEvent::PolyBrightness {
|
input_events.push_back(NoteEvent::PolyBrightness {
|
||||||
timing: raw_event.time - current_sample_idx as u32,
|
timing: raw_event.time - current_sample_idx as u32,
|
||||||
|
voice_id: if event.note_id != -1 {
|
||||||
|
Some(event.note_id)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
channel: event.channel as u8,
|
channel: event.channel as u8,
|
||||||
note: event.key as u8,
|
note: event.key as u8,
|
||||||
brightness: event.value as f32,
|
brightness: event.value as f32,
|
||||||
|
|
|
@ -105,7 +105,8 @@ impl NoteExpressionController {
|
||||||
timing: u32,
|
timing: u32,
|
||||||
event: &NoteExpressionValueEvent,
|
event: &NoteExpressionValueEvent,
|
||||||
) -> Option<NoteEvent> {
|
) -> Option<NoteEvent> {
|
||||||
let (_, note, channel) = *self
|
// We're calling it a voice ID, VST3 (and CLAP) calls it a note ID
|
||||||
|
let (note_id, note, channel) = *self
|
||||||
.note_ids
|
.note_ids
|
||||||
.iter()
|
.iter()
|
||||||
.find(|(note_id, _, _)| *note_id == event.note_id)?;
|
.find(|(note_id, _, _)| *note_id == event.note_id)?;
|
||||||
|
@ -113,6 +114,7 @@ impl NoteExpressionController {
|
||||||
match event.type_id {
|
match event.type_id {
|
||||||
VOLUME_EXPRESSION_ID => Some(NoteEvent::PolyVolume {
|
VOLUME_EXPRESSION_ID => Some(NoteEvent::PolyVolume {
|
||||||
timing,
|
timing,
|
||||||
|
voice_id: Some(note_id),
|
||||||
channel,
|
channel,
|
||||||
note,
|
note,
|
||||||
// Because expression values in VST3 are always in the `[0, 1]` range, they added a
|
// Because expression values in VST3 are always in the `[0, 1]` range, they added a
|
||||||
|
@ -121,6 +123,7 @@ impl NoteExpressionController {
|
||||||
}),
|
}),
|
||||||
PAN_EXPRESSION_ID => Some(NoteEvent::PolyPan {
|
PAN_EXPRESSION_ID => Some(NoteEvent::PolyPan {
|
||||||
timing,
|
timing,
|
||||||
|
voice_id: Some(note_id),
|
||||||
channel,
|
channel,
|
||||||
note,
|
note,
|
||||||
// Our panning expressions are symmetrical around 0
|
// Our panning expressions are symmetrical around 0
|
||||||
|
@ -128,6 +131,7 @@ impl NoteExpressionController {
|
||||||
}),
|
}),
|
||||||
TUNING_EXPRESSION_ID => Some(NoteEvent::PolyTuning {
|
TUNING_EXPRESSION_ID => Some(NoteEvent::PolyTuning {
|
||||||
timing,
|
timing,
|
||||||
|
voice_id: Some(note_id),
|
||||||
channel,
|
channel,
|
||||||
note,
|
note,
|
||||||
// This denormalized to the same [-120, 120] range used by CLAP and our expression
|
// This denormalized to the same [-120, 120] range used by CLAP and our expression
|
||||||
|
@ -136,18 +140,21 @@ impl NoteExpressionController {
|
||||||
}),
|
}),
|
||||||
VIBRATO_EXPRESSION_ID => Some(NoteEvent::PolyVibrato {
|
VIBRATO_EXPRESSION_ID => Some(NoteEvent::PolyVibrato {
|
||||||
timing,
|
timing,
|
||||||
|
voice_id: Some(note_id),
|
||||||
channel,
|
channel,
|
||||||
note,
|
note,
|
||||||
vibrato: event.value as f32,
|
vibrato: event.value as f32,
|
||||||
}),
|
}),
|
||||||
EXPRESSION_EXPRESSION_ID => Some(NoteEvent::PolyBrightness {
|
EXPRESSION_EXPRESSION_ID => Some(NoteEvent::PolyBrightness {
|
||||||
timing,
|
timing,
|
||||||
|
voice_id: Some(note_id),
|
||||||
channel,
|
channel,
|
||||||
note,
|
note,
|
||||||
brightness: event.value as f32,
|
brightness: event.value as f32,
|
||||||
}),
|
}),
|
||||||
BRIGHTNESS_EXPRESSION_ID => Some(NoteEvent::PolyExpression {
|
BRIGHTNESS_EXPRESSION_ID => Some(NoteEvent::PolyExpression {
|
||||||
timing,
|
timing,
|
||||||
|
voice_id: Some(note_id),
|
||||||
channel,
|
channel,
|
||||||
note,
|
note,
|
||||||
expression: event.value as f32,
|
expression: event.value as f32,
|
||||||
|
|
|
@ -1162,6 +1162,11 @@ impl<P: Vst3Plugin> IAudioProcessor for Wrapper<P> {
|
||||||
timing,
|
timing,
|
||||||
event: NoteEvent::NoteOn {
|
event: NoteEvent::NoteOn {
|
||||||
timing,
|
timing,
|
||||||
|
voice_id: if event.note_id != -1 {
|
||||||
|
Some(event.note_id)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
channel: event.channel as u8,
|
channel: event.channel as u8,
|
||||||
note: event.pitch as u8,
|
note: event.pitch as u8,
|
||||||
velocity: event.velocity,
|
velocity: event.velocity,
|
||||||
|
@ -1173,6 +1178,11 @@ impl<P: Vst3Plugin> IAudioProcessor for Wrapper<P> {
|
||||||
timing,
|
timing,
|
||||||
event: NoteEvent::NoteOff {
|
event: NoteEvent::NoteOff {
|
||||||
timing,
|
timing,
|
||||||
|
voice_id: if event.note_id != -1 {
|
||||||
|
Some(event.note_id)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
channel: event.channel as u8,
|
channel: event.channel as u8,
|
||||||
note: event.pitch as u8,
|
note: event.pitch as u8,
|
||||||
velocity: event.velocity,
|
velocity: event.velocity,
|
||||||
|
@ -1184,6 +1194,11 @@ impl<P: Vst3Plugin> IAudioProcessor for Wrapper<P> {
|
||||||
timing,
|
timing,
|
||||||
event: NoteEvent::PolyPressure {
|
event: NoteEvent::PolyPressure {
|
||||||
timing,
|
timing,
|
||||||
|
voice_id: if event.note_id != -1 {
|
||||||
|
Some(event.note_id)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
channel: event.channel as u8,
|
channel: event.channel as u8,
|
||||||
note: event.pitch as u8,
|
note: event.pitch as u8,
|
||||||
pressure: event.pressure,
|
pressure: event.pressure,
|
||||||
|
@ -1531,9 +1546,13 @@ impl<P: Vst3Plugin> IAudioProcessor for Wrapper<P> {
|
||||||
// There's also a ppqPos field, but uh how about no
|
// There's also a ppqPos field, but uh how about no
|
||||||
vst3_event.sample_offset = event.timing() as i32 + block_start as i32;
|
vst3_event.sample_offset = event.timing() as i32 + block_start as i32;
|
||||||
|
|
||||||
|
// `voice_id.onwrap_or(|| ...)` triggers
|
||||||
|
// https://github.com/rust-lang/rust-clippy/issues/8522
|
||||||
|
#[allow(clippy::unnecessary_lazy_evaluations)]
|
||||||
match event {
|
match event {
|
||||||
NoteEvent::NoteOn {
|
NoteEvent::NoteOn {
|
||||||
timing: _,
|
timing: _,
|
||||||
|
voice_id,
|
||||||
channel,
|
channel,
|
||||||
note,
|
note,
|
||||||
velocity,
|
velocity,
|
||||||
|
@ -1547,11 +1566,13 @@ impl<P: Vst3Plugin> IAudioProcessor for Wrapper<P> {
|
||||||
length: 0, // What?
|
length: 0, // What?
|
||||||
// We'll use this for our note IDs, that way we don't have
|
// We'll use this for our note IDs, that way we don't have
|
||||||
// to do anything complicated here
|
// to do anything complicated here
|
||||||
note_id: ((channel as i32) << 8) | note as i32,
|
note_id: voice_id
|
||||||
|
.unwrap_or_else(|| ((channel as i32) << 8) | note as i32),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
NoteEvent::NoteOff {
|
NoteEvent::NoteOff {
|
||||||
timing: _,
|
timing: _,
|
||||||
|
voice_id,
|
||||||
channel,
|
channel,
|
||||||
note,
|
note,
|
||||||
velocity,
|
velocity,
|
||||||
|
@ -1561,12 +1582,14 @@ impl<P: Vst3Plugin> IAudioProcessor for Wrapper<P> {
|
||||||
channel: channel as i16,
|
channel: channel as i16,
|
||||||
pitch: note as i16,
|
pitch: note as i16,
|
||||||
velocity,
|
velocity,
|
||||||
note_id: ((channel as i32) << 8) | note as i32,
|
note_id: voice_id
|
||||||
|
.unwrap_or_else(|| ((channel as i32) << 8) | note as i32),
|
||||||
tuning: 0.0,
|
tuning: 0.0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
NoteEvent::PolyPressure {
|
NoteEvent::PolyPressure {
|
||||||
timing: _,
|
timing: _,
|
||||||
|
voice_id,
|
||||||
channel,
|
channel,
|
||||||
note,
|
note,
|
||||||
pressure,
|
pressure,
|
||||||
|
@ -1575,20 +1598,50 @@ impl<P: Vst3Plugin> IAudioProcessor for Wrapper<P> {
|
||||||
vst3_event.event.poly_pressure = PolyPressureEvent {
|
vst3_event.event.poly_pressure = PolyPressureEvent {
|
||||||
channel: channel as i16,
|
channel: channel as i16,
|
||||||
pitch: note as i16,
|
pitch: note as i16,
|
||||||
note_id: ((channel as i32) << 8) | note as i32,
|
note_id: voice_id
|
||||||
|
.unwrap_or_else(|| ((channel as i32) << 8) | note as i32),
|
||||||
pressure,
|
pressure,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
event @ (NoteEvent::PolyVolume { channel, note, .. }
|
event @ (NoteEvent::PolyVolume {
|
||||||
| NoteEvent::PolyPan { channel, note, .. }
|
voice_id,
|
||||||
| NoteEvent::PolyTuning { channel, note, .. }
|
channel,
|
||||||
| NoteEvent::PolyVibrato { channel, note, .. }
|
note,
|
||||||
| NoteEvent::PolyExpression { channel, note, .. }
|
..
|
||||||
| NoteEvent::PolyBrightness { channel, note, .. })
|
}
|
||||||
if P::MIDI_OUTPUT >= MidiConfig::Basic =>
|
| NoteEvent::PolyPan {
|
||||||
{
|
voice_id,
|
||||||
|
channel,
|
||||||
|
note,
|
||||||
|
..
|
||||||
|
}
|
||||||
|
| NoteEvent::PolyTuning {
|
||||||
|
voice_id,
|
||||||
|
channel,
|
||||||
|
note,
|
||||||
|
..
|
||||||
|
}
|
||||||
|
| NoteEvent::PolyVibrato {
|
||||||
|
voice_id,
|
||||||
|
channel,
|
||||||
|
note,
|
||||||
|
..
|
||||||
|
}
|
||||||
|
| NoteEvent::PolyExpression {
|
||||||
|
voice_id,
|
||||||
|
channel,
|
||||||
|
note,
|
||||||
|
..
|
||||||
|
}
|
||||||
|
| NoteEvent::PolyBrightness {
|
||||||
|
voice_id,
|
||||||
|
channel,
|
||||||
|
note,
|
||||||
|
..
|
||||||
|
}) if P::MIDI_OUTPUT >= MidiConfig::Basic => {
|
||||||
match NoteExpressionController::translate_event_reverse(
|
match NoteExpressionController::translate_event_reverse(
|
||||||
((channel as i32) << 8) | note as i32,
|
voice_id
|
||||||
|
.unwrap_or_else(|| ((channel as i32) << 8) | note as i32),
|
||||||
&event,
|
&event,
|
||||||
) {
|
) {
|
||||||
Some(translated_event) => {
|
Some(translated_event) => {
|
||||||
|
|
Loading…
Reference in a new issue