diff --git a/src/reskit/soundtrack/engines/echo.rs b/src/reskit/soundtrack/engines/echo.rs index 3e6b789..9a3c923 100644 --- a/src/reskit/soundtrack/engines/echo.rs +++ b/src/reskit/soundtrack/engines/echo.rs @@ -344,6 +344,54 @@ fn apply_effects_to_channel( channel: &mut Channel, effects: &LinkedHashSet ) -> Result, Box> { + let mut new_events: Vec = Vec::new(); + + let mut current_sequence: Vec = Vec::new(); + for event in events { + if let Some( esf_event_type ) = event.iter().next() { + if *esf_event_type == ESF_DELAY_SHORT || *esf_event_type == ESF_DELAY_LONG { + // Continue to push delay events into current_sequence + current_sequence.push( event ); + } else { + // Coalesce all current delays in current_sequence and push them + // onto the new event stream. + let mut cumulative_delay: u16 = 0; + for delay_event in ¤t_sequence { + let mut iter = delay_event.iter(); + let delay_type = *iter.next().ok_or( "internal error: empty event" )?; + + if delay_type & 0xF0 == ESF_DELAY_SHORT { + cumulative_delay += ( delay_type & 0x0F ) as u16; + } else if delay_type == ESF_DELAY_LONG { + cumulative_delay += ( *iter.next().ok_or( "internal error: expected delay byte" )? ) as u16; + } + } + + if cumulative_delay > 0 { + // Push amount of full-256 wait events + for _ in 0..cumulative_delay / 256 { + new_events.push( vec![ ESF_DELAY_LONG, 0x00 ] ); + } + + // Push the remainder under 256 event + new_events.push( get_delay( ( cumulative_delay % 256 ) as u8 )? ); + + // Reset the current sequence + current_sequence.clear(); + } + + new_events.push( event ); + } + } + } + + Ok( new_events ) +} + /** * For an entire row across all channels, generate the events that apply to the row as a whole. This usually means applying * the waits so that the row can be flushed to Echo and played - ESF ticks are until the nearest wait or stop event. @@ -390,5 +438,5 @@ pub fn get_events_for_row( channels: &mut [Channel], subrows: Vec<&PatternRow>, events.push( get_delay( ticks_to_wait )? ); } - Ok( events ) + Ok( compact_delays( events )? ) } \ No newline at end of file