Implement SoundDataNew block type as Duke Nukem 3D VOC files use it.

This commit is contained in:
Pedro de Oliveira 2023-04-28 11:57:15 +01:00
parent b8dc6b10bb
commit c7a6001b8b
1 changed files with 55 additions and 3 deletions

View File

@ -38,6 +38,15 @@ pub enum BlockType {
count: u16,
},
RepeatEnd,
//8 ExtraInformation
SoundDataNew {
sample_rate: u32,
bits: u8,
channels: u8,
codec: Codec,
reserved: u32,
data: Vec<u8>,
},
}
impl BlockType {
@ -80,6 +89,17 @@ impl BlockType {
BlockType::RepeatEnd => {
println!("End repeat")
}
BlockType::SoundDataNew {
sample_rate, bits, channels, codec, reserved, data
} => println!(
"Sound data (NEW): sample rate = {}, bits = {}, channels = {}, codec = {:?}, reserved: {}, size = {}",
sample_rate,
bits,
channels,
codec,
reserved,
data.len()
)
}
}
}
@ -120,7 +140,6 @@ pub fn parse_block(input: &[u8]) -> nom::IResult<&[u8], BlockType> {
4 => Codec::Pcm16BitSigned,
5 => Codec::Alaw,
6 => Codec::Ulaw,
7 => Codec::Adpcm4to16,
_ => panic!("Invalid sound format"),
};
let (input, data) = nom::bytes::complete::take(block_size - 2)(input)?;
@ -177,7 +196,39 @@ pub fn parse_block(input: &[u8]) -> nom::IResult<&[u8], BlockType> {
Ok((input, BlockType::RepeatStart { count }))
}
7 => Ok((input, BlockType::RepeatEnd)),
_ => panic!("Invalid block type"),
8 => panic!("ExtraInformation - Not Implemented"),
9 => {
let (input, block_size) = number::streaming::le_u24(input)?;
let (input, sample_rate) = number::streaming::le_u32(input)?;
let (input, bits) = number::streaming::le_u8(input)?;
let (input, channels) = number::streaming::le_u8(input)?;
let (input, codec_id) = number::streaming::le_u16(input)?;
let (input, reserved) = number::streaming::le_u32(input)?;
let (input, data) = nom::bytes::complete::take(block_size - 12)(input)?;
let codec = match codec_id {
0 => Codec::Pcm8BitUnsigned,
1 => Codec::Adpcm4to8,
2 => Codec::Adpcm3to8,
3 => Codec::Adpcm2to8,
4 => Codec::Pcm16BitSigned,
5 => Codec::Alaw,
6 => Codec::Ulaw,
0x0200 => Codec::Adpcm4to16,
_ => panic!("Invalid sound format"),
};
Ok((
input,
BlockType::SoundDataNew {
sample_rate,
bits,
channels,
codec,
reserved,
data: data.to_vec(),
},
))
}
_ => panic!("Invalid block type - {}", block_type),
}
}
@ -226,7 +277,8 @@ pub fn parse_voc(input: &[u8]) -> nom::IResult<&[u8], Voc> {
}
fn main() {
let f = include_bytes!("../EDEN.MUS");
//let f = include_bytes!("../EDEN.MUS");
let f = include_bytes!("../ADOOR2.VOC");
match parse_voc(f) {
Ok((_, voc)) => {
println!("Version: {}.{}", voc.version.major, voc.version.minor);