# Awedio   [![Docs Passing]][docs.rs] [![Latest Version]][crates.io]
A low-overhead and adaptable audio playback library for Rust.
By default supports playing mp3, wav, flac, aac, ogg, qoa and all other formats
supported by [Symphonia](https://crates.io/crates/symphonia).
## Examples
Play a single sound file:
```rust ignore
let (mut manager, backend) = awedio::start()?;
manager.play(awedio::sounds::open_file("test.wav")?);
```
Play a sound with adjustable volume controllable after playback has started:
```rust ignore
use awedio::Sound;
let (mut manager, backend) = awedio::start()?;
let (sound, mut controller) = awedio::sounds::SineWav::new(400.0)
.with_adjustable_volume_of(0.25)
.pausable()
.controllable();
manager.play(Box::new(sound));
std::thread::sleep(std::time::Duration::from_millis(100));
controller.set_volume(0.5);
std::thread::sleep(std::time::Duration::from_millis(100));
controller.set_paused(true);
```
## Design Goals
- Modular design. Easy to add new backends, wrappers and decoders.
- Very low overhead. For example, a Wav file with i16 samples with the same
same sample rate as the output device will have samples sent to the backend
unchanged.
- Only pay the performance cost of features if they are needed. For example
pausability, volume adjustment, or controlling a sound after playback has
started are all added to a Sound only as needed. This is done by wrapping
types that implement `Sound` similar to `Iterator` in the standard library.
- Usable in low resource environments such as the esp32 microcontroller.
Currently does require std.
- Samples are i16 for simplicity at least for now (if this prevents you from
using this library please let me know your use case)
## API Overview
- [Sound] trait - Provides samples of a sound to be played. Has
functions to modify sounds with wrappers.
- [Manager] - Play Sounds to a backend.
- [SoundList] - A sequence of Sounds to play one after the other.
## Current backends
- [cpal] - For popular environments such as Linux,
Windows, Mac OS, Android... Enabled by the `cpal` feature (on by default).
- [esp32][awedio_esp32] - For esp32 microcontrollers using
esp-idf. Implemented in its [own crate][awedio_esp32].
Backends are implemented by pulling samples from the [Renderer].
## Cargo Features
- `async`: Enable async features that depend on
[tokio-sync](https://docs.rs/tokio/latest/tokio/sync/index.html)
- `cpal`: Enable the [cpal] backend.
- `symphonia-all`: Enable all formats and codecs supported by
[Symphonia](https://crates.io/crates/symphonia)
- `symphonia-`: All feature flags of symphonia are re-exported with the `symphonia-` prefix.
- `hound-wav`: Enable wav decoding using [Hound](https://crates.io/crates/hound)
- `rmp3-mp3`: Enable mp3 decoding using [rmp3](https://crates.io/crates/rmp3)
- `qoa`: Enable qoa decoding using [qoaudio](https://crates.io/crates/qoaudio)
By default all features are enabled excluding `hound-wav` and `rmp3-mp3`
since symphonia handles those formats by default.
Depending libraries should disable default features.
## Motivation
Built for creating activities for [10 Buttons](https://www.10Buttons.com), a
screen-less tablet for kids. Purposefully kept generic to be usable in other
contexts.
## Alternatives and Inspiration
Thanks to the following audio playback libraries which inspired and were
a reference for this library:
- [Rodio](https://docs.rs/rodio/)
- Very popular crate for audio playback with Rust.
- Tightly coupled to cpal. Awedio allows for easy integration with cpal or
other backends.
- Has a [Sink](https://docs.rs/rodio/latest/rodio/#sink) which is similar to
`SoundList::new().pausable().with_adjustable_volume().controllable()`...
- Mixer converts everything to an f32. Awedio uses i16 consistently.
- Sources have the concept of a frame length where metadata should not change
but this does not work well for some wrappers such as Speed.
- Uses the standard Iterator trait for its Source. Awedio's Sound is its own
enum that handles Metadata Changes, Pausing and Finishing sounds.
- Does not have a way to propagate errors through Sources. Awedio's sound
returns a result so errors can be explicitly handled if desired.
- [Kira](https://docs.rs/kira/)
- Has very nice API for tweening and effects.
- [Sound](https://docs.rs/kira/latest/kira/sound/trait.Sound.html) trait
requires a left/right track instead of supporting 1 or N tracks.
- Samples are all f32. Thus frames are always 8 bytes. A frame for a mono
Sound in awedio is only 2 bytes.
- Uses symphonia for audio format parsing and has several internal buffers
requiring more memory. Awedio optionally uses symphonia or other decoding
crates with less buffering required.
- All samples are resampled based on the timestamp and sample rate. Awedio
only resamples if the source and output rates do not match.
## License
This project is licensed under either of
[Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0) or
[MIT license](https://opensource.org/licenses/MIT) at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall
be dual licensed as above, without any additional terms or conditions.
[Latest Version]: https://img.shields.io/crates/v/awedio.svg
[crates.io]: https://crates.io/crates/awedio
[Docs Passing]: https://img.shields.io/docsrs/awedio.svg
[docs.rs]: https://docs.rs/awedio
[cpal]: https://crates.io/crates/cpal
[awedio_esp32]: https://crates.io/crates/awedio_esp32
[Sound]: https://docs.rs/awedio/latest/awedio/trait.Sound.html
[Manager]: https://docs.rs/awedio/latest/awedio/manager/struct.Manager.html
[SoundList]: https://docs.rs/awedio/latest/awedio/sounds/struct.SoundList.html
[Renderer]: https://docs.rs/awedio/latest/awedio/manager/struct.Renderer.html