mousiki
An Opus decoder library in Rust, ported from the Go implementation in pion/opus. The core crate is #![no_std] and performs zero heap allocations.
Capabilities and limitations (current)
- Mono only; stereo is not supported yet.
- SILK-only mode; Hybrid and CELT are not supported yet.
- Single-frame packets only; multi-frame/variable-frame packets currently return “unsupported”.
- Output is 48 kHz PCM:
- Either
i16little-endian (LE) orf32, depending on the API you call. - A 20 ms frame yields 960 samples (mono), i.e., 1920 bytes for
i16output.
- Either
Quick start
Run the examples
- Decode Ogg Opus (mono, SILK-only) to a PCM file:
- Play directly (requires an audio output device; uses
cpal):
Use in your code
The snippet below decodes a single Opus packet into i16 PCM (mono, 48 kHz):
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:
use Decoder;
let packet: & = /* your Opus packet */;
let mut pcm_f32 = ;
let mut decoder = new;
let = decoder.decode_float32?;
assert!;
Tip: If your input is an Ogg-encapsulated Opus stream, see the example oggreader usage to extract raw Opus packets before decoding.
Compatibility and roadmap
- Target environments: no_std, constrained memory, real-time systems, no dynamic allocation.
- Implemented: SILK-only, mono, single-frame packets, 48 kHz output, basic examples (decode/playback).
- Planned:
- Stereo support.
- Hybrid/CELT decode paths.
- Richer frame structures (multi-frame/variable-frame) support.
License and acknowledgements
- License: MIT (see
LICENSE). - Thanks to the upstream
pion/opus(Go) implementation and the community.