Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
audio-opus-bsd
Opus codec (RFC 6716) encoder
and decoder. It wraps system libopus through the opus crate and
emits/consumes planar AudioFrames (from the audio-core-bsd dependency).
Encode and decode run on worker threads — this crate is deliberately not
real-time safe; decoded frames are handed to the RT audio thread through a
lock-free rtrb ring buffer.
The doc comments on each public item are the primary reference. This README is an overview only.
Overview
audio-opus-bsd is a standalone Opus codec crate: it depends only on
audio-core-bsd (the shared planar AudioFrame type) and the system libopus
library, and can be built and used independently of any larger audio framework.
It turns planar AudioFrames into Opus packets and back. Because
the opus crate is a thin FFI binding over libopus (which allocates and may
make syscalls), all encode/decode work is moved onto a dedicated worker thread.
The real-time audio thread touches only the lock-free rtrb::Consumer::pop —
never the codec. This is the standard RT-safety boundary for FFI-based audio
codecs: the real-time path stays wait-free and allocation-free.
Why a worker thread?
| Layer | What runs | Allocation |
|---|---|---|
| Worker thread | libopus encode/decode, planar↔interleaved conversion, packet framing | allowed |
| RT audio thread | rtrb::Consumer::pop of a pre-decoded AudioFrame |
none (wait-free) |
The rt_alloc_free integration test asserts the RT pop path performs zero
heap allocations.
Core types
| Type | Description |
|---|---|
AudioEncoder |
The public trait: encode(&[f32]) -> Result<Vec<u8>> (interleaved PCM in) + set_bitrate. |
AudioDecoder |
The public trait: decode(&[u8]) -> Result<Vec<f32>> (interleaved PCM out). |
OpusEncoder |
libopus-backed encoder; also offers encode_frame(&AudioFrame) (planar in). |
OpusDecoder |
libopus-backed decoder; also offers decode_frame(&[u8]) -> AudioFrame (planar out). |
OpusDecodeWorker |
Spawns a decode worker thread; returns a rtrb::Consumer<AudioFrame> for the RT side. |
OpusEncodeWorker |
Spawns an encode worker thread; returns a rtrb::Consumer<Vec<u8>> for the sender side. |
OpusError |
Error enum (thiserror-backed): Encode, Decode, InvalidSampleRate, UnsupportedChannels, BufferTooSmall, LayoutMismatch, WorkerThread. |
Result<T> |
Alias for core::result::Result<T, OpusError>. |
Opus supports only mono (1) or stereo (2) channels and the standard 8/12/16/24/48 kHz sample rates. The canonical encode/decode block is 960 samples/channel (20 ms @ 48 kHz).
Dependencies
| Dependency | Version | Purpose | License |
|---|---|---|---|
audio-core-bsd |
0.1.0 | AudioFrame (planar) I/O type |
BSD-2-Clause |
opus |
0.3 | libopus FFI binding (encode_float/decode_float) |
MIT OR Apache-2.0 |
rtrb |
0.3 | lock-free SPSC ring buffer (RT↔worker channel) | MIT OR Apache-2.0 |
thiserror |
2.0 | OpusError derive |
MIT OR Apache-2.0 |
proptest (dev) |
1.11.0 | property tests | MIT OR Apache-2.0 |
System dependency — libopus
This crate links the system libopus (audio/opus port on FreeBSD,
libopus-dev on Debian/Ubuntu). On FreeBSD:
On Debian/Ubuntu: sudo apt-get install -y libopus-dev.
Licensing: the opus Rust crate is MIT OR Apache-2.0; the system
library it links, libopus, is BSD-3-Clause. Both are permissive and
compatible with this crate's BSD-2-Clause license — no copyleft
contamination.
Status
0.x — experimental. The API is not yet frozen (pre-1.0 breaking changes are allowed before 1.0).
- edition: 2021
- MSRV: 1.85
- license: BSD-2-Clause
Example
Encode planar AudioFrames and decode them back through the worker-thread
boundary:
use ;
use AudioFrame;
// 20 ms mono block @ 48 kHz.
let mut enc = new?;
enc.set_bitrate;
let frame = silence;
let packet = enc.encode_frame?;
let mut dec = new?;
let back = dec.decode_frame?;
assert_eq!;
# Ok::
For the RT-safe path (decode on a worker, consume wait-free on the RT thread),
see OpusDecodeWorker and the examples/ directory.
Worker-thread safety boundary
OpusEncoder / OpusDecoder are not real-time safe — they perform FFI and
heap allocation, which is correct and intended. Always move them onto a worker
thread (OpusDecodeWorker / OpusEncodeWorker) and let the RT audio thread
consume only from the returned rtrb::Consumer. The rt_alloc_free and
worker_xrun integration tests verify this contract.
License
BSD-2-Clause. See LICENSE.