Skip to main content

ProcessBufferStorage

Struct ProcessBufferStorage 

Source
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 buses
  • aux_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: usize

Max 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>

Source

pub fn new() -> Self

Create empty storage (no capacity reserved).

Source

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 configuration
  • max_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);
Source

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 channels
  • main_out_channels - Number of main output channels
  • aux_in_buses - Number of auxiliary input buses
  • aux_out_buses - Number of auxiliary output buses
  • aux_channels - Channels per aux bus (assumes uniform)
Source

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.

Source

pub fn input_channel_count(&self) -> usize

Get the number of input channels collected.

Source

pub fn output_channel_count(&self) -> usize

Get the number of output channels collected.

Source

pub fn aux_input_bus_count(&self) -> usize

Get the number of auxiliary input buses.

Source

pub fn aux_output_bus_count(&self) -> usize

Get the number of auxiliary output buses.

Source

pub fn max_frames(&self) -> usize

Get the maximum frames for internal buffers.

Source

pub fn has_internal_output_buffers(&self) -> bool

Check if internal output buffers are available.

Source

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.

Source

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.

Source

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.

Source

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.

Source

pub fn main_input_capacity(&self) -> usize

Get the main input capacity.

Source

pub fn main_output_capacity(&self) -> usize

Get the main output capacity.

Source

pub fn aux_input_capacity(&self, bus_index: usize) -> usize

Get an auxiliary input bus capacity.

Source

pub fn aux_output_capacity(&self, bus_index: usize) -> usize

Get an auxiliary output bus capacity.

Source

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
Source

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
Source

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
Source

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.

Source

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
Source

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.

Source

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>

Source§

fn clone(&self) -> ProcessBufferStorage<S>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<S: Sample> Default for ProcessBufferStorage<S>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<S: Sample> Send for ProcessBufferStorage<S>

Source§

impl<S: Sample> Sync for ProcessBufferStorage<S>

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.