From ed0179f4de3ca3995c5c7b189e7e010f93522436 Mon Sep 17 00:00:00 2001 From: Cuyler36 <24523422+Cuyler36@users.noreply.github.com> Date: Tue, 4 Jun 2024 02:24:37 -0400 Subject: [PATCH] Link jaudio_NES/audiothread.c --- common.py | 3 +- config/disasm_overrides.yml | 1 + config/dol_slices.yml | 6 + configure.py | 3 +- include/dolphin/hw_regs.h | 114 +++++++++++++++++ include/dolphin/os/OSFastCast.h | 108 ++++++++++++++++ include/jaudio_NES/audiocommon.h | 6 + include/jaudio_NES/audiothread.h | 21 +++- include/jaudio_NES/cpubuf.h | 10 ++ include/jaudio_NES/dspboot.h | 8 ++ include/jaudio_NES/dspbuf.h | 4 + include/jaudio_NES/dspinterface.h | 8 ++ include/jaudio_NES/dspproc.h | 8 ++ include/jaudio_NES/dvdthread.h | 2 + include/jaudio_NES/ja_calc.h | 8 ++ include/jaudio_NES/neosthread.h | 8 ++ include/jaudio_NES/playercall.h | 16 +++ include/jaudio_NES/rate.h | 1 + src/static/jaudio_NES/audiothread.c | 187 ++++++++++++++++++++++++++++ 19 files changed, 517 insertions(+), 5 deletions(-) create mode 100644 include/dolphin/hw_regs.h create mode 100644 include/dolphin/os/OSFastCast.h create mode 100644 include/jaudio_NES/cpubuf.h create mode 100644 include/jaudio_NES/dspboot.h create mode 100644 include/jaudio_NES/dspinterface.h create mode 100644 include/jaudio_NES/dspproc.h create mode 100644 include/jaudio_NES/ja_calc.h create mode 100644 include/jaudio_NES/neosthread.h create mode 100644 include/jaudio_NES/playercall.h create mode 100644 src/static/jaudio_NES/audiothread.c diff --git a/common.py b/common.py index 708e87ca..b98479a5 100644 --- a/common.py +++ b/common.py @@ -449,7 +449,8 @@ JAUDIO_BASE = CFLAGS + [ ] + DOL_DEFINES JAUDIO_FUNC_ALIGN_32 = [ "-func_align 32", - "-str readonly" + "-str readonly", + "-inline off" ] JSYSTEM_CFLAGS = ' '.join(JSYSTEM_BASE + LOCAL_CFLAGS) diff --git a/config/disasm_overrides.yml b/config/disasm_overrides.yml index f5bf07b5..064b20ec 100644 --- a/config/disasm_overrides.yml +++ b/config/disasm_overrides.yml @@ -2,6 +2,7 @@ trim_ctors: true symbol_aligns: 0x80018920: 32 + 0x800190e0: 32 0x80207458: 8 # align RunQueue to 0x001251d8 0x800b9140: 32 # align gam_win_moji1_tex to 32 bytes 0x801f71c0: 32 # align texture_buffer_data to 32 bytes diff --git a/config/dol_slices.yml b/config/dol_slices.yml index fa591fcf..9dbcf6f2 100644 --- a/config/dol_slices.yml +++ b/config/dol_slices.yml @@ -43,6 +43,12 @@ jaudio_NES/dummyrom.c: .rodata: [0x800aa518, 0x800aa528] # .bss: [0x8020d78c, 0x8020d7a0] # placed in common bss .sbss: [0x80218420, 0x80218440] +jaudio_NES/audiothread.c: + .text: [0x80018bc0, 0x800190e0] + .rodata: [0x800aa528, 0x800aa538] + .bss: [0x8017cfc0, 0x80180020] + .sbss: [0x80218440, 0x80218460] + .sdata2: [0x80218db8, 0x80218dc0] # jaudio_NES/game64.c: # TODO: finish # .rodata: [0x800a9938, 0x800a9b98] #jaudio_NES/verysimple.c: diff --git a/configure.py b/configure.py index 1440224d..f1e6500f 100644 --- a/configure.py +++ b/configure.py @@ -627,7 +627,8 @@ class AsmSource(Source): JAUDIO_FUNC_ALIGN_32_TUS = [ "sample.c", "aictrl.c", - "dummyrom.c" + "dummyrom.c", + "audiothread.c" ] class CSource(Source): diff --git a/include/dolphin/hw_regs.h b/include/dolphin/hw_regs.h new file mode 100644 index 00000000..13f56cc4 --- /dev/null +++ b/include/dolphin/hw_regs.h @@ -0,0 +1,114 @@ +#ifndef _DOLPHIN_HW_REGS_H_ +#define _DOLPHIN_HW_REGS_H_ + +#ifdef __MWERKS__ +volatile u16 __VIRegs[59] : 0xCC002000; +volatile u32 __PIRegs[12] : 0xCC003000; +volatile u16 __MEMRegs[64] : 0xCC004000; +volatile u16 __DSPRegs[] : 0xCC005000; +volatile u32 __DIRegs[] : 0xCC006000; +volatile u32 __SIRegs[0x100] : 0xCC006400; +volatile u32 __EXIRegs[0x40] : 0xCC006800; +volatile u32 __AIRegs[8] : 0xCC006C00; +#else +#define __VIRegs ((volatile u16*)0xCC002000) +#define __PIRegs ((volatile u32*)0xCC003000) +#define __MEMRegs ((volatile u16*)0xCC004000) +#define __DSPRegs ((volatile u16*)0xCC005000) +#define __DIRegs ((volatile u32*)0xCC006000) +#define __SIRegs ((volatile u32*)0xCC006400) +#define __EXIRegs ((volatile u32*)0xCC006800) +#define __AIRegs ((volatile u32*)0xCC006C00) +#endif + +// Offsets for __VIRegs + +// offsets for __VIRegs[i] +#define VI_VERT_TIMING (0) +#define VI_DISP_CONFIG (1) +#define VI_HORIZ_TIMING_0L (2) +#define VI_HORIZ_TIMING_0U (3) +#define VI_HORIZ_TIMING_1L (4) +#define VI_HORIZ_TIMING_1U (5) +#define VI_VERT_TIMING_ODD (6) +#define VI_VERT_TIMING_ODD_U (7) +#define VI_VERT_TIMING_EVEN (8) +#define VI_VERT_TIMING_EVEN_U (9) + +#define VI_BBI_ODD (10) // burst blanking interval +#define VI_BBI_ODD_U (11) // burst blanking interval +#define VI_BBI_EVEN (12) // burst blanking interval +#define VI_BBI_EVEN_U (13) // burst blanking interval + +#define VI_TOP_FIELD_BASE_LEFT (14) // top in 2d, top of left pic in 3d +#define VI_TOP_FIELD_BASE_LEFT_U (15) // top in 2d, top of left pic in 3d + +#define VI_TOP_FIELD_BASE_RIGHT (16) // top of right pic in 3d +#define VI_TOP_FIELD_BASE_RIGHT_U (17) // top of right pic in 3d + +#define VI_BTTM_FIELD_BASE_LEFT (18) // bottom in 2d, bottom of left pic in 3d +#define VI_BTTM_FIELD_BASE_LEFT_U (19) // bottom in 2d, bottom of left pic in 3d + +#define VI_BTTM_FIELD_BASE_RIGHT (20) // bottom of right pic in 3d +#define VI_BTTM_FIELD_BASE_RIGHT_U (21) // bottom of right pic in 3d + +#define VI_VERT_COUNT (22) // vertical display position +#define VI_HORIZ_COUNT (23) // horizontal display position + +#define VI_DISP_INT_0 (24) // display interrupt 0L +#define VI_DISP_INT_0U (25) // display interrupt 0U +#define VI_DISP_INT_1 (26) // display interrupt 1L +#define VI_DISP_INT_1U (27) // display interrupt 1U +#define VI_DISP_INT_2 (28) // display interrupt 2L +#define VI_DISP_INT_2U (29) // display interrupt 2U +#define VI_DISP_INT_3 (30) // display interrupt 3L +#define VI_DISP_INT_3U (31) // display interrupt 3U + +#define VI_HSW (36) // horizontal scaling width +#define VI_HSR (37) // horizontal scaling register + +#define VI_FCT_0 (38) // filter coefficient table 0L +#define VI_FCT_0U (39) // filter coefficient table 0U +#define VI_FCT_1 (40) // filter coefficient table 1L +#define VI_FCT_1U (41) // filter coefficient table 1U +#define VI_FCT_2 (42) // filter coefficient table 2L +#define VI_FCT_2U (43) // filter coefficient table 2U +#define VI_FCT_3 (44) // filter coefficient table 3L +#define VI_FCT_3U (45) // filter coefficient table 3U +#define VI_FCT_4 (46) // filter coefficient table 4L +#define VI_FCT_4U (47) // filter coefficient table 4U +#define VI_FCT_5 (48) // filter coefficient table 5L +#define VI_FCT_5U (49) // filter coefficient table 5U +#define VI_FCT_6 (50) // filter coefficient table 6L +#define VI_FCT_6U (51) // filter coefficient table 6U + +#define VI_CLOCK_SEL (54) // clock select +#define VI_DTV_STAT (55) // DTV status + +#define VI_WIDTH (56) + +// offsets for __DSPRegs[i] +#define DSP_MAILBOX_IN_HI (0) +#define DSP_MAILBOX_IN_LO (1) +#define DSP_MAILBOX_OUT_HI (2) +#define DSP_MAILBOX_OUT_LO (3) +#define DSP_CONTROL_STATUS (5) + +#define DSP_ARAM_SIZE (9) +#define DSP_ARAM_MODE (11) +#define DSP_ARAM_REFRESH (13) +#define DSP_ARAM_DMA_MM_HI (16) // Main mem address +#define DSP_ARAM_DMA_MM_LO (17) +#define DSP_ARAM_DMA_ARAM_HI (18) // ARAM address +#define DSP_ARAM_DMA_ARAM_LO (19) +#define DSP_ARAM_DMA_SIZE_HI (20) // DMA buffer size +#define DSP_ARAM_DMA_SIZE_LO (21) + +#define DSP_DMA_START_HI (24) // DMA start address +#define DSP_DMA_START_LO (25) +#define DSP_DMA_CONTROL_LEN (27) +#define DSP_DMA_BYTES_LEFT (29) + +#define DSP_DMA_START_FLAG (0x8000) // set to start DSP + +#endif diff --git a/include/dolphin/os/OSFastCast.h b/include/dolphin/os/OSFastCast.h new file mode 100644 index 00000000..d94587ce --- /dev/null +++ b/include/dolphin/os/OSFastCast.h @@ -0,0 +1,108 @@ +#ifndef _DOLPHIN_OS_OSFASTCAST_H +#define _DOLPHIN_OS_OSFASTCAST_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +/////// FAST CAST DEFINES //////// +// GQR formats. +#define OS_GQR_U8 (0x0004) // GQR 1 +#define OS_GQR_U16 (0x0005) // GQR 2 +#define OS_GQR_S8 (0x0006) // GQR 3 +#define OS_GQR_S16 (0x0007) // GQR 4 + +// GQRs for fast casting. +#define OS_FASTCAST_U8 (2) +#define OS_FASTCAST_U16 (3) +#define OS_FASTCAST_S8 (4) +#define OS_FASTCAST_S16 (5) + +////////////////////////////////// + +/////// FAST CAST INLINES //////// +// Initialise fast casting. +static inline void OSInitFastCast() { +#ifdef __MWERKS__ // clang-format off + asm { + li r3, OS_GQR_U8 + oris r3, r3, OS_GQR_U8 + mtspr 0x392, r3 + li r3, OS_GQR_U16 + oris r3, r3, OS_GQR_U16 + mtspr 0x393, r3 + li r3, OS_GQR_S8 + oris r3, r3, OS_GQR_S8 + mtspr 0x394, r3 + li r3, OS_GQR_S16 + oris r3, r3, OS_GQR_S16 + mtspr 0x395, r3 + } +#endif // clang-format on +} + +// Float to int. +static inline s16 __OSf32tos16(register f32 inF) { + register s16 out; + u32 tmp; + register u32* tmpPtr = &tmp; +#ifdef __MWERKS__ // clang-format off + asm { + psq_st inF, 0(tmpPtr), 0x1, OS_FASTCAST_S16 + lha out, 0(tmpPtr) + } +#endif // clang-format on + + return out; +} + +static inline void OSf32tos16(f32* f, s16* out) { + *out = __OSf32tos16(*f); +} + +static inline u8 __OSf32tou8(register f32 inF) { + register u8 out; + u32 tmp; + register u32* tmpPtr = &tmp; +#ifdef __MWERKS__ // clang-format off + asm { + psq_st inF, 0(tmpPtr), 0x1, OS_FASTCAST_U8 + lbz out, 0(tmpPtr) + } +#endif // clang-format on + + return out; +} + +static inline void OSf32tou8(f32* f, u8* out) { + *out = __OSf32tou8(*f); +} + +static inline s8 __OSf32tos8(register f32 inF) { + register s8 out; + u32 tmp; + register u32* tmpPtr = &tmp; +#ifdef __MWERKS__ // clang-format off + asm { + psq_st inF, 0(tmpPtr), 0x1, OS_FASTCAST_S8 + lbz out, 0(tmpPtr) + extsb out, out + } +#endif // clang-format on + + return out; +} + +static inline void OSf32tos8(f32* f, s8* out) { + *out = __OSf32tos8(*f); +} + +////////////////////////////////// + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/include/jaudio_NES/audiocommon.h b/include/jaudio_NES/audiocommon.h index 6f3a7ce6..60478a32 100644 --- a/include/jaudio_NES/audiocommon.h +++ b/include/jaudio_NES/audiocommon.h @@ -13,6 +13,12 @@ extern "C" { #define AUDIO_ARAM_SIZE 0x400000 /* 4MB */ #define AUDIO_ARAM_HEAP_SIZE 0xC000 +typedef enum DSPBUF_EVENTS { + DSPBUF_EVENTS_0 = 0, + DSPBUF_EVENTS_1 = 1, + DSPBUF_EVENTS_2 = 2, +} DSPBUF_EVENTS; + #ifdef __cplusplus } #endif diff --git a/include/jaudio_NES/audiothread.h b/include/jaudio_NES/audiothread.h index 55a368c9..664c537d 100644 --- a/include/jaudio_NES/audiothread.h +++ b/include/jaudio_NES/audiothread.h @@ -1,16 +1,31 @@ #ifndef AUDIOTHREAD_H #define AUDIOTHREAD_H - #include "types.h" +#include "types.h" +#include "jaudio_NES/audiostruct.h" +#include "dolphin/os.h" + +#define AUDIO_THREAD_FLAG_DVD (1 << 0) +#define AUDIO_THREAD_FLAG_AUDIO (1 << 1) +#define AUDIO_THREAD_FLAG_NEOS (1 << 2) + +extern volatile int intcount; +OSThread jac_audioThread[3]; +OSThread jac_neosThread; +OSThread jac_dvdThread; + +extern void NeosSync(void); #ifdef __cplusplus extern "C" { #endif -void StartAudioThread(void*, u32, u32, u32); +extern void DspSyncCountClear(int count); +extern int DspSyncCountCheck(void); +extern void StartAudioThread(void* pHeap, s32 heapSize, u32 aramSize, u32 flags); #ifdef __cplusplus } #endif -#endif \ No newline at end of file +#endif diff --git a/include/jaudio_NES/cpubuf.h b/include/jaudio_NES/cpubuf.h new file mode 100644 index 00000000..eb222104 --- /dev/null +++ b/include/jaudio_NES/cpubuf.h @@ -0,0 +1,10 @@ +#ifndef CPUBUF_H +#define CPUBUF_H + +#include "types.h" +#include "jaudio_NES/audiocommon.h" + +extern u32 CpubufProcess(DSPBUF_EVENTS event); +extern void CpuFrameEnd(void); + +#endif diff --git a/include/jaudio_NES/dspboot.h b/include/jaudio_NES/dspboot.h new file mode 100644 index 00000000..0839e0d4 --- /dev/null +++ b/include/jaudio_NES/dspboot.h @@ -0,0 +1,8 @@ +#ifndef DSPBOOT_H +#define DSPBOOT_H + +#include "types.h" + +extern void DspBoot(void); + +#endif diff --git a/include/jaudio_NES/dspbuf.h b/include/jaudio_NES/dspbuf.h index d0f5c114..c45a713e 100644 --- a/include/jaudio_NES/dspbuf.h +++ b/include/jaudio_NES/dspbuf.h @@ -2,7 +2,11 @@ #define DSPBUF_H #include "types.h" +#include "jaudio_NES/audiocommon.h" +extern u32 DspbufProcess(DSPBUF_EVENTS event); extern s16* MixDsp(s32 nSamples); +extern void UpdateDSP(void); +extern void DspFrameEnd(void); #endif diff --git a/include/jaudio_NES/dspinterface.h b/include/jaudio_NES/dspinterface.h new file mode 100644 index 00000000..0cc55ead --- /dev/null +++ b/include/jaudio_NES/dspinterface.h @@ -0,0 +1,8 @@ +#ifndef DSPINTERFACE_H +#define DSPINTERFACE_H + +#include "types.h" + +extern void DSP_InitBuffer(void); + +#endif diff --git a/include/jaudio_NES/dspproc.h b/include/jaudio_NES/dspproc.h new file mode 100644 index 00000000..5bd9e1a3 --- /dev/null +++ b/include/jaudio_NES/dspproc.h @@ -0,0 +1,8 @@ +#ifndef DSPPROC_H +#define DSPPROC_H + +#include "types.h" + +extern u32 DSPReleaseHalt(void); + +#endif diff --git a/include/jaudio_NES/dvdthread.h b/include/jaudio_NES/dvdthread.h index 2d0a4a64..2cbe83ec 100644 --- a/include/jaudio_NES/dvdthread.h +++ b/include/jaudio_NES/dvdthread.h @@ -9,5 +9,7 @@ typedef void (*Jac_DVDCallback)(u32); extern s32 DVDT_DRAMtoARAM(u32 owner, u32 dram, u32 aram, u32 len, u32* outLen, Jac_DVDCallback callback); extern s32 DVDT_ARAMtoDRAM(u32 owner, u32 dram, u32 aram, u32 len, u32* outLen, Jac_DVDCallback callback); extern u32 Jac_CheckFile(char* path); +extern void* jac_dvdproc(void* param); +extern void jac_dvdproc_init(void); #endif diff --git a/include/jaudio_NES/ja_calc.h b/include/jaudio_NES/ja_calc.h new file mode 100644 index 00000000..a361ad8c --- /dev/null +++ b/include/jaudio_NES/ja_calc.h @@ -0,0 +1,8 @@ +#ifndef JA_CALC_H +#define JA_CALC_H + +#include "types.h" + +extern void Jac_InitSinTable(void); + +#endif diff --git a/include/jaudio_NES/neosthread.h b/include/jaudio_NES/neosthread.h new file mode 100644 index 00000000..fe7ab696 --- /dev/null +++ b/include/jaudio_NES/neosthread.h @@ -0,0 +1,8 @@ +#ifndef NEOSTHREAD_H +#define NEOSTHREAD_H + +#include "types.h" + +extern void* neosproc(void* param); + +#endif diff --git a/include/jaudio_NES/playercall.h b/include/jaudio_NES/playercall.h new file mode 100644 index 00000000..bc8e4d95 --- /dev/null +++ b/include/jaudio_NES/playercall.h @@ -0,0 +1,16 @@ +#ifndef PLAYERCALL_H +#define PLAYERCALL_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern void ResetPlayerCallback(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/jaudio_NES/rate.h b/include/jaudio_NES/rate.h index 3450ddb7..f063e142 100644 --- a/include/jaudio_NES/rate.h +++ b/include/jaudio_NES/rate.h @@ -7,6 +7,7 @@ extern "C" { #endif +extern u32 JAC_AI_SETTING; extern u32 JAC_FRAMESAMPLES; extern u32 DAC_SIZE; diff --git a/src/static/jaudio_NES/audiothread.c b/src/static/jaudio_NES/audiothread.c new file mode 100644 index 00000000..bafc71ca --- /dev/null +++ b/src/static/jaudio_NES/audiothread.c @@ -0,0 +1,187 @@ +#include "jaudio_NES/audiothread.h" + +#include "dolphin/os.h" +#include "dolphin/os/OSFastCast.h" +#include "dolphin/hw_regs.h" +#include "dolphin/ai.h" +#include "jaudio_NES/dspproc.h" +#include "jaudio_NES/cpubuf.h" +#include "jaudio_NES/dummyprobe.h" +#include "jaudio_NES/rate.h" +#include "jaudio_NES/aictrl.h" +#include "jaudio_NES/dummyrom.h" +#include "jaudio_NES/neosthread.h" +#include "jaudio_NES/dvdthread.h" +#include "jaudio_NES/dspboot.h" +#include "jaudio_NES/ja_calc.h" +#include "jaudio_NES/dspinterface.h" +#include "jaudio_NES/playercall.h" +#include "jaudio_NES/dspbuf.h" + +#define AUDIO_STACK_SIZE 0x1000 +#define AUDIOPROC_MQ_BUF_COUNT 16 + +#define AUDIOPROC_MESSAGE_UPDATE_DAC ((OSMessage)0) +#define AUDIOPROC_MESSAGE_DSP_SYNC ((OSMessage)1) +#define AUDIOPROC_MESSAGE_NEOS_SYNC ((OSMessage)2) +#define AUDIOPROC_MESSAGE_3 ((OSMessage)3) + +static u8 audioStack[AUDIO_STACK_SIZE] ATTRIBUTE_ALIGN(32); +static u8 neosStack[AUDIO_STACK_SIZE] ATTRIBUTE_ALIGN(32); +static u8 dvdStack[AUDIO_STACK_SIZE] ATTRIBUTE_ALIGN(32); +static OSMessageQueue audioproc_mq; +static OSMessage msgbuf[AUDIOPROC_MQ_BUF_COUNT]; +static u32 audioproc_mq_init = FALSE; +volatile int intcount = 0; + +extern void DspSyncCountClear(int count) { + intcount = count; +} + +extern int DspSyncCountCheck(void) { + return intcount; +} + +static void DspSync(void) { + if (audioproc_mq_init) { + OSSendMessage(&audioproc_mq, AUDIOPROC_MESSAGE_DSP_SYNC, OS_MESSAGE_NOBLOCK); + } else { + DSPReleaseHalt(); + } +} + +static void AudioSync(void) { + static BOOL first = TRUE; + + if (first == FALSE) { + Probe_Finish(4); + } + + first = FALSE; + Probe_Start(4, "UPDATE-DAC"); + if (audioproc_mq_init) { + OSSendMessage(&audioproc_mq, AUDIOPROC_MESSAGE_UPDATE_DAC, OS_MESSAGE_NOBLOCK); + } +} + +extern void NeosSync(void) { + if (audioproc_mq_init) { + OSSendMessage(&audioproc_mq, AUDIOPROC_MESSAGE_NEOS_SYNC, OS_MESSAGE_BLOCK); + } +} + +static void __DspSync(__OSInterrupt interrupt, OSContext* context) { + u16 reg = __DSPRegs[DSP_CONTROL_STATUS]; + reg &= ~(1 << 3); /* clear AI interrupt */ + reg &= ~(1 << 5); /* clear AR interrupt */ + reg |= (1 << 7); /* set DSP interrupt */ + __DSPRegs[DSP_CONTROL_STATUS] = reg; + + OSContext tmp_context; + OSClearContext(&tmp_context); + OSSetCurrentContext(&tmp_context); + DspSync(); + OSClearContext(&tmp_context); + OSSetCurrentContext(context); +} + +static void __DspReg(void) { + BOOL enable = OSDisableInterrupts(); + __OSSetInterruptHandler(OS_INTR_DSP_DSP, &__DspSync); + OSRestoreInterrupts(enable); +} + +static void* audioproc(void* param) { + OSInitFastCast(); + OSInitMessageQueue(&audioproc_mq, msgbuf, AUDIOPROC_MQ_BUF_COUNT); + audioproc_mq_init = TRUE; + Jac_Init(); + Jac_InitSinTable(); + ResetPlayerCallback(); + DspbufProcess(DSPBUF_EVENTS_0); + CpubufProcess(DSPBUF_EVENTS_0); + DspBoot(); + DSP_InitBuffer(); + __DspReg(); + AISetDSPSampleRate(JAC_AI_SETTING); + AIRegisterDMACallback(&AudioSync); + AIStartDMA(); + + while (TRUE) { + OSMessage msg; + + OSReceiveMessage(&audioproc_mq, &msg, OS_MESSAGE_BLOCK); + switch ((int)msg) { + case (int)AUDIOPROC_MESSAGE_UPDATE_DAC: + Jac_UpdateDAC(); + break; + case (int)AUDIOPROC_MESSAGE_DSP_SYNC: + if (intcount == 0) { + return; + } + + intcount--; + if (intcount == 0) { + Probe_Finish(7); + DspFrameEnd(); + } else { + Probe_Start(2, "SFR_DSP"); + UpdateDSP(); + Probe_Finish(2); + } + + break; + case (int)AUDIOPROC_MESSAGE_NEOS_SYNC: + CpuFrameEnd(); + break; + case (int)AUDIOPROC_MESSAGE_3: + OSExitThread(NULL); + break; + } + } +} + +static BOOL priority_set = FALSE; +static OSPriority pri = 0; +static OSPriority pri2 = 0; +static OSPriority pri3 = 0; + +extern void StartAudioThread(void* pHeap, s32 heapSize, u32 aramSize, u32 flags) { + if (priority_set == FALSE) { + OSPriority base_prio = OSGetThreadPriority(OSGetCurrentThread()) - 3; + + pri = base_prio; + pri3 = base_prio + 1; + pri2 = base_prio + 2; + } + + u32 neos_flag; + + Jac_HeapSetup(pHeap, heapSize); + Jac_SetAudioARAMSize(aramSize); + + neos_flag = flags & AUDIO_THREAD_FLAG_NEOS; + Jac_InitARAM(neos_flag); + + if ((flags & AUDIO_THREAD_FLAG_AUDIO)) { + // point to top of audioStack + u8* stack_p = audioStack; + OSCreateThread(&jac_audioThread[0], &audioproc, NULL, &stack_p[AUDIO_STACK_SIZE], AUDIO_STACK_SIZE, pri, 0); + OSResumeThread(&jac_audioThread[0]); + } + + if ((flags & AUDIO_THREAD_FLAG_DVD)) { + jac_dvdproc_init(); + // point to top of dvdStack + u8* stack_p = dvdStack; + OSCreateThread(&jac_dvdThread, &jac_dvdproc, NULL, &stack_p[AUDIO_STACK_SIZE], AUDIO_STACK_SIZE, pri3, 0); + OSResumeThread(&jac_dvdThread); + } + + if (neos_flag) { + // point to top of neosStack + u8* stack_p = neosStack; + OSCreateThread(&jac_neosThread, &neosproc, NULL, &stack_p[AUDIO_STACK_SIZE], AUDIO_STACK_SIZE, pri2, 0); + OSResumeThread(&jac_neosThread); + } +}