Expand description
Pure Rust AMBE 3600×2400 voice codec decoder for D-STAR digital radio.
The AMBE (Advanced Multi-Band Excitation) 3600×2400 codec compresses speech at 3600 bits/second with 2400 bits of voice data and 1200 bits of forward error correction (FEC). It is the mandatory voice codec for the JARL D-STAR digital radio standard, used in all D-STAR transceivers and reflectors worldwide.
Each voice frame is 9 bytes (72 bits), transmitted at 50 frames per second (20 ms per frame). The codec models speech as a sum of harmonically related sinusoids, with each band independently classified as voiced or unvoiced.
§Usage
use mbelib_rs::AmbeDecoder;
// Create one decoder per voice stream — it carries inter-frame state
// needed for delta decoding and phase-continuous synthesis.
let mut decoder = AmbeDecoder::new();
// Feed 9-byte AMBE frames from D-STAR VoiceFrame.ambe field.
let ambe_frame: [u8; 9] = [0; 9];
let pcm: [i16; 160] = decoder.decode_frame(&ambe_frame);
// Output: 160 samples at 8 kHz, 16-bit signed PCM (20 ms of audio).
assert_eq!(pcm.len(), 160);§Decode Pipeline
Each frame passes through these stages:
- Bit unpacking — 72-bit frame → 4 FEC codeword bitplanes
- Error correction — Golay(23,12) on C0 and C1 (3-error correction). AMBE 3600×2400 does not apply Hamming to C3; those 14 bits are copied verbatim into the parameter vector.
- Demodulation — LFSR descrambling of C1 using C0 seed
- Parameter extraction — 49 decoded bits → fundamental frequency, harmonic count, voiced/unvoiced decisions, spectral magnitudes. Frames with b0 in the erasure range (120..=123) or tone range (126..=127) trigger the same repeat/conceal path as Golay-C0 failures, since D-STAR does not use codec-level tone signaling.
- Spectral enhancement — adaptive amplitude weighting for clarity
- Adaptive smoothing — JMBE algorithms #111-116, gracefully damps spurious magnitudes/voicing decisions on noisy frames
- Frame muting check — comfort noise on excessive errors or sustained repeat frames (JMBE-compatible)
- Synthesis — voiced bands per-band cosine oscillators (with JMBE phase/amplitude interpolation for low harmonics) plus a single FFT-based unvoiced pass (JMBE algorithms #117-126)
- Output conversion — float PCM → i16 with SIMD-vectorized gain and clamping
Modules§
- validation
- Validation-only exposure of the internal quantize pipeline.
Structs§
- Ambe
Decoder - Stateful AMBE 3600×2400 voice frame decoder.
- Ambe
Encoder - Top-level D-STAR AMBE 3600×2400 encoder.
- Encoder
Buffers - Per-stream encoder working buffers.
- FftPlan
- Per-stream FFT planning cache.
- Pitch
Estimate - Result of a pitch-estimation pass on one 20 ms frame.
- Pitch
Tracker - Per-stream pitch-tracker state, matching OP25’s
pitch_estmember variables. All fields are prefixedprevby design — they’re the rolling history the look-back / cumulative-error tests consume. - Spectral
Amplitudes - Per-frame spectral amplitudes.
- VuvDecisions
- Per-frame V/UV decision vector.
- VuvState
- Per-stream V/UV state carried across frames.
Enums§
- Decode
Error - Errors that can occur during AMBE frame decoding.
Constants§
- MAX_
BANDS - Maximum number of V/UV bands (12 per AMBE spec).
- MAX_
HARMONICS - Maximum number of harmonic amplitudes (matches IMBE/AMBE L).
Functions§
- analyze_
frame - Ingest one 160-sample frame and run the front-end analysis.
- compute_
e_ p - Compute IMBE’s
E(p)detectability function for one 301-sample pitch-estimation buffer. - decode_
trace - Inspection helper for golden-vector validation.
- detect_
vuv - Stateless one-shot V/UV convenience wrapper.
- detect_
vuv_ and_ sa - Integrated V/UV + spectral amplitude extraction.
- extract_
spectral_ amplitudes - Extract harmonic amplitudes from the FFT half-spectrum.
- pack_
frame - Pack a 72-bit FEC-codeword array into a 9-byte AMBE wire frame.