Split stuff to start to implement the writer.
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Pedro de Oliveira 2023-04-30 03:27:39 +01:00
parent 650227a781
commit 03fd0b7641
9 changed files with 117 additions and 78 deletions

View File

@ -1 +1,3 @@
pub mod parser;
pub mod reader;
pub mod types;
pub mod writer;

View File

@ -1,60 +1,9 @@
use crate::types::*;
use nom::bytes::streaming::{tag, take};
use nom::error::{Error, ErrorKind};
use nom::number::streaming::{le_u16, le_u24, le_u32, le_u8};
use nom::{Err, IResult};
#[derive(Eq, Debug, PartialEq)]
pub enum Codec {
Pcm8BitUnsigned,
Adpcm4to8,
Adpcm3to8,
Adpcm2to8,
Pcm16BitSigned,
Alaw,
Ulaw,
Adpcm4to16,
}
#[derive(Eq, Debug, PartialEq)]
pub enum BlockType {
Terminator,
SoundData {
sample_rate: u32,
codec: Codec,
data: Vec<u8>,
},
SoundDataContinuation {
data: Vec<u8>,
},
Silence {
length: u16,
sample_rate: u32,
},
Marker {
value: u16,
},
Text {
data: Vec<u8>,
},
RepeatStart {
count: u16,
},
RepeatEnd,
ExtraInformation {
sample_rate: u32,
codec: Codec,
channels: u8,
},
SoundDataNew {
sample_rate: u32,
bits: u8,
channels: u8,
codec: Codec,
reserved: u32,
data: Vec<u8>,
},
}
impl BlockType {
pub fn info(&self) {
match self {
@ -116,25 +65,6 @@ impl BlockType {
}
}
#[derive(Debug)]
pub struct Version {
pub major: u8,
pub minor: u8,
}
#[derive(Debug)]
pub struct Checksum {
pub value: u16,
pub valid: bool,
}
#[derive(Debug)]
pub struct Voc {
pub version: Version,
pub checksum: Checksum,
pub blocks: Vec<BlockType>,
}
fn parse_sound_data(input: &[u8]) -> IResult<&[u8], BlockType> {
let (input, block_size) = le_u24(input)?;
let (input, frequency_divisor) = le_u8(input)?;
@ -286,8 +216,8 @@ pub fn parse_block(input: &[u8]) -> IResult<&[u8], BlockType> {
}
pub fn parse_voc(input: &[u8]) -> IResult<&[u8], Voc> {
let (input, _) = tag("Creative Voice File")(input)?;
let (input, _) = tag(&[0x1a, 0x1a, 0])(input)?;
let (input, _) = tag(SIGNATURE1)(input)?;
let (input, _) = tag(SIGNATURE2)(input)?;
let (input, version_minor) = le_u8(input)?;
let (input, version_major) = le_u8(input)?;
let (input, checksum) = le_u16(input)?;

73
src/types.rs Normal file
View File

@ -0,0 +1,73 @@
pub const SIGNATURE1: &str = "Creative Voice File";
pub const SIGNATURE2: [u8; 3] = [0x1A, 0x1A, 0x0];
#[derive(Eq, Debug, PartialEq)]
pub enum Codec {
Pcm8BitUnsigned,
Adpcm4to8,
Adpcm3to8,
Adpcm2to8,
Pcm16BitSigned,
Alaw,
Ulaw,
Adpcm4to16,
}
#[derive(Eq, Debug, PartialEq)]
pub enum BlockType {
Terminator,
SoundData {
sample_rate: u32,
codec: Codec,
data: Vec<u8>,
},
SoundDataContinuation {
data: Vec<u8>,
},
Silence {
length: u16,
sample_rate: u32,
},
Marker {
value: u16,
},
Text {
data: Vec<u8>,
},
RepeatStart {
count: u16,
},
RepeatEnd,
ExtraInformation {
sample_rate: u32,
codec: Codec,
channels: u8,
},
SoundDataNew {
sample_rate: u32,
bits: u8,
channels: u8,
codec: Codec,
reserved: u32,
data: Vec<u8>,
},
}
#[derive(Debug)]
pub struct Version {
pub major: u8,
pub minor: u8,
}
#[derive(Debug)]
pub struct Checksum {
pub value: u16,
pub valid: bool,
}
#[derive(Debug)]
pub struct Voc {
pub version: Version,
pub checksum: Checksum,
pub blocks: Vec<BlockType>,
}

18
src/writer.rs Normal file
View File

@ -0,0 +1,18 @@
use crate::types::*;
pub fn write_voc(voc: &Voc) -> Vec<u8> {
let mut bytes: Vec<u8> = Vec::new();
// Signature 1
bytes.extend_from_slice(SIGNATURE1.as_bytes());
// Signature 2
bytes.extend_from_slice(&SIGNATURE2);
// Version
bytes.extend_from_slice(&[voc.version.minor, voc.version.major]);
// Checksum
let checksum = (!i16::from_le_bytes([voc.version.minor, voc.version.major]) + 0x1234) as u16;
bytes.extend_from_slice(&checksum.to_le_bytes());
bytes
}

View File

@ -1,4 +1,5 @@
use vocnom::parser::{parse_voc, BlockType, Codec};
use vocnom::reader::parse_voc;
use vocnom::types::{BlockType, Codec};
const VOC_CONTENTS: &[u8] = include_bytes!("../assets/ADOOR2.VOC");

View File

@ -1,4 +1,5 @@
use vocnom::parser::{parse_voc, BlockType, Codec};
use vocnom::reader::parse_voc;
use vocnom::types::{BlockType, Codec};
const VOC_CONTENTS: &[u8] = include_bytes!("../assets/CONGA.VOC");

View File

@ -1,4 +1,5 @@
use vocnom::parser::{parse_voc, BlockType, Codec};
use vocnom::reader::parse_voc;
use vocnom::types::{BlockType, Codec};
const VOC_CONTENTS: &[u8] = include_bytes!("../assets/EDEN.MUS");

View File

@ -1,4 +1,5 @@
use vocnom::parser::{parse_voc, BlockType, Codec};
use vocnom::reader::parse_voc;
use vocnom::types::{BlockType, Codec};
const VOC_CONTENTS: &[u8] = include_bytes!("../assets/GUARDIAN.VOC");

12
tests/test_write.rs Normal file
View File

@ -0,0 +1,12 @@
use vocnom::reader::parse_voc;
use vocnom::writer::write_voc;
const VOC_CONTENTS: &[u8] = include_bytes!("../assets/EDEN.MUS");
#[test]
fn version_test() {
let (_, voc) = parse_voc(VOC_CONTENTS).unwrap();
let bytes = write_voc(&voc);
println!("{:02x?}", bytes);
}