mirror of
https://github.com/lifegpc/msg-tool.git
synced 2026-06-07 13:28:47 +08:00
Add circus pcm audio support
This commit is contained in:
@@ -13,6 +13,8 @@ pub mod files;
|
||||
pub mod img;
|
||||
pub mod macros;
|
||||
pub mod name_replacement;
|
||||
#[cfg(feature = "utils-pcm")]
|
||||
pub mod pcm;
|
||||
#[cfg(feature = "utils-str")]
|
||||
pub mod str;
|
||||
pub mod struct_pack;
|
||||
|
||||
48
src/utils/pcm.rs
Normal file
48
src/utils/pcm.rs
Normal file
@@ -0,0 +1,48 @@
|
||||
use crate::ext::io::*;
|
||||
use crate::types::*;
|
||||
use crate::utils::struct_pack::*;
|
||||
use anyhow::Result;
|
||||
use msg_tool_macro::*;
|
||||
use std::io::{Read, Seek, Write};
|
||||
|
||||
#[derive(Debug, StructPack, StructUnpack)]
|
||||
pub struct PcmFormat {
|
||||
format_tag: u16,
|
||||
channels: u16,
|
||||
sample_rate: u32,
|
||||
average_bytes_per_second: u32,
|
||||
block_align: u16,
|
||||
bits_per_sample: u16,
|
||||
}
|
||||
|
||||
pub fn write_pcm<W: Write + Seek, R: Read>(
|
||||
format: &PcmFormat,
|
||||
mut reader: R,
|
||||
mut writer: W,
|
||||
) -> Result<()> {
|
||||
writer.write_all(b"RIFF")?;
|
||||
let mut total_size = 0x24u32;
|
||||
writer.write_u32(0)?; // Placeholder for total size
|
||||
writer.write_all(b"WAVE")?;
|
||||
writer.write_all(b"fmt ")?;
|
||||
writer.write_u32(16)?; // Size of fmt chunk
|
||||
format.pack(&mut writer, false, Encoding::Utf8)?;
|
||||
writer.write_all(b"data")?;
|
||||
let mut data_size = 0u32;
|
||||
writer.write_u32(0)?; // Placeholder for data size
|
||||
let mut buffer = [0u8; 4096];
|
||||
loop {
|
||||
let bytes_read = reader.read(&mut buffer)?;
|
||||
if bytes_read == 0 {
|
||||
break;
|
||||
}
|
||||
writer.write_all(&buffer[..bytes_read])?;
|
||||
data_size += bytes_read as u32;
|
||||
}
|
||||
total_size += data_size;
|
||||
writer.seek(std::io::SeekFrom::Start(4))?;
|
||||
writer.write_u32(total_size)?;
|
||||
writer.seek(std::io::SeekFrom::Start(40))?;
|
||||
writer.write_u32(data_size)?;
|
||||
Ok(())
|
||||
}
|
||||
@@ -47,3 +47,19 @@ impl StructPack for bool {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: StructPack> StructPack for Option<T> {
|
||||
fn pack<W: Write>(&self, writer: &mut W, big: bool, encoding: Encoding) -> Result<()> {
|
||||
if let Some(value) = self {
|
||||
value.pack(writer, big, encoding)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: StructUnpack> StructUnpack for Option<T> {
|
||||
fn unpack<R: Read + Seek>(reader: R, big: bool, encoding: Encoding) -> Result<Self> {
|
||||
let value = T::unpack(reader, big, encoding)?;
|
||||
Ok(Some(value))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user