From 2ec1e23fe5bdefe8593a27437c9c25a1fc702d93 Mon Sep 17 00:00:00 2001 From: Cuyler36 <24523422+Cuyler36@users.noreply.github.com> Date: Sun, 9 Jun 2024 20:29:22 -0400 Subject: [PATCH] Implement & link jaudio_NES/[dspbuf.c, cpubuf.c] --- config/dol_slices.yml | 9 ++ include/jaudio_NES/audiocommon.h | 6 +- include/jaudio_NES/cpubuf.h | 3 +- include/jaudio_NES/dspbuf.h | 3 +- include/jaudio_NES/dspdriver.h | 8 ++ include/jaudio_NES/dspinterface.h | 1 + include/jaudio_NES/dspproc.h | 1 + include/jaudio_NES/ipldec.h | 8 ++ include/jaudio_NES/neosthread.h | 3 + include/jaudio_NES/playercall.h | 4 + include/jaudio_NES/rate.h | 1 + src/static/jaudio_NES/internal/audiothread.c | 4 +- src/static/jaudio_NES/internal/cpubuf.c | 93 ++++++++++++++++ src/static/jaudio_NES/internal/dspbuf.c | 111 +++++++++++++++++++ src/static/jaudio_NES/internal/neosthread.c | 2 +- src/static/jaudio_NES/internal/playercall.c | 71 ++++++------ 16 files changed, 284 insertions(+), 44 deletions(-) create mode 100644 include/jaudio_NES/dspdriver.h create mode 100644 include/jaudio_NES/ipldec.h create mode 100644 src/static/jaudio_NES/internal/cpubuf.c create mode 100644 src/static/jaudio_NES/internal/dspbuf.c diff --git a/config/dol_slices.yml b/config/dol_slices.yml index 2cae983b..bbf18cb8 100644 --- a/config/dol_slices.yml +++ b/config/dol_slices.yml @@ -89,6 +89,15 @@ jaudio_NES/internal/streamctrl.c: .data: [0x800d01a8, 0x800d0278] .bss: [0x80186440, 0x801864b0] .sdata2: [0x80218dc0, 0x80218dd0] +jaudio_NES/internal/dspbuf.c: + .text: [0x80019760, 0x80019ae0] + .rodata: [0x800aa558, 0x800aa570] + .bss: [0x801864b0, 0x801864c0] + .sbss: [0x80218478, 0x80218488] +jaudio_NES/internal/cpubuf.c: + .text: [0x80019ae0, 0x80019dc0] + .bss: [0x801864c0, 0x801864d0] + .sbss: [0x80218488, 0x80218498] jaudio_NES/internal/playercall.c: .text: [0x80019dc0, 0x8001a0c0] .bss: [0x801864d0,0x80186590] diff --git a/include/jaudio_NES/audiocommon.h b/include/jaudio_NES/audiocommon.h index 6165526d..d62dd1d4 100644 --- a/include/jaudio_NES/audiocommon.h +++ b/include/jaudio_NES/audiocommon.h @@ -20,9 +20,9 @@ extern "C" { (u32)((((a0) & 0xFF) << 24) | (((a1) & 0xFF) << 16) | (((a2) & 0xFF) << 8) | (((a3) & 0xFF) << 0)) typedef enum DSPBUF_EVENTS { - DSPBUF_EVENTS_0 = 0, - DSPBUF_EVENTS_1 = 1, - DSPBUF_EVENTS_2 = 2, + DSPBUF_EVENT_INIT = 0, + DSPBUF_EVENT_FRAME_END = 1, + DSPBUF_EVENT_MIX = 2, } DSPBUF_EVENTS; typedef enum SampleMedium { diff --git a/include/jaudio_NES/cpubuf.h b/include/jaudio_NES/cpubuf.h index a90de7e4..a834d4b0 100644 --- a/include/jaudio_NES/cpubuf.h +++ b/include/jaudio_NES/cpubuf.h @@ -2,9 +2,10 @@ #define CPUBUF_H #include "types.h" +#include "jaudio_NES/rate.h" #include "jaudio_NES/audiocommon.h" -extern u32 CpubufProcess(DSPBUF_EVENTS event); +extern s16* CpubufProcess(DSPBUF_EVENTS event); extern void CpuFrameEnd(void); extern s16* MixCpu(s32 nSamples); diff --git a/include/jaudio_NES/dspbuf.h b/include/jaudio_NES/dspbuf.h index c45a713e..0068df77 100644 --- a/include/jaudio_NES/dspbuf.h +++ b/include/jaudio_NES/dspbuf.h @@ -3,8 +3,9 @@ #include "types.h" #include "jaudio_NES/audiocommon.h" +#include "jaudio_NES/rate.h" -extern u32 DspbufProcess(DSPBUF_EVENTS event); +extern s16* DspbufProcess(DSPBUF_EVENTS event); extern s16* MixDsp(s32 nSamples); extern void UpdateDSP(void); extern void DspFrameEnd(void); diff --git a/include/jaudio_NES/dspdriver.h b/include/jaudio_NES/dspdriver.h new file mode 100644 index 00000000..0e3fbba6 --- /dev/null +++ b/include/jaudio_NES/dspdriver.h @@ -0,0 +1,8 @@ +#ifndef DSPDRIVER_H +#define DSPDRIVER_H + +#include "types.h" + +extern void UpdateDSPchannelAll(void); + +#endif diff --git a/include/jaudio_NES/dspinterface.h b/include/jaudio_NES/dspinterface.h index 0cc55ead..d1f35aea 100644 --- a/include/jaudio_NES/dspinterface.h +++ b/include/jaudio_NES/dspinterface.h @@ -4,5 +4,6 @@ #include "types.h" extern void DSP_InitBuffer(void); +extern void DSP_InvalChannelAll(void); #endif diff --git a/include/jaudio_NES/dspproc.h b/include/jaudio_NES/dspproc.h index 5bd9e1a3..018be422 100644 --- a/include/jaudio_NES/dspproc.h +++ b/include/jaudio_NES/dspproc.h @@ -4,5 +4,6 @@ #include "types.h" extern u32 DSPReleaseHalt(void); +extern void DsyncFrame(u32 subframes, u32 dspbuf_start, u32 dspbuf_end); #endif diff --git a/include/jaudio_NES/ipldec.h b/include/jaudio_NES/ipldec.h new file mode 100644 index 00000000..c86fc8c1 --- /dev/null +++ b/include/jaudio_NES/ipldec.h @@ -0,0 +1,8 @@ +#ifndef IPLDEC_H +#define IPLDEC_H + +#include "types.h" + +extern BOOL DspExtraTaskCheck(void); + +#endif diff --git a/include/jaudio_NES/neosthread.h b/include/jaudio_NES/neosthread.h index 17e552b3..c0600c44 100644 --- a/include/jaudio_NES/neosthread.h +++ b/include/jaudio_NES/neosthread.h @@ -4,6 +4,9 @@ #include "types.h" #include "jaudio_NES/audiostruct.h" +extern u32 Neos_Update(s16* dst); +extern void ImageLoaded(u32 param); +extern BOOL Neos_CheckBoot(void); extern void* neosproc(void* param); #endif diff --git a/include/jaudio_NES/playercall.h b/include/jaudio_NES/playercall.h index 1f242e98..9b9a5cab 100644 --- a/include/jaudio_NES/playercall.h +++ b/include/jaudio_NES/playercall.h @@ -16,4 +16,8 @@ extern s32 Jac_RegisterPlayerCallback(PlayerCallBack callback, void* arg); } #endif +/* C++ linkage, should these go in a different header file? */ +extern void PlayerCallback(); +extern void DspPlayerCallback(); + #endif diff --git a/include/jaudio_NES/rate.h b/include/jaudio_NES/rate.h index f063e142..ef121740 100644 --- a/include/jaudio_NES/rate.h +++ b/include/jaudio_NES/rate.h @@ -8,6 +8,7 @@ extern "C" { #endif extern u32 JAC_AI_SETTING; +extern u32 JAC_SUBFRAMES; extern u32 JAC_FRAMESAMPLES; extern u32 DAC_SIZE; diff --git a/src/static/jaudio_NES/internal/audiothread.c b/src/static/jaudio_NES/internal/audiothread.c index bafc71ca..5d3ffeb6 100644 --- a/src/static/jaudio_NES/internal/audiothread.c +++ b/src/static/jaudio_NES/internal/audiothread.c @@ -98,8 +98,8 @@ static void* audioproc(void* param) { Jac_Init(); Jac_InitSinTable(); ResetPlayerCallback(); - DspbufProcess(DSPBUF_EVENTS_0); - CpubufProcess(DSPBUF_EVENTS_0); + DspbufProcess(DSPBUF_EVENT_INIT); + CpubufProcess(DSPBUF_EVENT_INIT); DspBoot(); DSP_InitBuffer(); __DspReg(); diff --git a/src/static/jaudio_NES/internal/cpubuf.c b/src/static/jaudio_NES/internal/cpubuf.c new file mode 100644 index 00000000..684c5c44 --- /dev/null +++ b/src/static/jaudio_NES/internal/cpubuf.c @@ -0,0 +1,93 @@ +#include "jaudio_NES/cpubuf.h" + +#include "jaudio_NES/aictrl.h" +#include "jaudio_NES/audiothread.h" +#include "jaudio_NES/neosthread.h" +#include "jaudio_NES/playercall.h" +#include "jaudio_NES/dummyprobe.h" + +#define DSPBUF_NUM 3 + +static u8 write_buffer = 0; +static u8 read_buffer = 0; +static u8 dspstatus = 0; +static s16* dsp_buf[DSPBUF_NUM]; +static u32 dac_sync_counter = 0; + +extern s16* CpubufProcess(DSPBUF_EVENTS event) { + u32 i; + u32 j; + + switch (event) { + case DSPBUF_EVENT_INIT: + write_buffer = 2; + read_buffer = 0; + for (i = 0; i < DSPBUF_NUM; i++) { + dsp_buf[i] = (s16*)OSAlloc2(JAC_FRAMESAMPLES << 2); + for (j = 0; j < (JAC_FRAMESAMPLES << 1); j++) { + dsp_buf[i][j] = 0; + } + + DCStoreRange(dsp_buf[i], JAC_FRAMESAMPLES << 2); + } + + dspstatus = 0; + break; + case DSPBUF_EVENT_FRAME_END: + u8 write = write_buffer + 1; + + if (write == DSPBUF_NUM) { + write = 0; + } + + if (write == read_buffer) { + dspstatus = 0; + } else { + write_buffer = write; + if (Neos_Update(dsp_buf[write_buffer]) == TRUE) { + dspstatus = 1; + } + } + break; + case DSPBUF_EVENT_MIX: + u8 read = read_buffer + 1; + if (read == DSPBUF_NUM) { + read = 0; + } + + if (read == write_buffer) { + s16 left = dsp_buf[read_buffer][(JAC_FRAMESAMPLES / 2) - 1]; + s16 right = dsp_buf[read_buffer][JAC_FRAMESAMPLES - 1]; + + for (i = 0; i < JAC_FRAMESAMPLES; i++) { + dsp_buf[read_buffer][i] = right; + } + + for (i = JAC_FRAMESAMPLES; i < (JAC_FRAMESAMPLES << 1); i++) { + dsp_buf[read_buffer][i] = left; + } + + if (dspstatus == 0) { + CpubufProcess(DSPBUF_EVENT_FRAME_END); + } + } else { + read_buffer = read; + if (dspstatus == 0) { + CpubufProcess(DSPBUF_EVENT_FRAME_END); + } + } + + return dsp_buf[read_buffer]; + } + + return nullptr; +} + +extern s16* MixCpu(s32 n_samples) { + static s32 cur = 0; + return CpubufProcess(DSPBUF_EVENT_MIX); +} + +extern void CpuFrameEnd(void) { + CpubufProcess(DSPBUF_EVENT_FRAME_END); +} diff --git a/src/static/jaudio_NES/internal/dspbuf.c b/src/static/jaudio_NES/internal/dspbuf.c new file mode 100644 index 00000000..63108ef6 --- /dev/null +++ b/src/static/jaudio_NES/internal/dspbuf.c @@ -0,0 +1,111 @@ +#include "jaudio_NES/dspbuf.h" + +#include "jaudio_NES/aictrl.h" +#include "jaudio_NES/ipldec.h" +#include "jaudio_NES/audiothread.h" +#include "jaudio_NES/dspproc.h" +#include "jaudio_NES/dspdriver.h" +#include "jaudio_NES/dspinterface.h" +#include "jaudio_NES/playercall.h" +#include "jaudio_NES/dummyprobe.h" + +#define DSPBUF_NUM 3 + +static u8 write_buffer = 0; +static u8 read_buffer = 0; +static u8 dspstatus = 0; +static s16* dsp_buf[DSPBUF_NUM]; +static u32 dac_sync_counter = 0; + +extern s16* DspbufProcess(DSPBUF_EVENTS event) { + u32 i; + u32 j; + + switch (event) { + case DSPBUF_EVENT_INIT: + write_buffer = 2; + read_buffer = 0; + for (i = 0; i < DSPBUF_NUM; i++) { + dsp_buf[i] = (s16*)OSAlloc2(JAC_FRAMESAMPLES << 2); + for (j = 0; j < (JAC_FRAMESAMPLES << 1); j++) { + dsp_buf[i][j] = 0; + } + + DCStoreRange(dsp_buf[i], JAC_FRAMESAMPLES << 2); + } + + dspstatus = 0; + break; + case DSPBUF_EVENT_FRAME_END: + DspExtraTaskCheck(); + u8 write = write_buffer + 1; + + if (write == DSPBUF_NUM) { + write = 0; + } + + if (write == read_buffer) { + dspstatus = 0; + } else { + write_buffer = write; + DspSyncCountClear(JAC_SUBFRAMES); + Probe_Start(7, "DSP-MAIN"); + DsyncFrame(JAC_SUBFRAMES, (u32)dsp_buf[write_buffer], (u32)&dsp_buf[write_buffer][JAC_FRAMESAMPLES]); + dspstatus = 1; + UpdateDSP(); + } + break; + case DSPBUF_EVENT_MIX: + u8 read = read_buffer + 1; + if (read == DSPBUF_NUM) { + read = 0; + } + + if (read == write_buffer) { + s16 left = dsp_buf[read_buffer][(JAC_FRAMESAMPLES / 2) - 1]; + s16 right = dsp_buf[read_buffer][JAC_FRAMESAMPLES - 1]; + + for (i = 0; i < JAC_FRAMESAMPLES; i++) { + dsp_buf[read_buffer][i] = left; + } + + for (i = JAC_FRAMESAMPLES; i < (JAC_FRAMESAMPLES << 1); i++) { + dsp_buf[read_buffer][i] = right; + } + + if (dspstatus == 0) { + DspbufProcess(DSPBUF_EVENT_FRAME_END); + } + } else { + read_buffer = read; + DCInvalidateRange(dsp_buf[read_buffer], JAC_FRAMESAMPLES << 2); + if (dspstatus == 0) { + DspbufProcess(DSPBUF_EVENT_FRAME_END); + } + } + + return dsp_buf[read_buffer]; + } + + return nullptr; +} + +extern void UpdateDSP(void) { + dac_sync_counter++; + Probe_Start(3, "SFR-UPDATE"); + DSP_InvalChannelAll(); + DspPlayerCallback(); + UpdateDSPchannelAll(); + DSPReleaseHalt(); + PlayerCallback(); + Probe_Finish(3); +} + +extern s16* MixDsp(s32 n_samples) { + static s32 cur = 0; + return DspbufProcess(DSPBUF_EVENT_MIX); +} + +extern void DspFrameEnd(void) { + DspbufProcess(DSPBUF_EVENT_FRAME_END); +} diff --git a/src/static/jaudio_NES/internal/neosthread.c b/src/static/jaudio_NES/internal/neosthread.c index 73f93298..db0fe564 100644 --- a/src/static/jaudio_NES/internal/neosthread.c +++ b/src/static/jaudio_NES/internal/neosthread.c @@ -22,7 +22,7 @@ static u32 neosproc_mq_init = FALSE; static s16* tmp_buf = nullptr; static BOOL neos_ready = FALSE; -extern BOOL Neos_Update(s16* dst) { +extern u32 Neos_Update(s16* dst) { if (neosproc_mq_init) { if (OSSendMessage(&neosproc_mq, (OSMessage)dst, OS_MESSAGE_NOBLOCK) == TRUE) { return TRUE; diff --git a/src/static/jaudio_NES/internal/playercall.c b/src/static/jaudio_NES/internal/playercall.c index 8ae19009..58a13730 100644 --- a/src/static/jaudio_NES/internal/playercall.c +++ b/src/static/jaudio_NES/internal/playercall.c @@ -3,29 +3,29 @@ static PLAYER_CALL PLAYER_CALLLIST[16]; -extern void ResetPlayerCallback(){ +extern void ResetPlayerCallback() { int i; - for(i = 0; i < 16; i++){ + for (i = 0; i < 16; i++) { PLAYER_CALLLIST[i].callback = nullptr; } } -static s32 Jac_CheckPlayerCallback(PlayerCallBack callback, void* arg){ - int i; +static s32 Jac_CheckPlayerCallback(PlayerCallBack callback, void* arg) { + int i; - for(i = 0; i < 16; i++){ - if(PLAYER_CALLLIST[i].callback == callback && PLAYER_CALLLIST[i].arg == arg){ + for (i = 0; i < 16; i++) { + if (PLAYER_CALLLIST[i].callback == callback && PLAYER_CALLLIST[i].arg == arg) { return i; } - } + } return -1; } -extern s32 Jac_RegisterDspPlayerCallback(PlayerCallBack callback, void* arg){ - s32 idx = Jac_RegisterPlayerCallback(callback,arg); +extern s32 Jac_RegisterDspPlayerCallback(PlayerCallBack callback, void* arg) { + s32 idx = Jac_RegisterPlayerCallback(callback, arg); - if(idx == -1){ + if (idx == -1) { return -1; } @@ -34,23 +34,22 @@ extern s32 Jac_RegisterDspPlayerCallback(PlayerCallBack callback, void* arg){ return idx; } -extern s32 Jac_RegisterPlayerCallback(PlayerCallBack callback, void* arg){ - u32 i; +extern s32 Jac_RegisterPlayerCallback(PlayerCallBack callback, void* arg) { + u32 i; - for(i = 0; i < 16; i++){ - if(PLAYER_CALLLIST[i].callback == nullptr){ + for (i = 0; i < 16; i++) { + if (PLAYER_CALLLIST[i].callback == nullptr) { break; } - } + } - if(i == 16){ + if (i == 16) { return -1; } - - if(Jac_CheckPlayerCallback(callback,arg) != -1){ + + if (Jac_CheckPlayerCallback(callback, arg) != -1) { return -1; - } - else{ + } else { PLAYER_CALLLIST[i].callback = callback; PLAYER_CALLLIST[i].arg = arg; PLAYER_CALLLIST[i].DSP_mode = false; @@ -60,24 +59,24 @@ extern s32 Jac_RegisterPlayerCallback(PlayerCallBack callback, void* arg){ return -1; } -extern void PlayerCallback(){ - u32 i; +extern void PlayerCallback() { + u32 i; - for(i = 0; i < 16; i++){ + for (i = 0; i < 16; i++) { PlayerCallBack callback = PLAYER_CALLLIST[i].callback; - if(callback != nullptr && PLAYER_CALLLIST[i].DSP_mode == false && callback(PLAYER_CALLLIST[i].arg) == -1){ - PLAYER_CALLLIST[i].callback = nullptr; - } - } -} - -extern void DspPlayerCallback(){ - u32 i; - - for(i = 0; i < 16; i++){ - PlayerCallBack callback = PLAYER_CALLLIST[i].callback; - if(callback != nullptr && PLAYER_CALLLIST[i].DSP_mode == true && callback(PLAYER_CALLLIST[i].arg) == -1){ + if (callback != nullptr && PLAYER_CALLLIST[i].DSP_mode == false && callback(PLAYER_CALLLIST[i].arg) == -1) { PLAYER_CALLLIST[i].callback = nullptr; } } -} \ No newline at end of file +} + +extern void DspPlayerCallback() { + u32 i; + + for (i = 0; i < 16; i++) { + PlayerCallBack callback = PLAYER_CALLLIST[i].callback; + if (callback != nullptr && PLAYER_CALLLIST[i].DSP_mode == true && callback(PLAYER_CALLLIST[i].arg) == -1) { + PLAYER_CALLLIST[i].callback = nullptr; + } + } +}