A crate for working with audio in Rust
audio
A crate for working with audio in Rust.
This is made up of several parts, each can be used independently of each other:
- [audio-core] - The core crate, which defines traits that allows for
- [audio] - This crate, which provides a collection of high-quality audio
- [audio-device] - A crate for interacting with audio devices in idiomatic
- [audio-generator] - A crate for generating audio.
Buffers
This crate provides several structs for storing buffers of multichannel audio. The examples represent how the two channels [1, 2, 3, 4] and [5, 6, 7, 8] are stored in memory:
- [Dynamic]: each channel is stored in its own heap allocation. So
[1, 2,
[5, 6, 7, 8]. This may be more performant when resizing
freqently. Generally prefer one of the other buffer types for better CPU
cache locality.
- [Interleaved]: samples of each channel are interleaved in one heap
[1, 5, 2, 6, 3, 7, 4, 8].
- [Sequential]: each channel is stored one after the other in one heap
[1, 2, 3, 4, 5, 6, 7, 8].
These all implement the [Buf] and [BufMut] traits, allowing library authors to abstract over any one specific format. The exact channel and frame count of a buffer is known as its topology. The following example allocates buffers with 4 frames and 2 channels. The buffers are arranged in memory differently, but data is copied into them using the same API.
use audio::{BufMut, ChannelMut};
let mut dynamic = audio::dynamic![[0i16; 4]; 2]; let mut interleaved = audio::interleaved![[0i16; 4]; 2]; let mut sequential = audio::sequential![[0i16; 4]; 2];
audio::channel::copyiter(0i16.., dynamic.getmut(0).unwrap()); audio::channel::copyiter(0i16.., interleaved.getmut(0).unwrap()); audio::channel::copyiter(0i16.., sequential.getmut(0).unwrap());
We also support [wrapping][wrap] external buffers so that they can interoperate like other audio buffers.
Example: [play-mp3]
Play an mp3 file with [minimp3-rs], [cpal], and [rubato] for resampling.
This example can handle with any channel and sample rate configuration.
cargo run --release --package audio-examples --bin play-mp3 -- path/to/file.mp3
Examples
use rand::Rng;
let mut buf = audio::buf::Dynamic::<f32>::new();
buf.resize_channels(2); buf.resize_frames(2048);
/// Fill both channels with random noise. let mut rng = rand::thread_rng(); rng.fill(&mut buf[0]); rng.fill(&mut buf[1]);
For convenience we also provide several macros for constructing various forms of dynamic audio buffers. These should mostly be used for testing.
let mut buf = audio::buf::Dynamic::<f32>::with_topology(4, 8);
for mut channel in &mut buf { for f in channel.iter_mut() { *f = 2.0; } }
assert_eq! { buf, audio::dynamic![[2.0; 8]; 4], };
assert_eq! { buf, audio::dynamic![[2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0]; 4], };
[audio-core]: https://docs.rs/audio-core [audio-device]: https://docs.rs/audio-device [audio-generator]: https://docs.rs/audio-generator [audio]: https://docs.rs/audio [Buf]: https://docs.rs/audio-core/latest/audio_core/trait.Buf.html [BufMut]: https://docs.rs/audio-core/latest/audio_core/trait.BufMut.html [cpal]: https://github.com/RustAudio/cpal [Dynamic::resize]: https://docs.rs/audio/latest/audio/dynamic/struct.Dynamic.html#method.resize [dynamic!]: https://docs.rs/audio/latest/audio/macros/macro.dynamic.html [Dynamic]: https://docs.rs/audio/latest/audio/dynamic/struct.Dynamic.html [Interleaved]: https://docs.rs/audio/latest/audio/interleaved/struct.Interleaved.html [minimp3-rs]: https://github.com/germangb/minimp3-rs [play-mp3]: https://github.com/udoprog/audio/tree/main/examples/src/bin/play-mp3.rs [rubato]: https://github.com/HEnquist/rubato [Sequential]: https://docs.rs/audio/latest/audio/sequential/struct.Sequential.html [wrap]: https://docs.rs/audio/latest/audio/wrap/index.html