pub struct AmbeEncoder { /* private fields */ }Expand description
Top-level D-STAR AMBE 3600×2400 encoder.
Owns one instance of every per-stream state object. Not thread-safe; construct one per concurrent voice stream.
§Usage
use mbelib_rs::AmbeEncoder;
let mut encoder = AmbeEncoder::new();
// Feed 160-sample (20 ms at 8 kHz) frames of f32 PCM in [-1.0, 1.0).
let pcm: [f32; 160] = [0.0; 160];
let ambe_frame: [u8; 9] = encoder.encode_frame(&pcm);Implementations§
Source§impl AmbeEncoder
impl AmbeEncoder
Sourcepub fn new() -> Self
pub fn new() -> Self
Construct a fresh encoder using OP25’s single-frame
(look-back + sub-multiples) pitch tracker. Zero added
latency; each encode_frame call
commits pitch for the just-received frame.
This is the backwards-compatible default. Real-voice inputs
work well here because sub-multiples analysis resolves the
common octave ambiguities; pure-sine synthetic tests can
lose the 2P-vs-P disambiguation on settled tones. For the
full OP25 pitch pipeline (2-frame look-ahead DP), see
Self::new_with_lookahead — it costs 40 ms of latency and
an extra 2-frame warmup but matches OP25’s pitch decisions
on pure sines as well as voice.
Sourcepub fn new_with_lookahead() -> Self
pub fn new_with_lookahead() -> Self
Construct a fresh encoder WITH the 2-frame look-ahead DP
enabled. The first two encode_frame
calls return AMBE_SILENCE while the pipeline fills; frame
N-2’s pitch is committed on the third call (frame N).
Adds ≈40 ms end-to-end latency; matches OP25’s pitch-tracking
behaviour across pure sines and pitch transitions.
Sourcepub fn encode_frame(&mut self, pcm: &[f32]) -> [u8; 9]
pub fn encode_frame(&mut self, pcm: &[f32]) -> [u8; 9]
Encode one 20 ms PCM frame into a 9-byte AMBE wire frame.
pcmmust contain at least 160 f32 samples in[-1.0, 1.0). Convert fromi16by dividing by 32768.0.
§Output
Returns a 9-byte D-STAR AMBE frame. Silent or near-silent
input (pitch tracker confidence below SILENCE_CONFIDENCE)
short-circuits to the canonical AMBE_SILENCE pattern that
MMDVMHost and DVSI chips use for zero-audio frames, so silent
stretches stay wire-compatible with conformant receivers.
§Panics
Never panics under normal use. The look-ahead pipeline’s
internal invariant — self.pending is Some iff the encoder
was built with Self::new_with_lookahead — is enforced at
construction and never mutated afterwards; the unreachable
expect is kept as a defensive check rather than removed
entirely.
Sourcepub fn encode_frame_i16(&mut self, pcm: &[i16]) -> [u8; 9]
pub fn encode_frame_i16(&mut self, pcm: &[i16]) -> [u8; 9]
Convenience: encode from i16 PCM. Divides by 32768.0 first.