From f565e89c684485d8c7306ec535c7f83dbf2335dc Mon Sep 17 00:00:00 2001 From: Prince Frizzy Date: Tue, 15 Feb 2022 01:36:44 -0800 Subject: [PATCH] sound: Add extended channel mode for sequences. Provided by theclashingfritz --- include/seq_macros.inc | 10 ++ sound/sequences/00_sound_player.s | 3 +- src/audio/seq_channel_layer_process_script.h | 19 ++++ src/audio/seqplayer.c | 109 +++++++++++++++++++ 4 files changed, 140 insertions(+), 1 deletion(-) diff --git a/include/seq_macros.inc b/include/seq_macros.inc index 4ff87db9..e4f95b8d 100644 --- a/include/seq_macros.inc +++ b/include/seq_macros.inc @@ -78,6 +78,16 @@ .byte \a >> 8, \a & 0xff .endm +.macro seq_disablechannels_extended a + .byte 0xc0 + .byte \a >> 24, \a >> 16, \a >> 8, \a & 0xff +.endm + +.macro seq_initchannels_extended a + .byte 0xc1 + .byte \a >> 24, \a >> 16, \a >> 8, \a & 0xff +.endm + .macro seq_changevol a .byte 0xda .byte \a diff --git a/sound/sequences/00_sound_player.s b/sound/sequences/00_sound_player.s index 5179c49b..17934ef8 100644 --- a/sound/sequences/00_sound_player.s +++ b/sound/sequences/00_sound_player.s @@ -7,7 +7,8 @@ seq_setmutebhv 0x60 seq_setmutescale 0 seq_setvol 127 seq_settempo 120 -seq_initchannels 0xfff +#seq_initchannels 0xfff +seq_initchannels_extended 0xfff seq_startchannel 0, .channel0 seq_startchannel 1, .channel1 seq_startchannel 2, .channel2 diff --git a/src/audio/seq_channel_layer_process_script.h b/src/audio/seq_channel_layer_process_script.h index 17f67335..2f287b4c 100644 --- a/src/audio/seq_channel_layer_process_script.h +++ b/src/audio/seq_channel_layer_process_script.h @@ -64,6 +64,25 @@ } #endif +#if COPT +#define M64_READ_S32(state, dst) \ + dst = m64_read_s32(state); +#else +#define M64_READ_S32(state, dst) \ +{ \ + s32 _ret; \ + _ret = *(*state).pc << 24; \ + ((*state).pc)++; \ + _ret = (*(*state).pc << 16) | _ret; \ + ((*state).pc)++; \ + _ret = (*(*state).pc << 8) | _ret; \ + ((*state).pc)++; \ + _ret = *(*state).pc | _ret; \ + ((*state).pc)++; \ + dst = _ret; \ +} +#endif + #if COPT #define GET_INSTRUMENT(seqChannel, instId, _instOut, _adsr, dst, l) \ dst = get_instrument(seqChannel, instId, _instOut, _adsr); diff --git a/src/audio/seqplayer.c b/src/audio/seqplayer.c index 91146bbb..098a15bc 100644 --- a/src/audio/seqplayer.c +++ b/src/audio/seqplayer.c @@ -1,5 +1,10 @@ #include +#ifdef DEVELOPMENT +#include +#include +#endif + #include "data.h" #include "effects.h" #include "external.h" @@ -243,6 +248,79 @@ void sequence_player_disable_channels(struct SequencePlayer *seqPlayer, u16 chan } } +void sequence_player_init_channels_extended(struct SequencePlayer* seqPlayer, u32 channelBits) { + struct SequenceChannel* seqChannel; + s32 i; + +#ifdef DEVELOPMENT + printf("debug: Enabling channels (extended) with corresponding bits %X\n", channelBits); +#endif + + for (i = 0; i < CHANNELS_MAX; i++) { + if (channelBits & 1) { + seqChannel = seqPlayer->channels[i]; + if (IS_SEQUENCE_CHANNEL_VALID(seqChannel) == TRUE && seqChannel->seqPlayer == seqPlayer) { + sequence_channel_disable(seqChannel); + seqChannel->seqPlayer = NULL; +} + seqChannel = allocate_sequence_channel(); + if (IS_SEQUENCE_CHANNEL_VALID(seqChannel) == FALSE) { + gAudioErrorFlags = i + 0x10000; + seqPlayer->channels[i] = seqChannel; + } + else { + sequence_channel_init(seqChannel); + seqPlayer->channels[i] = seqChannel; + seqChannel->seqPlayer = seqPlayer; + seqChannel->bankId = seqPlayer->defaultBank[0]; + seqChannel->muteBehavior = seqPlayer->muteBehavior; + seqChannel->noteAllocPolicy = seqPlayer->noteAllocPolicy; + } + +#ifdef DEVELOPMENT + printf("debug: Tried to enable channel (extended) %i with result of validity %u.\n", i, IS_SEQUENCE_CHANNEL_VALID(seqChannel)); +#endif + } + +#ifdef DEVELOPMENT + printf("debug: Checked channel (extended) %i for enable with bit %u.\n", i, channelBits & 1); +#endif + +#ifdef VERSION_EU + channelBits = channelBits >> 1; +#else + channelBits >>= 1; +#endif + } +} + +void sequence_player_disable_channels_extended(struct SequencePlayer* seqPlayer, u32 channelBits) { + struct SequenceChannel* seqChannel; + s32 i; + +#ifdef DEVELOPMENT + printf("debug: Disabling channels (extended) with corresponding bits %X\n", channelBits); +#endif + + for (i = 0; i < CHANNELS_MAX; i++) { + if (channelBits & 1) { + seqChannel = seqPlayer->channels[i]; + if (IS_SEQUENCE_CHANNEL_VALID(seqChannel) == TRUE) { + if (seqChannel->seqPlayer == seqPlayer) { + sequence_channel_disable(seqChannel); + seqChannel->seqPlayer = NULL; + } + seqPlayer->channels[i] = &gSequenceChannelNone; + } + } +#ifdef VERSION_EU + channelBits = channelBits >> 1; +#else + channelBits >>= 1; +#endif + } +} + void sequence_channel_enable(struct SequencePlayer *seqPlayer, u8 channelIndex, void *arg2) { struct SequenceChannel *seqChannel = seqPlayer->channels[channelIndex]; s32 i; @@ -363,12 +441,20 @@ u8 m64_read_u8(struct M64ScriptState *state) { } s16 m64_read_s16(struct M64ScriptState *state) { +#ifdef DEVELOPMENT + assert(state != NULL); + assert(state->pc != NULL); +#endif s16 ret = *(state->pc++) << 8; ret = *(state->pc++) | ret; return ret; } u16 m64_read_compressed_u16(struct M64ScriptState *state) { +#ifdef DEVELOPMENT + assert(state != NULL); + assert(state->pc != NULL); +#endif u16 ret = *(state->pc++); if (ret & 0x80) { ret = (ret << 8) & 0x7f00; @@ -377,6 +463,18 @@ u16 m64_read_compressed_u16(struct M64ScriptState *state) { return ret; } +s32 m64_read_s32(struct M64ScriptState* state) { +#ifdef DEVELOPMENT + assert(state != NULL); + assert(state->pc != NULL); +#endif + s32 ret = *(state->pc++) << 24; + ret = (*(state->pc++) << 16) | ret; + ret = (*(state->pc++) << 8) | ret; + ret = *(state->pc++) | ret; + return ret; +} + #if defined(VERSION_EU) void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) { struct SequencePlayer *seqPlayer; // sp5C, t4 @@ -1547,6 +1645,7 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) { s32 value; s32 i; u16 u16v; + u32 u32v; u8 *tempPtr; struct M64ScriptState *state; #ifdef VERSION_EU @@ -1870,6 +1969,16 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) { sequence_player_disable_channels(seqPlayer, u16v); break; + case 0xc1: // seq_initchannels_extended + u32v = m64_read_s32(state); + sequence_player_init_channels_extended(seqPlayer, u32v); + break; + + case 0xc0: // seq_disablechannels_extended + u32v = m64_read_s32(state); + sequence_player_disable_channels_extended(seqPlayer, u32v); + break; + case 0xd5: // seq_setmutescale temp = m64_read_u8(state); seqPlayer->muteVolumeScale = (f32) (s8)temp / US_FLOAT(127.0);