Don't process audio at all with invalid buffers
If the host does some kind of flush this way with num_samples > 0 but without any outputs or with zero output channels then we should not try to read from the now invalid pointers from the previous cycle.
This commit is contained in:
parent
ddc28eef5e
commit
3d454bfc9c
|
@ -1593,17 +1593,21 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
|
|
||||||
// Right now we don't handle any auxiliary outputs
|
// Right now we don't handle any auxiliary outputs
|
||||||
// This vector has been preallocated to contain enough slices as there are output
|
// This vector has been preallocated to contain enough slices as there are output
|
||||||
// channels
|
// channels. If the host does not provide outputs or if it does not provide the
|
||||||
|
// required number of channels (should not happen, but Ableton Live does this for
|
||||||
|
// bypassed VST3 plugins) then we'll skip audio processing .
|
||||||
// TODO: The audio buffers have a latency field, should we use those?
|
// TODO: The audio buffers have a latency field, should we use those?
|
||||||
// TODO: Like with VST3, should we expose some way to access or set the silence/constant
|
// TODO: Like with VST3, should we expose some way to access or set the silence/constant
|
||||||
// flags?
|
// flags?
|
||||||
let mut output_buffer = wrapper.output_buffer.borrow_mut();
|
let mut output_buffer = wrapper.output_buffer.borrow_mut();
|
||||||
|
let mut buffer_is_valid = false;
|
||||||
output_buffer.with_raw_vec(|output_slices| {
|
output_buffer.with_raw_vec(|output_slices| {
|
||||||
if !process.audio_outputs.is_null()
|
if !process.audio_outputs.is_null()
|
||||||
&& !(*process.audio_outputs).data32.is_null()
|
&& !(*process.audio_outputs).data32.is_null()
|
||||||
{
|
{
|
||||||
let audio_outputs = &*process.audio_outputs;
|
let audio_outputs = &*process.audio_outputs;
|
||||||
let num_output_channels = audio_outputs.channel_count as usize;
|
let num_output_channels = audio_outputs.channel_count as usize;
|
||||||
|
buffer_is_valid = num_output_channels == output_slices.len();
|
||||||
nih_debug_assert_eq!(num_output_channels, output_slices.len());
|
nih_debug_assert_eq!(num_output_channels, output_slices.len());
|
||||||
|
|
||||||
// NOTE: This `.take()` should not be necessary, but we'll do it as a safe
|
// NOTE: This `.take()` should not be necessary, but we'll do it as a safe
|
||||||
|
@ -1752,12 +1756,14 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = {
|
let result = if buffer_is_valid {
|
||||||
let mut plugin = wrapper.plugin.write();
|
let mut plugin = wrapper.plugin.write();
|
||||||
let mut context = wrapper.make_process_context(transport);
|
let mut context = wrapper.make_process_context(transport);
|
||||||
let result = plugin.process(&mut output_buffer, &mut context);
|
let result = plugin.process(&mut output_buffer, &mut context);
|
||||||
wrapper.last_process_status.store(result);
|
wrapper.last_process_status.store(result);
|
||||||
result
|
result
|
||||||
|
} else {
|
||||||
|
ProcessStatus::Normal
|
||||||
};
|
};
|
||||||
|
|
||||||
let clap_result = match result {
|
let clap_result = match result {
|
||||||
|
|
|
@ -967,12 +967,16 @@ impl<P: Vst3Plugin> IAudioProcessor for Wrapper<P> {
|
||||||
parameter_values_changed = false;
|
parameter_values_changed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This vector has been preallocated to contain enough slices as there are
|
// This vector has been preallocated to contain enough slices as there are output
|
||||||
// output channels
|
// channels. In case the does does not provide an output or if they don't provide
|
||||||
|
// all of the channels (this should not happen, but Ableton Live might do it) then
|
||||||
|
// we'll skip the process function.
|
||||||
let mut output_buffer = self.inner.output_buffer.borrow_mut();
|
let mut output_buffer = self.inner.output_buffer.borrow_mut();
|
||||||
|
let mut buffer_is_valid = false;
|
||||||
output_buffer.with_raw_vec(|output_slices| {
|
output_buffer.with_raw_vec(|output_slices| {
|
||||||
if !data.outputs.is_null() {
|
if !data.outputs.is_null() {
|
||||||
let num_output_channels = (*data.outputs).num_channels as usize;
|
let num_output_channels = (*data.outputs).num_channels as usize;
|
||||||
|
buffer_is_valid = num_output_channels == output_slices.len();
|
||||||
nih_debug_assert_eq!(num_output_channels, output_slices.len());
|
nih_debug_assert_eq!(num_output_channels, output_slices.len());
|
||||||
|
|
||||||
// In case the host does provide fewer output channels than we expect, we
|
// In case the host does provide fewer output channels than we expect, we
|
||||||
|
@ -1084,12 +1088,15 @@ impl<P: Vst3Plugin> IAudioProcessor for Wrapper<P> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = {
|
let result = if buffer_is_valid {
|
||||||
let mut plugin = self.inner.plugin.write();
|
let mut plugin = self.inner.plugin.write();
|
||||||
let mut context = self.inner.make_process_context(transport);
|
let mut context = self.inner.make_process_context(transport);
|
||||||
plugin.process(&mut output_buffer, &mut context)
|
let result = plugin.process(&mut output_buffer, &mut context);
|
||||||
|
self.inner.last_process_status.store(result);
|
||||||
|
result
|
||||||
|
} else {
|
||||||
|
ProcessStatus::Normal
|
||||||
};
|
};
|
||||||
self.inner.last_process_status.store(result);
|
|
||||||
|
|
||||||
// Send any events output by the plugin during the process cycle
|
// Send any events output by the plugin during the process cycle
|
||||||
if let Some(events) = data.output_events.upgrade() {
|
if let Some(events) = data.output_events.upgrade() {
|
||||||
|
|
Loading…
Reference in a new issue