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::wrapper::clap::util::{read_stream, write_stream};
|
||||
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
|
||||
/// 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();
|
||||
while let Some(event) = output_events.pop_front() {
|
||||
// Out of bounds events are clamped to the buffer's size
|
||||
let time = event.timing() + current_sample_idx as u32;
|
||||
nih_debug_assert!(
|
||||
time < total_buffer_len as u32,
|
||||
"Output event is out of bounds, will be clamped to the buffer's size"
|
||||
let time = clamp_output_event_timing(
|
||||
event.timing() + current_sample_idx as u32,
|
||||
total_buffer_len as u32,
|
||||
);
|
||||
let time = time.min(total_buffer_len as u32 - 1);
|
||||
|
||||
let push_successful = match event {
|
||||
NoteEvent::NoteOn {
|
||||
|
@ -1423,12 +1423,10 @@ impl<P: ClapPlugin> Wrapper<P> {
|
|||
let raw_event = &*event;
|
||||
|
||||
// Out of bounds events are clamped to the buffer's size
|
||||
let timing = raw_event.time - current_sample_idx 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 = clamp_input_event_timing(
|
||||
raw_event.time - current_sample_idx as u32,
|
||||
total_buffer_len as u32,
|
||||
);
|
||||
let timing = timing.min(total_buffer_len as u32 - 1);
|
||||
|
||||
match (raw_event.space_id, raw_event.type_) {
|
||||
(CLAP_CORE_EVENT_SPACE_ID, CLAP_EVENT_PARAM_VALUE) => {
|
||||
|
|
|
@ -15,6 +15,7 @@ use crate::buffer::Buffer;
|
|||
use crate::context::process::Transport;
|
||||
use crate::midi::{MidiConfig, MidiResult, NoteEvent, PluginNoteEvent};
|
||||
use crate::plugin::Plugin;
|
||||
use crate::wrapper::util::{clamp_input_event_timing, clamp_output_event_timing};
|
||||
|
||||
/// Uses JACK audio and MIDI.
|
||||
pub struct Jack {
|
||||
|
@ -122,11 +123,7 @@ impl<P: Plugin> Backend<P> for Jack {
|
|||
input_events.clear();
|
||||
if let Some(midi_input) = &midi_input {
|
||||
input_events.extend(midi_input.iter(ps).filter_map(|midi| {
|
||||
nih_debug_assert!(
|
||||
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);
|
||||
let timing = clamp_input_event_timing(midi.time, num_frames);
|
||||
|
||||
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);
|
||||
for event in output_events.drain(..) {
|
||||
// Out of bounds events are clamped to the buffer's size
|
||||
nih_debug_assert!(
|
||||
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);
|
||||
let timing = clamp_output_event_timing(event.timing(), num_frames as u32);
|
||||
|
||||
match event.as_midi() {
|
||||
Some(MidiResult::Basic(midi_data)) => {
|
||||
|
|
|
@ -61,6 +61,34 @@ pub fn strlcpy(dest: &mut [c_char], src: &str) {
|
|||
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
|
||||
/// 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
|
||||
|
|
|
@ -37,7 +37,7 @@ use crate::plugin::{
|
|||
};
|
||||
use crate::util::permit_alloc;
|
||||
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
|
||||
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
|
||||
// `event.subtract_timing(block_start)` before it is passed to the
|
||||
// plugin. Out of bounds events are clamped to the buffer>
|
||||
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 = clamp_input_event_timing(
|
||||
sample_offset as u32,
|
||||
total_buffer_len as u32,
|
||||
);
|
||||
let timing = timing.min(total_buffer_len as u32 - 1);
|
||||
|
||||
let value = value as f32;
|
||||
|
||||
// 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);
|
||||
|
||||
let event = event.assume_init();
|
||||
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 = clamp_input_event_timing(
|
||||
event.sample_offset as u32,
|
||||
total_buffer_len as u32,
|
||||
);
|
||||
let timing = timing.min(total_buffer_len as u32 - 1);
|
||||
|
||||
if event.type_ == EventTypes::kNoteOnEvent as u16 {
|
||||
let event = event.event.note_on;
|
||||
|
@ -1573,15 +1567,10 @@ impl<P: Vst3Plugin> IAudioProcessor for Wrapper<P> {
|
|||
let mut vst3_event: Event = mem::zeroed();
|
||||
vst3_event.bus_index = 0;
|
||||
// There's also a ppqPos field, but uh how about no
|
||||
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);
|
||||
vst3_event.sample_offset = clamp_output_event_timing(
|
||||
event.timing() + block_start as u32,
|
||||
total_buffer_len as u32,
|
||||
) as i32;
|
||||
|
||||
// `voice_id.unwrap_or(|| ...)` triggers
|
||||
// https://github.com/rust-lang/rust-clippy/issues/8522
|
||||
|
|
Loading…
Reference in a new issue