Implement the 7 first Block Types of a VOC file.

This commit is contained in:
Pedro de Oliveira 2022-11-13 06:14:51 +00:00
parent 5d4edf3247
commit 89c335fc7f
2 changed files with 145 additions and 33 deletions

View File

@ -22,7 +22,7 @@ fn main() {
let filename = arguments.get_one::<String>("file").unwrap();
let voc = voc::VocFile::from_file(filename);
println!("{:?}", voc);
println!("{:02X?}", voc.to_bytes());
voc.to_file("lulz.voc");
}
_ => unreachable!("parser should ensure only valid subcommand names are used"),
};

View File

@ -22,8 +22,8 @@ pub enum BlockType {
Silence,
Marker,
Text,
Repeat,
EndRepeat,
RepeatStart,
RepeatEnd,
}
#[derive(Debug)]
@ -79,8 +79,8 @@ impl VocFile {
3 => BlockType::Silence,
4 => BlockType::Marker,
5 => BlockType::Text,
6 => BlockType::Repeat,
7 => BlockType::EndRepeat,
6 => BlockType::RepeatStart,
7 => BlockType::RepeatEnd,
_ => panic!("Bad block type. Got {}", block_type_buffer[0])
};
@ -103,7 +103,7 @@ impl VocFile {
BlockType::SoundData => {
let mut frequency_divisor_buffer: [u8; 1] = [0];
drop(fp.read(&mut frequency_divisor_buffer));
let sample_rate: i32 = 1000000i32 / (256i32 - frequency_divisor_buffer[0] as i32);
let sample_rate: u32 = 1000000u32 / (256u32 - frequency_divisor_buffer[0] as u32);
let mut codec_buffer: [u8; 1] = [0];
drop(fp.read(&mut codec_buffer));
@ -136,13 +136,21 @@ impl VocFile {
BlockType::Silence => {
let mut length_buffer: [u8; 2] = [0; 2];
drop(fp.read(&mut length_buffer));
let length = i16::from_le_bytes(length_buffer);
let length = u16::from_le_bytes(length_buffer) + 1;
let mut frequency_divisor_buffer: [u8; 1] = [0];
drop(fp.read(&mut frequency_divisor_buffer));
let sample_rate: i32 = 1000000i32 / (256i32 - frequency_divisor_buffer[0] as i32);
let sample_rate: u32 = 1000000u32 / (256u32 - frequency_divisor_buffer[0] as u32);
let block = Silence { block_type, size: block_size, sample_rate, length };
let block = Silence::new(length, sample_rate);
voc.blocks.push(Box::new(block));
}
BlockType::Marker => {
let mut value_buffer: [u8; 2] = [0; 2];
drop(fp.read(&mut value_buffer));
let value = u16::from_le_bytes(value_buffer);
let block = Marker::new(value);
voc.blocks.push(Box::new(block));
}
BlockType::Text => {
@ -152,6 +160,18 @@ impl VocFile {
let block = Text::new(data);
voc.blocks.push(Box::new(block));
}
BlockType::RepeatStart => {
let mut count_buffer: [u8; 2] = [0; 2];
drop(fp.read(&mut count_buffer));
let count = u16::from_le_bytes(count_buffer);
let block = RepeatStart::new(count);
voc.blocks.push(Box::new(block));
}
BlockType::RepeatEnd => {
let block = RepeatEnd::new();
voc.blocks.push(Box::new(block));
}
_ => panic!("block Type {:?} not implemented", block_type),
}
}
@ -226,13 +246,13 @@ impl fmt::Debug for Terminator {
pub struct SoundData {
block_type: BlockType,
pub sample_rate: i32,
pub sample_rate: u32,
pub codec: Codec,
pub data: Vec<u8>,
}
impl SoundData {
pub fn new(sample_rate: i32, codec: Codec, data: Vec<u8>) -> Self {
pub fn new(sample_rate: u32, codec: Codec, data: Vec<u8>) -> Self {
Self {
block_type: BlockType::SoundData,
sample_rate,
@ -266,7 +286,7 @@ impl fmt::Debug for SoundData {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("SoundData")
.field("size", &self.data.len())
.field("sample_rate", &self.sample_rate)
.field("sample rate", &self.sample_rate)
.field("codec", &self.codec)
.finish()
}
@ -313,41 +333,97 @@ impl fmt::Debug for SoundDataContinuation {
// Silence
#[derive(Debug)]
pub struct Silence {
pub block_type: BlockType,
pub size: i32,
pub sample_rate: i32,
pub length: i16,
pub length: u16,
pub sample_rate: u32,
}
impl Silence {
pub fn new(length: u16, sample_rate: u32) -> Self {
Self {
block_type: BlockType::Silence,
length,
sample_rate
}
}
}
impl Block for Silence {
fn to_bytes(&self) -> Vec<u8> {
panic!("Not implemented");
vec![self.block_type as u8]
let size_bytes: [u8; 4] = (3 as u32).to_le_bytes();
let length_bytes: [u8; 2] = (self.length - 1).to_le_bytes();
let frequency_divisor: u8 = (256i32 - 1000000i32 / self.sample_rate as i32) as u8;
let mut result: Vec<u8> = vec![
self.block_type as u8,
size_bytes[0],
size_bytes[1],
size_bytes[2],
length_bytes[0],
length_bytes[1],
frequency_divisor,
];
result
}
}
impl fmt::Debug for Silence {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Silence")
.field("length", &self.length)
.field("sample rate", &self.sample_rate)
.finish()
}
}
// Marker
#[derive(Debug)]
pub struct Marker {
block_type: BlockType,
size: i32,
value: i16,
value: u16,
}
impl Marker {
pub fn new(value: u16) -> Self {
Self {
block_type: BlockType::Marker,
value
}
}
}
impl Block for Marker {
fn to_bytes(&self) -> Vec<u8> {
panic!("Not implemented");
vec![self.block_type as u8]
let size_bytes: [u8; 4] = (2 as u32).to_le_bytes();
let value_bytes: [u8; 2] = self.value.to_le_bytes();
let mut result: Vec<u8> = vec![
self.block_type as u8,
size_bytes[0],
size_bytes[1],
size_bytes[2],
value_bytes[0],
value_bytes[1],
];
result
}
}
impl fmt::Debug for Marker {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Marker")
.field("value", &self.value)
.finish()
}
}
// Text
pub struct Text {
pub block_type: BlockType,
block_type: BlockType,
pub data: Vec<u8>,
}
@ -387,31 +463,67 @@ impl fmt::Debug for Text {
// RepeatStart
#[derive(Debug)]
pub struct RepeatStart {
block_type: BlockType,
size: i32,
repeat: i16,
pub count: u16
}
impl RepeatStart {
pub fn new(count: u16) -> Self {
Self {
block_type: BlockType::RepeatStart,
count
}
}
}
impl Block for RepeatStart {
fn to_bytes(&self) -> Vec<u8> {
panic!("Not implemented");
vec![self.block_type as u8]
let size_bytes: [u8; 4] = (2 as u32).to_le_bytes();
let count_bytes: [u8; 2] = self.count.to_le_bytes();
let mut result: Vec<u8> = vec![
self.block_type as u8,
size_bytes[0],
size_bytes[1],
size_bytes[2],
count_bytes[0],
count_bytes[1],
];
result
}
}
impl fmt::Debug for RepeatStart {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("RepeatStart")
.field("count", &self.count)
.finish()
}
}
// RepeatEnd
#[derive(Debug)]
pub struct RepeatEnd {
block_type: BlockType,
size: i32,
block_type: BlockType
}
impl RepeatEnd {
pub fn new() -> Self {
Self { block_type: BlockType::RepeatEnd }
}
}
impl Block for RepeatEnd {
fn to_bytes(&self) -> Vec<u8> {
panic!("Not implemented");
vec![self.block_type as u8]
}
}
impl fmt::Debug for RepeatEnd {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("RepeatEnd")
.finish()
}
}