Add program change events
This commit is contained in:
parent
1bb1cde913
commit
2447344dab
3 changed files with 75 additions and 0 deletions
39
src/midi.rs
39
src/midi.rs
|
@ -256,6 +256,14 @@ pub enum NoteEvent {
|
||||||
/// The note's brightness amount, from 0 to 1.
|
/// The note's brightness amount, from 0 to 1.
|
||||||
brightness: f32,
|
brightness: f32,
|
||||||
},
|
},
|
||||||
|
/// A MIDI program change event, available on [`MidiConfig::MidiCCs`] and up.
|
||||||
|
MidiProgramChange {
|
||||||
|
timing: u32,
|
||||||
|
/// The affected channel, from 0 to 16.
|
||||||
|
channel: u8,
|
||||||
|
/// The program number.
|
||||||
|
program: u8,
|
||||||
|
},
|
||||||
/// A MIDI channel pressure event, available on [`MidiConfig::MidiCCs`] and up.
|
/// A MIDI channel pressure event, available on [`MidiConfig::MidiCCs`] and up.
|
||||||
MidiChannelPressure {
|
MidiChannelPressure {
|
||||||
timing: u32,
|
timing: u32,
|
||||||
|
@ -307,6 +315,7 @@ impl NoteEvent {
|
||||||
NoteEvent::PolyVibrato { timing, .. } => *timing,
|
NoteEvent::PolyVibrato { timing, .. } => *timing,
|
||||||
NoteEvent::PolyExpression { timing, .. } => *timing,
|
NoteEvent::PolyExpression { timing, .. } => *timing,
|
||||||
NoteEvent::PolyBrightness { timing, .. } => *timing,
|
NoteEvent::PolyBrightness { timing, .. } => *timing,
|
||||||
|
NoteEvent::MidiProgramChange { timing, .. } => *timing,
|
||||||
NoteEvent::MidiChannelPressure { timing, .. } => *timing,
|
NoteEvent::MidiChannelPressure { timing, .. } => *timing,
|
||||||
NoteEvent::MidiPitchBend { timing, .. } => *timing,
|
NoteEvent::MidiPitchBend { timing, .. } => *timing,
|
||||||
NoteEvent::MidiCC { timing, .. } => *timing,
|
NoteEvent::MidiCC { timing, .. } => *timing,
|
||||||
|
@ -329,6 +338,7 @@ impl NoteEvent {
|
||||||
NoteEvent::PolyVibrato { voice_id, .. } => *voice_id,
|
NoteEvent::PolyVibrato { voice_id, .. } => *voice_id,
|
||||||
NoteEvent::PolyExpression { voice_id, .. } => *voice_id,
|
NoteEvent::PolyExpression { voice_id, .. } => *voice_id,
|
||||||
NoteEvent::PolyBrightness { voice_id, .. } => *voice_id,
|
NoteEvent::PolyBrightness { voice_id, .. } => *voice_id,
|
||||||
|
NoteEvent::MidiProgramChange { .. } => None,
|
||||||
NoteEvent::MidiChannelPressure { .. } => None,
|
NoteEvent::MidiChannelPressure { .. } => None,
|
||||||
NoteEvent::MidiPitchBend { .. } => None,
|
NoteEvent::MidiPitchBend { .. } => None,
|
||||||
NoteEvent::MidiCC { .. } => None,
|
NoteEvent::MidiCC { .. } => None,
|
||||||
|
@ -363,6 +373,11 @@ impl NoteEvent {
|
||||||
note: midi_data[1],
|
note: midi_data[1],
|
||||||
pressure: midi_data[2] as f32 / 127.0,
|
pressure: midi_data[2] as f32 / 127.0,
|
||||||
}),
|
}),
|
||||||
|
midi::PROGRAM_CHANGE => Ok(NoteEvent::MidiProgramChange {
|
||||||
|
timing,
|
||||||
|
channel,
|
||||||
|
program: midi_data[1],
|
||||||
|
}),
|
||||||
midi::CHANNEL_KEY_PRESSURE => Ok(NoteEvent::MidiChannelPressure {
|
midi::CHANNEL_KEY_PRESSURE => Ok(NoteEvent::MidiChannelPressure {
|
||||||
timing,
|
timing,
|
||||||
channel,
|
channel,
|
||||||
|
@ -422,6 +437,15 @@ impl NoteEvent {
|
||||||
note,
|
note,
|
||||||
(pressure * 127.0).round().clamp(0.0, 127.0) as u8,
|
(pressure * 127.0).round().clamp(0.0, 127.0) as u8,
|
||||||
]),
|
]),
|
||||||
|
NoteEvent::MidiProgramChange {
|
||||||
|
timing: _,
|
||||||
|
channel,
|
||||||
|
program,
|
||||||
|
} => Some([
|
||||||
|
midi::PROGRAM_CHANGE | channel,
|
||||||
|
program,
|
||||||
|
0,
|
||||||
|
]),
|
||||||
NoteEvent::MidiChannelPressure {
|
NoteEvent::MidiChannelPressure {
|
||||||
timing: _,
|
timing: _,
|
||||||
channel,
|
channel,
|
||||||
|
@ -487,6 +511,7 @@ impl NoteEvent {
|
||||||
NoteEvent::PolyVibrato { timing, .. } => *timing -= samples,
|
NoteEvent::PolyVibrato { timing, .. } => *timing -= samples,
|
||||||
NoteEvent::PolyExpression { timing, .. } => *timing -= samples,
|
NoteEvent::PolyExpression { timing, .. } => *timing -= samples,
|
||||||
NoteEvent::PolyBrightness { timing, .. } => *timing -= samples,
|
NoteEvent::PolyBrightness { timing, .. } => *timing -= samples,
|
||||||
|
NoteEvent::MidiProgramChange { timing, .. } => *timing -= samples,
|
||||||
NoteEvent::MidiChannelPressure { timing, .. } => *timing -= samples,
|
NoteEvent::MidiChannelPressure { timing, .. } => *timing -= samples,
|
||||||
NoteEvent::MidiPitchBend { timing, .. } => *timing -= samples,
|
NoteEvent::MidiPitchBend { timing, .. } => *timing -= samples,
|
||||||
NoteEvent::MidiCC { timing, .. } => *timing -= samples,
|
NoteEvent::MidiCC { timing, .. } => *timing -= samples,
|
||||||
|
@ -549,6 +574,20 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_program_change_midi_conversion() {
|
||||||
|
let event = NoteEvent::MidiProgramChange {
|
||||||
|
timing: TIMING,
|
||||||
|
channel: 1,
|
||||||
|
program: 42,
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
NoteEvent::from_midi(TIMING, event.as_midi().unwrap()).unwrap(),
|
||||||
|
event
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_channel_pressure_midi_conversion() {
|
fn test_channel_pressure_midi_conversion() {
|
||||||
let event = NoteEvent::MidiChannelPressure {
|
let event = NoteEvent::MidiChannelPressure {
|
||||||
|
|
|
@ -1212,6 +1212,29 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
|
|
||||||
clap_call! { out=>try_push(out, &event.header) }
|
clap_call! { out=>try_push(out, &event.header) }
|
||||||
}
|
}
|
||||||
|
NoteEvent::MidiProgramChange {
|
||||||
|
timing: _,
|
||||||
|
channel,
|
||||||
|
program,
|
||||||
|
} if P::MIDI_OUTPUT >= MidiConfig::MidiCCs => {
|
||||||
|
let event = clap_event_midi {
|
||||||
|
header: clap_event_header {
|
||||||
|
size: mem::size_of::<clap_event_midi>() as u32,
|
||||||
|
time,
|
||||||
|
space_id: CLAP_CORE_EVENT_SPACE_ID,
|
||||||
|
type_: CLAP_EVENT_MIDI,
|
||||||
|
flags: 0,
|
||||||
|
},
|
||||||
|
port_index: 0,
|
||||||
|
data: [
|
||||||
|
midi::PROGRAM_CHANGE | channel as u8,
|
||||||
|
program,
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
clap_call! { out=>try_push(out, &event.header) }
|
||||||
|
}
|
||||||
NoteEvent::MidiChannelPressure {
|
NoteEvent::MidiChannelPressure {
|
||||||
timing: _,
|
timing: _,
|
||||||
channel,
|
channel,
|
||||||
|
|
|
@ -1667,6 +1667,19 @@ impl<P: Vst3Plugin> IAudioProcessor for Wrapper<P> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
NoteEvent::MidiProgramChange {
|
||||||
|
timing: _,
|
||||||
|
channel,
|
||||||
|
program,
|
||||||
|
} if P::MIDI_OUTPUT >= MidiConfig::MidiCCs => {
|
||||||
|
vst3_event.type_ = EventTypes::kLegacyMIDICCOutEvent as u16;
|
||||||
|
vst3_event.event.legacy_midi_cc_out = LegacyMidiCCOutEvent {
|
||||||
|
control_number: 130, // kCtrlProgramChange
|
||||||
|
channel: channel as i8,
|
||||||
|
value: program as i8,
|
||||||
|
value2: 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
NoteEvent::MidiChannelPressure {
|
NoteEvent::MidiChannelPressure {
|
||||||
timing: _,
|
timing: _,
|
||||||
channel,
|
channel,
|
||||||
|
|
Loading…
Add table
Reference in a new issue