Fix assorted bugs and get this shit workingggg...except maybe being off-key :x

master
Ashley N. 2023-08-26 18:48:01 -04:00
parent a1b9a5dde5
commit f50b974f4b
2 changed files with 42 additions and 27 deletions

View File

@ -293,7 +293,7 @@ fn apply_effects_to_channel( channel: &mut Channel, effects: &LinkedHashSet<Effe
// Add new note cut. Being an effect requiring delay generation, it will generate (and expire) in get_delays // 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 } ); 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;
@ -332,25 +332,11 @@ fn apply_effects_to_channel( channel: &mut Channel, effects: &LinkedHashSet<Effe
Ok( events ) Ok( events )
} }
/** fn sequence_to_compacted_delay( current_sequence: &Vec<EchoEvent> ) -> Result<Vec<EchoEvent>, Box<dyn Error>> {
* Replace concurrent sequences of waits with single larger waits. This reduces the ESF stream size.
*/
pub fn compact_delays( events: Vec<EchoEvent> ) -> Result<Vec<EchoEvent>, Box<dyn Error>> {
let mut new_events: Vec<EchoEvent> = Vec::new(); let mut new_events: Vec<EchoEvent> = Vec::new();
let mut current_sequence: Vec<EchoEvent> = Vec::new();
for event in events {
if let Some( esf_event_type ) = event.iter().next() {
if *esf_event_type & 0xF0 == ESF_DELAY_SHORT || *esf_event_type == ESF_DELAY_LONG {
// Continue to push delay events into current_sequence
current_sequence.push( event );
} else {
// Encountered a non-delay event - we will always push something here,
// but let's check first if we need to push a current_sequence of waits.
// Coalesce all current delays in current_sequence and push them
// onto the new event stream.
let mut cumulative_delay: u16 = 0; let mut cumulative_delay: u16 = 0;
for delay_event in &current_sequence { for delay_event in current_sequence {
let mut iter = delay_event.iter(); let mut iter = delay_event.iter();
let delay_type = *iter.next().ok_or( "internal error: empty event" )?; let delay_type = *iter.next().ok_or( "internal error: empty event" )?;
@ -369,8 +355,27 @@ pub fn compact_delays( events: Vec<EchoEvent> ) -> Result<Vec<EchoEvent>, Box<dy
// Push the remainder under 256 event // Push the remainder under 256 event
new_events.push( get_delay( ( cumulative_delay % 256 ) as u8 )? ); new_events.push( get_delay( ( cumulative_delay % 256 ) as u8 )? );
}
// Reset the current sequence Ok( new_events )
}
/**
* Replace concurrent sequences of waits with single larger waits. This reduces the ESF stream size.
*/
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();
for event in events {
if let Some( esf_event_type ) = event.iter().next() {
if *esf_event_type & 0xF0 == ESF_DELAY_SHORT || *esf_event_type == ESF_DELAY_LONG {
// Continue to push delay events into current_sequence
current_sequence.push( event );
} else {
let compacted_delay = sequence_to_compacted_delay( &current_sequence )?;
if !compacted_delay.is_empty() {
new_events.extend( compacted_delay.into_iter() );
current_sequence.clear(); current_sequence.clear();
} }
@ -379,6 +384,8 @@ pub fn compact_delays( events: Vec<EchoEvent> ) -> Result<Vec<EchoEvent>, Box<dy
} }
} }
new_events.extend( sequence_to_compacted_delay( &current_sequence )?.into_iter() );
Ok( new_events ) Ok( new_events )
} }
@ -454,6 +461,12 @@ fn get_note_cut( channel: &mut Channel, note_cut_effect: &Effect, tick: u8 ) ->
if tick >= after_ticks { if tick >= after_ticks {
if channel.active_note.is_some() { if channel.active_note.is_some() {
channel.active_note = None; channel.active_note = None;
// Consume the note cut after we are done with it - it does not remain active
channel.active_effects = channel.active_effects
.clone()
.into_iter()
.filter( | effect | !( matches!( effect, Effect::NoteCut { after_ticks: _ } ) ) )
.collect();
return Ok( vec![ ESF_NOTE_OFF | channel.id ] ); return Ok( vec![ ESF_NOTE_OFF | channel.id ] );
} }
} }

View File

@ -952,6 +952,8 @@ impl EchoFormat for DmfModule {
esf.extend( event ); esf.extend( event );
} }
esf.push( 0xFF ); // Terminate the stream
Ok( esf ) Ok( esf )
} }