Support for effect Bxx (looping)

master
Ashley N. 2023-08-29 22:22:02 -04:00
parent db302a7f7e
commit 33b16767db
3 changed files with 23 additions and 8 deletions

View File

@ -3,7 +3,7 @@ use convert_case::{Case, Casing};
use samplerate::convert; use samplerate::convert;
use uuid::Uuid; use uuid::Uuid;
use crate::reskit::{soundtrack::{formats::dmf::{DmfModule, ECHO_EWF_SAMPLE_RATE}, types::{InstrumentType, SampleFormat, Channel, PatternRow}}, utility::{print_warning, Ring}}; use crate::reskit::{soundtrack::{formats::dmf::{DmfModule, ECHO_EWF_SAMPLE_RATE}, types::{InstrumentType, SampleFormat, Channel, PatternRow}}, utility::{print_warning, Ring}};
use super::engine::{EchoFormat, ESF_FM_1, ESF_FM_2, ESF_FM_3, ESF_FM_4, ESF_FM_5, ESF_FM_6, ESF_PSG_1, ESF_PSG_2, ESF_PSG_3, ESF_PSG_4, EchoEvent, get_events_for_row, compact_delays}; use super::engine::{EchoFormat, ESF_FM_1, ESF_FM_2, ESF_FM_3, ESF_FM_4, ESF_FM_5, ESF_FM_6, ESF_PSG_1, ESF_PSG_2, ESF_PSG_3, ESF_PSG_4, EchoEvent, get_events_for_row, compact_delays, ESF_SET_LOOP, ESF_GO_TO_LOOP, ESF_STOP};
impl EchoFormat for DmfModule { impl EchoFormat for DmfModule {
@ -332,10 +332,16 @@ impl EchoFormat for DmfModule {
self.instruments.len() as u8 self.instruments.len() as u8
)?; )?;
// Is this the pattern matrix row that we repeat to?
// If so, insert an ESF_LOOP_SET here.
if let Some( repeat_row ) = self.loop_at {
if row_number == repeat_row {
all_events.push( vec![ ESF_SET_LOOP ] );
}
}
// Transfer ESF events to the main stream // Transfer ESF events to the main stream
all_events.extend( events_this_row ); all_events.extend( events_this_row );
// Any jumps?
} }
// Compact sequences of delays to save rom space // Compact sequences of delays to save rom space
@ -344,7 +350,7 @@ impl EchoFormat for DmfModule {
esf.extend( event ); esf.extend( event );
} }
esf.push( 0xFF ); // Terminate the stream esf.push( if let None = self.loop_at { ESF_STOP } else { ESF_GO_TO_LOOP } ); // Terminate the stream
Ok( esf ) Ok( esf )
} }

View File

@ -15,10 +15,10 @@ const ESF_SET_FM_DIRECT_0: u8 = 0xF8;
const ESF_SET_FM_DIRECT_1: u8 = 0xF9; const ESF_SET_FM_DIRECT_1: u8 = 0xF9;
const ESF_SET_FLAGS: u8 = 0xFA; const ESF_SET_FLAGS: u8 = 0xFA;
const ESF_CLEAR_FLAGS: u8 = 0xFB; const ESF_CLEAR_FLAGS: u8 = 0xFB;
const ESF_GOTO: u8 = 0xFC; pub const ESF_GO_TO_LOOP: u8 = 0xFC;
const ESF_LOOP_SET: u8 = 0xFD; pub const ESF_SET_LOOP: u8 = 0xFD;
const ESF_DELAY_LONG: u8 = 0xFE; const ESF_DELAY_LONG: u8 = 0xFE;
const ESF_STOP: u8 = 0xFF; pub const ESF_STOP: u8 = 0xFF;
pub const ESF_FM_1: u8 = 0x00; pub const ESF_FM_1: u8 = 0x00;
pub const ESF_FM_2: u8 = 0x01; pub const ESF_FM_2: u8 = 0x01;
@ -537,6 +537,9 @@ fn apply_effects_to_channel( channel: &mut Channel, effects: &LinkedHashSet<Effe
print_warning( "Effect:DcsgNoiseMode can only be applied to SN4. ignoring..." ); print_warning( "Effect:DcsgNoiseMode can only be applied to SN4. ignoring..." );
} }
}, },
Effect::PositionJump { pattern: _ } => {
// Nothing to do - handled as we iterate through the rows.
},
unsupported_effect => print_warning( &format!( "effect unsupported: {:?}. your soundtrack may sound different than expected.", unsupported_effect ) ) unsupported_effect => print_warning( &format!( "effect unsupported: {:?}. your soundtrack may sound different than expected.", unsupported_effect ) )
} }
} }

View File

@ -37,6 +37,7 @@ pub struct DmfModule {
frame_mode: FrameMode, frame_mode: FrameMode,
pub rows_per_pattern: u32, pub rows_per_pattern: u32,
pattern_matrix: Vec<Vec<u16>>, pattern_matrix: Vec<Vec<u16>>,
pub loop_at: Option<u32>,
pub channel_patterns: Vec<Vec<PatternRow>>, pub channel_patterns: Vec<Vec<PatternRow>>,
pub instruments: Vec<Instrument>, pub instruments: Vec<Instrument>,
pub samples: Vec<Sample> pub samples: Vec<Sample>
@ -449,6 +450,7 @@ impl DmfModule {
} }
// (channel, patterns) // (channel, patterns)
let mut loop_at: Option<u32> = None;
let mut channel_patterns: Vec<Vec<PatternRow>> = Vec::new(); let mut channel_patterns: Vec<Vec<PatternRow>> = Vec::new();
for channel in 0..system_total_channels { for channel in 0..system_total_channels {
let mut channel_rows: Vec<PatternRow> = Vec::new(); let mut channel_rows: Vec<PatternRow> = Vec::new();
@ -527,6 +529,10 @@ impl DmfModule {
DMF_EFFECT_POSITION_JUMP => { DMF_EFFECT_POSITION_JUMP => {
let pattern = effect_value.ok_or( "invalid file: expected effect value for position jump" )?; let pattern = effect_value.ok_or( "invalid file: expected effect value for position jump" )?;
if let None = loop_at {
loop_at = Some( pattern as u32 * rows_per_pattern );
}
Effect::PositionJump { pattern } Effect::PositionJump { pattern }
}, },
DMF_EFFECT_PATTERN_BREAK => { DMF_EFFECT_PATTERN_BREAK => {
@ -659,7 +665,7 @@ impl DmfModule {
Ok( Ok(
DmfModule { DmfModule {
path: path.to_string(), platform, version, time_base, speed_a, speed_b, frame_mode, rows_per_pattern, path: path.to_string(), platform, version, time_base, speed_a, speed_b, frame_mode, rows_per_pattern,
pattern_matrix, channel_patterns, instruments, samples pattern_matrix, loop_at, channel_patterns, instruments, samples
} }
) )
} }