Skip to main content

Crate rusty_mp3

Crate rusty_mp3 

Source
Expand description

rusty_mp3 — an in-house, pure-Rust MP3 (MPEG-1/2/2.5 Audio Layer III) decoder and encoder. Zero dependencies, no C, no FFI.

Why in-house: the robust Rust MP3 crate (Symphonia) is MPL-2.0, which trips a no-copyleft license gate; the permissive one (puremp3) is incomplete, and every existing Rust MP3 encoder option is an FFI binding to LAME. MP3’s patents expired in 2017 and Layer III is exhaustively documented, so we built our own.

§Layout (the framework, built brick by brick)

  • shared: header (frame header), frame (side-info + types), bitio (MSB-first bit I/O), tables (ISO constant tables)
  • decode: side-info → reservoir → Huffman → scalefactors → requantize → stereo → antialias → IMDCT → synthesis filterbank → PCM
  • encode: analysis filterbank → MDCT → psychoacoustic model → two-loop quantizer → Huffman → bitstream

§Stream API

Mp3Decoder and Mp3Encoder are the packet-level entry points: push bytes/PCM in, pull frames/packets out. The pull calls follow FFmpeg’s EAGAIN/EOF drain protocol via Error::Again / Error::Eof — see error. The frame-level engines (Mp3Decode / Mp3Encode) are also public for callers that do their own framing.

Re-exports§

pub use decode::Mp3Decode;
pub use encode::Mp3Encode;
pub use error::Error;
pub use error::Result;

Modules§

bitio
MSB-first bit I/O over the main-data byte stream.
decode
MP3 decode pipeline.
encode
MP3 encode pipeline (the inverse of decode, plus a psychoacoustic model).
error
Dependency-free error type for the MP3 codec.
frame
Shared MP3 types: channel layout, block types, side-information, and the fixed structural constants. These are read by the decoder and written by the encoder, so they live in one place.
header
MP3 frame header — the 32-bit sync header that prefixes every frame.
tables
Constant tables defined by ISO/IEC 11172-3 (MPEG-1) and 13818-3 (MPEG-2).

Structs§

DecodedAudio
One decoded chunk of PCM — the output of Mp3Decoder::next_frame. samples is interleaved f32 in [-1, 1], samples.len() = per-channel samples × channels.
Mp3Decoder
Stream-level MP3 decoder: push raw bytes (packets may split/join frames — the decoder frame-syncs internally, skipping ID3 and garbage), then drain decoded PCM with next_frame.
Mp3Encoder
Stream-level MP3 encoder: accumulates per-channel PCM, emits one MP3 frame per 1152 samples per channel (576 for MPEG-2/2.5). MPEG-1/2/2.5, CBR or VBR, psychoacoustic noise shaping; mono, stereo, or per-frame mid/side joint stereo. Configured via Mp3EncoderConfig.
Mp3EncoderConfig
Configuration for Mp3Encoder.

Constants§

MAX_INPUT_AMPLITUDE
The largest input magnitude the encoder accepts: 8x (+18 dB over) full scale. Ordinary PCM, f32 overs included, is far inside it and passes through untouched. Beyond it, input is clamped – the rate loop was measured to fit up to 4096x full scale and to fail by 65536x, which used to surface as a panic in the reservoir assembly on hostile PCM (integer-valued “f32” samples, random bit patterns).

Functions§

decode_pipelined
Decode a complete MP3 stream with a two-stage pipeline across two threads.
encoder_header
Build the frame header from the input’s sample rate, channel count, and the configured CBR bitrate (VBR overrides the bitrate per frame later).
snap_bitrate
Snap a requested bitrate (kbps) to the nearest valid Layer III value for the MPEG version (the V1 and V2/2.5 bitrate tables differ).
vbr_quality_index
Map an ffmpeg/LAME-style VBR quality index (-q:a, 0 = best … 9 = smallest) to the peak-NMR target Mp3EncoderConfig::vbr_quality expects.