From 375d85adb09e5321aef7dd0e4d1dbb1beeecb2d0 Mon Sep 17 00:00:00 2001 From: ashley Date: Sun, 27 Aug 2023 14:00:14 -0400 Subject: [PATCH] Apply default psg instrument --- src/reskit/soundtrack/engines/echo/dmf.rs | 1 + src/reskit/soundtrack/engines/echo/engine.rs | 30 +++++++++++++++++--- src/reskit/soundtrack/formats/dmf.rs | 2 +- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/reskit/soundtrack/engines/echo/dmf.rs b/src/reskit/soundtrack/engines/echo/dmf.rs index 111dfa6..3e9f401 100644 --- a/src/reskit/soundtrack/engines/echo/dmf.rs +++ b/src/reskit/soundtrack/engines/echo/dmf.rs @@ -311,6 +311,7 @@ impl EchoFormat for DmfModule { for row_number in 0..self.rows_per_pattern { let events_this_row: Vec = get_events_for_row( &mut channels, + &self.instruments, { let mut columns: Vec<&PatternRow> = Vec::new(); for channel in 0..10 { diff --git a/src/reskit/soundtrack/engines/echo/engine.rs b/src/reskit/soundtrack/engines/echo/engine.rs index 783a6c0..fd1148e 100644 --- a/src/reskit/soundtrack/engines/echo/engine.rs +++ b/src/reskit/soundtrack/engines/echo/engine.rs @@ -1,6 +1,6 @@ use std::{collections::HashMap, error::Error}; use linked_hash_set::LinkedHashSet; -use crate::reskit::{soundtrack::types::{PatternRow, Note, Channel, OctaveFrequency, Effect}, utility::print_warning}; +use crate::reskit::{soundtrack::types::{PatternRow, Note, Channel, OctaveFrequency, Effect, Instrument}, utility::print_warning}; // https://github.com/sikthehedgehog/Echo/blob/master/doc/esf.txt const ESF_NOTE_ON: u8 = 0x00; @@ -169,7 +169,7 @@ pub fn get_delay( delay: u8 ) -> Result> { * For a specific row and channel, get the events this row and channel contribute to the stream. * While doing so, update the state of the channel for future event generation. */ -pub fn get_events_for_channel( channel: &mut Channel, row: &PatternRow, pcm_offset: u8 ) -> Result, Box> { +pub fn get_events_for_channel( channel: &mut Channel, row: &PatternRow, pcm_offset: u8, default_psg_instr_index: Option ) -> Result, Box> { let mut events: Vec = Vec::new(); // Adjust volume @@ -187,6 +187,18 @@ pub fn get_events_for_channel( channel: &mut Channel, row: &PatternRow, pcm_offs events.push( vec![ ESF_SET_INSTRUMENT | channel.id, *instrument as u8 ] ); channel.active_instrument = Some( *instrument ); } + } else { + // This is SN1, SN2, or SN3 with no active instrument + // Check if the channel needs "__reskit_default_psg_instrument" set before a note is set + if channel.active_instrument.is_none() && ( 6..=8 ).contains( &channel.id ) { + if row.note.is_some() { + // Set "__reskit_default_psg_instrument" + let instrument = default_psg_instr_index.ok_or( "internal error: no default psg instrument to apply" )?; + + events.push( vec![ ESF_SET_INSTRUMENT | channel.id, instrument as u8 ] ); + channel.active_instrument = Some( instrument ); + } + } } // Key on or key off note @@ -555,16 +567,26 @@ pub fn get_delays( events: Vec, channels: &mut [Channel], ticks_to_wa * 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. */ -pub fn get_events_for_row( channels: &mut [Channel], subrows: Vec<&PatternRow>, ticks_to_wait: u8, pcm_offset: u8 ) -> Result, Box> { +pub fn get_events_for_row( channels: &mut [Channel], instruments: &Vec, subrows: Vec<&PatternRow>, ticks_to_wait: u8, pcm_offset: u8 ) -> Result, Box> { let mut events: Vec = Vec::new(); + let mut index = 0; + let default_psg_instr_index: Option = instruments.iter().find_map( | item | { + if item.name == "__reskit_default_psg_instrument" { + Some( index ) + } else { + index += 1; + None + } + } ); + // Get events for each subrow (part of the total row for each channel) for i in 0..channels.len() { // Apply effects to channel's current state events.extend( apply_effects_to_channel( &mut channels[ i ], &subrows[ i ].effects )? ); // Get the ESF events for this channel's part of the row - events.extend( get_events_for_channel( &mut channels[ i ], subrows[ i ], pcm_offset )? ); + events.extend( get_events_for_channel( &mut channels[ i ], subrows[ i ], pcm_offset, default_psg_instr_index )? ); } Ok( get_delays( events, channels, ticks_to_wait )? ) diff --git a/src/reskit/soundtrack/formats/dmf.rs b/src/reskit/soundtrack/formats/dmf.rs index 2b5b76f..b8df736 100644 --- a/src/reskit/soundtrack/formats/dmf.rs +++ b/src/reskit/soundtrack/formats/dmf.rs @@ -587,7 +587,7 @@ impl DmfModule { if DmfModule::uses_default_psg( &channel_patterns )? { print_info( "One or more channels use the default PSG instrument" ); instruments.push( Instrument{ - name: format!( "Default PSG Instrument" ), + name: format!( "__reskit_default_psg_instrument" ), instrument_type: InstrumentType::PsgDcsg( PsgSettings { volume: PsgEnvelope { envelope: vec![ 0x0F as u32 ],