Compact sequences of delays globally instead of locally per row

master
Ashley N. 2023-08-25 13:34:28 -04:00
parent 8df69b7eae
commit 38e5cfaf18
2 changed files with 14 additions and 9 deletions

View File

@ -385,7 +385,7 @@ fn apply_effects_to_channel( channel: &mut Channel, effects: &LinkedHashSet<Effe
/**
* Replace concurrent sequences of waits with single larger waits. This reduces the ESF stream size.
*/
fn compact_delays( events: Vec<EchoEvent> ) -> Result<Vec<EchoEvent>, Box<dyn Error>> {
pub fn compact_delays( events: Vec<EchoEvent> ) -> Result<Vec<EchoEvent>, Box<dyn Error>> {
let mut new_events: Vec<EchoEvent> = Vec::new();
let mut current_sequence: Vec<EchoEvent> = Vec::new();
@ -435,8 +435,8 @@ fn compact_delays( events: Vec<EchoEvent> ) -> Result<Vec<EchoEvent>, Box<dyn Er
/**
* Get the delays due at the end of a row. These delays are what flushes the tick to Echo so that it can play.
*/
fn get_delays( channels: &mut [Channel], ticks_to_wait: u8 ) -> Result<Vec<EchoEvent>, Box<dyn Error>> {
let mut events: Vec<EchoEvent> = Vec::new();
fn get_delays( events: Vec<EchoEvent>, channels: &mut [Channel], ticks_to_wait: u8 ) -> Result<Vec<EchoEvent>, Box<dyn Error>> {
let mut events: Vec<EchoEvent> = events;
// All portamento effects deploy per tick, not per row. So we need to aggregate all portamentos across all
// channels for this row, then flush them once per `ticks_to_wait` for this row.
@ -469,7 +469,7 @@ fn get_delays( channels: &mut [Channel], ticks_to_wait: u8 ) -> Result<Vec<EchoE
events.push( get_delay( ticks_to_wait )? );
}
Ok( compact_delays( events )? )
Ok( events )
}
/**
@ -488,5 +488,5 @@ pub fn get_events_for_row( channels: &mut [Channel], subrows: Vec<&PatternRow>,
events.extend( get_events_for_channel( &mut channels[ i ], subrows[ i ] )? );
}
Ok( get_delays( channels, ticks_to_wait )? )
Ok( get_delays( events, channels, ticks_to_wait )? )
}

View File

@ -3,7 +3,7 @@ use flate2::read::ZlibDecoder;
use linked_hash_set::LinkedHashSet;
use samplerate::convert;
use uuid::Uuid;
use crate::reskit::{utility::{get_string, get_u8, skip, get_u32, get_i8, get_i32, get_u16, get_i16, Ring, print_warning, print_info}, soundtrack::{types::{SampleFormat, PsgEnvelope, Note, Sample, PsgSettings, PatternRow, Effect, DcsgChannelMode, NoiseType, Channel}, engines::echo::{EchoFormat, EchoEvent, ESF_FM_1, ESF_FM_2, ESF_FM_3, ESF_FM_4, ESF_FM_5, ESF_PSG_1, ESF_FM_6, ESF_PSG_2, ESF_PSG_3, ESF_PSG_4, get_events_for_row}}};
use crate::reskit::{utility::{get_string, get_u8, skip, get_u32, get_i8, get_i32, get_u16, get_i16, Ring, print_warning, print_info}, soundtrack::{types::{SampleFormat, PsgEnvelope, Note, Sample, PsgSettings, PatternRow, Effect, DcsgChannelMode, NoiseType, Channel}, engines::echo::{EchoFormat, EchoEvent, ESF_FM_1, ESF_FM_2, ESF_FM_3, ESF_FM_4, ESF_FM_5, ESF_PSG_1, ESF_FM_6, ESF_PSG_2, ESF_PSG_3, ESF_PSG_4, get_events_for_row, compact_delays}}};
const DMF_MAGIC_NUMBER: &'static str = ".DelekDefleMask.";
const DMF_SUPPORTED_VERSION: u8 = 27;
@ -942,6 +942,7 @@ impl EchoFormat for DmfModule {
// Iterate for each row, for each channel
// Recall items are stored as self.channel_patterns[ channel ][ row_number ]
let mut all_events: Vec<EchoEvent> = Vec::new();
for row_number in 0..self.rows_per_pattern {
let events_this_row: Vec<EchoEvent> = get_events_for_row(
&mut channels,
@ -961,9 +962,13 @@ impl EchoFormat for DmfModule {
)?;
// Transfer ESF events to the main stream
for event in events_this_row {
esf.extend( event );
all_events.extend( events_this_row );
}
// Compact sequences of delays to save rom space
let all_events = compact_delays( all_events )?;
for event in all_events {
esf.extend( event );
}
Ok( esf )