diff --git a/src/reskit/soundtrack.rs b/src/reskit/soundtrack.rs index b31ed2c..c4dd390 100644 --- a/src/reskit/soundtrack.rs +++ b/src/reskit/soundtrack.rs @@ -102,6 +102,31 @@ pub struct PatternRow { instrument_index: Option } +#[derive(Debug)] +pub enum SampleRate { + Hz8000, + Hz11025, + Hz16000, + Hz22050, + Hz32000 +} + +#[derive(Debug)] +pub enum SampleFormat { + Bits8, + Bits16 +} + +#[derive(Debug)] +pub struct Sample { + name: String, + rate: SampleRate, + pitch: i8, + amp: u8, + bitrate: SampleFormat, + data: Vec +} + pub struct DmfModule { platform: u8, version: u8, @@ -111,7 +136,8 @@ pub struct DmfModule { frame_mode: FrameMode, rows_per_pattern: u32, pattern_matrix: Vec>, - instruments: Vec + instruments: Vec, + samples: Vec } fn get_string( bytes: &mut Iter<'_, u8>, take: usize ) -> Result> { @@ -640,12 +666,45 @@ impl DmfModule { channel_patterns.push( channel_rows ); } - // TODO: PCM Samples !! + println!( "PCM Samples:" ); + let mut samples: Vec = Vec::new(); + let num_samples = get_u8( bytes.by_ref() )?; + for i in 0..num_samples { + let sample_size = get_u32( bytes.by_ref() )?; + let sample_name_chars = get_u8( bytes.by_ref() )?; + let name = get_string( bytes.by_ref(), sample_name_chars.into() )?; + let rate = match get_u8( bytes.by_ref() )? { + 1 => SampleRate::Hz8000, + 2 => SampleRate::Hz11025, + 3 => SampleRate::Hz16000, + 4 => SampleRate::Hz22050, + 5 => SampleRate::Hz32000, + invalid => return Err( format!( "invalid file: invalid sample rate {}", invalid ) )? + }; + + let pitch = get_i8( bytes.by_ref() )? - 5; + let amp = get_u8( bytes.by_ref() )?; + let bitrate = match get_u8( bytes.by_ref() )? { + 8 => SampleFormat::Bits8, + 16 => SampleFormat::Bits16, + invalid => return Err( format!( "invalid file: invalid bitrate {}", invalid ) )? + }; + + let mut sample = Sample { name, rate, pitch, amp, bitrate, data: Vec::new() }; + + println!( "{}:\t{:?}", i, sample ); + + for _ in 0..sample_size { + sample.data.push( get_u16( bytes.by_ref() )? ); + } + + samples.push( sample ); + } Ok( DmfModule { platform, version, time_base, speed_a, speed_b, frame_mode, rows_per_pattern, - pattern_matrix, instruments + pattern_matrix, instruments, samples } ) }