Skip to content

Playing the same sound several times requires allocating a new buffer each time #141

Open

Description

@Darksonn

I've been looking at the various Rodio sources for a while and I'm unable to find any sources that allow reusing a buffer of sound.

The closest solution appears to be using SamplesBuffer and cloning the vector each time, but this is inefficient as it requires an allocation and deallocation for each played sound.

I believe this crate should contain a source that wraps a vector of samples in an Arc, allowing the allocated memory to be reused.

I've attached a sample implementation of such a source: main.rs.

Activity

  1. Xaeroxe commented on Oct 12, 2017

    @Xaeroxe
    Contributor

    @Darksonn Hey! We had a similar problem in the Amethyst game engine. What I chose to do was create an Arc of the raw encoded file data (Arc<Vec<u8>>) and then implement std::convert::AsRef<[u8]> for a wrapper structure over that Arc, then when I needed to play the sound I'd initialize a new std::io::Cursor over that structure and feed it into a new rodio::Decoder. I like this approach because it allows the in-memory representation to stay compressed with the original audio compression algorithm, audio compression algorithms can reduce the memory footprint of a sound by up to 10x in some instances.

  2. sinesc commented on Apr 22, 2018

    @sinesc

    I think this is a minimal example of the above approach. Thanks @Xaeroxe

    use rodio;
    use std::io;
    use std::convert::AsRef;
    
    pub struct Sound (Arc<Vec<u8>>);
    
    impl AsRef<[u8]> for Sound {
        fn as_ref(&self) -> &[u8] {
            &self.0
        }
    }
    
    impl Sound {
        pub fn load(filename: &str) -> io::Result<Sound> {
            use std::fs::File;
            let mut buf = Vec::new();
            let mut file = File::open(filename)?;
            file.read_to_end(&mut buf)?;
            Ok(Sound(Arc::new(buf)))
        }
        pub fn cursor(self: &Self) -> io::Cursor<Sound> {
            io::Cursor::new(Sound(self.0.clone()))
        }
        pub fn decoder(self: &Self) -> rodio::Decoder<io::Cursor<Sound>> {
            rodio::Decoder::new(self.cursor()).unwrap()
        }
    }
    
    ...
    
    rodio::play_raw(&device, sound.decoder().convert_samples());
  3. HastagGuigui commented on Aug 25, 2025

    @HastagGuigui

    This example snippet doesn't work in latest crate (especially play_raw)... Is there any alternative way to do this?

  4. roderickvd commented on Aug 25, 2025

    @roderickvd
    Member

    In #786 I will implement TryFrom<Arc<Vec<T>>> for Decoder and Box<Vec<T>> to make this easier.

  5. added a commit that references this issue on Sep 26, 2025
    128b718
  6. added a commit that references this issue on Oct 10, 2025
    bda20c5
  7. added a commit that references this issue on Jan 10, 2026
    8d05bfa
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions