Upgrade dmf to file version 27 and fix issues

master
Ashley N. 2023-08-19 15:45:45 -04:00
parent 3aa311c8f5
commit 8add785d78
2 changed files with 35 additions and 8 deletions

View File

@ -4,4 +4,6 @@ pub trait EchoFormat {
fn get_eefs( &self ) -> Result<HashMap<String, Vec<u8>>, Box<dyn Error>>; fn get_eefs( &self ) -> Result<HashMap<String, Vec<u8>>, Box<dyn Error>>;
fn get_eifs( &self ) -> Result<HashMap<String, Vec<u8>>, Box<dyn Error>>;
} }

View File

@ -3,7 +3,7 @@ use flate2::read::ZlibDecoder;
use crate::reskit::{utility::{get_string, get_u8, skip, get_u32, get_i8, get_i32, get_u16, get_i16, Ring}, soundtrack::{types::{SampleRate, SampleFormat, PsgEnvelope, Note, Sample, PsgSettings}, engines::echo::EchoFormat}}; use crate::reskit::{utility::{get_string, get_u8, skip, get_u32, get_i8, get_i32, get_u16, get_i16, Ring}, soundtrack::{types::{SampleRate, SampleFormat, PsgEnvelope, Note, Sample, PsgSettings}, engines::echo::EchoFormat}};
const DMF_MAGIC_NUMBER: &'static str = ".DelekDefleMask."; const DMF_MAGIC_NUMBER: &'static str = ".DelekDefleMask.";
const DMF_SUPPORTED_VERSION: u8 = 0x18; const DMF_SUPPORTED_VERSION: u8 = 27;
const DMF_MD: u8 = 0x02; const DMF_MD: u8 = 0x02;
const DMF_MD_ENHANCED_CH3: u8 = 0x42; const DMF_MD_ENHANCED_CH3: u8 = 0x42;
@ -74,7 +74,7 @@ pub struct DmfModule {
speed_b: u8, speed_b: u8,
frame_mode: FrameMode, frame_mode: FrameMode,
rows_per_pattern: u32, rows_per_pattern: u32,
pattern_matrix: Vec<Vec<u8>>, pattern_matrix: Vec<Vec<u16>>,
instruments: Vec<Instrument>, instruments: Vec<Instrument>,
samples: Vec<Sample> samples: Vec<Sample>
} }
@ -166,12 +166,12 @@ impl DmfModule {
13 13
}; };
let mut pattern_matrix: Vec<Vec<u8>> = vec![vec![0; system_total_channels]; patterns_count.into()]; let mut pattern_matrix: Vec<Vec<u16>> = vec![vec![0; system_total_channels]; patterns_count.into()];
for channel in 0..system_total_channels { for channel in 0..system_total_channels {
for pattern in 0..patterns_count { for pattern in 0..patterns_count {
let channel: usize = channel.into(); let channel: usize = channel.into();
let pattern: usize = pattern.into(); let pattern: usize = pattern.into();
pattern_matrix[ pattern ][ channel ] = get_u8( bytes.by_ref() )?; pattern_matrix[ pattern ][ channel ] = get_u16( bytes.by_ref() )?;
} }
} }
@ -471,10 +471,17 @@ impl DmfModule {
instruments.push( Instrument { name, instrument_type } ); instruments.push( Instrument { name, instrument_type } );
} }
// Wavetables are not used in fm synthesis, this should validate as 0 or error // Version 27 of DMF specifies "1 wavetable of 0 bytes" for sega megadrive
let wavetable_count = get_u8( bytes.by_ref() )?; // They will never be used in the megadrive, barring use of the audio
if wavetable_count > 0 { // expansion on the cartridge slot (e.g. mp3 fpga, spc700 fpga)
return Err( "invalid file: wavetables should be zero for system type Sega Megadrive" )?; // It may just be easier here to eat the wavetables as they are indicated
// instead of throwing a validation error if anything is present here.
let wavetable_len = get_u8( bytes.by_ref() )?;
for _ in 0..wavetable_len {
let wavetable_size: usize = get_u32( bytes.by_ref() )?.try_into()?;
if wavetable_size > 0 {
skip( bytes.by_ref(), wavetable_size * 4 );
}
} }
// (channel, patterns) // (channel, patterns)
@ -584,6 +591,9 @@ impl DmfModule {
} }
samples.push( sample ); samples.push( sample );
// Fast forward 8 bytes that are unused at the end of the sample
skip( bytes.by_ref(), 8 );
} }
Ok( Ok(
@ -727,6 +737,21 @@ impl EchoFormat for DmfModule {
Ok( eefs ) Ok( eefs )
} }
fn get_eifs( &self ) -> Result<HashMap<String, Vec<u8>>, Box<dyn Error>> {
let mut eifs: HashMap<String, Vec<u8>> = HashMap::new();
for instrument in &self.instruments {
if let InstrumentType::Fm( settings ) = &instrument.instrument_type {
// Create feedback + algorithm byte
let alg_fb: u8 = ( settings.fb << 3 ) | settings.alg;
todo!()
}
}
Ok( eifs )
}
} }
fn get_eef_volume( dmf_volume: u8 ) -> Result<u8, Box<dyn Error>> { fn get_eef_volume( dmf_volume: u8 ) -> Result<u8, Box<dyn Error>> {