msg_tool\utils/
pcm.rs

1//! PCM Utilities
2use 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)]
10/// PCM Audio Format
11pub struct PcmFormat {
12    /// The format tag
13    pub format_tag: u16,
14    /// The number of channels
15    pub channels: u16,
16    /// The sample rate
17    pub sample_rate: u32,
18    /// The average bytes per second
19    pub average_bytes_per_second: u32,
20    /// The block alignment
21    pub block_align: u16,
22    /// The bits per sample
23    pub bits_per_sample: u16,
24}
25
26/// Writes PCM data to a file.
27///
28/// * `format` - The PCM format to write.
29/// * `reader` - The reader to read PCM data from.
30/// * `writer` - The writer to write PCM data to.
31pub 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)?; // Placeholder for total size
39    writer.write_all(b"WAVE")?;
40    writer.write_all(b"fmt ")?;
41    writer.write_u32(16)?; // Size of fmt chunk
42    format.pack(&mut writer, false, Encoding::Utf8)?;
43    writer.write_all(b"data")?;
44    let mut data_size = 0u32;
45    writer.write_u32(0)?; // Placeholder for data size
46    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}