AUDIO
Source snapshot · 12 October 2026

Prepared signal processing

Prepared comb filters

CombFilter::new(CombKind, delay_samples, coefficient) prepares a one-channel f64 comb with a fixed delay D of 1..=1048576 whole samples. Feedforward computes y[n] = x[n] + g*x[n-D], a finite input echo; Feedback computes y[n] = x[n] + g*y[n-D], a recursive echo train. Both include current input at unity gain. Positive and negative coefficients change the comb's reinforcement and cancellation frequencies. Feedforward accepts any finite g (including +/-1 for complete notches); feedback requires finite |g| < 1 for fixed-coefficient stability. Delay is measured in samples, so consumers convert their own time/rate.

use ravet_signal::{CombFilter, CombKind};

let mut comb = CombFilter::new(CombKind::Feedback, 2, 0.5).unwrap();
let mut impulse = [1.0, 0.0, 0.0, 0.0, 0.0];
comb.process_in_place(&mut impulse);
assert_eq!(impulse, [1.0, 0.0, 0.5, 0.0, 0.25]);

Preparation validates before allocating exactly D f64 history values (at most 8 MiB, excluding overhead). set_coefficient validates before mutation and retains history without smoothing. A zero coefficient returns input exactly while advancing history. process_sample, process_in_place and reset use existing storage; empty blocks do nothing and arbitrary partitions match. Reset retains the prepared kind, delay and latest coefficient. Type/delay changes require a new instance; instantiate separately for channels.

This standalone profile supplies no damping, fractional delay or normalization. Feedback near unity has substantial gain and a long tail; consumers own headroom, smoothing, nonfinite/denormal policy and deadlines. The reverb below has its own private lowpass-feedback comb network. Tests cover exact signed impulse timing, independent full-history recurrence with live edits, analytic complex frequency response, partition/reset/zero history, atomic invalid edits and bounded maximum storage with 10000 heap-instrumented prepared workloads. See decision 0150.