pub struct StreamingWang { /* private fields */ }Expand description
Streaming Wang fingerprinter — fully incremental.
Maintains a rolling spectrogram window (2·neighborhood_t + 1 rows),
detects peaks frame-by-frame as they ripen, accumulates per-second
candidate buckets, finalises buckets via the per-second adaptive
threshold, and grows per-anchor target heaps until each anchor’s
target zone is fully observed. Per-push CPU cost is proportional to
the number of new frames (not the total stream length).
For whole-second (and many other) clip lengths, the legacy
StreamingFingerprinter::flush hash multiset matches
Wang::extract — verified by the streaming_offline_* tests.
At certain fractional-second remainders (audit F01) legacy flush
may emit fewer hashes; use flush_complete
when you need offline parity.
The pipeline itself is shared with
StreamingPanako via the
crate-internal streaming core; this wrapper supplies
only the Wang-specific hash emission.
§Example
use audiofp::{SampleRate, StreamingFingerprinter};
use audiofp::classical::StreamingWang;
let mut s = StreamingWang::default();
// Feed 4 seconds of silence in two chunks; nothing should be emitted.
let zeros = vec![0.0_f32; 8_000 * 2];
assert!(s.push(&zeros).unwrap().is_empty());
assert!(s.push(&zeros).unwrap().is_empty());
assert!(s.flush().unwrap().is_empty());Implementations§
Source§impl StreamingWang
impl StreamingWang
Sourcepub fn new(cfg: WangConfig) -> Self
pub fn new(cfg: WangConfig) -> Self
Build a streaming Wang extractor with the given config.
Clamps target_zone_t to a minimum of 1 and fan_out to a
minimum of 1 to prevent underflows/empty output from degenerate
configurations. Caps target_zone_t at 512 and fan_out at 64
to prevent OOM from extreme values.
Sourcepub fn config(&self) -> &WangConfig
pub fn config(&self) -> &WangConfig
Borrow the configuration this stream was built with.
Sourcepub fn reset(&mut self)
pub fn reset(&mut self)
Reset all internal state. The stream behaves as if freshly constructed: no buffered audio, no pending peaks or anchors. Call between independent streams sharing one instance so stale data from a previous stream doesn’t bleed into the first emitted hash.
Sourcepub fn flush_complete(&mut self) -> Result<Vec<(TimestampMs, WangHash)>>
pub fn flush_complete(&mut self) -> Result<Vec<(TimestampMs, WangHash)>>
Corrected end-of-stream finalisation matching offline
Wang::extract.
The default StreamingFingerprinter::flush is legacy: it may
emit fewer hashes than offline extraction at certain clip lengths
(notably fractional-second remainders such as 18 000 samples at 8 kHz)
because anchors are drained before later target buckets are finalised.
Call this opt-in API when you need offline parity; keep using flush
only when byte-identical legacy streaming output is required.
Idempotent with respect to anchor emission: a second call with no
intervening push returns nothing. Safe after push following an
earlier flush_complete (pending anchors/targets are empty).
Sourcepub fn flush_complete_with<F>(&mut self, callback: F) -> Result<usize>
pub fn flush_complete_with<F>(&mut self, callback: F) -> Result<usize>
Callback variant of flush_complete.
Trait Implementations§
Source§impl Default for StreamingWang
impl Default for StreamingWang
Source§impl StreamingFingerprinter for StreamingWang
impl StreamingFingerprinter for StreamingWang
Source§fn required_sample_rate(&self) -> u32
fn required_sample_rate(&self) -> u32
Source§fn push(&mut self, samples: &[f32]) -> Result<Vec<(TimestampMs, Self::Frame)>>
fn push(&mut self, samples: &[f32]) -> Result<Vec<(TimestampMs, Self::Frame)>>
Source§fn push_with<F>(&mut self, samples: &[f32], callback: F) -> Result<usize>
fn push_with<F>(&mut self, samples: &[f32], callback: F) -> Result<usize>
callback for each fingerprint frame
that became available during this push. Read moreSource§fn flush(&mut self) -> Result<Vec<(TimestampMs, Self::Frame)>>
fn flush(&mut self) -> Result<Vec<(TimestampMs, Self::Frame)>>
Source§fn flush_with<F>(&mut self, callback: F) -> Result<usize>
fn flush_with<F>(&mut self, callback: F) -> Result<usize>
callback for each frame. Read moreSource§fn latency_ms(&self) -> u32
fn latency_ms(&self) -> u32
push to the time the fingerprint covering it
is returned.Source§fn push_strict(
&mut self,
samples: &[f32],
) -> Result<Vec<(TimestampMs, Self::Frame)>>
fn push_strict( &mut self, samples: &[f32], ) -> Result<Vec<(TimestampMs, Self::Frame)>>
impl ZeroAllocStreaming for StreamingWang
Auto Trait Implementations§
impl !RefUnwindSafe for StreamingWang
impl !UnwindSafe for StreamingWang
impl Freeze for StreamingWang
impl Send for StreamingWang
impl Sync for StreamingWang
impl Unpin for StreamingWang
impl UnsafeUnpin for StreamingWang
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more