mousiki
A Rust port of the Xiph opus-c reference implementation. The core crate is
#![no_std] and uses alloc (some APIs allocate).
Known gaps
- Fixed-point decode backend
Quick start
Run the examples
- Decode Ogg Opus (SILK-only path used by
decoder::Decoder) to a PCM file:
- Play directly (requires an audio output device; uses
cpal):
- Round-trip a full 48 kHz stereo PCM sample through the trivial encoder/decoder:
- Convert the raw PCM output to WAV for playback:
Run the tests
- Full test suite:
- Default-build golden regression check for the trivial 48 kHz stereo round-trip configuration:
- Decode integration test (ported from
opus-c/tests/test_opus_decode.c):
- Opt-in to the fuzz-heavy decode section (longer runtime), or to strict final-range checks:
TEST_OPUS_FUZZ=1
TEST_OPUS_STRICT_FINAL_RANGE=1
- DRED vector validation (optional; vectors are distributed separately):
# Fetch vectors into testdata/dred_vectors (requires DRED_VECTORS_URL).
# Run the vector checks (uses DRED_VECTORS_PATH or testdata/dred_vectors).
# If deep_plc_weights is disabled, set DNN_BLOB or pass --dnn-blob.
DRED_VECTORS_PATH=testdata/dred_vectors
Fuzzing (manual/on-demand)
Fuzzing uses cargo-fuzz and is not part of CI by default.
Seed corpus lives in fuzz/corpus/decode_fuzzer/.
Use in your code
The preferred high-level API is exported at the crate root and wraps the full Opus front-end (SILK/CELT/Hybrid, stereo) with typed enums and method-based state:
use ;
const SAMPLE_RATE: u32 = 48_000;
const FRAME_SIZE: usize = 960;
const MAX_FRAME_SIZE: usize = 6 * 960;
const MAX_PACKET_SIZE: usize = 3 * 1276;
let mut encoder = builder
.bitrate
.build?;
let mut decoder = new?;
let pcm_in = ;
let mut packet = ;
let packet_len = encoder.encode?;
let mut pcm_out = ;
let decoded = decoder.decode?;
let total_samples = decoded * Stereo.count;
let _decoded_pcm = &pcm_out;
If you need API parity with the C entry points, use
mousiki::c_style_api::*.
If you only need the lightweight SILK-only, single-frame decoder (mono,
48 kHz), use decoder::Decoder directly:
use Decoder;
// `packet` is a single Opus SILK-only, mono packet (already decontainerized; not an Ogg page).
let packet: & = /* your Opus packet */;
// Output buffer (20 ms -> 960 samples, each sample is 2 bytes for i16)
let mut pcm_bytes = ;
let mut decoder = new;
let = decoder.decode?;
assert!;
// `pcm_bytes` now contains 48 kHz i16 little-endian PCM data
For f32 output, use decode_float32 and a buffer of length 960 for a 20 ms frame.
For Ogg input, see the decode example and the mousiki::oggreader module to
extract raw Opus packets.
License and acknowledgements
- License: MIT (see
LICENSE). - Thanks to the upstream
pion/opus(Go) implementation and the community.