1use crate::ext::io::*;
3use crate::types::*;
4use crate::utils::struct_pack::*;
5use anyhow::Result;
6use msg_tool_macro::*;
7use std::io::{Read, Seek, Write};
8
9#[derive(Debug, StructPack, StructUnpack)]
10pub struct PcmFormat {
12 pub format_tag: u16,
14 pub channels: u16,
16 pub sample_rate: u32,
18 pub average_bytes_per_second: u32,
20 pub block_align: u16,
22 pub bits_per_sample: u16,
24}
25
26pub fn write_pcm<W: Write + Seek, R: Read>(
32 format: &PcmFormat,
33 mut reader: R,
34 mut writer: W,
35) -> Result<()> {
36 writer.write_all(b"RIFF")?;
37 let mut total_size = 0x24u32;
38 writer.write_u32(0)?; writer.write_all(b"WAVE")?;
40 writer.write_all(b"fmt ")?;
41 writer.write_u32(16)?; format.pack(&mut writer, false, Encoding::Utf8)?;
43 writer.write_all(b"data")?;
44 let mut data_size = 0u32;
45 writer.write_u32(0)?; let mut buffer = [0u8; 4096];
47 loop {
48 let bytes_read = reader.read(&mut buffer)?;
49 if bytes_read == 0 {
50 break;
51 }
52 writer.write_all(&buffer[..bytes_read])?;
53 data_size += bytes_read as u32;
54 }
55 total_size += data_size;
56 writer.seek(std::io::SeekFrom::Start(4))?;
57 writer.write_u32(total_size)?;
58 writer.seek(std::io::SeekFrom::Start(40))?;
59 writer.write_u32(data_size)?;
60 Ok(())
61}