hound icon indicating copy to clipboard operation
hound copied to clipboard

Writing a wav in memory

Open PaulDotSH opened this issue 1 year ago • 5 comments

Hi, I have a usecase where I would need to send the wav to a server and I would like to write it in memory and send it that way, there shouldn't be a need to touch the disk at all, is this possible with hound? Since write_sample only works on a WavWriter which requires seek which isnt implemented by BufWriter

PaulDotSH avatar Oct 20 '24 21:10 PaulDotSH

Yes this is possible, you can write to an std::io::Cursor<Vec<u8>>.

ruuda avatar Oct 21 '24 21:10 ruuda

However, in this case there’s still a problem: once ownership has been transferred to the Cursor, you won’t be able to get it back. Perhaps what we need is an into_inner() method that can be called after flush(). For the cases if not possible to use a reference to the Cursor.

therustmonk avatar Apr 19 '25 13:04 therustmonk

i also got this problem, and having into_inner() would help a lot

BlazarBlade avatar Apr 26 '25 23:04 BlazarBlade

You can enclose the writing in a block as a workaround:

let mut file_u8: Vec<u8> = Vec::new();

{
      let spec = hound::WavSpec {
           channels: 2,
           sample_rate: 44100,
           bits_per_sample: 32,
           sample_format: hound::SampleFormat::Float,
       };
       let u8_writer = Cursor::new(&mut file_u8);
       let mut writer = hound::WavWriter::new(u8_writer, spec).unwrap();

       // write samples here
           
        writer.finalize().unwrap();
}
// now the writer will go out of scope and you can use the byte buffer again

the-drunk-coder avatar Jul 04 '25 14:07 the-drunk-coder

I used this approach as I needed to access the cursor later:

#[derive(Clone)]                                                                                                               
struct Cursor(Arc<Mutex<std::io::Cursor<Vec<u8>>>>);

impl std::io::Write for Cursor {
    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {                                                                
        self.0.lock().unwrap().write(buf)
    }   
                                                                                                                               
    fn flush(&mut self) -> std::io::Result<()> {                                                                               
        self.0.lock().unwrap().flush()
    }           
}               
                
impl std::io::Seek for Cursor {
    fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result<u64> {
        self.0.lock().unwrap().seek(pos)
    }
}

MathieuDuponchelle avatar Sep 30 '25 18:09 MathieuDuponchelle