BypassHandler

Struct BypassHandler 

Source
pub struct BypassHandler { /* private fields */ }
Expand description

Utility for handling bypass with smooth crossfading.

Maintains bypass state and provides automatic crossfade between wet (processed) and dry (passthrough) signals when bypass is toggled.

§Sample Type Flexibility

BypassHandler is not generic over sample type - instead, the process() method is generic. This means a single BypassHandler instance can process both Buffer<f32> and Buffer<f64> buffers, and plugins don’t need separate handlers for different precision modes.

§Real-Time Safety

This struct performs no heap allocations and is safe to use in audio processing callbacks.

§Example

use beamer_core::{BypassHandler, CrossfadeCurve, Buffer};

struct MyPlugin {
    bypass_handler: BypassHandler,
    // ...
}

impl AudioProcessor for MyPlugin {
    fn setup(&mut self, sample_rate: f64, _max_buffer_size: usize) {
        // 10ms crossfade with equal-power curve
        let ramp_samples = (sample_rate * 0.01) as u32;
        self.bypass_handler = BypassHandler::new(ramp_samples, CrossfadeCurve::EqualPower);
    }

    fn process(&mut self, buffer: &mut Buffer, aux: &mut AuxiliaryBuffers, ctx: &ProcessContext) {
        let is_bypassed = self.params.bypass_value() > 0.5;

        self.bypass_handler.process(buffer, is_bypassed, |buf| {
            // Your DSP code here - only called when processing is needed
            self.apply_reverb(buf, aux);
        });
    }

    fn bypass_ramp_samples(&self) -> u32 {
        self.bypass_handler.ramp_samples()
    }
}

Implementations§

Source§

impl BypassHandler

Source

pub fn new(ramp_samples: u32, curve: CrossfadeCurve) -> Self

Create a new bypass handler.

§Arguments
  • ramp_samples - Number of samples for crossfade (0 = instant bypass)
  • curve - Crossfade curve shape
Source

pub fn state(&self) -> BypassState

Get the current bypass state.

Source

pub fn is_ramping(&self) -> bool

Returns true if currently in a ramping (crossfading) state.

Source

pub fn is_bypassed(&self) -> bool

Returns true if fully bypassed (not ramping).

Source

pub fn is_active(&self) -> bool

Returns true if fully active (not ramping, not bypassed).

Source

pub fn ramp_samples(&self) -> u32

Get the configured ramp length in samples.

Source

pub fn set_ramp_samples(&mut self, samples: u32)

Set the ramp length. Takes effect on next state transition.

Source

pub fn set_curve(&mut self, curve: CrossfadeCurve)

Set the crossfade curve. Takes effect on next state transition.

Source

pub fn set_bypass(&mut self, bypassed: bool)

Update bypass target state.

Call this at the start of each process() with the current bypass parameter value. State transitions happen automatically.

When ramp_samples == 0 (instant bypass), state snaps directly to Bypassed or Active without passing through ramping states.

Source

pub fn process<S: Sample, F>( &mut self, buffer: &mut Buffer<'_, S>, bypassed: bool, process_fn: F, )
where F: FnOnce(&mut Buffer<'_, S>),

Process audio with bypass handling.

This is the main method plugins should call. It handles:

  • Passthrough when fully bypassed
  • Normal processing when fully active
  • Crossfading during transitions
§Type Parameter

S is the sample type (f32 or f64). The same BypassHandler instance can process buffers of either precision.

§Arguments
  • buffer - Audio buffer to process
  • bypassed - Current bypass parameter state (true = bypassed)
  • process_fn - Closure that performs DSP (only called when needed)
§Behavior
Stateprocess_fn called?Output
ActiveYesWet signal
RampingToBypassedYesCrossfade wet→dry
BypassedNoDry passthrough
RampingToActiveYesCrossfade dry→wet

Trait Implementations§

Source§

impl Default for BypassHandler

Source§

fn default() -> Self

Create a bypass handler with default settings (64 samples, linear curve).

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> 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, 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.