diff --git a/src/reskit/soundtrack/engines/echo.rs b/src/reskit/soundtrack/engines/echo.rs index 613d46f..b566042 100644 --- a/src/reskit/soundtrack/engines/echo.rs +++ b/src/reskit/soundtrack/engines/echo.rs @@ -341,6 +341,19 @@ fn apply_effects_to_channel( channel: &mut Channel, effects: &LinkedHashSet { + let after_ticks = *after_ticks; + + // Remove all previous note cuts + channel.active_effects = channel.active_effects + .clone() + .into_iter() + .filter( | effect | !( matches!( effect, Effect::NoteCut { after_ticks: _ } ) ) ) + .collect(); + + // Add new note cut. Being an effect requiring delay generation, it will generate (and expire) in get_delays + channel.active_effects.insert( Effect::NoteCut { after_ticks } ); + } Effect::SetPanning { left, right } => { let left = *left; let right = *right; @@ -430,10 +443,13 @@ pub fn compact_delays( events: Vec ) -> Result, Box, channels: &mut [Channel], ticks_to_wait: u8 ) -> Result, Box> { - let mut events: Vec = events; +fn get_delays_for_effects( channels: &mut [Channel], ticks_to_wait: u8 ) -> Result, Box> { + let mut events: Vec = Vec::new(); // 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. @@ -449,9 +465,6 @@ fn get_delays( events: Vec, channels: &mut [Channel], ticks_to_wait: } } - // Do we have any active portamentos? If so, push them according to the portamento wait pattern. - // So let's say portamentos are defined on FM1 and FM5 and ticks_to_wait is 3. The generated events are: - // [ freq_shift_fm1, freq_shift_fm5, wait 1 tick, freq_shift_fm1, freq_shift_fm5, wait 1 tick, freq_shift_fm1, freq_shift_fm5, wait 1 tick ] if !active_portamentos.is_empty() { for _tick in 0..ticks_to_wait { for ( channel_id, portamento ) in &active_portamentos { @@ -461,9 +474,24 @@ fn get_delays( events: Vec, channels: &mut [Channel], ticks_to_wait: events.push( get_delay( 1 )? ); } - } else { + } + + Ok( events ) +} + +/** + * 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( events: Vec, channels: &mut [Channel], ticks_to_wait: u8 ) -> Result, Box> { + let mut events: Vec = events; + + let applied_effects = get_delays_for_effects( channels, ticks_to_wait )?; + if applied_effects.is_empty() { // Push the amount of ticks to wait for this row. ticks_to_wait is speed_a or speed_b, times base_speed. events.push( get_delay( ticks_to_wait )? ); + } else { + // Do not push the default "wait n ticks" event but rather push the delay events generated by effects + events.extend( applied_effects.into_iter() ); } Ok( events )