Move event timing clamping to functions
So this doesn't need to be repeated everywhere.
This commit is contained in:
parent
d5a8eb42ec
commit
55c3701d2e
|
@ -94,7 +94,9 @@ use crate::plugin::{
|
||||||
use crate::util::permit_alloc;
|
use crate::util::permit_alloc;
|
||||||
use crate::wrapper::clap::util::{read_stream, write_stream};
|
use crate::wrapper::clap::util::{read_stream, write_stream};
|
||||||
use crate::wrapper::state::{self, PluginState};
|
use crate::wrapper::state::{self, PluginState};
|
||||||
use crate::wrapper::util::{hash_param_id, process_wrapper, strlcpy};
|
use crate::wrapper::util::{
|
||||||
|
clamp_input_event_timing, clamp_output_event_timing, hash_param_id, process_wrapper, strlcpy,
|
||||||
|
};
|
||||||
|
|
||||||
/// How many output parameter changes we can store in our output parameter change queue. Storing
|
/// How many output parameter changes we can store in our output parameter change queue. Storing
|
||||||
/// more than this many parameters at a time will cause changes to get lost.
|
/// more than this many parameters at a time will cause changes to get lost.
|
||||||
|
@ -1079,12 +1081,10 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
let mut output_events = self.output_events.borrow_mut();
|
let mut output_events = self.output_events.borrow_mut();
|
||||||
while let Some(event) = output_events.pop_front() {
|
while let Some(event) = output_events.pop_front() {
|
||||||
// Out of bounds events are clamped to the buffer's size
|
// Out of bounds events are clamped to the buffer's size
|
||||||
let time = event.timing() + current_sample_idx as u32;
|
let time = clamp_output_event_timing(
|
||||||
nih_debug_assert!(
|
event.timing() + current_sample_idx as u32,
|
||||||
time < total_buffer_len as u32,
|
total_buffer_len as u32,
|
||||||
"Output event is out of bounds, will be clamped to the buffer's size"
|
|
||||||
);
|
);
|
||||||
let time = time.min(total_buffer_len as u32 - 1);
|
|
||||||
|
|
||||||
let push_successful = match event {
|
let push_successful = match event {
|
||||||
NoteEvent::NoteOn {
|
NoteEvent::NoteOn {
|
||||||
|
@ -1423,12 +1423,10 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
let raw_event = &*event;
|
let raw_event = &*event;
|
||||||
|
|
||||||
// Out of bounds events are clamped to the buffer's size
|
// Out of bounds events are clamped to the buffer's size
|
||||||
let timing = raw_event.time - current_sample_idx as u32;
|
let timing = clamp_input_event_timing(
|
||||||
nih_debug_assert!(
|
raw_event.time - current_sample_idx as u32,
|
||||||
timing < total_buffer_len as u32,
|
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);
|
|
||||||
|
|
||||||
match (raw_event.space_id, raw_event.type_) {
|
match (raw_event.space_id, raw_event.type_) {
|
||||||
(CLAP_CORE_EVENT_SPACE_ID, CLAP_EVENT_PARAM_VALUE) => {
|
(CLAP_CORE_EVENT_SPACE_ID, CLAP_EVENT_PARAM_VALUE) => {
|
||||||
|
|
|
@ -15,6 +15,7 @@ use crate::buffer::Buffer;
|
||||||
use crate::context::process::Transport;
|
use crate::context::process::Transport;
|
||||||
use crate::midi::{MidiConfig, MidiResult, NoteEvent, PluginNoteEvent};
|
use crate::midi::{MidiConfig, MidiResult, NoteEvent, PluginNoteEvent};
|
||||||
use crate::plugin::Plugin;
|
use crate::plugin::Plugin;
|
||||||
|
use crate::wrapper::util::{clamp_input_event_timing, clamp_output_event_timing};
|
||||||
|
|
||||||
/// Uses JACK audio and MIDI.
|
/// Uses JACK audio and MIDI.
|
||||||
pub struct Jack {
|
pub struct Jack {
|
||||||
|
@ -122,11 +123,7 @@ impl<P: Plugin> Backend<P> for Jack {
|
||||||
input_events.clear();
|
input_events.clear();
|
||||||
if let Some(midi_input) = &midi_input {
|
if let Some(midi_input) = &midi_input {
|
||||||
input_events.extend(midi_input.iter(ps).filter_map(|midi| {
|
input_events.extend(midi_input.iter(ps).filter_map(|midi| {
|
||||||
nih_debug_assert!(
|
let timing = clamp_input_event_timing(midi.time, num_frames);
|
||||||
midi.time < num_frames,
|
|
||||||
"Input event is out of bounds, will be clamped to the buffer's size"
|
|
||||||
);
|
|
||||||
let timing = midi.time.min(num_frames - 1);
|
|
||||||
|
|
||||||
NoteEvent::from_midi(timing, midi.bytes).ok()
|
NoteEvent::from_midi(timing, midi.bytes).ok()
|
||||||
}));
|
}));
|
||||||
|
@ -139,11 +136,7 @@ impl<P: Plugin> Backend<P> for Jack {
|
||||||
let mut midi_writer = midi_output.writer(ps);
|
let mut midi_writer = midi_output.writer(ps);
|
||||||
for event in output_events.drain(..) {
|
for event in output_events.drain(..) {
|
||||||
// Out of bounds events are clamped to the buffer's size
|
// Out of bounds events are clamped to the buffer's size
|
||||||
nih_debug_assert!(
|
let timing = clamp_output_event_timing(event.timing(), num_frames as u32);
|
||||||
event.timing() < num_frames,
|
|
||||||
"Output event is out of bounds, will be clamped to the buffer's size"
|
|
||||||
);
|
|
||||||
let timing = event.timing().min(num_frames - 1);
|
|
||||||
|
|
||||||
match event.as_midi() {
|
match event.as_midi() {
|
||||||
Some(MidiResult::Basic(midi_data)) => {
|
Some(MidiResult::Basic(midi_data)) => {
|
||||||
|
|
|
@ -61,6 +61,34 @@ pub fn strlcpy(dest: &mut [c_char], src: &str) {
|
||||||
dest[copy_len] = 0;
|
dest[copy_len] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Clamp an input event's timing to the buffer length. Emits a debug assertion failure if it was
|
||||||
|
/// out of bounds.
|
||||||
|
#[inline]
|
||||||
|
pub fn clamp_input_event_timing(timing: u32, total_buffer_len: u32) -> u32 {
|
||||||
|
let last_valid_index = total_buffer_len.saturating_sub(1);
|
||||||
|
|
||||||
|
nih_debug_assert!(
|
||||||
|
timing < last_valid_index,
|
||||||
|
"Input event is out of bounds, will be clamped to the buffer's size"
|
||||||
|
);
|
||||||
|
|
||||||
|
timing.min(last_valid_index)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Clamp an output event's timing to the buffer length. Emits a debug assertion failure if it was
|
||||||
|
/// out of bounds.
|
||||||
|
#[inline]
|
||||||
|
pub fn clamp_output_event_timing(timing: u32, total_buffer_len: u32) -> u32 {
|
||||||
|
let last_valid_index = total_buffer_len.saturating_sub(1);
|
||||||
|
|
||||||
|
nih_debug_assert!(
|
||||||
|
timing < last_valid_index,
|
||||||
|
"Output event is out of bounds, will be clamped to the buffer's size"
|
||||||
|
);
|
||||||
|
|
||||||
|
timing.min(last_valid_index)
|
||||||
|
}
|
||||||
|
|
||||||
/// Set up the logger so that the `nih_*!()` logging and assertion macros log output to a
|
/// Set up the logger so that the `nih_*!()` logging and assertion macros log output to a
|
||||||
/// centralized location and panics also get written there. By default this logs to STDERR unless
|
/// centralized location and panics also get written there. By default this logs to STDERR unless
|
||||||
/// the user is running Windows and a debugger has been attached, in which case
|
/// the user is running Windows and a debugger has been attached, in which case
|
||||||
|
|
|
@ -37,7 +37,7 @@ use crate::plugin::{
|
||||||
};
|
};
|
||||||
use crate::util::permit_alloc;
|
use crate::util::permit_alloc;
|
||||||
use crate::wrapper::state;
|
use crate::wrapper::state;
|
||||||
use crate::wrapper::util::process_wrapper;
|
use crate::wrapper::util::{clamp_input_event_timing, clamp_output_event_timing, process_wrapper};
|
||||||
|
|
||||||
// Alias needed for the VST3 attribute macro
|
// Alias needed for the VST3 attribute macro
|
||||||
use vst3_sys as vst3_com;
|
use vst3_sys as vst3_com;
|
||||||
|
@ -1101,14 +1101,10 @@ 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. Out of bounds events are clamped to the buffer>
|
// plugin. Out of bounds events are clamped to the buffer>
|
||||||
let timing = sample_offset as u32;
|
let timing = clamp_input_event_timing(
|
||||||
nih_debug_assert!(
|
sample_offset as u32,
|
||||||
timing < total_buffer_len as u32,
|
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
|
||||||
|
@ -1175,12 +1171,10 @@ impl<P: Vst3Plugin> IAudioProcessor for Wrapper<P> {
|
||||||
nih_debug_assert_eq!(result, kResultOk);
|
nih_debug_assert_eq!(result, kResultOk);
|
||||||
|
|
||||||
let event = event.assume_init();
|
let event = event.assume_init();
|
||||||
let timing = event.sample_offset as u32;
|
let timing = clamp_input_event_timing(
|
||||||
nih_debug_assert!(
|
event.sample_offset as u32,
|
||||||
timing < total_buffer_len as u32,
|
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;
|
||||||
|
@ -1573,15 +1567,10 @@ impl<P: Vst3Plugin> IAudioProcessor for Wrapper<P> {
|
||||||
let mut vst3_event: Event = mem::zeroed();
|
let mut vst3_event: Event = mem::zeroed();
|
||||||
vst3_event.bus_index = 0;
|
vst3_event.bus_index = 0;
|
||||||
// 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 = clamp_output_event_timing(
|
||||||
|
event.timing() + block_start as u32,
|
||||||
// Out of bounds events are clamped to the buffer
|
total_buffer_len as u32,
|
||||||
nih_debug_assert!(
|
) as i32;
|
||||||
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
|
||||||
|
|
Loading…
Reference in a new issue