pub struct BlipBuf { /* private fields */ }Expand description
Streaming BLEP decimator + filter chain that feeds host-rate samples to the frontend’s audio thread.
Implementations§
Source§impl BlipBuf
impl BlipBuf
Sourcepub fn new(sample_rate: u32, cpu_rate: f64) -> Self
pub fn new(sample_rate: u32, cpu_rate: f64) -> Self
Create a new band-limited buffer.
sample_rate is the host audio rate in Hz (typically 44 100).
cpu_rate is the NES CPU rate in Hz (CPU_HZ_NTSC or
CPU_HZ_PAL).
Sourcepub fn set_filter_model(&mut self, model: FilterModel)
pub fn set_filter_model(&mut self, model: FilterModel)
v2.1.3 — swap the analog output-filter model (see
crate::mixer::FilterModel), rebuilding the filter chain at the
current sample rate. This resets the filter’s IIR state, so switching
while audio is playing (the Settings selector applies it live) produces a
brief transient — as with any live filter swap. The frontend also applies
it at ROM load / power-cycle, where there is no audible discontinuity.
Sourcepub fn reset(&mut self)
pub fn reset(&mut self)
Reset to silence. Empties the input ring, the pending output queue, and the filter chain state.
Sourcepub fn add_sample(&mut self, value: f32)
pub fn add_sample(&mut self, value: f32)
Add one mixed sample at CPU resolution. The buffer accumulates
host-rate samples internally; drain via Self::drain or
Self::drain_all.
The mixer’s output is approximately in [-0.5, 0.5] for the 2A03
alone, with on-cart audio expansions pushing the absolute range
up somewhat. We clamp value defensively so a stray NaN/Inf or
runaway mapper can’t propagate non-finite values into the FIR
state. The clamp range is far outside any sane mixer output, so
the gate is purely a saturation backstop, not a normal-operation
limiter.
Sourcepub fn drain(&mut self, out: &mut [f32]) -> usize
pub fn drain(&mut self, out: &mut [f32]) -> usize
Drain finalized samples into out. Returns the number written.
Excess pending samples are kept; if out.len() < self.samples.len()
the remainder waits for the next drain.
Sourcepub fn drain_all(&mut self) -> Vec<f32>
pub fn drain_all(&mut self) -> Vec<f32>
Drain all finalized samples into a new Vec.
The filled buffer goes to the caller, and a fresh one with the same
capacity takes its place (v2.7.5, core audit IMP-07). A buffer returned
by value must be replaced every call whatever happens; the choice is
only whether its replacement starts empty. With mem::take it started
at capacity zero and regrew by doubling through the next frame’s pushes
(about nine reallocations for a frame’s ~800 samples); now it is one
allocation of the size the last frame needed, up to
DRAIN_ALL_KEEP_CAPACITY samples. Measured -0.89% frame
time on a steady-state frame-then-drain workload, reproduced on two
runs (docs/performance.md §v2.7.5). Callers that drain into their own
buffer with Self::drain allocate nothing and are unaffected. The
samples themselves are untouched, so the output is byte-identical.