mirror of https://github.com/PrimeDecomp/prime.git
parent
eedb4229d3
commit
927d07d839
|
@ -16,16 +16,34 @@ typedef struct _SynthInfo {
|
|||
u8 studios;
|
||||
} SynthInfo;
|
||||
|
||||
typedef struct DSPVoice {
|
||||
char data1[0x18];
|
||||
u32 _18;
|
||||
u32 priority;
|
||||
u32 _20;
|
||||
u32 flags[5];
|
||||
char data2[0x70 - 0x38];
|
||||
u16 sampleId;
|
||||
u16 _72;
|
||||
char data3[0x90 - 0x74];
|
||||
u32 sampleType;
|
||||
char data4[0xec - 0x94];
|
||||
u8 active;
|
||||
char data5[0xf0 - 0xed];
|
||||
u32 itdFlags;
|
||||
} DSPVoice;
|
||||
|
||||
extern DSPVoice* dspVoice;
|
||||
typedef s32 (*SND_COMPARE)(u16*, u8*);
|
||||
|
||||
void dataInit(u32, s32); /* extern */
|
||||
void dataInitStack(); /* extern */
|
||||
s32 hwInit(s32*, u8, u8, s32); /* extern */
|
||||
void s3dInit(s32); /* extern */
|
||||
void seqInit(); /* extern */
|
||||
void streamInit(); /* extern */
|
||||
void synthInit(u32, u8); /* extern */
|
||||
void vsInit(); /* extern */
|
||||
void dataInit(u32, s32); /* extern */
|
||||
void dataInitStack(); /* extern */
|
||||
s32 hwInit(u32* rate, u8 numVoices, u8 numStudios, u32 flags); /* extern */
|
||||
void s3dInit(s32); /* extern */
|
||||
void seqInit(); /* extern */
|
||||
void streamInit(); /* extern */
|
||||
void synthInit(u32, u8); /* extern */
|
||||
void vsInit(); /* extern */
|
||||
void hwExit();
|
||||
void dataExit();
|
||||
void s3dExit();
|
||||
|
@ -39,10 +57,16 @@ void sndConvertTicks(u32* out, u32 seconds);
|
|||
u32 sndConvert2Ms(u32 time);
|
||||
|
||||
void hwDeactivateStudio(u8);
|
||||
u32 hwIsActive(s32);
|
||||
bool hwIsActive(s32);
|
||||
|
||||
extern SND_HOOKS salHooks;
|
||||
extern u8 sndActive;
|
||||
extern s8 synthIdleWaitActive;
|
||||
extern SynthInfo synthInfo;
|
||||
typedef s32 (*SND_MESSAGE_CALLBACK)(s32, u32);
|
||||
typedef void (*SND_SOME_CALLBACK)();
|
||||
|
||||
extern SND_MESSAGE_CALLBACK salMessageCallback;
|
||||
/* Math */
|
||||
void salApplyMatrix(const SND_FMATRIX* a, const SND_FVECTOR* b, SND_FVECTOR* out);
|
||||
float salNormalizeVector(SND_FVECTOR* vec);
|
||||
|
@ -50,6 +74,11 @@ void salCrossProduct(SND_FVECTOR* out, const SND_FVECTOR* a, const SND_FVECTOR*
|
|||
void salInvertMatrix(SND_FMATRIX* out, const SND_FMATRIX* in);
|
||||
|
||||
/* hardware */
|
||||
u32 salInitAi(SND_SOME_CALLBACK, u32, u32*);
|
||||
u32 salInitDsp(u32);
|
||||
u32 salInitDspCtrl(u32, u32, u16);
|
||||
u32 salStartAi();
|
||||
|
||||
/* TODO: Figure out what `unk` is */
|
||||
bool hwAddInput(u8 studio, void* unk);
|
||||
bool hwRemoveInput(u8 studio, void* unk);
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
#include "musyx/musyx_priv.h"
|
||||
|
||||
u8 salFrame;
|
||||
u8 salAuxFrame;
|
||||
u8 salNumVoices;
|
||||
u8 salMaxStudioNum;
|
||||
SND_HOOKS salHooks;
|
||||
u8 salTimeOffset;
|
||||
|
||||
void snd_handle_irq() {
|
||||
s32 i;
|
||||
if (sndActive == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
streamCorrectLoops();
|
||||
hwIRQEnterCriticalSection();
|
||||
salCtrlDsp(salAiGetDest());
|
||||
hwIRQLeaveCriticalSection();
|
||||
hwIRQEnterCriticalSection();
|
||||
salHandleAuxProcessing();
|
||||
hwIRQLeaveCriticalSection();
|
||||
hwIRQEnterCriticalSection();
|
||||
salFrame ^= 1;
|
||||
salAuxFrame = (salAuxFrame + 1) % 3;
|
||||
}
|
||||
s32 hwInit(u32* rate, u8 numVoices, u8 numStudios, u32 flags) {
|
||||
hwInitIrq();
|
||||
salFrame = 0;
|
||||
salAuxFrame = 0;
|
||||
salMessageCallback = NULL;
|
||||
if (salInitAi(snd_handle_irq, flags, rate) == 0) {
|
||||
// OSReport("Could not initialize AI.\n");
|
||||
} else {
|
||||
// OSReport("salInitAi() is done.\n\n");
|
||||
if (salInitDspCtrl(numVoices, numStudios, flags & 1) == 0) {
|
||||
// OSReport("Could not initialize DSP control logic.\n");
|
||||
} else {
|
||||
// OSReport("salInitDspCtrl() is done.\n\n");
|
||||
if (salInitDsp(flags)) {
|
||||
// OSReport("salInitDsp() is done.\n\n");
|
||||
hwEnableIrq();
|
||||
// OSReport("Starting AI DMA...\n\n");
|
||||
salStartAi();
|
||||
// OSReport("hwInit() done.\n\n");
|
||||
return 0;
|
||||
}
|
||||
// OSReport("Could not initialize DSP.\n");
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void hwExit() {
|
||||
hwDisableIrq();
|
||||
salExitDsp();
|
||||
salExitDspCtrl();
|
||||
salExitAi();
|
||||
hwEnableIrq();
|
||||
hwExitIrq();
|
||||
}
|
||||
|
||||
void hwSetTimeOffset(s8 offset) { salTimeOffset = offset; }
|
||||
|
||||
u8 hwGetTimeOffset() { return salTimeOffset; }
|
||||
|
||||
bool hwIsActive(s32 idx) { return dspVoice[idx].active != 0; }
|
||||
|
||||
void hwSetMesgCallback(SND_MESSAGE_CALLBACK callback) { salMessageCallback = callback; }
|
||||
|
||||
void hwSetPriority(s32 idx, s32 priority) { dspVoice[idx].priority = priority; }
|
||||
|
||||
void hwInitSamplePlayback(s32 vid, u16 sampleId, u32* param_3, int param_4, u32 priority,
|
||||
u32 param_6, int param_7, u32 itdMode) {
|
||||
u8 i;
|
||||
s32 flags;
|
||||
s32 tmpFlags;
|
||||
flags = 0;
|
||||
for (i = 0; i <= salTimeOffset; ++i) {
|
||||
tmpFlags = dspVoice[vid].flags[i];
|
||||
dspVoice[vid].flags[i] = 0;
|
||||
flags |= tmpFlags & 0x20;
|
||||
}
|
||||
|
||||
dspVoice[vid].flags[0] = flags;
|
||||
dspVoice[vid].priority = priority;
|
||||
dspVoice[vid]._18 = param_6;
|
||||
dspVoice[vid].itdFlags = 0;
|
||||
dspVoice[vid].sampleId = sampleId;
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
#include "math.h"
|
||||
#include "musyx/musyx_priv.h"
|
||||
|
||||
static void DLsetdelay(_SND_REVHI_DELAYLINE* delayline, s32 len) {
|
||||
delayline->outPoint = delayline->inPoint - (len * sizeof(f32));
|
||||
while (delayline->outPoint < 0) {
|
||||
delayline->outPoint += delayline->length;
|
||||
}
|
||||
}
|
||||
|
||||
static void DLcreate(_SND_REVHI_DELAYLINE* delayline, s32 length) {
|
||||
delayline->length = length * sizeof(f32);
|
||||
delayline->inputs = (f32*)salMalloc(length * sizeof(f32));
|
||||
memset(delayline->inputs, 0, length * sizeof(length));
|
||||
delayline->lastOutput = 0.f;
|
||||
DLsetdelay(delayline, length * sizeof(f32));
|
||||
delayline->inPoint = 0;
|
||||
delayline->outPoint = 0;
|
||||
}
|
||||
|
||||
static void DLdelete(_SND_REVHI_DELAYLINE* delayline) { salFree(delayline->inputs); }
|
||||
bool ReverbHICreate(_SND_REVHI_WORK* rev, f32 coloration, f32 time, f32 mix, f32 damping,
|
||||
f32 preDelay, f32 crosstalk) {
|
||||
static int lens[] = {1789, 1999, 2333, 433, 149, 47, 73, 67};
|
||||
u8 i;
|
||||
u8 j;
|
||||
if (coloration < 0.f || coloration > 1.f || time < 0.01f || time > 10.f || mix < 0.f ||
|
||||
mix > 1.f || crosstalk < 0.f || crosstalk > 1.f || damping < 0.f || damping > 1.f ||
|
||||
preDelay < 0.f || preDelay > 0.1f) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memset(rev, 0, sizeof(_SND_REVHI_WORK));
|
||||
|
||||
for (i = 0; i < 3; ++i) {
|
||||
for (j = 0; j < 3; ++j) {
|
||||
DLcreate(&rev->C[i], lens[j] + 2);
|
||||
DLsetdelay(&rev->C[i], lens[j]);
|
||||
rev->combCoef[j + i * 3] = pow(10.f, (lens[j] * -3) / (32000.f * time));
|
||||
}
|
||||
|
||||
for (j = 0; j < 2; ++j) {
|
||||
DLcreate(&rev->AP[i], lens[j + 3] + 2);
|
||||
DLsetdelay(&rev->AP[i], lens[j + 3]);
|
||||
}
|
||||
DLcreate(&rev->AP[i], lens[i + 5] + 2);
|
||||
DLsetdelay(&rev->AP[i], lens[i + 5]);
|
||||
rev->lpLastout[i] = 0.f;
|
||||
}
|
||||
|
||||
rev->allPassCoeff = coloration;
|
||||
rev->level = mix;
|
||||
rev->crosstalk = crosstalk;
|
||||
rev->damping = damping;
|
||||
if (rev->damping < 0.05f) {
|
||||
rev->damping = 0.05f;
|
||||
}
|
||||
|
||||
rev->damping = 1.f - ((rev->damping * 0.8f) + 0.5f);
|
||||
if (preDelay != 0.f) {
|
||||
rev->preDelayTime = preDelay * 32000.f;
|
||||
for (i = 0; i < 3; ++i) {
|
||||
rev->preDelayLine[i] = (f32*)salMalloc(rev->preDelayTime * sizeof(f32));
|
||||
memset(rev->preDelayLine[i], 0, rev->preDelayTime * sizeof(f32));
|
||||
rev->preDelayPtr[i] = rev->preDelayLine[i];
|
||||
}
|
||||
} else {
|
||||
rev->preDelayTime = 0;
|
||||
for (i = 0; i < 3; ++i) {
|
||||
rev->preDelayPtr[i] = NULL;
|
||||
rev->preDelayLine[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
void DoCrossTalk() {}
|
||||
|
||||
void HandleReverb_0() {}
|
||||
|
||||
void ReverbHICallback() {}
|
||||
|
||||
void ReverbHIFree(_SND_REVHI_WORK* rv) {
|
||||
u8 i;
|
||||
for (i = 0; i < 9; ++i) {
|
||||
DLdelete(&rv->AP[i]);
|
||||
}
|
||||
for (i = 0; i < 9; ++i) {
|
||||
DLdelete(&rv->C[i]);
|
||||
}
|
||||
if (rv->preDelayTime != 0) {
|
||||
for (i = 0; i < 3; ++i) {
|
||||
salFree(rv->preDelayLine[i]);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,9 +5,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
/* TODO: Move these to a more approprate location */
|
||||
extern s8 sndActive;
|
||||
extern s8 synthIdleWaitActive;
|
||||
extern SynthInfo synthInfo;
|
||||
|
||||
|
||||
s32 DoInit(u32 rate, u32 aramSize, u8 voices, u32 flags) {
|
||||
dataInitStack();
|
||||
|
@ -24,7 +22,7 @@ s32 DoInit(u32 rate, u32 aramSize, u8 voices, u32 flags) {
|
|||
}
|
||||
|
||||
s32 sndInit(u8 voices, u8 music, u8 sfx, u8 studios, u32 flags, u32 aramSize) {
|
||||
s32 rate;
|
||||
u32 rate;
|
||||
s32 ret;
|
||||
|
||||
sndActive = 0;
|
||||
|
|
Loading…
Reference in New Issue