Apply default psg instrument
parent
2f84d47d99
commit
375d85adb0
|
@ -311,6 +311,7 @@ impl EchoFormat for DmfModule {
|
|||
for row_number in 0..self.rows_per_pattern {
|
||||
let events_this_row: Vec<EchoEvent> = get_events_for_row(
|
||||
&mut channels,
|
||||
&self.instruments,
|
||||
{
|
||||
let mut columns: Vec<&PatternRow> = Vec::new();
|
||||
for channel in 0..10 {
|
||||
|
|
|
@ -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<EchoEvent, Box<dyn Error>> {
|
|||
* 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<Vec<EchoEvent>, Box<dyn Error>> {
|
||||
pub fn get_events_for_channel( channel: &mut Channel, row: &PatternRow, pcm_offset: u8, default_psg_instr_index: Option<u16> ) -> Result<Vec<EchoEvent>, Box<dyn Error>> {
|
||||
let mut events: Vec<EchoEvent> = 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<EchoEvent>, 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<Vec<EchoEvent>, Box<dyn Error>> {
|
||||
pub fn get_events_for_row( channels: &mut [Channel], instruments: &Vec<Instrument>, subrows: Vec<&PatternRow>, ticks_to_wait: u8, pcm_offset: u8 ) -> Result<Vec<EchoEvent>, Box<dyn Error>> {
|
||||
let mut events: Vec<EchoEvent> = Vec::new();
|
||||
|
||||
let mut index = 0;
|
||||
let default_psg_instr_index: Option<u16> = 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 )? )
|
||||
|
|
|
@ -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 ],
|
||||
|
|
Loading…
Reference in New Issue