Skip to main content

SplitProcess

Trait SplitProcess 

Source
pub trait SplitProcess<X: Copy, Y = X, S: ?Sized = ()> {
    // Required method
    fn process(&self, state: &mut S, x: X) -> Y;

    // Provided method
    fn block(&self, state: &mut S, x: &[X], y: &mut [Y]) { ... }
}
Expand description

Processing with split state

Splitting configuration (the part of the filter that is unaffected by processing inputs, e.g. “coefficients”), from state (the part that is modified by processing) allows:

  • Separating mutable from immutable state guarantees consistency (configuration can not change state and processing can not change configuration)
  • Reduces memory traffic when swapping configuration
  • Allows the same filter to be applied to multiple states (e.g. IQ data, multiple lanes) guaranteeing consistency, reducing memory usage, and improving caching.

This is the central abstraction used throughout dsp-process. A typical DSP filter coefficient set becomes Self, while delay lines, accumulators, and history buffers become the separate state argument.

Use this when one configuration should drive many runtime states, or when it is beneficial to keep mutable state small and move immutable data out of hot loops.

Process is often easier when state and configuration naturally live together, while crate::Split turns a SplitProcess back into a stateful Process value.

§Examples

use dsp_process::SplitProcess;

#[derive(Copy, Clone)]
struct Gain(i32);

impl SplitProcess<i32> for Gain {
    fn process(&self, _: &mut (), x: i32) -> i32 {
        self.0 * x
    }
}

let mut state = ();
assert_eq!(Gain(4).process(&mut state, 3), 12);

Required Methods§

Source

fn process(&self, state: &mut S, x: X) -> Y

Process an input into an output

See also Process::process

Provided Methods§

Source

fn block(&self, state: &mut S, x: &[X], y: &mut [Y])

Process a block of inputs

See also Process::block

Length matching is a caller precondition in release builds.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementations on Foreign Types§

Source§

impl<X: Copy, C, S> SplitProcess<X, X, [S]> for [C]
where C: SplitInplace<X, S>,

Chain multiple homogeneous processors over one sample type.

The slice may be empty, in which case block() acts as identity.

Source§

fn process(&self, state: &mut [S], x: X) -> X

Source§

fn block(&self, state: &mut [S], x: &[X], y: &mut [X])

Source§

impl<X: Copy, Y, P: Process<X, Y>> SplitProcess<X, Y, Unsplit<P>> for ()

Configuration-less filters

Source§

fn process(&self, state: &mut Unsplit<P>, x: X) -> Y

Source§

fn block(&self, state: &mut Unsplit<P>, x: &[X], y: &mut [Y])

Source§

impl<X: Copy, Y, S: ?Sized, T: SplitProcess<X, Y, S>> SplitProcess<X, Y, S> for &T

Source§

fn process(&self, state: &mut S, x: X) -> Y

Source§

fn block(&self, state: &mut S, x: &[X], y: &mut [Y])

Source§

impl<X: Copy, Y, S: ?Sized, T: SplitProcess<X, Y, S>> SplitProcess<X, Y, S> for &mut T

Source§

fn process(&self, state: &mut S, x: X) -> Y

Source§

fn block(&self, state: &mut S, x: &[X], y: &mut [Y])

Source§

impl<X: Copy, Y: Copy, C0, C1, S0, S1> SplitProcess<X, Y, (S0, S1)> for (C0, C1)
where C0: SplitProcess<X, Y, S0>, C1: SplitInplace<Y, S1>,

Chain two different processors with an explicit intermediate type.

This is the heterogeneous serial-composition primitive for tuples. The first stage may change the sample type, while the second stage must accept that intermediate value in place.

Source§

fn process(&self, state: &mut (S0, S1), x: X) -> Y

Source§

fn block(&self, state: &mut (S0, S1), x: &[X], y: &mut [Y])

Source§

impl<X: Copy, Y: Copy, C, S, const N: usize> SplitProcess<X, Y, [S; N]> for [C; N]
where C: SplitProcess<X, Y, S> + SplitInplace<Y, S>,

Chain a non-empty homogeneous array of processors with one initial type change.

Source§

fn process(&self, state: &mut [S; N], x: X) -> Y

Source§

fn block(&self, state: &mut [S; N], x: &[X], y: &mut [Y])

Implementors§

Source§

impl<C, S, X: Copy, Y: Default + Copy, const N: usize, const R: usize, const M: usize> SplitProcess<[X; N], [Y; M], S> for ChunkOut<C, R>
where C: SplitProcess<X, [Y; R], S>,

Source§

impl<C, S, X: Copy, Y: Default + Copy, const Q: usize, const N: usize, const R: usize, const M: usize> SplitProcess<[X; N], [Y; M], S> for ChunkInOut<C, Q, R>
where C: SplitProcess<[X; Q], [Y; R], S>,

Source§

impl<C, S, X: Copy, Y: Pod, const N: usize, const R: usize, const M: usize> SplitProcess<[X; N], [Y; M], S> for ChunkOutPod<C, R>
where C: SplitProcess<X, [Y; R], S>,

Available on crate feature bytemuck only.
Source§

impl<C: SplitProcess<X, Y, S>, S, X: Copy, Y, const N: usize> SplitProcess<[X; N], [Y; N], S> for Chunk<C>

Source§

impl<C: SplitProcess<[X; R], Y, S>, S, X: Copy, Y, const N: usize, const R: usize, const M: usize> SplitProcess<[X; N], [Y; M], S> for ChunkIn<C, R>

Source§

impl<F: Fn(&mut S, X) -> Y, X: Copy, Y, S> SplitProcess<X, Y, S> for FnSplitProcess<F>

Source§

impl<T: Copy + Ord> SplitProcess<T> for Clamp<T>

Source§

impl<X0: Copy, X1: Copy, Y0, Y1, C0, C1, S0, S1> SplitProcess<(X0, X1), (Y0, Y1), (S0, S1)> for Parallel<(C0, C1)>
where C0: SplitProcess<X0, Y0, S0>, C1: SplitProcess<X1, Y1, S1>,

Source§

impl<X: Copy + Add<T, Output = Y>, Y, T: Copy> SplitProcess<X, Y> for Offset<T>

Offset using Add

Source§

impl<X: Copy + Mul<T, Output = Y>, Y, T: Copy> SplitProcess<X, Y> for Gain<T>

Gain using Mul

Source§

impl<X: Copy, C, S> SplitProcess<X, X, [S]> for Minor<[C], X>
where C: SplitProcess<X, X, S>,

A chain of multiple small filters of the same type

Source§

impl<X: Copy, U: Copy + Default, Y, C0, C1, S0, S1, const N: usize> SplitProcess<X, Y, (S0, S1)> for Major<(C0, C1), [U; N]>
where C0: SplitProcess<X, U, S0>, C1: SplitProcess<U, Y, S1>,

Source§

impl<X: Copy, U: Copy, Y, C0, C1, S0, S1> SplitProcess<X, Y, (S0, S1)> for Minor<(C0, C1), U>
where C0: SplitProcess<X, U, S0>, C1: SplitProcess<U, Y, S1>,

Source§

impl<X: Copy, Y, C0, C1, S0, S1> SplitProcess<[X; 2], [Y; 2], (S0, S1)> for ByLane<(C0, C1)>
where C0: SplitProcess<X, Y, S0>, C1: SplitProcess<X, Y, S1>,

Source§

impl<X: Copy, Y, C0, C1, S0, S1> SplitProcess<[X; 2], [Y; 2], (S0, S1)> for Parallel<(C0, C1)>
where C0: SplitProcess<X, Y, S0>, C1: SplitProcess<X, Y, S1>,

Source§

impl<X: Copy, Y, C, S, const N: usize> SplitProcess<[X; N], [Y; N], [S; N]> for ByLane<[C; N]>
where C: SplitProcess<X, Y, S>,

Source§

impl<X: Copy, Y, C, S, const N: usize> SplitProcess<[X; N], [Y; N], [S; N]> for Lanes<C>
where C: SplitProcess<X, Y, S>,

Process data from multiple lanes with a common configuration.

For layout-sensitive view processing use View<_, _, LaneMajor, _>.

Source§

impl<X: Copy, Y, C, S, const N: usize> SplitProcess<[X; N], [Y; N], [S; N]> for Parallel<[C; N]>
where C: SplitProcess<X, Y, S>,

Source§

impl<X: Copy, Y, C: SplitProcess<Option<X>, Y, S>, S, const N: usize> SplitProcess<X, [Y; N], S> for Interpolator<C>

Source§

impl<X: Copy, Y, C: SplitProcess<X, Option<Y>, S>, S, const N: usize> SplitProcess<[X; N], Result<Y, DecimatorError>, S> for TryDecimator<C>

Source§

impl<X: Copy, Y, C: SplitProcess<X, Option<Y>, S>, S, const N: usize> SplitProcess<[X; N], Y, S> for Decimator<C>

Source§

impl<X: Copy, Y, C: SplitProcess<X, Y, S>, S, E: Copy> SplitProcess<Result<X, E>, Result<Y, E>, S> for Map<C>

Source§

impl<X: Copy, Y, C: SplitProcess<X, Y, S>, S> SplitProcess<Option<X>, Option<Y>, S> for Map<C>

Source§

impl<X: Copy, Y: Copy, C, S, const N: usize> SplitProcess<X, Y, [S; N]> for Minor<[C; N], Y>
where C: SplitProcess<X, Y, S> + SplitProcess<Y, Y, S>,

A chain of multiple small filters of the same type

Source§

impl<X: Copy> SplitProcess<X, Option<X>, u32> for Downsample