Generate EIF files
parent
029b7d654a
commit
e55f9e3fe8
|
@ -89,6 +89,13 @@ fn run() -> Result<(), Box<dyn Error>> {
|
|||
file.write_all( &data )?
|
||||
}
|
||||
|
||||
let eif_files = result.get_eifs()?;
|
||||
for ( filename, data ) in eif_files {
|
||||
println!( "Creating EIF instrument file {}", filename );
|
||||
let mut file = File::create( filename )?;
|
||||
file.write_all( &data )?
|
||||
}
|
||||
|
||||
// TODO !!
|
||||
|
||||
Ok( () )
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::{error::Error, fs::File, io::Read, convert::TryInto, collections::HashMap, cmp::{min, max}};
|
||||
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, print_warning}, soundtrack::{types::{SampleRate, SampleFormat, PsgEnvelope, Note, Sample, PsgSettings}, engines::echo::EchoFormat}};
|
||||
|
||||
const DMF_MAGIC_NUMBER: &'static str = ".DelekDefleMask.";
|
||||
const DMF_SUPPORTED_VERSION: u8 = 27;
|
||||
|
@ -377,35 +377,6 @@ impl DmfModule {
|
|||
}
|
||||
|
||||
// Operator 3
|
||||
{
|
||||
operators[ 2 ].am = get_u8( bytes.by_ref() )?;
|
||||
operators[ 2 ].ar = get_u8( bytes.by_ref() )?;
|
||||
operators[ 2 ].dr = get_u8( bytes.by_ref() )?;
|
||||
operators[ 2 ].mult = get_u8( bytes.by_ref() )?;
|
||||
operators[ 2 ].rr = get_u8( bytes.by_ref() )?;
|
||||
operators[ 2 ].sl = get_u8( bytes.by_ref() )?;
|
||||
operators[ 2 ].tl = get_u8( bytes.by_ref() )?;
|
||||
operators[ 2 ].dt2 = get_u8( bytes.by_ref() )?;
|
||||
operators[ 2 ].rs = get_u8( bytes.by_ref() )?;
|
||||
operators[ 2 ].dt = get_i8( bytes.by_ref() )? - 3;
|
||||
operators[ 2 ].d2r = get_u8( bytes.by_ref() )?;
|
||||
operators[ 2 ].ssg_mode = get_u8( bytes.by_ref() )?;
|
||||
|
||||
println!( "Op 3 AM:\t{}", operators[ 2 ].am );
|
||||
println!( "Op 3 AR:\t{}", operators[ 2 ].ar );
|
||||
println!( "Op 3 DR:\t{}", operators[ 2 ].dr );
|
||||
println!( "Op 3 MULT:\t{}", operators[ 2 ].mult );
|
||||
println!( "Op 3 RR:\t{}", operators[ 2 ].rr );
|
||||
println!( "Op 3 SL:\t{}", operators[ 2 ].sl );
|
||||
println!( "Op 3 TL:\t{}", operators[ 2 ].tl );
|
||||
println!( "Op 3 DT2:\t{}", operators[ 2 ].dt2 );
|
||||
println!( "Op 3 RS:\t{}", operators[ 2 ].rs );
|
||||
println!( "Op 3 DT:\t{}", operators[ 2 ].dt );
|
||||
println!( "Op 3 D2R:\t{}", operators[ 2 ].d2r );
|
||||
println!( "Op 3 SSG_MODE:\t{}\n", operators[ 2 ].ssg_mode );
|
||||
}
|
||||
|
||||
// Operator 2
|
||||
{
|
||||
operators[ 1 ].am = get_u8( bytes.by_ref() )?;
|
||||
operators[ 1 ].ar = get_u8( bytes.by_ref() )?;
|
||||
|
@ -420,18 +391,47 @@ impl DmfModule {
|
|||
operators[ 1 ].d2r = get_u8( bytes.by_ref() )?;
|
||||
operators[ 1 ].ssg_mode = get_u8( bytes.by_ref() )?;
|
||||
|
||||
println!( "Op 2 AM:\t{}", operators[ 1 ].am );
|
||||
println!( "Op 2 AR:\t{}", operators[ 1 ].ar );
|
||||
println!( "Op 2 DR:\t{}", operators[ 1 ].dr );
|
||||
println!( "Op 2 MULT:\t{}", operators[ 1 ].mult );
|
||||
println!( "Op 2 RR:\t{}", operators[ 1 ].rr );
|
||||
println!( "Op 2 SL:\t{}", operators[ 1 ].sl );
|
||||
println!( "Op 2 TL:\t{}", operators[ 1 ].tl );
|
||||
println!( "Op 2 DT2:\t{}", operators[ 1 ].dt2 );
|
||||
println!( "Op 2 RS:\t{}", operators[ 1 ].rs );
|
||||
println!( "Op 2 DT:\t{}", operators[ 1 ].dt );
|
||||
println!( "Op 2 D2R:\t{}", operators[ 1 ].d2r );
|
||||
println!( "Op 2 SSG_MODE:\t{}\n", operators[ 1 ].ssg_mode );
|
||||
println!( "Op 3 AM:\t{}", operators[ 1 ].am );
|
||||
println!( "Op 3 AR:\t{}", operators[ 1 ].ar );
|
||||
println!( "Op 3 DR:\t{}", operators[ 1 ].dr );
|
||||
println!( "Op 3 MULT:\t{}", operators[ 1 ].mult );
|
||||
println!( "Op 3 RR:\t{}", operators[ 1 ].rr );
|
||||
println!( "Op 3 SL:\t{}", operators[ 1 ].sl );
|
||||
println!( "Op 3 TL:\t{}", operators[ 1 ].tl );
|
||||
println!( "Op 3 DT2:\t{}", operators[ 1 ].dt2 );
|
||||
println!( "Op 3 RS:\t{}", operators[ 1 ].rs );
|
||||
println!( "Op 3 DT:\t{}", operators[ 1 ].dt );
|
||||
println!( "Op 3 D2R:\t{}", operators[ 1 ].d2r );
|
||||
println!( "Op 3 SSG_MODE:\t{}\n", operators[ 1 ].ssg_mode );
|
||||
}
|
||||
|
||||
// Operator 2
|
||||
{
|
||||
operators[ 2 ].am = get_u8( bytes.by_ref() )?;
|
||||
operators[ 2 ].ar = get_u8( bytes.by_ref() )?;
|
||||
operators[ 2 ].dr = get_u8( bytes.by_ref() )?;
|
||||
operators[ 2 ].mult = get_u8( bytes.by_ref() )?;
|
||||
operators[ 2 ].rr = get_u8( bytes.by_ref() )?;
|
||||
operators[ 2 ].sl = get_u8( bytes.by_ref() )?;
|
||||
operators[ 2 ].tl = get_u8( bytes.by_ref() )?;
|
||||
operators[ 2 ].dt2 = get_u8( bytes.by_ref() )?;
|
||||
operators[ 2 ].rs = get_u8( bytes.by_ref() )?;
|
||||
operators[ 2 ].dt = get_i8( bytes.by_ref() )? - 3;
|
||||
operators[ 2 ].d2r = get_u8( bytes.by_ref() )?;
|
||||
operators[ 2 ].ssg_mode = get_u8( bytes.by_ref() )?;
|
||||
|
||||
println!( "Op 2 AM:\t{}", operators[ 2 ].am );
|
||||
println!( "Op 2 AR:\t{}", operators[ 2 ].ar );
|
||||
println!( "Op 2 DR:\t{}", operators[ 2 ].dr );
|
||||
println!( "Op 2 MULT:\t{}", operators[ 2 ].mult );
|
||||
println!( "Op 2 RR:\t{}", operators[ 2 ].rr );
|
||||
println!( "Op 2 SL:\t{}", operators[ 2 ].sl );
|
||||
println!( "Op 2 TL:\t{}", operators[ 2 ].tl );
|
||||
println!( "Op 2 DT2:\t{}", operators[ 2 ].dt2 );
|
||||
println!( "Op 2 RS:\t{}", operators[ 2 ].rs );
|
||||
println!( "Op 2 DT:\t{}", operators[ 2 ].dt );
|
||||
println!( "Op 2 D2R:\t{}", operators[ 2 ].d2r );
|
||||
println!( "Op 2 SSG_MODE:\t{}\n", operators[ 2 ].ssg_mode );
|
||||
}
|
||||
|
||||
// Operator 4
|
||||
|
@ -747,7 +747,56 @@ impl EchoFormat for DmfModule {
|
|||
// Create feedback + algorithm byte
|
||||
let alg_fb: u8 = ( settings.fb << 3 ) | settings.alg;
|
||||
|
||||
todo!()
|
||||
// The operators are laid out as FmOperator objects in order 1 -> 3 -> 2 -> 4
|
||||
// EIF instrument layout below
|
||||
let mut mult_dt: [u8; 4] = [ 0x00, 0x00, 0x00, 0x00 ];
|
||||
let mut tl: [u8; 4] = [ 0x00, 0x00, 0x00, 0x00 ];
|
||||
let mut ar_rs: [u8; 4] = [ 0x00, 0x00, 0x00, 0x00 ];
|
||||
let mut dr_am: [u8; 4] = [ 0x00, 0x00, 0x00, 0x00 ];
|
||||
let mut sr: [u8; 4] = [ 0x00, 0x00, 0x00, 0x00 ];
|
||||
let mut rr_sl: [u8; 4] = [ 0x00, 0x00, 0x00, 0x00 ];
|
||||
let mut ssg_eg: [u8; 4] = [ 0x00, 0x00, 0x00, 0x00 ];
|
||||
|
||||
// Likewise, "operators" is laid out 1 -> 3 -> 2 -> 4
|
||||
for i in 0..4 {
|
||||
let dt: u8 = match settings.operators[ i ].dt {
|
||||
0 => 0b000,
|
||||
1 => 0b001,
|
||||
2 => 0b010,
|
||||
3 => 0b011,
|
||||
-1 => 0b101,
|
||||
-2 => 0b110,
|
||||
-3 => 0b111,
|
||||
_ => return Err( "invalid file: invalid value given for dt" )?
|
||||
};
|
||||
|
||||
// https://plutiedev.com/ym2612-registers
|
||||
// https://github.com/sikthehedgehog/Echo/blob/master/doc/eif.txt
|
||||
mult_dt[ i ] = ( dt << 4 ) | settings.operators[ i ].mult;
|
||||
tl[ i ] = settings.operators[ i ].tl;
|
||||
ar_rs[ i ] = ( settings.operators[ i ].rs << 6 ) | settings.operators[ i ].ar;
|
||||
dr_am[ i ] = ( settings.operators[ i ].am << 7 ) | settings.operators[ i ].dr;
|
||||
sr[ i ] = settings.operators[ i ].d2r; // "Sometimes also called 'second decay rate' (D2R)."
|
||||
rr_sl[ i ] = ( settings.operators[ i ].sl << 4 ) | settings.operators[ i ].rr;
|
||||
|
||||
if settings.operators[ i ].ssg_mode > 0 {
|
||||
print_warning( &format!( "SSG-EG mode set on instrument {}, operator {}. this operator may not work on clone hardware or certain emulators", instrument.name, i ) );
|
||||
}
|
||||
|
||||
ssg_eg[ i ] = settings.operators[ i ].ssg_mode;
|
||||
}
|
||||
|
||||
let mut eif: Vec<u8> = Vec::new();
|
||||
eif.push( alg_fb );
|
||||
eif.extend( mult_dt );
|
||||
eif.extend( tl );
|
||||
eif.extend( ar_rs );
|
||||
eif.extend( dr_am );
|
||||
eif.extend( sr );
|
||||
eif.extend( rr_sl );
|
||||
eif.extend( ssg_eg );
|
||||
|
||||
eifs.insert( format!( "{}.eif", instrument.name), eif );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -45,6 +45,10 @@ pub fn print_good( message: &str ) {
|
|||
green!( "success: " ); println!( "{}", message );
|
||||
}
|
||||
|
||||
pub fn print_warning( message: &str ) {
|
||||
yellow!( "warning: " ); println!( "{}", message );
|
||||
}
|
||||
|
||||
pub fn get_string( bytes: &mut Iter<'_, u8>, take: usize ) -> Result<String, Box<dyn Error>> {
|
||||
let took = bytes.take( take );
|
||||
let took: Vec<u8> = took.cloned().collect();
|
||||
|
|
Loading…
Reference in New Issue