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 } );
|
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 } => {
|
Effect::SetPanning { left, right } => {
|
||||||
let left = *left;
|
let left = *left;
|
||||||
let right = *right;
|
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>> {
|
fn get_delays_for_effects( channels: &mut [Channel], ticks_to_wait: u8 ) -> Result<Vec<EchoEvent>, Box<dyn Error>> {
|
||||||
let mut events: Vec<EchoEvent> = events;
|
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
|
// 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.
|
// 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() {
|
if !active_portamentos.is_empty() {
|
||||||
for _tick in 0..ticks_to_wait {
|
for _tick in 0..ticks_to_wait {
|
||||||
for ( channel_id, portamento ) in &active_portamentos {
|
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 )? );
|
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.
|
// 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 )? );
|
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 )
|
Ok( events )
|
||||||
|
|
Loading…
Reference in New Issue