Writing a wav in memory
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
Yes this is possible, you can write to an std::io::Cursor<Vec<u8>>.
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.
i also got this problem, and having into_inner() would help a lot
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
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)
}
}