Skip to main content

Crate dsp_process

Crate dsp_process 

Source
Expand description

§dsp-process

Small no_std traits for static DSP composition. State, layout, and loop shape remain explicit; no allocation or dynamic dispatch is required.

§Processing shapes

ShapeRepresentationUse
one config, one stateSplit<C, S>ordinary stateful filter
one config, many statesSplit<C, S>::lanes()shared coefficients
many configs, one statedirect SplitProcess callsprediction/correction phases
many config/state pairstuples, arrays, Minor, Majorstatic pipelines

SplitProcess<X, Y, S> is the primitive: &self is immutable configuration; &mut S is caller-owned state. Different configurations may therefore operate on the same state:

use dsp_process::SplitProcess;

struct State(i32);
struct Predict(i32);
struct Correct;

impl SplitProcess<(), (), State> for Predict {
    fn process(&self, state: &mut State, (): ()) {
        state.0 += self.0;
    }
}

impl SplitProcess<i32, i32, State> for Correct {
    fn process(&self, state: &mut State, measurement: i32) -> i32 {
        state.0 = (state.0 + measurement) / 2;
        state.0
    }
}

let mut state = State(2);
Predict(3).process(&mut state, ());
assert_eq!(Correct.process(&mut state, 9), 7);

This is useful when processing has distinct phases but one state, such as a Kalman transition and observation. Tuple composition instead gives each stage its own state.

§Owned processors

Split<C, S> binds one configuration to one state and implements Process:

use dsp_process::{Offset, Process, Split};

let mut offset = Split::stateless(Offset(3));
assert_eq!(offset.process(5), 8);

One configuration can drive several independent states:

use dsp_process::{Offset, Process, Split};

let mut lanes = Split::stateless(Offset(3)).lanes::<2>();
assert_eq!(lanes.process([1, 10]), [4, 13]);

§Composition

Tuples and arrays form serial pipelines. Parallel forms branches. Minor and Major select loop nesting and scratch placement.

use dsp_process::{Gain, Offset, Process, Split};

let mut pipeline = (Split::stateless(Offset(3)) * Split::stateless(Gain(4))).minor();
assert_eq!(pipeline.process(5), 32);

Adapters (Chunk, ChunkIn, ChunkOut, Interpolator, Decimator, Map) change rate or call shape without hiding state.

§Layout

Layout-sensitive processing uses typed views. FrameMajor and LaneMajor make the physical interpretation part of the type; sample newtypes do not.

use dsp_process::{LaneMajor, Offset, Split, View, ViewMut, ViewProcess};

let mut lanes = Split::stateless(Offset(3)).lanes::<2>();
let input = View::<_, LaneMajor, 2>::from_flat(&[1, 2, 3, 10, 20, 30], 3);
let mut output = [0; 6];
let output = ViewMut::<_, LaneMajor, 2>::from_flat(&mut output, 3);
lanes.process_view(input, output);

Use Split::per_frame() to apply a chunk processor to each frame of a frame-major view.

§Implementing a stage

  • Implement SplitProcess when configuration and state are distinct.
  • Implement Process when one value naturally owns both.
  • Implement SplitInplace or Inplace for a real in-place specialization.
  • Override block() only to improve the loop or memory traffic.

Runtime fields hold values; const generics encode shape; wrappers encode composition and layout.

Structs§

Add
Summation
Buffer
Fixed-size sample buffer used as a delay line or chunk accumulator.
Butterfly
Sum and difference of a two-element input.
ByLane
Explicit lane-major view interpretation for parallel compositions.
Chunk
Elementwise fixed-size chunk lifting.
ChunkIn
Fixed-ratio chunk adapter for grouped input.
ChunkInOut
General fixed-ratio regrouping adapter for chunked input and output.
ChunkOut
Fixed-ratio chunk adapter for grouped output.
ChunkOutPod
POD-specialized ChunkOut variant.
Clamp
Clamp between min and max using Ord
Comb
Comb (derivative)
Decimator
Adapt a scalar optional-output stage to chunk input mode.
Downsample
Scalar downsampler with explicit tick phase.
FnProcess
Wrap a FnMut into a Process/Inplace
FnSplitProcess
Wrap a Fn into a SplitProcess/SplitInplace
FrameMajor
Frame-major view layout marker.
Gain
Multiplication by a constant in split form.
Hold
Zero-order hold over optional input samples.
Identity
Identity stage and simple fan-out/fan-in adapter.
Integrator
Running sum / discrete-time integrator.
Interpolator
Adapt a scalar optional-input stage to chunk output mode.
LaneMajor
Lane-major view layout marker.
Lanes
Multiple lanes with one shared configuration and separate states.
Major
Stage-major slice composition with explicit scratch storage.
Map
Lift a processor through Option or Result.
Minor
Processor-minor, data-major serial composition.
Mul
Product
Neg
Inversion using Neg.
Nyquist
Nyquist zero with gain 2
Offset
Addition of a constant in split form.
Parallel
Parallel branch composition over tuple or array-shaped data.
PerFrame
Apply a chunk-based processor frame by frame to a frame-major view.
Rate
Select or place one sample in a fixed-size rate-conversion slot.
Split
A stateful processor assembled from split configuration and state.
Sub
Difference
TryDecimator
Checked variant of Decimator.
Unsplit
Marker for values that should live in the opposite half of a Split.
View
Immutable typed view of a DSP slice.
ViewMut
Mutable typed view of a DSP slice.

Enums§

DecimatorError
Error returned by TryDecimator when the inner decimator does not tick exactly once per input chunk.

Traits§

Inplace
Inplace processing
Process
Processing block
SplitInplace
Inplace processing with a split state
SplitProcess
Processing with split state
SplitViewInplace
Split-state in-place processing API over typed views.
SplitViewProcess
Split-state processing API over typed views.
ViewInplace
Explicit in-place processing API over typed views.
ViewProcess
Explicit processing API over typed views.

Type Aliases§

Pair
Parallel filter pair