Working
This commit is contained in:
parent
d55935c54b
commit
8e7c90a770
158
src/voc.rs
158
src/voc.rs
|
@ -1,9 +1,9 @@
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{Read, Seek, SeekFrom};
|
use std::io::{Read, Seek, SeekFrom};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub enum Codec {
|
pub enum Codec {
|
||||||
Pcm8BitUnsigned,
|
Pcm8BitUnsigned,
|
||||||
Adpcm4to8,
|
Adpcm4to8,
|
||||||
Adpcm3to8,
|
Adpcm3to8,
|
||||||
|
@ -12,10 +12,10 @@
|
||||||
Alaw,
|
Alaw,
|
||||||
Ulaw,
|
Ulaw,
|
||||||
Adpcm4to16,
|
Adpcm4to16,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||||
pub enum BlockType {
|
pub enum BlockType {
|
||||||
Terminator,
|
Terminator,
|
||||||
SoundData,
|
SoundData,
|
||||||
SoundDataContinuation,
|
SoundDataContinuation,
|
||||||
|
@ -24,15 +24,15 @@
|
||||||
Text,
|
Text,
|
||||||
Repeat,
|
Repeat,
|
||||||
EndRepeat,
|
EndRepeat,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct VocFile {
|
pub struct VocFile {
|
||||||
pub version: (u8, u8),
|
pub version: (u8, u8),
|
||||||
pub blocks: Vec<BlockT>
|
pub blocks: Vec<BlockT>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VocFile {
|
impl VocFile {
|
||||||
pub(crate) fn from_file(file_name: &str) -> Self {
|
pub(crate) fn from_file(file_name: &str) -> Self {
|
||||||
println!("Parsing {} ...", file_name);
|
println!("Parsing {} ...", file_name);
|
||||||
let mut fp = File::open(file_name).unwrap();
|
let mut fp = File::open(file_name).unwrap();
|
||||||
|
@ -68,7 +68,7 @@
|
||||||
panic!("Bad file. Expected {:02X?} got {:02X?}", checksum, checksum_buffer);
|
panic!("Bad file. Expected {:02X?} got {:02X?}", checksum, checksum_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut voc = VocFile{ version, blocks: Vec::new() };
|
let mut voc = VocFile { version, blocks: Vec::new() };
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let mut block_type_buffer: [u8; 1] = [0];
|
let mut block_type_buffer: [u8; 1] = [0];
|
||||||
|
@ -128,14 +128,14 @@
|
||||||
|
|
||||||
let block = SoundData::new(block_size, sample_rate, codec, data);
|
let block = SoundData::new(block_size, sample_rate, codec, data);
|
||||||
voc.blocks.push(Box::new(block));
|
voc.blocks.push(Box::new(block));
|
||||||
},
|
}
|
||||||
BlockType::SoundDataContinuation => {
|
BlockType::SoundDataContinuation => {
|
||||||
let mut data: Vec<u8> = vec![0; (next - address) as usize];
|
let mut data: Vec<u8> = vec![0; (next - address) as usize];
|
||||||
drop(fp.read(&mut data));
|
drop(fp.read(&mut data));
|
||||||
|
|
||||||
let block = SoundDataContinuation::new(block_size, data);
|
let block = SoundDataContinuation::new(block_size, data);
|
||||||
voc.blocks.push(Box::new(block));
|
voc.blocks.push(Box::new(block));
|
||||||
},
|
}
|
||||||
BlockType::Silence => {
|
BlockType::Silence => {
|
||||||
let mut length_buffer: [u8; 2] = [0; 2];
|
let mut length_buffer: [u8; 2] = [0; 2];
|
||||||
drop(fp.read(&mut length_buffer));
|
drop(fp.read(&mut length_buffer));
|
||||||
|
@ -145,7 +145,7 @@
|
||||||
drop(fp.read(&mut frequency_divisor_buffer));
|
drop(fp.read(&mut frequency_divisor_buffer));
|
||||||
let sample_rate: i32 = 1000000i32 / (256i32 - frequency_divisor_buffer[0] as i32);
|
let sample_rate: i32 = 1000000i32 / (256i32 - frequency_divisor_buffer[0] as i32);
|
||||||
|
|
||||||
let block = Silence { block_type, size: block_size, sample_rate, length};
|
let block = Silence { block_type, size: block_size, sample_rate, length };
|
||||||
voc.blocks.push(Box::new(block));
|
voc.blocks.push(Box::new(block));
|
||||||
}
|
}
|
||||||
BlockType::Text => {
|
BlockType::Text => {
|
||||||
|
@ -154,29 +154,27 @@
|
||||||
|
|
||||||
let block = Text { block_type, size: block_size, data };
|
let block = Text { block_type, size: block_size, data };
|
||||||
voc.blocks.push(Box::new(block));
|
voc.blocks.push(Box::new(block));
|
||||||
|
}
|
||||||
},
|
|
||||||
_ => panic!("block Type {:?} not implemented", block_type),
|
_ => panic!("block Type {:?} not implemented", block_type),
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
voc
|
voc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Block: std::fmt::Debug {
|
pub trait Block: std::fmt::Debug {
|
||||||
fn to_bytes(&self) -> Vec<u8>;
|
fn to_bytes(&self) -> Vec<u8>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Block for Terminator {
|
impl Block for Terminator {
|
||||||
fn to_bytes(&self) -> Vec<u8> {
|
fn to_bytes(&self) -> Vec<u8> {
|
||||||
vec![self.block_type as u8]
|
vec![self.block_type as u8]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Block for SoundData {
|
impl Block for SoundData {
|
||||||
fn to_bytes(&self) -> Vec<u8> {
|
fn to_bytes(&self) -> Vec<u8> {
|
||||||
let size_bytes : [u8; 4] = self.size.to_le_bytes();
|
let size_bytes: [u8; 4] = self.size.to_le_bytes();
|
||||||
let frequency_divisor: u8 = (256i32 - 1000000i32 / self.sample_rate as i32) as u8;
|
let frequency_divisor: u8 = (256i32 - 1000000i32 / self.sample_rate as i32) as u8;
|
||||||
|
|
||||||
let mut result: Vec<u8> = vec![
|
let mut result: Vec<u8> = vec![
|
||||||
|
@ -185,40 +183,40 @@
|
||||||
size_bytes[1],
|
size_bytes[1],
|
||||||
size_bytes[2],
|
size_bytes[2],
|
||||||
frequency_divisor,
|
frequency_divisor,
|
||||||
self.codec as u8
|
self.codec as u8,
|
||||||
];
|
];
|
||||||
|
|
||||||
result.extend_from_slice(&self.data);
|
result.extend_from_slice(&self.data);
|
||||||
|
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Block for SoundDataContinuation {
|
impl Block for SoundDataContinuation {
|
||||||
fn to_bytes(&self) -> Vec<u8> {
|
fn to_bytes(&self) -> Vec<u8> {
|
||||||
let mut result: Vec<u8> = vec![self.block_type as u8];
|
let mut result: Vec<u8> = vec![self.block_type as u8];
|
||||||
result.extend_from_slice(&self.data);
|
result.extend_from_slice(&self.data);
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Block for Silence {
|
impl Block for Silence {
|
||||||
fn to_bytes(&self) -> Vec<u8> {
|
fn to_bytes(&self) -> Vec<u8> {
|
||||||
panic!("Not implemented");
|
panic!("Not implemented");
|
||||||
vec![self.block_type as u8]
|
vec![self.block_type as u8]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Block for Marker {
|
impl Block for Marker {
|
||||||
fn to_bytes(&self) -> Vec<u8> {
|
fn to_bytes(&self) -> Vec<u8> {
|
||||||
panic!("Not implemented");
|
panic!("Not implemented");
|
||||||
vec![self.block_type as u8]
|
vec![self.block_type as u8]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Block for Text {
|
impl Block for Text {
|
||||||
fn to_bytes(&self) -> Vec<u8> {
|
fn to_bytes(&self) -> Vec<u8> {
|
||||||
let size_bytes : [u8; 4] = self.size.to_le_bytes();
|
let size_bytes: [u8; 4] = self.size.to_le_bytes();
|
||||||
|
|
||||||
let mut result: Vec<u8> = vec![
|
let mut result: Vec<u8> = vec![
|
||||||
self.block_type as u8,
|
self.block_type as u8,
|
||||||
|
@ -231,50 +229,50 @@
|
||||||
|
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Block for RepeatStart {
|
impl Block for RepeatStart {
|
||||||
fn to_bytes(&self) -> Vec<u8> {
|
fn to_bytes(&self) -> Vec<u8> {
|
||||||
panic!("Not implemented");
|
panic!("Not implemented");
|
||||||
vec![self.block_type as u8]
|
vec![self.block_type as u8]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Block for RepeatEnd {
|
impl Block for RepeatEnd {
|
||||||
fn to_bytes(&self) -> Vec<u8> {
|
fn to_bytes(&self) -> Vec<u8> {
|
||||||
panic!("Not implemented");
|
panic!("Not implemented");
|
||||||
vec![self.block_type as u8]
|
vec![self.block_type as u8]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type BlockT = Box<dyn Block>;
|
type BlockT = Box<dyn Block>;
|
||||||
|
|
||||||
pub struct Terminator {
|
pub struct Terminator {
|
||||||
block_type: BlockType,
|
block_type: BlockType,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for Terminator {
|
impl fmt::Debug for Terminator {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.debug_struct("Terminator")
|
f.debug_struct("Terminator")
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Terminator {
|
impl Terminator {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self { block_type: BlockType::Terminator }
|
Self { block_type: BlockType::Terminator }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SoundData {
|
pub struct SoundData {
|
||||||
block_type: BlockType,
|
block_type: BlockType,
|
||||||
pub size: i32,
|
pub size: i32,
|
||||||
pub sample_rate: i32,
|
pub sample_rate: i32,
|
||||||
pub codec: Codec,
|
pub codec: Codec,
|
||||||
pub data: Vec<u8>,
|
pub data: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for SoundData {
|
impl fmt::Debug for SoundData {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.debug_struct("SoundData")
|
f.debug_struct("SoundData")
|
||||||
.field("size", &self.size)
|
.field("size", &self.size)
|
||||||
|
@ -282,82 +280,82 @@
|
||||||
.field("codec", &self.codec)
|
.field("codec", &self.codec)
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SoundData {
|
impl SoundData {
|
||||||
pub fn new(size: i32, sample_rate: i32, codec: Codec, data: Vec<u8>) -> Self {
|
pub fn new(size: i32, sample_rate: i32, codec: Codec, data: Vec<u8>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
block_type: BlockType::SoundData,
|
block_type: BlockType::SoundData,
|
||||||
size,
|
size,
|
||||||
sample_rate,
|
sample_rate,
|
||||||
codec,
|
codec,
|
||||||
data
|
data,
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct SoundDataContinuation {
|
pub struct SoundDataContinuation {
|
||||||
pub block_type: BlockType,
|
pub block_type: BlockType,
|
||||||
pub size: i32,
|
pub size: i32,
|
||||||
pub data: Vec<u8>,
|
pub data: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for SoundDataContinuation {
|
impl fmt::Debug for SoundDataContinuation {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.debug_struct("SoundDataContinuation")
|
f.debug_struct("SoundDataContinuation")
|
||||||
.field("size", &self.size)
|
.field("size", &self.size)
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SoundDataContinuation {
|
impl SoundDataContinuation {
|
||||||
pub fn new(size: i32, data: Vec<u8>) -> Self {
|
pub fn new(size: i32, data: Vec<u8>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
block_type: BlockType::SoundDataContinuation,
|
block_type: BlockType::SoundDataContinuation,
|
||||||
size,
|
size,
|
||||||
data
|
data,
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Silence {
|
pub struct Silence {
|
||||||
pub block_type: BlockType,
|
pub block_type: BlockType,
|
||||||
pub size: i32,
|
pub size: i32,
|
||||||
pub sample_rate: i32,
|
pub sample_rate: i32,
|
||||||
pub length: i16,
|
pub length: i16,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Marker {
|
pub struct Marker {
|
||||||
block_type: BlockType,
|
block_type: BlockType,
|
||||||
size: i32,
|
size: i32,
|
||||||
value: i16,
|
value: i16,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Text {
|
pub struct Text {
|
||||||
pub block_type: BlockType,
|
pub block_type: BlockType,
|
||||||
pub size: i32,
|
pub size: i32,
|
||||||
pub data: Vec<u8>,
|
pub data: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for Text {
|
impl fmt::Debug for Text {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.debug_struct("Text")
|
f.debug_struct("Text")
|
||||||
.field("size", &self.size)
|
.field("size", &self.size)
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct RepeatStart {
|
pub struct RepeatStart {
|
||||||
block_type: BlockType,
|
block_type: BlockType,
|
||||||
size: i32,
|
size: i32,
|
||||||
repeat: i16,
|
repeat: i16,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct RepeatEnd {
|
pub struct RepeatEnd {
|
||||||
block_type: BlockType,
|
block_type: BlockType,
|
||||||
size: i32,
|
size: i32,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue