2022-10-18 18:00:53 -07:00
|
|
|
#include "musyx/musyx_priv.h"
|
|
|
|
|
|
|
|
u8 salFrame;
|
|
|
|
u8 salAuxFrame;
|
|
|
|
u8 salNumVoices;
|
|
|
|
u8 salMaxStudioNum;
|
|
|
|
SND_HOOKS salHooks;
|
|
|
|
u8 salTimeOffset;
|
2022-12-16 00:11:11 -08:00
|
|
|
void hwSetTimeOffset(u8 offset);
|
2022-10-18 18:00:53 -07:00
|
|
|
|
|
|
|
void snd_handle_irq() {
|
2022-12-16 00:11:11 -08:00
|
|
|
u8 i;
|
|
|
|
u8 j;
|
2022-10-18 18:00:53 -07:00
|
|
|
if (sndActive == 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
streamCorrectLoops();
|
2022-12-16 00:11:11 -08:00
|
|
|
hwIRQEnterCritical();
|
2022-10-18 18:00:53 -07:00
|
|
|
salCtrlDsp(salAiGetDest());
|
2022-12-16 00:11:11 -08:00
|
|
|
hwIRQLeaveCritical();
|
|
|
|
hwIRQEnterCritical();
|
2022-10-18 18:00:53 -07:00
|
|
|
salHandleAuxProcessing();
|
2022-12-16 00:11:11 -08:00
|
|
|
hwIRQLeaveCritical();
|
|
|
|
hwIRQEnterCritical();
|
2022-10-18 18:00:53 -07:00
|
|
|
salFrame ^= 1;
|
|
|
|
salAuxFrame = (salAuxFrame + 1) % 3;
|
2022-12-16 00:11:11 -08:00
|
|
|
|
|
|
|
for (i = 0; i < salNumVoices; ++i) {
|
|
|
|
for (j = 0; j < 5; ++j) {
|
2023-02-18 20:27:24 -08:00
|
|
|
dspVoice[i].flags = 0;
|
2022-12-16 00:11:11 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
hwIRQLeaveCritical();
|
|
|
|
|
|
|
|
for (i = 0; i < 5; ++i) {
|
|
|
|
hwIRQEnterCritical();
|
|
|
|
hwSetTimeOffset(i);
|
|
|
|
seqHandle(256);
|
|
|
|
synthHandle(256);
|
|
|
|
hwIRQLeaveCritical();
|
|
|
|
}
|
|
|
|
|
|
|
|
hwIRQEnterCritical();
|
|
|
|
hwSetTimeOffset(0);
|
|
|
|
s3dHandle();
|
|
|
|
hwIRQLeaveCritical();
|
|
|
|
hwIRQEnterCritical();
|
|
|
|
streamHandle();
|
|
|
|
hwIRQLeaveCritical();
|
|
|
|
hwIRQEnterCritical();
|
|
|
|
vsSampleUpdates();
|
|
|
|
hwIRQLeaveCritical();
|
2022-10-18 18:00:53 -07:00
|
|
|
}
|
2022-12-16 00:11:11 -08:00
|
|
|
|
2022-10-18 18:00:53 -07:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2022-12-16 00:11:11 -08:00
|
|
|
void hwSetTimeOffset(u8 offset) { salTimeOffset = offset; }
|
2022-10-18 18:00:53 -07:00
|
|
|
|
|
|
|
u8 hwGetTimeOffset() { return salTimeOffset; }
|
|
|
|
|
2023-02-18 20:27:24 -08:00
|
|
|
u32 hwIsActive(s32 idx) { return dspVoice[idx].state != 0; }
|
2022-10-18 18:00:53 -07:00
|
|
|
|
|
|
|
void hwSetMesgCallback(SND_MESSAGE_CALLBACK callback) { salMessageCallback = callback; }
|
|
|
|
|
2023-02-18 20:27:24 -08:00
|
|
|
void hwSetPriority(s32 idx, s32 priority) { dspVoice[idx].prio = priority; }
|
2022-10-18 18:00:53 -07:00
|
|
|
|
2023-02-18 20:27:24 -08:00
|
|
|
void hwInitSamplePlayback(s32 v, u16 smpID, void* newsmp, u32 set_defadsr, u32 priority,
|
|
|
|
u32 callbackUserValue, u32 setSRC, u32 itdMode) {
|
|
|
|
unsigned char i; // r30
|
|
|
|
unsigned long bf; // r29
|
|
|
|
DSPvoice* voice;
|
|
|
|
bf = 0;
|
2022-10-18 18:00:53 -07:00
|
|
|
for (i = 0; i <= salTimeOffset; ++i) {
|
2023-02-18 20:27:24 -08:00
|
|
|
bf |= dspVoice[v].changed[i] & 0x20;
|
|
|
|
dspVoice[v].changed[i] = 0;
|
2022-12-16 00:11:11 -08:00
|
|
|
}
|
|
|
|
|
2023-02-18 20:27:24 -08:00
|
|
|
dspVoice[v].changed[0] = bf;
|
|
|
|
dspVoice[v].prio = priority;
|
|
|
|
dspVoice[v].mesgCallBackUserValue = callbackUserValue;
|
|
|
|
dspVoice[v].flags = 0;
|
|
|
|
dspVoice[v].smp_id = smpID;
|
|
|
|
voice = &dspVoice[v];
|
|
|
|
((u32*)&voice->smp_info)[0] = ((u32*)newsmp)[0];
|
|
|
|
((u32*)&voice->smp_info)[1] = ((u32*)newsmp)[1];
|
|
|
|
((u32*)&voice->smp_info)[2] = ((u32*)newsmp)[2];
|
|
|
|
((u32*)&voice->smp_info)[3] = ((u32*)newsmp)[3];
|
|
|
|
((u32*)&voice->smp_info)[4] = ((u32*)newsmp)[4];
|
|
|
|
((u32*)&voice->smp_info)[5] = ((u32*)newsmp)[5];
|
|
|
|
((u32*)&voice->smp_info)[6] = ((u32*)newsmp)[6];
|
|
|
|
((u32*)&voice->smp_info)[7] = ((u32*)newsmp)[7];
|
|
|
|
|
|
|
|
if (set_defadsr != 0) {
|
|
|
|
dspVoice[v].adsr.mode = 0;
|
|
|
|
dspVoice[v].adsr.data.dls.aTime = 0;
|
|
|
|
dspVoice[v].adsr.data.dls.dTime = 0;
|
|
|
|
dspVoice[v].adsr.data.dls.sLevel = 0x7FFF;
|
|
|
|
dspVoice[v].adsr.data.dls.rTime = 0;
|
2022-12-16 00:11:11 -08:00
|
|
|
}
|
|
|
|
|
2023-02-18 20:27:24 -08:00
|
|
|
dspVoice[v].lastUpdate.pitch = 0xff;
|
|
|
|
dspVoice[v].lastUpdate.vol = 0xff;
|
|
|
|
dspVoice[v].lastUpdate.volA = 0xff;
|
|
|
|
dspVoice[v].lastUpdate.volB = 0xff;
|
2022-12-16 00:11:11 -08:00
|
|
|
|
2023-02-18 20:27:24 -08:00
|
|
|
if (setSRC != 0) {
|
|
|
|
hwSetSRCType(v, 0);
|
|
|
|
hwSetPolyPhaseFilter(v, 1);
|
2022-12-16 00:11:11 -08:00
|
|
|
}
|
|
|
|
|
2023-02-18 20:27:24 -08:00
|
|
|
hwSetITDMode(v, itdMode);
|
2022-12-16 00:11:11 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void hwBreak(s32 vid) {
|
2023-02-18 20:27:24 -08:00
|
|
|
if (dspVoice[vid].state == 1 && salTimeOffset == 0) {
|
|
|
|
dspVoice[vid].startupBreak = 1;
|
2022-12-16 00:11:11 -08:00
|
|
|
}
|
|
|
|
|
2023-02-18 20:27:24 -08:00
|
|
|
// dspVoice[vid].flags[salTimeOffset] |= 0x20;
|
2022-12-16 00:11:11 -08:00
|
|
|
}
|
|
|
|
|
2023-02-18 20:27:24 -08:00
|
|
|
void hwSetADSR(s32 vid, u32* param_2, u8 param_3) {}
|
2022-12-16 00:11:11 -08:00
|
|
|
|
2023-02-18 20:27:24 -08:00
|
|
|
void hwOff(s32 vid) { salDeactivateVoice(&dspVoice[vid]); }
|