2个版本
0.2.0 | 2023年12月4日 |
---|---|
0.2.0-alpha.4 | 2022年12月2日 |
0.2.0-alpha.3 |
|
0.1.0 |
|
0.0.2 |
|
#62 in 音频
2,290 每月下载量
在 4 crate 中使用
325KB
6.5K SLoC
audio
一个用于在Rust中处理音频的crate。
它由几个部分组成,每个部分都可以独立使用
- audio-core - 核心crate,它定义了允许独立于内存布局与音频缓冲区交互的trait。
- audio - 此crate,它提供了一组高质量的音频缓冲区,实现了audio-core中提供的trait。
- audio-device - 一个用于以惯用的Rust方式与音频设备交互的crate。
- audio-generator - 一个用于生成音频的crate。
此crate提供的音频缓冲区具有零个或多个可迭代的通道。通道简单地说是一系列样本。在某一时刻每个通道内的样本构成一个帧。缓冲区可以以多种方式在内存中存储通道,详细内容将在下一节中介绍。
缓冲区
此crate提供了一些用于存储多通道音频缓冲区的struct。以下示例表示两个通道 [1, 2, 3, 4] 和
[5, 6, 7, 8] 在内存中的存储方式
- Dynamic:每个通道都存储在自己的堆分配中。因此
[1, 2, 3, 4]
和[5, 6, 7, 8]
。这可能在频繁调整大小时性能更好。通常更倾向于使用其他缓冲区类型以获得更好的CPU缓存局部性。 - Interleaved:每个通道的样本在一个堆分配中交错存储。因此
[1, 5, 2, 6, 3, 7, 4, 8]
。 - Sequential:每个通道在一个堆分配中依次存储。因此
[1, 2, 3, 4, 5, 6, 7, 8]
。
这些都实现了 Buf 和 BufMut 特性,允许库作者抽象任何特定格式。缓冲区的确切通道和帧数称为其 拓扑。以下示例分配了具有4帧和2通道的缓冲区。缓冲区在内存中的排列方式不同,但使用相同的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());
我们还支持 wrapping 外部缓冲区,以便它们可以与其他音频缓冲区交互操作。
示例: play-mp3
使用 minimp3-rs、cpal 和 rubato 播放mp3文件以进行重采样。
此示例可以处理任何通道和采样率配置。
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]);
为了方便,我们还提供了一些宏来构建各种动态音频缓冲区形式。这些主要用于测试。
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],
};