AudioSamples Streaming
Chunk-based audio streaming in Rust using audio_samples
Chunk-based audio streaming for Rust. Reads and writes AudioSamples buffers through a common trait interface; WAV files, FLAC files, hardware devices, rodio, and async runtimes all speak the same language.
Core concepts
Two traits drive everything:
AudioStream— pull source.fill_chunk(&mut buffer)returnsOk(Some(n))per chunk,Ok(None)when exhausted.AudioSink— push destination.write_chunk(&buffer), thenfinalize()when done.
A pre-allocated AudioSamples buffer is passed to every call. No per-chunk allocation.
Sources and sinks
| Type | Direction | Feature |
|---|---|---|
WavFileStream |
source | wav |
WavFileSink |
sink | wav |
FlacFileStream |
source | flac |
DeviceCapture |
source | device |
DevicePlayback |
sink | device |
RodioSource |
source adapter | rodio |
AsyncAudioStream |
stream adapter | async |
Quick start
WAV to WAV — read a WAV file chunk by chunk and write it out, optionally processing each chunk in between:
use AudioSamples;
use ;
use ;
let mut source = open?;
let mut sink = create?;
let mut buffer = zeros_multi_channel;
run?;
sink.finalize?;
Choosing output bit depth — use create_typed when you need 24-bit or 32-bit integer output:
use WavFileSink;
use ValidatedSampleType;
let sink = create_typed?;
Device playback — stream a WAV file to speakers with a 10 ms target period:
use ;
use Duration;
let mut source = open?;
let mut sink = from_default_output?;
let mut buffer = zeros_multi_channel;
run?;
sink.finalize?;
Device capture — record the microphone to a WAV file using device-reported format:
use ;
use Duration;
let mut source = from_default_input?;
let mut sink = create?;
let mut buffer = zeros_multi_channel;
while let Some = source.fill_chunk?
sink.finalize?;
Device I/O and low-latency use
Both DeviceCapture and DevicePlayback are built for low-latency work:
-
Lock-free data path — rtrb SPSC ring buffer between the cpal callback and the application thread. No locks cross the real-time boundary.
-
Condvar notification — the application thread sleeps on a condvar; the RT callback wakes it immediately. No spin-sleep.
-
Period size control — pass
Some(Duration)to request a target callback period.Noneuses the driver default. Shorter periods mean lower latency but require more stable scheduling. -
RT thread priority — on Linux, the callback thread attempts
SCHED_FIFOpriority on its first invocation. This silently fails withoutCAP_SYS_NICEor rtkit access. For production, add the audio group to/etc/security/limits.d/audio.conf:@audio - rtprio 95 @audio - memlock unlimited -
Xrun counting —
.xruns()returns the cumulative count of capture overflows and playback underruns. Non-zero means lost audio; increase the period or reduce processing load to eliminate them.
Typical period targets
target_latency |
Suitability |
|---|---|
None |
General use, file playback |
from_millis(10) |
Applications, monitoring |
from_millis(5) |
Live processing, plugin hosts |
from_millis(2) |
Professional; requires RT scheduling and JACK/PipeWire |
FLAC
FlacFileStream decodes the full file into memory at construction, then streams from that buffer with no per-chunk allocation. This is appropriate for most file sizes; a 5-minute stereo 24-bit/48 kHz file is roughly 170 MB decoded as f32.
use FlacFileStream;
let mut source = open?;
println!;
Features
[]
= { = "...", = ["wav", "device"] }
| Feature | Enables |
|---|---|
wav |
WavFileStream, WavFileSink |
flac |
FlacFileStream |
device |
DeviceCapture, DevicePlayback via cpal |
rodio |
RodioSource adapter |
async |
AsyncAudioStream adapter |
No features are enabled by default.
Examples
Run any example with cargo run --example <name> --features <features>:
| Example | Features | Description |
|---|---|---|
file_to_file |
wav |
WAV → WAV via pipeline::run |
manual_loop |
wav |
Manual chunk loop with processing hooks |
device_playback |
device,wav |
Stream WAV to speakers |
device_capture |
device,wav |
Record microphone to WAV |
device_passthrough |
device |
Real-time mic → speakers |
rodio_source |
rodio,wav |
Stream WAV via rodio |
async_stream |
async,wav |
WAV as async stream |
Contributing
Contributions are welcome. Please submit a pull request and see CONTRIBUTING.md for guidance.