opus-decoder
A pure-Rust Opus decoder with no unsafe code and no FFI. Passes all 12 RFC 8251 conformance test vectors.
Features
- RFC 8251 conformant — all 12 official test vectors pass
opus_compare - All Opus modes — CELT, SILK, and Hybrid (SWB/FB)
- All output sample rates — 8, 12, 16, 24, 48 kHz
- Mono and stereo — including up/downmix
- Packet Loss Concealment (PLC) — CELT fade-out, SILK pitch extrapolation
- Multistream —
OpusMultistreamDecoderfor surround (5.1, 7.1) and call recording #![forbid(unsafe_code)]— throughout the correctness implementation- No FFI, no C dependencies — pure Rust
Quick Start
Add to Cargo.toml:
[]
= "0.1"
Decode a single packet
use ;
Packet Loss Concealment
// Pass an empty slice to trigger PLC
let mut pcm = vec!;
decoder.decode?; // generates concealment frame
Float output
let mut pcm_f32 = vec!;
decoder.decode_float?;
Multistream — call recording (2 speakers → stereo)
use OpusMultistreamDecoder;
// Two independent mono streams → stereo output
// Left channel: caller (Stream A), Right channel: callee (Stream B)
let mut decoder = new?;
let mut pcm = vec!;
decoder.decode?;
Multistream — 5.1 surround
let mut decoder = new?;
API Reference
OpusDecoder
sample_rate must be one of: 8000, 12000, 16000, 24000, 48000.
channels must be 1 or 2.
decode returns the number of samples decoded per channel.
An empty packet or fec: true triggers Packet Loss Concealment (PLC).
OpusMultistreamDecoder
mapping[i] = 255 silences output channel i.
The first nb_coupled_streams streams are stereo-coupled; the rest are mono.
OpusError
Conformance
All 12 RFC 8251 test vectors pass the opus_compare quality metric:
| Vector | Description | Result |
|---|---|---|
| tv01 | CELT stereo FB | ✅ PASS |
| tv02 | SILK NB 8 kHz mono | ✅ PASS |
| tv03 | SILK MB 12 kHz mono | ✅ PASS |
| tv04 | SILK WB 16 kHz mono | ✅ PASS |
| tv05 | Hybrid SWB transitions | ✅ PASS |
| tv06 | Hybrid FB transitions | ✅ PASS |
| tv07 | CELT mono FB | ✅ PASS |
| tv08 | SILK stereo + CELT NB stereo | ✅ PASS |
| tv09 | SILK→CELT transitions | ✅ PASS |
| tv10 | CeltOnly + Hybrid mix | ✅ PASS |
| tv11 | CELT stereo FB | ✅ PASS |
| tv12 | SILK bandwidth transitions | ✅ PASS |
Run conformance tests locally:
# Download test vectors
# Run all 12 vectors
for; do
OPUS_TESTVECTORS_DIR="testdata/opus_testvectors" \
OPUS_VECTOR=testvector \
|
done
Minimum Supported Rust Version (MSRV)
Rust 1.85 — enforced in CI.
Uses: std, thiserror. No nightly features.
Out of Scope
The following are intentionally not implemented in this crate:
- Encoder — decoder only
- Container parsing — Ogg/WebM demux belongs in a separate crate
- SIMD optimizations — correctness first; performance is a future phase
Implementation Notes
This crate is a pure Rust port of libopus based on RFC 6716 and RFC 8251, implemented function-by-function and verified against the reference libopus implementation. The floating-point decode path is used throughout (matching libopus float semantics).
Internal architecture:
lib.rs — public API, mode routing, mode transitions
├── celt/ — CELT decoder (MDCT, PVQ, band decode, anti-collapse, PLC)
├── silk/ — SILK decoder (NLSF→LPC, excitation, IIR/FIR resampler, PLC)
├── multistream.rs — OpusMultistreamDecoder
├── entropy.rs — Range coder (EcDec)
└── compare.rs — opus_compare quality metric port
Known Limitations
- Hybrid mode PLC uses SILK-only concealment (no CELT highband PLC)
- No fuzz harness yet (planned)
License
Licensed under either of:
at your option.
This crate ports algorithms from libopus, which is licensed under the BSD 3-Clause License.
Contributing
Conformance is the top priority. Any change must pass all 12 RFC 8251 test vectors before merging. Run: