rodio

repository·master·Indexed 25 days ago

https://github.com/rustaudio/rodio

A high-level Rust audio playback and recording library (v0.22.2) that abstracts audio hardware interfacing and format decoding. It supports decoding audio files, synthesizing sounds, applying effects, and mixing. Rodio provides flexible resampling via ResampleConfig (polynomial and sinc interpolation) and a DecoderBuilder for custom settings like gapless playback and reliable seeking. It integrates with Symphonia by default and supports optional decoders for FLAC, MP3, Vorbis, and WAV.

Tokens
14.7K
Snippets
29
Records
65
Agent score
81%

What's inside rodio

  1. Hardware requirements for rodio

    master

    Rodio playback requires a CPU with:

    1. Hardware support for 32-bit floating point (f32).
    2. Atomic operations that are at least 32 bits wide.

    Failure to meet these requirements may result in the CPU being unable to maintain real-time audio playback.

  2. Migrate from rodio 0.22 to current github version

    master

    If you are upgrading from 0.22 to a newer version on GitHub, note the following breaking changes:

    Output Configuration

    stream::supported_output_configs has been removed. To select a non-default device configuration:

    1. Call device.supported_output_configs() directly.
    2. Pass the chosen SupportedStreamConfig to DeviceSinkBuilder::with_supported_config.

    Done Callback

    Done no longer decrements an Arc<AtomicUsize>. It now uses a callback.

    • New Signature: Done<I, F> where I: Source and F: FnMut(&mut I).
    • To retain old behavior: Replace the Arc<AtomicUsize> argument in Done::new with a closure: move |_| { number.fetch_sub(1, std::sync::atomic::Ordering::Relaxed) }.

    Zero Samples

    Zero::new_samples() now returns Result<Zero, ZeroError> instead of Zero. Passing a num_samples value that is not a multiple of channels will now return an Err instead of producing a mis-aligned source.

  3. Migrate from rodio 0.20 or earlier to 0.21.1

    master

    Upgrading from 0.20 or earlier to 0.21.1 involves several significant changes to features, output streams, and decoders.

    Features and Decoders

    • Playback: Playback logic is now a feature enabled by default. If you use default_features = false, you must explicitly add features = ["playback"] to your Cargo.toml.
    • Decoders: The default decoders are now Symphonia (MPL licensed). To use the old decoders, set default_features = false and enable claxon (FLAC), hound (WAV), and lewton (Ogg Vorbis) in Cargo.toml.

    OutputStream Changes

    • OutputStreamHandle has been removed.
    • OutputStreamHandle::play_raw is removed; use OutputStream.mixer().add() instead.
    • Recommended way to open a stream: Use OutputStreamBuilder::open_default_stream()?.
    • Legacy behavior: To replicate old behavior, use open_stream_or_fallback()? by manually getting the default device via cpal and passing it to OutputStreamBuilder::from_device(default_device)?.
    • Logging: The output stream now prints to stderr or logs on drop. To disable this, use stream.log_on_drop(false).

    Sink and SpatialSink

    • Replace Sink::try_new with Sink::connect_new, passing an &Mixer (obtained via OutputStream.mixer()).
    • Replace Sink::new_idle with Sink::new.

    Example Migration (0.20 to 0.21):

    Old (0.20):

    let (_stream, handle) = rodio::OutputStream::try_default()?;
    let player = rodio::Player::try_new(&handle)?;

    New (0.21):

    let stream_handle = rodio::OutputStreamBuilder::open_default_stream()?;
    let player = rodio::Player::connect_new(stream_handle.mixer());

    Decoder Changes

    • Decoder::new_mp4 no longer accepts an Mp4Type hint.
    • Symphonia decoders no longer assume sources are seekable. Use DecoderBuilder::with_seekable or try_from on a File. You no longer need BufReader.

    Example Migration (0.20 to 0.21):

    Old (0.20):

    let file = File::open("music.ogg")?;
    let reader = BufReader::new(file);
    let source = Decoder::new(reader);

    New (0.21):

    let file = File::open("music.ogg")?;
    let source = Decoder::try_from(file)?;

    Other Changes

    • DynamicMixer: Replace DynamicMixerController with Mixer and DynamicMixer with MixerSource.
    • Noise: Source::white and Source::pink are deprecated. Use WhiteUniform::new and Pink::new.
    • Source Trait:
      • current_frame_len is renamed to current_span_len.
      • The Source trait is no longer generic over sample types (f32, u16, i16). It now works exclusively with f32. Remove any sample type generics, SampleConvertor usage, or convert_samples calls.
  4. Cross-compile rodio for aarch64/arm on Debian-based systems

    master

    Cross-compiling can be difficult due to the alsa dependency. To cross-compile for aarch64 on a Debian-based system (like Ubuntu or Pop!_OS), follow these steps:

    1. Install the cross-build toolchain and clang: sudo apt-get install crossbuild-essential-arm64 clang
    2. Add the target to rustup: rustup target add aarch64-unknown-linux-gnu
    3. Enable the arm64 architecture in apt: sudo dpkg --add-architecture arm64
    4. Install the multi-arch version of the ALSA development library: sudo apt install libasound2-dev:arm64
    5. Build using pkg-config to point to the sysroot and specify the linker:
    PKG_CONFIG_SYSROOT_DIR=/usr/aarch64-linux-gnu RUSTFLAGS="-C linker=aarch64-linux-gnu-gcc" cargo build --target aarch64-unknown-linux-gnu
  5. Key improvements in rodio 0.21

    master

    The 0.21 release introduced several improvements to the API and functionality:

    API Improvements

    • Easier Configuration: Many components, such as the decoder and outputstream, can now be configured using builder patterns.
    • Simplified Types: Types are no longer generic over the sample type, making them easier to work with.
    • Safety: The library now issues warnings when audio might stop unexpectedly without the developer's intention.
    • Feature Overhaul: Features have been redesigned with better defaults.

    New Functionality

    • Effects: Added support for amplification (using decibels or perceptually), distortion, and a limiter.
    • Synthesis: Added many new noise generators.
    • Headless Mode: Ability to analyze audio or generate wav files without a dependency on cpal.
  6. Migrate from rodio 0.21.1 to 0.22

    master

    In version 0.22, several core types were renamed to better reflect their roles. Functionality remains identical, but you must update your code to use the new names:

    Old NameNew Name
    OutputStreamMixerDeviceSink
    OutputStreamBuilderDeviceSinkBuilder
    open_stream_or_fallbackopen_sink_or_fallback
    open_default_streamopen_default_sink
    open_streamopen_mixer
    SinkPlayer
    SpatialSinkSpatialPlayer
    StreamErrorOsSinkError

    Additionally:

    • output_to_wav is now wav_to_file and now takes ownership of the Source.
    • SamplesBuffer::new now requires ChannelCount and SampleRate as arguments. You can use the nz! macro for literals or NonZero::new() for runtime values.
  7. Configure a minimal build for audio processing without playback

    master

    If you need to decode or process audio in an environment without audio output (e.g., a headless server or a system without ALSA), you can build rodio without the cpal dependency.

    To do this, disable default features and explicitly enable the decoders you need (e.g., symphonia-all).

    [dependencies]
    rodio = { version = "0.22.1", default-features = false, features = ["symphonia-all"] }
  8. Install Linux dependencies for rodio

    master

    Rodio relies on cpal for playback. On Linux, the audio host selection order is PipeWire > PulseAudio > ALSA.

    Required Base Layer

    ALSA is always required. You must install the development headers:

    • Debian/Ubuntu: libasound2-dev
    • Fedora: alsa-lib-devel

    Optional Features

    • PulseAudio: Enabled by default. It uses pulseaudio-rs (pure Rust) and requires no extra development libraries.
    • PipeWire: Requires the pipewire feature. You must install these development libraries:
      • Debian/Ubuntu: libpipewire-0.3-dev and libdbus-1-dev
  9. How to play audio in rodio

    master

    Playing audio in rodio typically involves three steps:

    1. Get an OS-Sink handle: Obtain a handle to a physical device (e.g., the system default) using DeviceSinkBuilder::open_default_sink().
    2. Create a Source: Create an object representing the sound, such as a Decoder from a file, a sine wave, or a custom type implementing the Source trait.
    3. Add to the Sink: Add the source to the OS-Sink using the mixer() method on the sink handle.

    Note: Playback occurs in a separate background thread. If the OS-Sink handle is dropped, playback stops. You must ensure the handle (and the Player if using one) lives as long as you want the sound to play.

    use std::fs::File;
    use rodio::{Decoder, MixerDeviceSink, source::Source};
    
    // Get an OS-Sink handle to the default physical sound device.
    let handle = rodio::DeviceSinkBuilder::open_default_sink()
            .expect("open default audio stream");
    let player = rodio::Player::connect_new(&handle.mixer());
    
    // Load a sound from a file
    let file = File::open("examples/music.ogg").unwrap();
    
    // Decode that sound file into a source
    let source = Decoder::try_from(file).unwrap();
    
    // Play the sound directly on the device
    handle.mixer().add(source);
    
    // Keep the main thread alive while playing
    std::thread::sleep(std::time::Duration::from_secs(5));
  10. Understand DeviceSinkConfig

    master

    The DeviceSinkConfig struct describes the configuration of the OS-Sink. It contains:

    • channel_count(): The number of channels.
    • sample_rate(): The sample rate.
    • buffer_size(): The buffer size.
    • sample_format(): The sample format (e.g., F32, I16).