Implement the 7 first Block Types of a VOC file.
This commit is contained in:
parent
5d4edf3247
commit
89c335fc7f
|
@ -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"),
|
||||
};
|
||||
|
|
176
src/voc.rs
176
src/voc.rs
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue