pub struct WaveNetA2<const CH: usize> {Show 17 fields
pub layers: Vec<A2Layer>,
pub rechannel_w_f32: AlignedVec<f32>,
pub head_conv: Option<A2HeadConv>,
pub head_accum: AlignedVec<f32>,
pub head_write_pos: usize,
pub head_ring_mask: usize,
pub layer_buffers: Vec<MirroredBuffer<f32>>,
pub layer_ring_sizes: Vec<usize>,
pub layer_lookbacks: Vec<usize>,
pub layer_buffer_starts: Vec<usize>,
pub layer_in: AlignedVec<f32>,
pub receptive_field_size: usize,
pub max_buffer_size: usize,
pub layer_raw: Option<Value>,
pub z_scratch: AlignedVec<f32>,
pub rt_status: Option<Arc<RtStatusFlags>>,
pub prewarm_on_reset: bool,
}Expand description
Complete WaveNet A2 Model.
CH = channel count (3 for Lite/Nano, 8 for Full/Standard).
Fields§
§layers: Vec<A2Layer>23 A2 layers (one per layer index). Populated by set_weights.
rechannel_w_f32: AlignedVec<f32>Input rechannel weights: Conv1x1(1 → CH) (no bias).
head_conv: Option<A2HeadConv>Head convolution (K=16 over skip-connection accumulator, bias, head_scale).
head_accum: AlignedVec<f32>Head accumulator ring buffer (skip-connection sum, column-major, pow2 size).
head_write_pos: usizeWrite position in head_accum (in columns, wraps via head_ring_mask).
head_ring_mask: usizeRing mask for head_accum (pow2 ring, mask = capacity - 1).
layer_buffers: Vec<MirroredBuffer<f32>>Per-layer history buffers: one MirroredBuffer per layer (23 total). Each buffer provides 2× virtual mapping for branchless ring access.
layer_ring_sizes: Vec<usize>Per-layer ring sizes in elements (pow2 page-aligned). For rewind: start -= ring_size.
layer_lookbacks: Vec<usize>Per-layer maximum dilation lookback = (kernel-1) * dilation.
layer_buffer_starts: Vec<usize>Per-layer buffer starts (advanced with each written frame, rewound near 2× boundary).
layer_in: AlignedVec<f32>Inter-layer data buffer: CH × max_buffer_size f32, reused across layers.
Each layer reads from it, then writes its l1x1 residual back (in-place update).
receptive_field_size: usizeTotal receptive field: sum of (kernel-1)*dilation + head kernel - 1.
max_buffer_size: usizeMaximum frames per processing block (= WAVENET_MAX_NUM_FRAMES).
layer_raw: Option<Value>Raw JSON for the single layer array, preserved for FiLM config parsing.
None when the model is constructed directly (not via JSON deserialization).
z_scratch: AlignedVec<f32>Per-frame scratch buffer for the fallback conv path (CH f32). Allocated once at model creation to avoid heap ops on the hot path.
rt_status: Option<Arc<RtStatusFlags>>RtStatusFlags for silent RT→Main telemetry (RF8).
prewarm_on_reset: boolWhether to execute prewarm during reset(). Default: true.
Implementations§
Source§impl<const CH: usize> WaveNetA2<CH>
impl<const CH: usize> WaveNetA2<CH>
Sourcepub fn process(&mut self, input: &[f32], output: &mut [f32])
pub fn process(&mut self, input: &[f32], output: &mut [f32])
Full forward pass through the A2 model.
Processes input samples and writes to output.
Requires layers to be populated via set_weights.
Outputs silence until weights are loaded.
§Ring buffer architecture
Layer history uses MirroredBuffer<f32> with power-of-2 sizes.
Writes go to unmasked positions in the 2× virtual mapping; reads are
branchless because the mirror maps [S, 2S) → [0, S). When
buffer_start approaches the 2× boundary, it rewinds by subtracting
ring_size. No copy_within / memmove on the hot path.
Head accumulator uses a plain AlignedVec with pow2 mask (& ring_mask).
A pre-write memmove preserves K-1 tail samples when the ring is about
to overflow, keeping the write-positions unmasked for vectorized stores.
Source§impl<const CH: usize> WaveNetA2<CH>
impl<const CH: usize> WaveNetA2<CH>
Sourcepub fn new() -> Result<Self>
pub fn new() -> Result<Self>
Creates a new uninitialized WaveNet A2 model.
Allocates ring buffers (MirroredBuffer per layer, pow2 head accumulator) sized for the architecture and computes the receptive field. Weight-bearing fields start empty and are populated by the weight loader.
Sourcepub fn inject_rt_status(&mut self, rt_status: Arc<RtStatusFlags>)
pub fn inject_rt_status(&mut self, rt_status: Arc<RtStatusFlags>)
Injects RtStatusFlags for RT→Main telemetry (RF8).
Sourcepub fn receptive_field(&self) -> usize
pub fn receptive_field(&self) -> usize
Returns the total receptive field size.
Sourcepub fn set_max_buffer_size(&mut self, max_buf: usize) -> Result<()>
pub fn set_max_buffer_size(&mut self, max_buf: usize) -> Result<()>
Reallocates internal buffers to support the given maximum block size.
Any block size is accepted: processing is internally chunked into
sub-blocks of ≤ WAVENET_MAX_NUM_FRAMES (64) by process, matching
the kernel scratch buffer capacity. Call this to inform the model
of the negotiated CLAP/audio host block size so that internal ring
buffers are sized correctly.
If max_buf is smaller than the current capacity, this is a no-op.
If max_buf equals the current capacity, state variables are reset
and all buffers are zero-filled in-place — avoiding heap allocation
on the RT thread (F9 / RT-Safety).
Sourcepub fn reset(&mut self, _sample_rate: u32, max_buffer_size: usize) -> Result<()>
pub fn reset(&mut self, _sample_rate: u32, max_buffer_size: usize) -> Result<()>
Resets internal state for a new sample rate and max buffer size.
Sourcepub fn has_weights(&self) -> bool
pub fn has_weights(&self) -> bool
Returns whether weights have been loaded via set_weights.
Sourcepub fn set_layer_raw(&mut self, raw: Option<Value>)
pub fn set_layer_raw(&mut self, raw: Option<Value>)
Stores the raw layer JSON for FiLM config parsing during weight loading.
Source§impl<const CH: usize> WaveNetA2<CH>
impl<const CH: usize> WaveNetA2<CH>
Sourcepub fn set_weights(&mut self, weights: &[f32]) -> Result<(), String>
pub fn set_weights(&mut self, weights: &[f32]) -> Result<(), String>
Loads weights from a flat f32 slice in the exact A2 stream order.
§Weight order (mirrors a2_fast.cpp:196-282)
_rechannel: weightsCHf32 (no bias — matches C++ A2FastModel)- Per layer 0..22:
_conv: weightsCH*CH*Kf32 + biasCHf32_input_mixin: weightsCHf32 (no bias)_layer1x1: weightsCH*CHf32 (col-major) + biasCHf32
_head_rechannel: conv k=16 weights16*CHf32 + head_bias1f32head_scale: last f32 in the stream
§Acceptance criteria
- Calls
verify_exhaustion()— consumed count must equalweights.len(). - Returns a clear error if the weight stream is shorter or longer than expected.
Trait Implementations§
Source§impl<const CH: usize> NamModel for WaveNetA2<CH>
impl<const CH: usize> NamModel for WaveNetA2<CH>
Source§fn process(&mut self, input: &[f32], output: &mut [f32])
fn process(&mut self, input: &[f32], output: &mut [f32])
Source§fn prewarm(&mut self, _num_samples: usize)
fn prewarm(&mut self, _num_samples: usize)
prewarm).Source§fn prewarm_samples(&self) -> usize
fn prewarm_samples(&self) -> usize
Source§fn set_max_buffer_size(&mut self, max_buf: usize) -> Result<()>
fn set_max_buffer_size(&mut self, max_buf: usize) -> Result<()>
Source§fn reset(&mut self, _sample_rate: u32, max_buffer_size: usize) -> Result<()>
fn reset(&mut self, _sample_rate: u32, max_buffer_size: usize) -> Result<()>
Source§fn prewarm_on_reset(&self) -> bool
fn prewarm_on_reset(&self) -> bool
reset(). Read moreSource§fn set_prewarm_on_reset(&mut self, val: bool)
fn set_prewarm_on_reset(&mut self, val: bool)
reset(). Read moreAuto Trait Implementations§
impl<const CH: usize> Freeze for WaveNetA2<CH>
impl<const CH: usize> RefUnwindSafe for WaveNetA2<CH>
impl<const CH: usize> Send for WaveNetA2<CH>
impl<const CH: usize> Sync for WaveNetA2<CH>
impl<const CH: usize> Unpin for WaveNetA2<CH>
impl<const CH: usize> UnsafeUnpin for WaveNetA2<CH>
impl<const CH: usize> UnwindSafe for WaveNetA2<CH>
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>. Box<dyn Any> can
then be further downcast into Box<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>. Rc<Any> 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.