Refactor for delays per effect
parent
686d44b137
commit
e45972316e
|
@ -341,6 +341,19 @@ fn apply_effects_to_channel( channel: &mut Channel, effects: &LinkedHashSet<Effe
|
|||
channel.active_effects.insert( Effect::PortamentoDown { speed } );
|
||||
}
|
||||
},
|
||||
Effect::NoteCut { after_ticks } => {
|
||||
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<EchoEvent> ) -> Result<Vec<EchoEvent>, Box<dy
|
|||
}
|
||||
|
||||
/**
|
||||
* Get the delays due at the end of a row. These delays are what flushes the tick to Echo so that it can play.
|
||||
* Calculate delays generated before and after effects applied across all channels. If there are no effects for this row,
|
||||
* an empty vec will be returned. This means you should just apply ticks_to_wait as the delay for that row. If there
|
||||
* -are- effects generated by this function, you should not apply ticks_to_wait, since this function will spend out
|
||||
* the tick budget for that row instead.
|
||||
*/
|
||||
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;
|
||||
fn get_delays_for_effects( channels: &mut [Channel], ticks_to_wait: u8 ) -> Result<Vec<EchoEvent>, Box<dyn Error>> {
|
||||
let mut events: Vec<EchoEvent> = 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<EchoEvent>, 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<EchoEvent>, 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<EchoEvent>, channels: &mut [Channel], ticks_to_wait: u8 ) -> Result<Vec<EchoEvent>, Box<dyn Error>> {
|
||||
let mut events: Vec<EchoEvent> = 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 )
|
||||
|
|
Loading…
Reference in New Issue