Expand description
LAC — Lo Audio Codec.
Lossless audio codec targeting FLAC-class compression. Integer-only, bit-exact, streaming-oriented. Scope:
- Input: signed 24-bit PCM (values in
[-2^23, 2^23 − 1]), sample rate is caller-specified and not encoded in the stream — the container or transport carries it. - Channels: mono per encoded stream. Stereo is delivered as two independent mono streams (e.g., two QUIC streams in a streaming context); cross-channel decorrelation is explicitly out of scope.
- Frames: self-contained. Each frame decodes independently — no cross-frame state. A lost or corrupt frame never affects subsequent frames.
§Pipeline
Encode: samples → LPC analysis → residuals → partitioned Rice coding → frame bytes. Decode is the exact inverse.
- LPC: Levinson-Durbin at any order in
[0, 32]. Order 0 is verbatim mode (residuals equal the raw samples). - Rice: residuals split into
2^partition_orderequal partitions withpartition_order ∈ [0, 7](1 to 128 partitions). Each partition chooses its own Rice parameterk ∈ [0, 23].
Both selections are made by the encoder via exhaustive search over the combinations whose partition count evenly divides the frame size.
§Error handling
Decode returns Err(DecodeError) on any structural failure (bad sync, invalid
header fields, truncated buffer). Callers are expected to substitute
frame_sample_count zeros (or equivalent silence) for the frame period —
never propagate partial state.
§no_std
The library is #![no_std] with a dependency on the alloc crate for
Vec-backed buffers. Targets with an allocator (std OSes, WASI/WASM,
embedded with heap) all link without feature flags. True bare-metal
(no allocator) is unsupported because variable-length residual and
coefficient buffers are fundamental to the codec. DecodeError
implements core::error::Error (stable since Rust 1.81), so
?-propagation through Result-returning traits works in both std
and no_std contexts.
§Wire-format touchpoints
The normative wire format lives in Specification.md; its implementation is
split across three crate-private modules by concern. Any future
wire-format revision (CRC tag, version flag, new partition mode, …)
touches at least frame plus whichever module owns the new bits.
frame— fixed header layout (sync word,prediction_order,partition_order,coefficient_shift,frame_sample_count, LPC coefficients) plus synthesis.parse_header,encode_frame,decode_frame, andAudioFrameHeaderall live here.rice(crate-private) — partitioned Rice bitstream. Owns the 5-bit per-partitionkfield, the zigzag mapping and its inverse, and theq > u32::MAX >> krejection bound from spec §4.2.bit_io(crate-private) — MSB-first bit reader / writer primitives. Byte-level packing semantics (first bit → bit 7 of first byte) live here; bothframeandriceare clients.
When reading the spec alongside the source, §3 maps to frame,
§4 to rice, and the bit-order conventions of §2 / §4 to bit_io.
Re-exports§
pub use frame::AudioFrameHeader;pub use frame::DecodeError;pub use frame::SYNC_WORD;pub use frame::decode_frame;pub use frame::decode_frame_into;pub use frame::encode_frame;pub use frame::encode_frame_into;pub use frame::parse_header;
Modules§
- frame
- Frame encode and decode.
Constants§
- MAX_
COEFFICIENT_ SHIFT - Maximum supported
coefficient_shift. At this value, coefficients span real-value range[−32, 32)— far beyond anything audio produces in practice. The bitstream decoder rejects larger values. - MAX_
LPC_ ORDER - Maximum supported LPC prediction order.
- MAX_
PARTITION_ ORDER - Maximum supported partition order.
partition_count = 1 << partition_order. - MAX_
RICE_ K - Maximum Rice parameter
k.