# audio-codec-bsd
[](./LICENSE)
[](https://www.rust-lang.org)
A multi-format audio container decoder that decodes **FLAC**, **PCM**, and
**WAV** files into planar `AudioFrame`s (from the `audio-core-bsd`
dependency). It is a pure-Rust, worker-thread codec: file I/O and heap
allocation happen here, never on a real-time audio thread.
> The doc comments on each public item are the primary reference. This README is
> an overview only.
## Overview
`audio-codec-bsd` reads compressed and uncompressed audio containers and emits
planar frames (one contiguous slice per channel) ready to feed an audio graph or
ring buffer. It is deliberately **not real-time safe**: decoding runs on a worker
thread, and decoded frames are handed off to the RT thread through a lock-free
channel.
### Supported formats
| FLAC | lossless compressed | `symphonia` (MPL-2.0, pure Rust) |
| WAV | RIFF PCM / IEEE-float | `hound` (Apache-2.0/MIT, pure Rust) |
| PCM | raw headerless little-endian | planned |
Both `WavDecoder` (hound) and `SymphoniaDecoder` (symphonia) are implemented.
The [`open`] factory sniffs the leading magic bytes and returns the matching
decoder, so callers do not need to know the format ahead of time.
## Core types
| `ContainerDecoder` | The public trait: `open()` a path, then iterate `next_frame()` → planar `AudioFrame`. |
| `StreamInfo` | Stream metadata populated at open time (format / rate / channels / bit depth / length). |
| `FormatKind` | Supported container: `Flac`, `Wav`, `Pcm`. |
| `CodecError` | Error enum (thiserror-backed): `Io`, `Format`, `Decode`, `Eof`, … |
| `Result<T>` | Alias for `core::result::Result<T, CodecError>`. |
## Dependencies
| `audio-core-bsd` | 0.1.0 | `AudioFrame` output type | BSD-2-Clause |
| `thiserror` | 2.0 | `CodecError` derive | MIT OR Apache-2.0 |
| `hound` | 3.5 | WAV / RIFF PCM + IEEE-float decode (`WavDecoder`) | Apache-2.0/MIT |
| `symphonia` | 0.6 | FLAC + PCM container decode (`SymphoniaDecoder`) | MPL-2.0 |
| `proptest` (dev) | 1.11.0 | property tests | MIT OR Apache-2.0 |
> `symphonia` is **MPL-2.0**. MPL-2.0 permits static/dynamic linking from a
> BSD-2-Clause crate without copyleft contamination, provided that any *modified*
> symphonia source files are republished under MPL-2.0. Unmodified use (the
> default) imposes only a notice obligation.
## Status
**0.x — experimental.** The API is not yet frozen. WAV and FLAC decode are
implemented; raw headerless PCM is planned.
- edition: 2021
- MSRV: 1.85
- license: BSD-2-Clause
## Example
Open a container by magic-byte sniffing and drain it frame by frame into planar
`AudioFrame`s:
```rust,no_run
use audio_codec_bsd::open;
use std::path::Path;
let mut dec = open(Path::new("song.flac"))?;
let _info = dec.open(Path::new("song.flac"))?;
while let Some(_frame) = dec.next_frame()? {
// push _frame into a lock-free ring for the RT thread.
}
# Ok::<(), audio_codec_bsd::CodecError>(())
```
## Worker-thread safety boundary
`ContainerDecoder` is **not** real-time safe. Implementations perform file I/O
and heap allocation — that is correct and intended. Decoded frames must be
handed to a lock-free ring buffer or similar channel so the RT audio thread
never blocks on or directly calls into this crate.
## License
BSD-2-Clause. See [`LICENSE`](./LICENSE).