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 {
|
for row_number in 0..self.rows_per_pattern {
|
||||||
let events_this_row: Vec<EchoEvent> = get_events_for_row(
|
let events_this_row: Vec<EchoEvent> = get_events_for_row(
|
||||||
&mut channels,
|
&mut channels,
|
||||||
|
&self.instruments,
|
||||||
{
|
{
|
||||||
let mut columns: Vec<&PatternRow> = Vec::new();
|
let mut columns: Vec<&PatternRow> = Vec::new();
|
||||||
for channel in 0..10 {
|
for channel in 0..10 {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::{collections::HashMap, error::Error};
|
use std::{collections::HashMap, error::Error};
|
||||||
use linked_hash_set::LinkedHashSet;
|
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
|
// https://github.com/sikthehedgehog/Echo/blob/master/doc/esf.txt
|
||||||
const ESF_NOTE_ON: u8 = 0x00;
|
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.
|
* 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.
|
* 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();
|
let mut events: Vec<EchoEvent> = Vec::new();
|
||||||
|
|
||||||
// Adjust volume
|
// 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 ] );
|
events.push( vec![ ESF_SET_INSTRUMENT | channel.id, *instrument as u8 ] );
|
||||||
channel.active_instrument = Some( *instrument );
|
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
|
// 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
|
* 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.
|
* 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 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)
|
// Get events for each subrow (part of the total row for each channel)
|
||||||
for i in 0..channels.len() {
|
for i in 0..channels.len() {
|
||||||
// Apply effects to channel's current state
|
// Apply effects to channel's current state
|
||||||
events.extend( apply_effects_to_channel( &mut channels[ i ], &subrows[ i ].effects )? );
|
events.extend( apply_effects_to_channel( &mut channels[ i ], &subrows[ i ].effects )? );
|
||||||
|
|
||||||
// Get the ESF events for this channel's part of the row
|
// 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 )? )
|
Ok( get_delays( events, channels, ticks_to_wait )? )
|
||||||
|
|
|
@ -587,7 +587,7 @@ impl DmfModule {
|
||||||
if DmfModule::uses_default_psg( &channel_patterns )? {
|
if DmfModule::uses_default_psg( &channel_patterns )? {
|
||||||
print_info( "One or more channels use the default PSG instrument" );
|
print_info( "One or more channels use the default PSG instrument" );
|
||||||
instruments.push( Instrument{
|
instruments.push( Instrument{
|
||||||
name: format!( "Default PSG Instrument" ),
|
name: format!( "__reskit_default_psg_instrument" ),
|
||||||
instrument_type: InstrumentType::PsgDcsg( PsgSettings {
|
instrument_type: InstrumentType::PsgDcsg( PsgSettings {
|
||||||
volume: PsgEnvelope {
|
volume: PsgEnvelope {
|
||||||
envelope: vec![ 0x0F as u32 ],
|
envelope: vec![ 0x0F as u32 ],
|
||||||
|
|
Loading…
Reference in New Issue