phonic is a cross-platform audio playback and DSP library for Rust, providing a flexible, low-latency audio engine and related tools for games and music applications.
Originally developed for the AFEC-Explorer app, phonic initially addressed the need for precise playback position monitoring not found in other Rust audio libraries. It is now also used as the default sample playback engine for the experimental algorithmic sequencer pattrns.
[!NOTE]
phonic has not yet reached a stable version, so expect breaking changes. The effects API in particular is a work in progress and will likely change in the future.
Features
-
Cross-Platform Audio Playback:
- Play audio on Windows, macOS, and Linux via cpal.
- WebAssembly support for in-browser audio via emscripten.
- Optional WAV file output device for rendering computed audio to a file instead of playing it back.
-
Flexible Audio Source Handling:
- Play, seek, stop, and mix preloaded (buffered) or streamed (on-the-fly decoded) audio files.
- Support for most common audio formats through Symphonia.
- Automatic resampling and channel mapping via a fast custom resampler and Rubato.
- Seamless loop playback using loop points from WAV and FLAC files.
-
Advanced Playback Control:
- Sample-precise scheduling for accurate sequencing.
- Real-time monitoring of playback position and status for GUI integration.
- Dynamic control over volume, panning, and playback speed.
-
Custom Synthesis and DSPs:
- Build simple or complex DSP graphs by routing audio through optional sub-mixers.
- Play completely custom-built synthesizers or use the optional dasp integration for creating synth sources.
- Apply custom-built DSP effects or use built-in effects (reverb, chorus, filter, compressor).
Documentation
Rust docs for the last published versions are available at https://docs.rs/phonic
Examples
See /examples directory for more examples.
File Playback with Monitoring
Play, seek and stop audio files on the default audio output device.
Monitor playback status of playing files.
use phonic::{
DefaultOutputDevice, Player, PlaybackStatusEvent, Error,
FilePlaybackOptions, SynthPlaybackOptions
};
fn main() -> Result<(), Error> {
let output_device = DefaultOutputDevice::open()?;
let (playback_status_sender, playback_status_receiver) = crossbeam_channel::bounded(32);
let mut player = Player::new(output_device, playback_status_sender);
let small_file_id = player.play_file(
"PATH_TO/some_small_file.wav",
FilePlaybackOptions::default())?;
let long_file_id = player.play_file(
"PATH_TO/some_long_file.mp3",
FilePlaybackOptions::default()
.streamed()
.volume_db(-6.0)
.speed(0.5)
.repeat(2),
)?;
std::thread::spawn(move || {
while let Ok(event) = playback_status_receiver.recv() {
match event {
PlaybackStatusEvent::Position { id, path, context: _, position } => {
println!("Playback pos of source #{id} '{path}': {pos}",
pos = position.as_secs_f32()
);
}
PlaybackStatusEvent::Stopped { id, path, context: _, exhausted, } => {
if exhausted {
println!("Playback of #{id} '{path}' finished");
} else {
println!("Playback of #{id} '{path}' was stopped");
}
}
}
}
});
player.seek_source(long_file_id, std::time::Duration::from_secs(5), None)?;
player.stop_source(small_file_id, None)?;
player.stop_all_sources()?;
player.play_file("PATH_TO/boom.wav", FilePlaybackOptions::default())?;
Ok(())
}
File playback with DSP Effects in a Mixer Graph
Create complex audio processing chains by routing sources through different mixers and effects.
use phonic::{
DefaultOutputDevice, Player, Error, FilePlaybackOptions,
effects::{ChorusEffect, ReverbEffect}
};
fn main() -> Result<(), Error> {
let mut player = Player::new(DefaultOutputDevice::open()?, None);
player.add_effect(ReverbEffect::with_parameters(0.6, 0.8), None)?;
let chorus_mixer_id = player.add_mixer(None)?;
player.add_effect(ChorusEffect::default(), chorus_mixer_id)?;
player.play_file(
"PATH_TO/some_file.wav",
FilePlaybackOptions::default(),
)?;
player.play_file(
"PATH_TO/another_file.wav",
FilePlaybackOptions::default().target_mixer(chorus_mixer_id),
)?;
Ok(())
}
Contributing
Patches are welcome! Please fork the latest git repository and create a feature or bugfix branch.
License
phonic is distributed under the terms of the GNU Affero General Public License V3.