More musyx imps

This commit is contained in:
Phillip Stephens 2022-10-18 18:00:53 -07:00
parent 2c60ca8c47
commit fc60e9b7c4
4 changed files with 226 additions and 13 deletions

View File

@ -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);

90
src/musyx/hardware.c Normal file
View File

@ -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;
}

96
src/musyx/reverb.c Normal file
View File

@ -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]);
}
}
}

View File

@ -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;