pub struct ProcessBufferStorage<S: Sample> {
pub main_inputs: Vec<*const S>,
pub main_outputs: Vec<*mut S>,
pub aux_inputs: Vec<Vec<*const S>>,
pub aux_outputs: Vec<Vec<*mut S>>,
pub internal_output_buffers: Option<Vec<Vec<S>>>,
pub max_frames: usize,
}Expand description
Pre-allocated storage for audio processing channel pointers.
Stores channel pointers collected from host audio buffers during render. The Vecs have pre-allocated capacity matching the actual bus configuration, ensuring no allocations occur during audio callbacks while minimizing memory usage.
§Memory Layout
The storage is optimized based on the actual plugin configuration:
main_inputs: Capacity = actual input channel count (e.g., 1 for mono, 2 for stereo)main_outputs: Capacity = actual output channel count (e.g., 1 for mono, 2 for stereo)aux_inputs: Only allocated if plugin declares aux input busesaux_outputs: Only allocated if plugin declares aux output buses
This means a simple stereo plugin uses only 32 bytes (4 pointers x 8 bytes), not the worst-case 4KB (MAX_CHANNELS x MAX_BUSES x pointer size).
§Type Parameter
S is the sample type (f32 or f64).
Fields§
§main_inputs: Vec<*const S>Main input channel pointers (capacity = actual channel count). Format wrappers may access this directly for performance-critical inline collection.
main_outputs: Vec<*mut S>Main output channel pointers (capacity = actual channel count). Format wrappers may access this directly for performance-critical inline collection.
aux_inputs: Vec<Vec<*const S>>Auxiliary input buses (only allocated if plugin uses them). Format wrappers may access this directly for performance-critical inline collection.
aux_outputs: Vec<Vec<*mut S>>Auxiliary output buses (only allocated if plugin uses them). Format wrappers may access this directly for performance-critical inline collection.
internal_output_buffers: Option<Vec<Vec<S>>>Internal output buffers for instruments (when host provides null pointers). Only allocated for plugins with no input buses (instruments/generators). When a host provides null output pointers, the format wrapper can use these buffers and update the host’s buffer list to point to them.
max_frames: usizeMax frames for internal buffers (set during allocation). Used to validate that num_samples doesn’t exceed buffer capacity.
Implementations§
Source§impl<S: Sample> ProcessBufferStorage<S>
impl<S: Sample> ProcessBufferStorage<S>
Sourcepub fn allocate_from_config(
bus_config: &CachedBusConfig,
max_frames: usize,
) -> Self
pub fn allocate_from_config( bus_config: &CachedBusConfig, max_frames: usize, ) -> Self
Create storage from cached bus configuration (recommended).
This is the preferred way to allocate storage as it automatically extracts the correct channel counts from the bus configuration. Should be called during plugin setup (non-real-time).
§Memory Optimization
This method implements smart allocation strategies:
- Allocates only for channels actually present in the config
- No pre-allocation for aux buses if plugin doesn’t use them
- Uses actual channel counts, not MAX_CHANNELS worst-case
- Zero heap allocation for simple mono/stereo plugins without aux buses
§Arguments
bus_config- Cached bus configurationmax_frames- Maximum frames per render call (for internal buffer allocation)
§Example
let config = extract_bus_config();
config.validate()?;
let storage = ProcessBufferStorage::allocate_from_config(&config, 4096);Sourcepub fn allocate(
main_in_channels: usize,
main_out_channels: usize,
aux_in_buses: usize,
aux_out_buses: usize,
aux_channels: usize,
) -> Self
pub fn allocate( main_in_channels: usize, main_out_channels: usize, aux_in_buses: usize, aux_out_buses: usize, aux_channels: usize, ) -> Self
Create new storage with pre-allocated capacity (manual).
This is a lower-level method for manual capacity specification.
Prefer allocate_from_config() when possible as it’s less error-prone.
§Arguments
main_in_channels- Number of main input channelsmain_out_channels- Number of main output channelsaux_in_buses- Number of auxiliary input busesaux_out_buses- Number of auxiliary output busesaux_channels- Channels per aux bus (assumes uniform)
Sourcepub fn clear(&mut self)
pub fn clear(&mut self)
Clear all pointer storage without deallocating.
This is O(1) - it only sets Vec lengths to 0 while preserving capacity. Call this at the start of each render call.
Sourcepub fn input_channel_count(&self) -> usize
pub fn input_channel_count(&self) -> usize
Get the number of input channels collected.
Sourcepub fn output_channel_count(&self) -> usize
pub fn output_channel_count(&self) -> usize
Get the number of output channels collected.
Sourcepub fn aux_input_bus_count(&self) -> usize
pub fn aux_input_bus_count(&self) -> usize
Get the number of auxiliary input buses.
Sourcepub fn aux_output_bus_count(&self) -> usize
pub fn aux_output_bus_count(&self) -> usize
Get the number of auxiliary output buses.
Sourcepub fn max_frames(&self) -> usize
pub fn max_frames(&self) -> usize
Get the maximum frames for internal buffers.
Sourcepub fn has_internal_output_buffers(&self) -> bool
pub fn has_internal_output_buffers(&self) -> bool
Check if internal output buffers are available.
Sourcepub unsafe fn push_main_input(&mut self, ptr: *const S)
pub unsafe fn push_main_input(&mut self, ptr: *const S)
Push a main input pointer.
§Safety
The pointer must be valid for the duration of the current render call.
Sourcepub unsafe fn push_main_output(&mut self, ptr: *mut S)
pub unsafe fn push_main_output(&mut self, ptr: *mut S)
Push a main output pointer.
§Safety
The pointer must be valid for the duration of the current render call.
Sourcepub unsafe fn push_aux_input(&mut self, bus_index: usize, ptr: *const S)
pub unsafe fn push_aux_input(&mut self, bus_index: usize, ptr: *const S)
Push an auxiliary input pointer for a specific bus.
§Safety
The pointer must be valid for the duration of the current render call.
Sourcepub unsafe fn push_aux_output(&mut self, bus_index: usize, ptr: *mut S)
pub unsafe fn push_aux_output(&mut self, bus_index: usize, ptr: *mut S)
Push an auxiliary output pointer for a specific bus.
§Safety
The pointer must be valid for the duration of the current render call.
Sourcepub fn main_input_capacity(&self) -> usize
pub fn main_input_capacity(&self) -> usize
Get the main input capacity.
Sourcepub fn main_output_capacity(&self) -> usize
pub fn main_output_capacity(&self) -> usize
Get the main output capacity.
Sourcepub fn aux_input_capacity(&self, bus_index: usize) -> usize
pub fn aux_input_capacity(&self, bus_index: usize) -> usize
Get an auxiliary input bus capacity.
Sourcepub fn aux_output_capacity(&self, bus_index: usize) -> usize
pub fn aux_output_capacity(&self, bus_index: usize) -> usize
Get an auxiliary output bus capacity.
Sourcepub unsafe fn input_slices(&self, num_samples: usize) -> Vec<&[S]>
pub unsafe fn input_slices(&self, num_samples: usize) -> Vec<&[S]>
Build input slices from collected pointers.
§Safety
- Pointers must still be valid (within same render call)
- num_samples must match what was used in collection
Sourcepub unsafe fn output_slices(&self, num_samples: usize) -> Vec<&mut [S]>
pub unsafe fn output_slices(&self, num_samples: usize) -> Vec<&mut [S]>
Build output slices from collected pointers.
§Safety
- Pointers must still be valid (within same render call)
- num_samples must match what was used in collection
§Clippy Allow: mut_from_ref
Returns &mut [S] from &self because we’re converting raw pointers stored in the struct,
not mutating self. This is a common and safe FFI pattern where:
- Raw pointers (
*mut S) are stored during collection - Those pointers are then converted back to safe references
- The mutable references are to the external buffer memory, not to
self - Host guarantees single-threaded render access, preventing aliasing
Sourcepub unsafe fn aux_input_slices(&self, num_samples: usize) -> Vec<Vec<&[S]>>
pub unsafe fn aux_input_slices(&self, num_samples: usize) -> Vec<Vec<&[S]>>
Build auxiliary input slices from collected pointers.
Returns a Vec of buses, where each bus is a Vec of channel slices.
§Safety
- Pointers must still be valid (within same render call)
- num_samples must match what was used in collection
Sourcepub unsafe fn aux_output_slices(&self, num_samples: usize) -> Vec<Vec<&mut [S]>>
pub unsafe fn aux_output_slices(&self, num_samples: usize) -> Vec<Vec<&mut [S]>>
Build auxiliary output slices from collected pointers.
Returns a Vec of buses, where each bus is a Vec of channel slices.
§Safety
- Pointers must still be valid (within same render call)
- num_samples must match what was used in collection
§Clippy Allow: mut_from_ref
Same justification as output_slices - converts raw pointers to mutable references.
Sourcepub fn internal_output_buffer_mut(
&mut self,
channel: usize,
) -> Option<&mut Vec<S>>
pub fn internal_output_buffer_mut( &mut self, channel: usize, ) -> Option<&mut Vec<S>>
Get a mutable pointer to an internal output buffer channel.
Returns None if internal buffers are not allocated or channel is out of range.
§Arguments
channel- The channel index
Sourcepub fn internal_output_buffer(&self, channel: usize) -> Option<&Vec<S>>
pub fn internal_output_buffer(&self, channel: usize) -> Option<&Vec<S>>
Get a reference to an internal output buffer channel.
Returns None if internal buffers are not allocated or channel is out of range.
Sourcepub fn internal_output_buffer_count(&self) -> usize
pub fn internal_output_buffer_count(&self) -> usize
Get the number of internal output buffer channels.
Trait Implementations§
Source§impl<S: Clone + Sample> Clone for ProcessBufferStorage<S>
impl<S: Clone + Sample> Clone for ProcessBufferStorage<S>
Source§fn clone(&self) -> ProcessBufferStorage<S>
fn clone(&self) -> ProcessBufferStorage<S>
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more