A crate for working with audio in Rust.
This is made up of several parts, each can be used independently of each other:
Audio buffers provided by this crate have zero or more channels that can be iterated over. A channel is simply a sequence of samples. The samples within each channel at one moment in time are a frame. A buffer can store channels in various ways in memory, as detailed in the next section.
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:
[1, 2, 3, 4]
and [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.[1, 5, 2, 6, 3, 7, 4, 8]
.[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::copy_iter(0i16.., dynamic.get_mut(0).unwrap());
audio::channel::copy_iter(0i16.., interleaved.get_mut(0).unwrap());
audio::channel::copy_iter(0i16.., sequential.get_mut(0).unwrap());
We also support wrapping external buffers so that they can interoperate like other audio buffers.
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
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],
};