This commit is contained in:
Cuyler36
2024-06-03 17:13:51 -04:00
parent 94858cd9fe
commit 58395b3461
8 changed files with 433 additions and 0 deletions
+50
View File
@@ -0,0 +1,50 @@
#ifndef _DOLPHIN_AI_H_
#define _DOLPHIN_AI_H_
#include "types.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef void (*AISCallback)(u32 count);
typedef void (*AIDCallback)();
#define AI_STREAM_START 1
#define AI_STREAM_STOP 0
#define AI_SAMPLERATE_32KHZ 0
#define AI_SAMPLERATE_48KHZ 1
AIDCallback AIRegisterDMACallback(AIDCallback callback);
void AIInitDMA(u32 start_addr, u32 length);
BOOL AIGetDMAEnableFlag(void);
void AIStartDMA(void);
void AIStopDMA(void);
u32 AIGetDMABytesLeft(void);
u32 AIGetDMAStartAddr(void);
u32 AIGetDMALength(void);
BOOL AICheckInit(void);
AISCallback AIRegisterStreamCallback(AISCallback callback);
u32 AIGetStreamSampleCount(void);
void AIResetStreamSampleCount(void);
void AISetStreamTrigger(u32 trigger);
u32 AIGetStreamTrigger(void);
void AISetStreamPlayState(u32 state);
u32 AIGetStreamPlayState(void);
void AISetDSPSampleRate(u32 rate);
u32 AIGetDSPSampleRate(void);
void AISetStreamSampleRate(u32 rate);
u32 AIGetStreamSampleRate(void);
void AISetStreamVolLeft(u8 vol);
u8 AIGetStreamVolLeft(void);
void AISetStreamVolRight(u8 vol);
u8 AIGetStreamVolRight(void);
void AIInit(u8* stack);
void AIReset(void);
#ifdef __cplusplus
}
#endif
#endif
+36
View File
@@ -0,0 +1,36 @@
#ifndef AICTRL_H
#define AICTRL_H
#include "types.h"
#ifdef __cplusplus
extern "C" {
#endif
extern u32 UNIVERSAL_DACCOUNTER;
extern u32 JAC_VFRAME_COUNTER;
typedef enum _MixMode {
MixMode_Mono,
MixMode_MonoWide,
MixMode_Extra,
MixMode_Interleave,
MixMode_Num
} MixMode;
typedef s16* (*MixCallback)(s32);
extern void Jac_HeapSetup(void* pHeap, s32 size);
extern void* OSAlloc2(u32 size);
extern void Jac_Init(void);
extern MixCallback Jac_GetMixcallback(u8* mixmode);
extern void Jac_RegisterMixcallback(MixCallback mixcallback, u8 mixmode);
extern void Jac_VframeWork(void);
extern void Jac_UpdateDAC(void);
#ifdef __cplusplus
}
#endif
#endif
+17
View File
@@ -0,0 +1,17 @@
#ifndef AUDIOCOMMON_H
#define AUDIOCOMMON_H
#include "types.h"
#ifdef __cplusplus
extern "C" {
#endif
#define S16_MIN (-0x8000)
#define S16_MAX (0x7FFF)
#ifdef __cplusplus
}
#endif
#endif
+8
View File
@@ -0,0 +1,8 @@
#ifndef DSPBUF_H
#define DSPBUF_H
#include "types.h"
extern s16* MixDsp(s32 nSamples);
#endif
+10
View File
@@ -0,0 +1,10 @@
#ifndef JAUDIO_MEMORY_H
#define JAUDIO_MEMORY_H
#include "types.h"
#include "jaudio_NES/audiostruct.h"
extern void Nas_HeapInit(ALHeap* heap, u8* base, s32 len);
extern void* Nas_HeapAlloc(ALHeap* heap, s32 size);
#endif
+17
View File
@@ -0,0 +1,17 @@
#ifndef RATE_H
#define RATE_H
#include "types.h"
#ifdef __cplusplus
extern "C" {
#endif
extern u32 JAC_FRAMESAMPLES;
extern u32 DAC_SIZE;
#ifdef __cplusplus
}
#endif
#endif
+8
View File
@@ -0,0 +1,8 @@
#ifndef STREAMCTRL_H
#define STREAMCTRL_H
#include "types.h"
extern void StreamMain(void);
#endif
+287
View File
@@ -0,0 +1,287 @@
#include "jaudio_NES/aictrl.h"
#include "jaudio_NES/dummyprobe.h"
#include "jaudio_NES/memory.h"
#include "jaudio_NES/sample.h"
#include "jaudio_NES/dspbuf.h"
#include "jaudio_NES/streamctrl.h"
#include "jaudio_NES/rate.h"
#include "dolphin/os.h"
#include "dolphin/ai.h"
typedef void (*DACCallback)(s16*, s32);
u32 UNIVERSAL_DACCOUNTER = 0;
static s16* dac[3];
static ALHeap audio_hp;
static BOOL audio_hp_exist = FALSE;
static s16* last_rsp_madep = nullptr;
static s16* use_rsp_madep = nullptr;
static BOOL vframe_work_running = FALSE;
static DACCallback DAC_CALLBACK_FUNC = nullptr;
u32 JAC_VFRAME_COUNTER = 0;
static MixCallback ext_mixcallback = nullptr;
static u8 ext_mixmode = MixMode_Mono;
extern void Jac_HeapSetup(void* pHeap, s32 size) {
if (pHeap != nullptr) {
Nas_HeapInit(&audio_hp, (u8*)pHeap, size);
audio_hp_exist = TRUE;
} else {
audio_hp_exist = FALSE;
}
}
extern void* OSAlloc2(u32 size) {
void* alloc;
BOOL enable = OSDisableInterrupts();
switch (audio_hp_exist) {
case FALSE:
alloc = OSAlloc(size);
break;
case TRUE:
alloc = Nas_HeapAlloc(&audio_hp, size);
break;
}
OSRestoreInterrupts(enable);
return alloc;
}
extern void Jac_Init(void) {
for (int i = 0; i < 3; i++) {
dac[i] = (s16*)OSAlloc2(DAC_SIZE * 2);
Jac_bzero(dac[i], DAC_SIZE * 2);
DCStoreRange(dac[i], DAC_SIZE * 2);
}
AIInit(nullptr);
AIInitDMA((u32)dac[2], DAC_SIZE * 2);
}
static void MixMonoTrack(s16* track, s32 nSamples, MixCallback callback) {
Probe_Start(5, "MONO-MIX");
s16* monoTrack = (*callback)(nSamples);
int mix;
if (monoTrack != nullptr) {
Probe_Finish(5);
s16* dst_p = track;
s16* src_p = monoTrack;
for (s32 i = 0; i < nSamples; i++) {
mix = dst_p[0] + src_p[0];
if (mix < S16_MIN) {
mix = S16_MIN + 1;
}
if (mix > S16_MAX) {
mix = S16_MAX;
}
dst_p[0] = (s16)mix;
mix = dst_p[1] + src_p[0];
if (mix < S16_MIN) {
mix = S16_MIN + 1;
}
if (mix > S16_MAX) {
mix = S16_MAX;
}
dst_p[1] = (s16)mix;
dst_p += 2;
src_p++;
}
}
}
static void MixMonoTrackWide(s16* track, s32 nSamples, MixCallback callback) {
Probe_Start(5, "MONO(W)-MIX");
s16* monoTrack = (*callback)(nSamples);
int mix;
if (monoTrack != nullptr) {
Probe_Finish(5);
s16* dst_p = track;
s16* src_p = monoTrack;
for (s32 i = 0; i < nSamples; i++) {
mix = dst_p[0] + src_p[0];
if (mix < S16_MIN) {
mix = S16_MIN + 1;
}
if (mix > S16_MAX) {
mix = S16_MAX;
}
dst_p[0] = (s16)mix;
mix = dst_p[1] - src_p[0];
if (mix < S16_MIN) {
mix = S16_MIN + 1;
}
if (mix > S16_MAX) {
mix = S16_MAX;
}
dst_p[1] = (s16)mix;
dst_p += 2;
src_p++;
}
}
}
static void MixExtraTrack(s16* track, s32 nSamples, MixCallback callback) {
Probe_Start(5, "DSPMIX");
s16* extraTrack = (*callback)(nSamples);
int mix;
if (extraTrack != nullptr) {
Probe_Finish(5);
Probe_Start(6, "MIXING");
s16* dst_p = track;
s16* src0_p = extraTrack + JAC_FRAMESAMPLES;
s16* src1_p = extraTrack;
for (s32 i = 0; i < nSamples; i++) {
mix = dst_p[0] + src0_p[0];
if (mix < S16_MIN) {
mix = S16_MIN + 1;
}
if (mix > S16_MAX) {
mix = S16_MAX;
}
dst_p[0] = (s16)mix;
mix = dst_p[1] + src1_p[0];
if (mix < S16_MIN) {
mix = S16_MIN + 1;
}
if (mix > S16_MAX) {
mix = S16_MAX;
}
dst_p[1] = (s16)mix;
dst_p += 2;
src0_p++;
src1_p++;
}
Probe_Finish(6);
}
}
static void MixInterleaveTrack(s16* track, s32 nSamples, MixCallback callback) {
s16* interleaveTrack = (*callback)(nSamples);
int mix;
if (interleaveTrack != nullptr) {
s16* track_p = track;
s32 max = nSamples * 2;
for (s32 i = 0; i < max; i++) {
mix = track_p[0] + interleaveTrack[0];
if (mix < S16_MIN) {
mix = S16_MIN + 1;
}
if (mix > S16_MAX) {
mix = S16_MAX;
}
track_p[0] = (s16)mix;
track_p++;
interleaveTrack++;
}
}
}
extern MixCallback Jac_GetMixcallback(u8* mixmode) {
*mixmode = ext_mixmode;
return ext_mixcallback;
}
extern void Jac_RegisterMixcallback(MixCallback mixcallback, u8 mixmode) {
ext_mixcallback = mixcallback;
ext_mixmode = mixmode;
}
extern void Jac_VframeWork(void) {
static u32 dacp = 0;
JAC_VFRAME_COUNTER++;
s16* mixedTrack = MixDsp(DAC_SIZE / 2);
Jac_imixcopy(&mixedTrack[JAC_FRAMESAMPLES], &mixedTrack[0], dac[dacp], DAC_SIZE / 2);
if (ext_mixcallback != nullptr) {
switch (ext_mixmode) {
case MixMode_Mono:
MixMonoTrack(dac[dacp], DAC_SIZE / 2, ext_mixcallback);
break;
case MixMode_MonoWide:
MixMonoTrackWide(dac[dacp], DAC_SIZE / 2, ext_mixcallback);
break;
case MixMode_Extra:
MixExtraTrack(dac[dacp], DAC_SIZE / 2, ext_mixcallback);
break;
case MixMode_Interleave:
MixInterleaveTrack(dac[dacp], DAC_SIZE / 2, ext_mixcallback);
break;
}
}
BOOL enable = OSDisableInterrupts();
DCStoreRange(dac[dacp], DAC_SIZE * 2);
OSRestoreInterrupts(enable);
last_rsp_madep = dac[dacp];
dacp++;
if (dacp == 3) {
dacp = 0;
}
vframe_work_running = FALSE;
}
extern void Jac_UpdateDAC(void) {
if (use_rsp_madep == nullptr) {
use_rsp_madep = last_rsp_madep;
last_rsp_madep = nullptr;
}
if (use_rsp_madep != nullptr) {
AIInitDMA((u32)use_rsp_madep, DAC_SIZE * 2);
use_rsp_madep = nullptr;
} else {
UNIVERSAL_DACCOUNTER++;
}
if (last_rsp_madep == nullptr && vframe_work_running == FALSE) {
Jac_VframeWork();
}
StreamMain();
if (DAC_CALLBACK_FUNC != nullptr) {
(*DAC_CALLBACK_FUNC)(last_rsp_madep, DAC_SIZE / 2);
}
}