https://github.com/udoprog/audio
A crate for working with audio in Rust
https://github.com/udoprog/audio
alsa audio rust wasapi
Last synced: 2 months ago
JSON representation
A crate for working with audio in Rust
- Host: GitHub
- URL: https://github.com/udoprog/audio
- Owner: udoprog
- License: apache-2.0
- Created: 2021-03-26T23:40:51.000Z (about 4 years ago)
- Default Branch: main
- Last Pushed: 2024-09-12T14:41:01.000Z (9 months ago)
- Last Synced: 2024-12-19T09:07:54.031Z (6 months ago)
- Topics: alsa, audio, rust, wasapi
- Language: Rust
- Homepage:
- Size: 1.1 MB
- Stars: 78
- Watchers: 3
- Forks: 11
- Open Issues: 17
-
Metadata Files:
- Readme: README.md
- License: LICENSE-APACHE
Awesome Lists containing this project
README
# audio
[
](https://github.com/udoprog/audio)
[](https://crates.io/crates/audio)
[](https://docs.rs/audio)
[](https://github.com/udoprog/audio/actions?query=branch%3Amain)
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
interacting with audio buffers independent of their layout in memory.
* [audio] - This crate, which provides a collection of high-quality audio
buffers which implements the traits provided in [audio-core].
* [audio-device] - A crate for interacting with audio devices in idiomatic
Rust.
* [audio-generator] - A crate for generating audio.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.
## 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,
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.
* [Interleaved]: samples of each channel are interleaved in one heap
allocation. So `[1, 5, 2, 6, 3, 7, 4, 8]`.
* [Sequential]: each channel is stored one after the other in one heap
allocation. So `[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.```rust
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][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.
```bash
cargo run --release --package audio-examples --bin play-mp3 -- path/to/file.mp3
```
## Examples
```rust
use rand::Rng;let mut buf = audio::buf::Dynamic::::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.```rust
let mut buf = audio::buf::Dynamic::::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