Module buffer

Module buffer 

Source
Expand description

Audio buffer abstractions for plugin processing.

This module provides Buffer for main audio I/O and AuxiliaryBuffers for sidechain and auxiliary bus access.

§Architecture

Audio processing in Beamer uses two separate buffer types:

  • Buffer: Main stereo/surround I/O - used by all plugins
  • AuxiliaryBuffers: Sidechain and aux buses - used by multi-bus plugins

This separation solves Rust’s lifetime variance constraints with nested mutable references while providing a clean, ergonomic API.

§Real-Time Safety

All buffer types use fixed-size stack storage with no heap allocations. This guarantees real-time safety in audio processing callbacks.

§Generic Sample Type

All buffer types are generic over S: Sample, defaulting to f32. This enables zero-cost generic processing for both 32-bit and 64-bit audio.

§Example: Simple Gain Plugin

fn process(&mut self, buffer: &mut Buffer, _aux: &mut AuxiliaryBuffers) {
    let gain = self.parameters.gain();
    for (input, output) in buffer.zip_channels() {
        for (i, o) in input.iter().zip(output.iter_mut()) {
            *o = *i * gain;
        }
    }
}

§Example: Block-Based Sidechain (RMS)

fn process(&mut self, buffer: &mut Buffer, aux: &mut AuxiliaryBuffers) {
    // Analyze sidechain input (block-level RMS)
    let key_level = aux.sidechain()
        .map(|sc| sc.rms(0))  // RMS of first channel
        .unwrap_or(0.0);

    // Apply compression based on sidechain
    let reduction = self.compute_gain_reduction(key_level);
    for output in buffer.outputs_mut() {
        for sample in output {
            *sample *= reduction;
        }
    }
}

§Example: Sample-Accurate Sidechain Processing

For sample-by-sample sidechain access (e.g., gates, duckers, lookahead compressors):

fn process(&mut self, buffer: &mut Buffer, aux: &mut AuxiliaryBuffers) {
    let sc = aux.sidechain();

    for i in 0..buffer.num_samples() {
        // Get sidechain sample (returns S::ZERO if disconnected)
        let key = sc.as_ref()
            .map(|s| s.sample(0, i).to_f64().abs())
            .unwrap_or_else(|| buffer.input(0)[i].to_f64().abs());

        // Compute per-sample gain reduction
        let gain = self.envelope.process(key);

        // Apply to output
        buffer.output(0)[i] = buffer.input(0)[i] * Sample::from_f64(gain);
    }
}

Structs§

AuxInput
Immutable view of an auxiliary input bus.
AuxOutput
Mutable view of an auxiliary output bus.
AuxiliaryBuffers
Auxiliary audio buffers for sidechain and multi-bus processing.
Buffer
Main audio buffer for plugin processing.