Clamp event timings for VST3 plugins
This commit is contained in:
parent
eac88c4477
commit
d5a8eb42ec
1 changed files with 27 additions and 4 deletions
|
@ -1042,6 +1042,8 @@ impl<P: Vst3Plugin> IAudioProcessor for Wrapper<P> {
|
||||||
);
|
);
|
||||||
nih_debug_assert!(data.num_samples >= 0);
|
nih_debug_assert!(data.num_samples >= 0);
|
||||||
|
|
||||||
|
let total_buffer_len = data.num_samples as usize;
|
||||||
|
|
||||||
// Before doing anything, clear out any auxiliary outputs since they may contain
|
// Before doing anything, clear out any auxiliary outputs since they may contain
|
||||||
// uninitialized data when the host assumes that we'll always write something there
|
// uninitialized data when the host assumes that we'll always write something there
|
||||||
let current_bus_config = self.inner.current_bus_config.load();
|
let current_bus_config = self.inner.current_bus_config.load();
|
||||||
|
@ -1057,7 +1059,7 @@ impl<P: Vst3Plugin> IAudioProcessor for Wrapper<P> {
|
||||||
ptr::write_bytes(
|
ptr::write_bytes(
|
||||||
*((*host_output).buffers.offset(channel_idx)) as *mut f32,
|
*((*host_output).buffers.offset(channel_idx)) as *mut f32,
|
||||||
0,
|
0,
|
||||||
data.num_samples as usize,
|
total_buffer_len,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1098,8 +1100,15 @@ impl<P: Vst3Plugin> IAudioProcessor for Wrapper<P> {
|
||||||
{
|
{
|
||||||
// Later this timing will be compensated for block splits by calling
|
// Later this timing will be compensated for block splits by calling
|
||||||
// `event.subtract_timing(block_start)` before it is passed to the
|
// `event.subtract_timing(block_start)` before it is passed to the
|
||||||
// plugin
|
// plugin. Out of bounds events are clamped to the buffer>
|
||||||
let timing = sample_offset as u32;
|
let timing = sample_offset as u32;
|
||||||
|
nih_debug_assert!(
|
||||||
|
timing < total_buffer_len as u32,
|
||||||
|
"Input event is out of bounds, will be clamped to the \
|
||||||
|
buffer's size"
|
||||||
|
);
|
||||||
|
let timing = timing.min(total_buffer_len as u32 - 1);
|
||||||
|
|
||||||
let value = value as f32;
|
let value = value as f32;
|
||||||
|
|
||||||
// MIDI CC messages, channel pressure, and pitch bend are also sent
|
// MIDI CC messages, channel pressure, and pitch bend are also sent
|
||||||
|
@ -1167,6 +1176,12 @@ impl<P: Vst3Plugin> IAudioProcessor for Wrapper<P> {
|
||||||
|
|
||||||
let event = event.assume_init();
|
let event = event.assume_init();
|
||||||
let timing = event.sample_offset as u32;
|
let timing = event.sample_offset as u32;
|
||||||
|
nih_debug_assert!(
|
||||||
|
timing < total_buffer_len as u32,
|
||||||
|
"Input event is out of bounds, will be clamped to the buffer's size"
|
||||||
|
);
|
||||||
|
let timing = timing.min(total_buffer_len as u32 - 1);
|
||||||
|
|
||||||
if event.type_ == EventTypes::kNoteOnEvent as u16 {
|
if event.type_ == EventTypes::kNoteOnEvent as u16 {
|
||||||
let event = event.event.note_on;
|
let event = event.event.note_on;
|
||||||
|
|
||||||
|
@ -1270,7 +1285,7 @@ impl<P: Vst3Plugin> IAudioProcessor for Wrapper<P> {
|
||||||
let mut input_events = self.inner.input_events.borrow_mut();
|
let mut input_events = self.inner.input_events.borrow_mut();
|
||||||
input_events.clear();
|
input_events.clear();
|
||||||
|
|
||||||
block_end = data.num_samples as usize;
|
block_end = total_buffer_len;
|
||||||
for event_idx in event_start_idx..process_events.len() {
|
for event_idx in event_start_idx..process_events.len() {
|
||||||
match &process_events[event_idx] {
|
match &process_events[event_idx] {
|
||||||
ProcessEvent::ParameterChange {
|
ProcessEvent::ParameterChange {
|
||||||
|
@ -1560,6 +1575,14 @@ 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;
|
||||||
|
|
||||||
|
// Out of bounds events are clamped to the buffer
|
||||||
|
nih_debug_assert!(
|
||||||
|
vst3_event.sample_offset < total_buffer_len as i32,
|
||||||
|
"Output event is out of bounds, will be clamped to the buffer's size"
|
||||||
|
);
|
||||||
|
vst3_event.sample_offset =
|
||||||
|
vst3_event.sample_offset.min(total_buffer_len as i32 - 1);
|
||||||
|
|
||||||
// `voice_id.unwrap_or(|| ...)` triggers
|
// `voice_id.unwrap_or(|| ...)` triggers
|
||||||
// https://github.com/rust-lang/rust-clippy/issues/8522
|
// https://github.com/rust-lang/rust-clippy/issues/8522
|
||||||
#[allow(clippy::unnecessary_lazy_evaluations)]
|
#[allow(clippy::unnecessary_lazy_evaluations)]
|
||||||
|
@ -1779,7 +1802,7 @@ impl<P: Vst3Plugin> IAudioProcessor for Wrapper<P> {
|
||||||
// If our block ends at the end of the buffer then that means there are no more
|
// If our block ends at the end of the buffer then that means there are no more
|
||||||
// unprocessed (parameter) events. If there are more events, we'll just keep going
|
// unprocessed (parameter) events. If there are more events, we'll just keep going
|
||||||
// through this process until we've processed the entire buffer.
|
// through this process until we've processed the entire buffer.
|
||||||
if block_end as i32 == data.num_samples {
|
if block_end == total_buffer_len {
|
||||||
break result;
|
break result;
|
||||||
} else {
|
} else {
|
||||||
block_start = block_end;
|
block_start = block_end;
|
||||||
|
|
Loading…
Add table
Reference in a new issue