diff --git a/Makefile b/Makefile index 90cf3be2..53a0ef65 100644 --- a/Makefile +++ b/Makefile @@ -130,6 +130,8 @@ $(BUILD_DIR)/src/musyx/snd_init.o: CFLAGS := $(CFLAGS_MUSYX) $(BUILD_DIR)/src/musyx/dsp_import.o: CFLAGS := $(CFLAGS_MUSYX) $(BUILD_DIR)/src/musyx/hw_memory.o: CFLAGS := $(CFLAGS_MUSYX) $(BUILD_DIR)/src/musyx/reverb_fx.o: CFLAGS := $(CFLAGS_MUSYX) +$(BUILD_DIR)/src/musyx/delay_fx.o: CFLAGS := $(CFLAGS_MUSYX) + #------------------------------------------------------------------------------- # Recipes diff --git a/include/musyx/musyx.h b/include/musyx/musyx.h index f1070ec4..0f64e5cb 100644 --- a/include/musyx/musyx.h +++ b/include/musyx/musyx.h @@ -4,7 +4,7 @@ #include "types.h" #ifndef bool8 -typedef char bool8; +typedef unsigned char bool8; #endif #ifdef __cplusplus @@ -26,6 +26,9 @@ typedef struct _SND_HOOKS { #define SND_AUX_NUMPARAMETERS 4 +#define SND_AUX_REASON_BUFFERUPDATE 0 +#define SND_AUX_REASON_PARAMETERUPDATE 1 + typedef struct SND_AUX_INFO { union SND_AUX_DATA { struct SND_AUX_BUFFERUPDATE { @@ -73,6 +76,31 @@ typedef struct SND_AUX_REVERBHI { f32 crosstalk; } SND_AUX_REVERBHI; +void sndAuxCallbackReverbHI(u8 reason, SND_AUX_INFO* info, void* user); +bool8 sndAuxCallbackPrepareReverbHI(SND_AUX_REVERBHI *rev); +bool8 sndAuxCallbackShutdownReverbHI(SND_AUX_REVERBHI* rev); + +typedef struct SND_AUX_DELAY { + u32 currentSize[3]; + u32 currentPos[3]; + u32 currentFeedback[3]; + u32 currentOutput[3]; + + s32* left; + s32* right; + s32* sur; + + u32 delay[3]; // Delay buffer length in ms per channel + u32 feedback[3]; // Feedback volume in % per channel + u32 output[3]; // Output volume in % per channel +} SND_AUX_DELAY; + + +void sndAuxCallbackDelay(u8 reason,SND_AUX_INFO *info, void *user); +bool8 sndAuxCallbackUpdateSettingsDelay(SND_AUX_DELAY *delay); +bool8 sndAuxCallbackPrepareDelay(SND_AUX_DELAY *rev); +bool8 sndAuxCallbackShutdownDelay(SND_AUX_DELAY* rev); + #ifdef __cplusplus } #endif diff --git a/obj_files.mk b/obj_files.mk index c6ba6c21..fa4bb3ea 100644 --- a/obj_files.mk +++ b/obj_files.mk @@ -810,7 +810,7 @@ MUSYX_FILES :=\ $(BUILD_DIR)/asm/musyx/creverb.o\ $(BUILD_DIR)/src/musyx/reverb_fx.o\ $(BUILD_DIR)/asm/musyx/reverb.o\ - $(BUILD_DIR)/asm/musyx/delay_fx.o\ + $(BUILD_DIR)/src/musyx/delay_fx.o\ $(BUILD_DIR)/asm/musyx/chorus_fx.o DTK_FILES :=\ diff --git a/src/musyx/delay_fx.c b/src/musyx/delay_fx.c new file mode 100644 index 00000000..2b6a4b27 --- /dev/null +++ b/src/musyx/delay_fx.c @@ -0,0 +1,101 @@ +#include "musyx/musyx_priv.h" + +void sndAuxCallbackDelay(u8 reason, SND_AUX_INFO* info, void* user) { + s32 curSur; + s32 curLeft; + s32 curRight; + s32 i; + s32* leftOffset; + s32* surOffset; + s32* rightOffset; + s32* leftPtr; + s32* rightPtr; + s32* surPtr; + SND_AUX_DELAY* delay; + + switch (reason) { + case 0: + delay = (SND_AUX_DELAY*)user; + leftOffset = delay->left + (delay->currentPos[0] * 160); + leftPtr = info->data.bufferUpdate.left; + rightPtr = info->data.bufferUpdate.right; + rightOffset = delay->right + (delay->currentPos[1] * 160); + surPtr = info->data.bufferUpdate.surround; + surOffset = delay->sur + (delay->currentPos[2] * 160); + for (i = 160; i > 0; --i) { + curLeft = *leftOffset; + curRight = *rightOffset; + curSur = *surOffset; + *leftOffset = *leftPtr + ((s32)(curLeft * delay->currentFeedback[0]) >> 7); + ++leftOffset; + *rightOffset = *rightPtr + ((s32)(curRight * delay->currentFeedback[1]) >> 7); + ++rightOffset; + *surOffset = *surPtr + ((s32)(curSur * delay->currentFeedback[2]) >> 7); + ++surOffset; + *leftPtr = (s32)(curLeft * delay->currentOutput[0]) >> 7; + ++leftPtr; + *rightPtr = (s32)(curRight * delay->currentOutput[1]) >> 7; + ++rightPtr; + *surPtr = (s32)(curSur * delay->currentOutput[2]) >> 7; + ++surPtr; + } + delay->currentPos[0] = (delay->currentPos[0] + 1) % delay->currentSize[0]; + delay->currentPos[1] = (delay->currentPos[1] + 1) % delay->currentSize[1]; + delay->currentPos[2] = (delay->currentPos[2] + 1) % delay->currentSize[2]; + /* fallthrough */ + case 1: + return; + } +} + +bool8 sndAuxCallbackUpdateSettingsDelay(SND_AUX_DELAY* delay) { + s32 i; + s32* left; + s32* right; + s32* sur; + sndAuxCallbackShutdownDelay(delay); + + for (i = 0; i < 3; ++i) { + delay->currentSize[i] = ((delay->delay[i] - 5) * 32 + 159) / 160; + delay->currentPos[i] = 0; + delay->currentFeedback[i] = (delay->feedback[i] << 7) / 100; + delay->currentOutput[i] = (delay->output[i] << 7) / 100; + } + + delay->left = (s32*)salMalloc(delay->currentSize[0] * 0x280); + delay->right = (s32*)salMalloc(delay->currentSize[1] * 0x280); + delay->sur = (s32*)salMalloc(delay->currentSize[2] * 0x280); + + left = delay->left; + right = delay->right; + sur = delay->sur; + + for (i = 0; i < delay->currentSize[0] * 160; ++i) { + *left = 0; + ++left; + } + + for (i = 0; i < delay->currentSize[1] * 160; ++i) { + *right = 0; + ++right; + } + for (i = 0; i < delay->currentSize[2] * 160; ++i) { + *sur = 0; + ++sur; + } + return 1; +} + +bool8 sndAuxCallbackPrepareDelay(SND_AUX_DELAY* delay) { + delay->left = NULL; + return sndAuxCallbackUpdateSettingsDelay(delay); +} + +bool8 sndAuxCallbackShutdownDelay(SND_AUX_DELAY* delay) { + if (delay->left != NULL) { + salFree(delay->left); + salFree(delay->right); + salFree(delay->sur); + } + return 1; +} diff --git a/src/musyx/reverb_fx.c b/src/musyx/reverb_fx.c index dfd8c8b2..82a3478b 100644 --- a/src/musyx/reverb_fx.c +++ b/src/musyx/reverb_fx.c @@ -1,20 +1,16 @@ #include "musyx/musyx_priv.h" - -#ifdef __cplusplus -extern "C" { -#endif - + extern bool8 ReverbHICreate(_SND_REVHI_WORK* rev, f32 coloration, f32 time, f32 mix, f32 damping, f32 preDelay, f32 crosstalk); extern void ReverbHIFree(_SND_REVHI_WORK* rev); void sndAuxCallbackReverbHI(u8 reason, SND_AUX_INFO* info, void* user) { switch (reason) { - case 0: - if (*((u8*)user + 0x1c4) == 0) { + case SND_AUX_REASON_BUFFERUPDATE: + if (((SND_AUX_REVERBHI*)user)->tempDisableFX == 0) { ReverbHICallback(info->data.bufferUpdate.left, info->data.bufferUpdate.right, info->data.bufferUpdate.surround, user); } /* fallthrough */ - case 1: + case SND_AUX_REASON_PARAMETERUPDATE: return; } } @@ -28,8 +24,3 @@ bool8 sndAuxCallbackShutdownReverbHI(SND_AUX_REVERBHI* rev) { ReverbHIFree(&rev->rv); return 1; } - - -#ifdef __cplusplus -} -#endif