Fully match snd_synthapi

This commit is contained in:
Phillip Stephens 2023-02-28 10:19:12 -08:00
parent 07e9934d0a
commit 4012ec3a16
7 changed files with 653 additions and 68 deletions

View File

@ -101,7 +101,7 @@ s32 sndInit(u8 voices, u8 music, u8 sfx, u8 studios, u32 flags, u32 aramSize);
void sndQuit(void); void sndQuit(void);
bool sndIsInstalled(); bool sndIsInstalled();
bool sndIsIdle(); u32 sndIsIdle();
SND_PLAYBACKINFO* sndGetPlayBackInfo(); SND_PLAYBACKINFO* sndGetPlayBackInfo();
void sndSetMaxVoices(u8 music, u8 sfx); void sndSetMaxVoices(u8 music, u8 sfx);

View File

@ -877,6 +877,7 @@ void* hwTransAddr(void* samples);
void seqInit(); /* extern */ void seqInit(); /* extern */
unsigned long seqStartPlay(PAGE* norm, PAGE* drum, MIDISETUP* midiSetup, u32* song, unsigned long seqStartPlay(PAGE* norm, PAGE* drum, MIDISETUP* midiSetup, u32* song,
SND_PLAYPARA* para, u8 studio, u16 sgid); SND_PLAYPARA* para, u8 studio, u16 sgid);
unsigned long seqGetPrivateId(unsigned long seqId);
void streamInit(); /* extern */ void streamInit(); /* extern */
void vsInit(); /* extern */ void vsInit(); /* extern */
void hwExit(); void hwExit();
@ -886,6 +887,7 @@ void s3dKillEmitterByFXID(FX_TAB* fxTab, unsigned long num);
void s3dExit(); void s3dExit();
void synthInit(u32, u8); /* extern */ void synthInit(u32, u8); /* extern */
void synthFXCloneMidiSetup(SYNTH_VOICE* dest, SYNTH_VOICE* src); void synthFXCloneMidiSetup(SYNTH_VOICE* dest, SYNTH_VOICE* src);
void synthSetMusicVolumeType(u8 vGroup, u8 type);
extern u32 synthGlobalVariable[16]; extern u32 synthGlobalVariable[16];
extern u16 voicePrioSortRootListRoot; extern u16 voicePrioSortRootListRoot;
@ -910,6 +912,9 @@ void hwActivateStudio(unsigned char studio, unsigned long isMaster, SND_STUDIO_T
void hwDeactivateStudio(u8); void hwDeactivateStudio(u8);
void hwSetPriority(unsigned long v, unsigned long prio); void hwSetPriority(unsigned long v, unsigned long prio);
u32 hwIsActive(u32); u32 hwIsActive(u32);
u32 hwGlobalActivity();
void hwSetAUXProcessingCallbacks(unsigned char studio, SND_AUX_CALLBACK auxA, void* userA,
SND_AUX_CALLBACK auxB, void* userB);
u32 sndGetPitch(u8 key, u32 sInfo); u32 sndGetPitch(u8 key, u32 sInfo);
extern SND_HOOKS salHooks; extern SND_HOOKS salHooks;
@ -917,10 +922,11 @@ extern u8 sndActive;
extern u8 synthIdleWaitActive; extern u8 synthIdleWaitActive;
extern SynthInfo synthInfo; extern SynthInfo synthInfo;
typedef s32 (*SND_MESSAGE_CALLBACK)(u32, u32); typedef s32 (*SND_MESSAGE_CALLBACK)(u32, u32);
typedef void (*SYNTH_MESSAGE_CALLBACK)(u32, s32);
typedef void (*SND_SOME_CALLBACK)(); typedef void (*SND_SOME_CALLBACK)();
extern SND_MESSAGE_CALLBACK salMessageCallback; extern SND_MESSAGE_CALLBACK salMessageCallback;
extern SND_MESSAGE_CALLBACK synthMessageCallback; extern SYNTH_MESSAGE_CALLBACK synthMessageCallback;
/* Math */ /* Math */
void salApplyMatrix(const SND_FMATRIX* a, const SND_FVECTOR* b, SND_FVECTOR* out); void salApplyMatrix(const SND_FMATRIX* a, const SND_FVECTOR* b, SND_FVECTOR* out);
float salNormalizeVector(SND_FVECTOR* vec); float salNormalizeVector(SND_FVECTOR* vec);

View File

@ -15,7 +15,7 @@ extern u8 synthAuxBMIDI[8];
extern u8 synthAuxBMIDISet[8]; extern u8 synthAuxBMIDISet[8];
extern void* synthAuxBUser[8]; extern void* synthAuxBUser[8];
extern u8 synthITDDefault[16]; extern synthITDInfo synthITDDefault[8];
extern u32 synthFlags; extern u32 synthFlags;
u32 vidGetInternalId(SND_VOICEID id); u32 vidGetInternalId(SND_VOICEID id);

View File

@ -1,4 +1,20 @@
/*
*/
#include "musyx/musyx_priv.h" #include "musyx/musyx_priv.h"
#ifdef _DEBUG #ifdef _DEBUG
@ -6,21 +22,37 @@ static u32 dbgActiveVoicesMax = 0;
#endif #endif
extern u8 salAuxFrame; extern u8 salAuxFrame;
DSPstudioinfo dspStudio[8]; DSPstudioinfo dspStudio[8];
static u32 dspARAMZeroBuffer = 0; static u32 dspARAMZeroBuffer = 0;
u16* dspCmdLastLoad = NULL; u16* dspCmdLastLoad = NULL;
u16* dspCmdLastBase = NULL; u16* dspCmdLastBase = NULL;
u16* dspCmdList = NULL; u16* dspCmdList = NULL;
u16 dspCmdLastSize = 0; u16 dspCmdLastSize = 0;
u16* dspCmdCurBase = NULL; u16* dspCmdCurBase = NULL;
u16* dspCmdMaxPtr = NULL; u16* dspCmdMaxPtr = NULL;
u16* dspCmdPtr = NULL; u16* dspCmdPtr = NULL;
u16 dspCmdFirstSize = 0; u16 dspCmdFirstSize = 0;
u32 dspHRTFOn = FALSE; u32 dspHRTFOn = FALSE;
s16* dspHrtfHistoryBuffer = NULL; s16* dspHrtfHistoryBuffer = NULL;
long* dspSurround = NULL; long* dspSurround = NULL;
s16* dspITDBuffer = NULL; s16* dspITDBuffer = NULL;
DSPvoice* dspVoice = NULL; DSPvoice* dspVoice = NULL;
SND_MESSAGE_CALLBACK salMessageCallback = NULL; SND_MESSAGE_CALLBACK salMessageCallback = NULL;
u32 salInitDspCtrl(u8 numVoices, u8 numStudios, u32 defaultStudioDPL2) { u32 salInitDspCtrl(u8 numVoices, u8 numStudios, u32 defaultStudioDPL2) {
@ -30,7 +62,7 @@ u32 salInitDspCtrl(u8 numVoices, u8 numStudios, u32 defaultStudioDPL2) {
salNumVoices = numVoices; salNumVoices = numVoices;
salMaxStudioNum = numStudios; salMaxStudioNum = numStudios;
#line 66
MUSY_ASSERT(salMaxStudioNum <= SAL_MAX_STUDIONUM); MUSY_ASSERT(salMaxStudioNum <= SAL_MAX_STUDIONUM);
dspARAMZeroBuffer = aramGetZeroBuffer(); dspARAMZeroBuffer = aramGetZeroBuffer();
if ((dspCmdList = salMalloc(1024 * sizeof(u16))) != NULL) { if ((dspCmdList = salMalloc(1024 * sizeof(u16))) != NULL) {
@ -186,7 +218,7 @@ static const u16 dspMixerCycles[32] = {
void salDeactivateStudio(u8 studio) { dspStudio[studio].state = 0; } void salDeactivateStudio(u8 studio) { dspStudio[studio].state = 0; }
u32 salCheckVolErrorAndResetDelta(u16* dsp_vol, u16* dsp_delta, u16* last_vol, u16 targetVol, static u32 salCheckVolErrorAndResetDelta(u16* dsp_vol, u16* dsp_delta, u16* last_vol, u16 targetVol,
u16* resetFlags, u16 resetMask) { u16* resetFlags, u16 resetMask) {
s16 d; // r31 s16 d; // r31
s16 x; // r30 s16 x; // r30
@ -194,23 +226,23 @@ u32 salCheckVolErrorAndResetDelta(u16* dsp_vol, u16* dsp_delta, u16* last_vol, u
if (targetVol != *last_vol) { if (targetVol != *last_vol) {
d = (s16)targetVol - (s16)*last_vol; d = (s16)targetVol - (s16)*last_vol;
if ((s16)d >= 32 && (s16)d < 160) { if ((s16)d >= 32 && (s16)d < 160) {
d = (s16)d >> 5; x = (s16)d >> 5;
if ((s16)d < 5) { if ((s16)x < 5) {
resetFlags[d] |= resetMask; resetFlags[x] |= resetMask;
} }
*dsp_delta = 1; *dsp_delta = 1;
*last_vol = *last_vol + (d * 32); *last_vol += (x << 5);
return 1; return 1;
} }
if (-32 >= (s16)d && -160 < (s16)d) { if (-32 >= (s16)d && -160 < (s16)d) {
d = -(s16)d >> 5; x = -(s16)d >> 5;
if (d < 5) { if (x < 5) {
resetFlags[d] |= resetMask; resetFlags[x] |= resetMask;
} }
*dsp_delta = 0xFFFF; *dsp_delta = 0xFFFF;
*last_vol -= (s16)d * 32; *last_vol -= x << 5;
return 1; return 1;
} }
@ -223,12 +255,12 @@ u32 salCheckVolErrorAndResetDelta(u16* dsp_vol, u16* dsp_delta, u16* last_vol, u
return 0; return 0;
} }
void sal_setup_dspvol(u16* dsp_delta, u16* last_vol, u16 vol) { static void sal_setup_dspvol(u16* dsp_delta, u16* last_vol, u16 vol) {
*dsp_delta = ((s16)vol - (s16)*last_vol) / 160; *dsp_delta = ((s16)vol - (s16)*last_vol) / 160;
*last_vol += (s16)*dsp_delta * 160; *last_vol += (s16)*dsp_delta * 160;
} }
void sal_update_hostplayinfo(DSPvoice* dsp_vptr) { static void sal_update_hostplayinfo(DSPvoice* dsp_vptr) {
u32 old_lo; // r30 u32 old_lo; // r30
u32 pitch; // r31 u32 pitch; // r31
@ -252,12 +284,12 @@ void sal_update_hostplayinfo(DSPvoice* dsp_vptr) {
} }
} }
void AddDpop(long* sum, s16 delta) { static void AddDpop(long* sum, s16 delta) {
*sum += (int)delta; *sum += (int)delta;
*sum = (*sum > 0x7fffff) ? 0x7fffff : (*sum < -0x7fffff ? -0x7fffff : *sum); *sum = (*sum > 0x7fffff) ? 0x7fffff : (*sum < -0x7fffff ? -0x7fffff : *sum);
} }
void DoDepopFade(long* dspStart, s16* dspDelta, long* hostSum) { static void DoDepopFade(long* dspStart, s16* dspDelta, long* hostSum) {
if (*hostSum <= -160) { if (*hostSum <= -160) {
*dspDelta = (*hostSum <= -3200) ? 0x14 : (s16)(-*hostSum / 160); *dspDelta = (*hostSum <= -3200) ? 0x14 : (s16)(-*hostSum / 160);
} else if (*hostSum >= 160) { } else if (*hostSum >= 160) {
@ -270,7 +302,7 @@ void DoDepopFade(long* dspStart, s16* dspDelta, long* hostSum) {
*hostSum += *dspDelta * 160; *hostSum += *dspDelta * 160;
} }
void HandleDepopVoice(DSPstudioinfo* stp, DSPvoice* dsp_vptr) { static void HandleDepopVoice(DSPstudioinfo* stp, DSPvoice* dsp_vptr) {
_PB* pb; // r31 _PB* pb; // r31
dsp_vptr->postBreak = 0; dsp_vptr->postBreak = 0;
dsp_vptr->pb->state = 0; dsp_vptr->pb->state = 0;
@ -301,7 +333,7 @@ void HandleDepopVoice(DSPstudioinfo* stp, DSPvoice* dsp_vptr) {
} }
} }
void SortVoices(DSPvoice** voices, long l, long r) { static void SortVoices(DSPvoice** voices, long l, long r) {
long i; // r28 long i; // r28
long last; // r29 long last; // r29
DSPvoice* tmp; // r27 DSPvoice* tmp; // r27
@ -311,11 +343,11 @@ void SortVoices(DSPvoice** voices, long l, long r) {
} }
tmp = voices[l]; tmp = voices[l];
last = (l + r) / 2; voices[l] = voices[(l + r) / 2];
voices[l] = voices[last]; voices[(l + r) / 2] = tmp;
voices[last] = tmp;
i = l + 1;
last = l; last = l;
i = l + 1;
for (; i <= r; ++i) { for (; i <= r; ++i) {
if (voices[i]->prio < voices[l]->prio) { if (voices[i]->prio < voices[l]->prio) {
last += 1; last += 1;
@ -334,6 +366,7 @@ void SortVoices(DSPvoice** voices, long l, long r) {
void salBuildCommandList(signed short* dest, unsigned long nsDelay) { void salBuildCommandList(signed short* dest, unsigned long nsDelay) {
static const u16 pbOffsets[9] = {10, 12, 24, 13, 16, 26, 18, 20, 22}; static const u16 pbOffsets[9] = {10, 12, 24, 13, 16, 26, 18, 20, 22};
static DSPvoice * voices[64];
} }
u32 salSynthSendMessage(DSPvoice* dsp_vptr, u32 mesg) { u32 salSynthSendMessage(DSPvoice* dsp_vptr, u32 mesg) {
@ -421,21 +454,17 @@ u32 salAddStudioInput(DSPstudioinfo* stp, SND_STUDIO_INPUT* desc) {
unsigned long salRemoveStudioInput(DSPstudioinfo* stp, SND_STUDIO_INPUT* desc) { unsigned long salRemoveStudioInput(DSPstudioinfo* stp, SND_STUDIO_INPUT* desc) {
long i; // r31 long i; // r31
i = 0; for (i = 0; i < stp->numInputs; ++i) {
while (i < stp->numInputs) {
if (stp->in[i].desc == desc) { if (stp->in[i].desc == desc) {
break; for (; i <= stp->numInputs - 2; ++i) {
stp->in[i] = stp->in[i + 1];
}
--stp->numInputs;
return 1;
} }
++i;
} }
while (i <= stp->numInputs - 2) { return 0;
stp->in[i] = stp->in[i + 1];
++i;
}
--stp->numInputs;
return 1;
} }
void salHandleAuxProcessing() { void salHandleAuxProcessing() {

View File

@ -1,89 +1,419 @@
#include "musyx/synth.h" /* ---------------------------------------
---------------------------------------
*/
#include "musyx/synth.h"
#include <stdarg.h>
/*
*/
bool sndFXCtrl(SND_VOICEID vid, u8 ctrl, u8 value) { bool sndFXCtrl(SND_VOICEID vid, u8 ctrl, u8 value) {
bool ret; bool ret;
MUSY_ASSERT_MSG(sndActive != 0, "Sound system is not initialized.");
hwDisableIrq(); hwDisableIrq();
ret = synthFXSetCtrl(vid, ctrl, value); ret = synthFXSetCtrl(vid, ctrl, value);
hwEnableIrq(); hwEnableIrq();
return ret; return ret;
} }
/*
*/
bool sndFXCtrl14(SND_VOICEID vid, u8 ctrl, u16 value) { bool sndFXCtrl14(SND_VOICEID vid, u8 ctrl, u16 value) {
bool ret; bool ret;
MUSY_ASSERT_MSG(sndActive != 0, "Sound system is not initialized.");
hwDisableIrq(); hwDisableIrq();
ret = synthFXSetCtrl14(vid, ctrl, value); ret = synthFXSetCtrl14(vid, ctrl, value);
hwEnableIrq(); hwEnableIrq();
return ret; return ret;
} }
/*
*/
bool sndFXKeyOff(SND_VOICEID vid) { bool sndFXKeyOff(SND_VOICEID vid) {
bool ret; bool ret;
MUSY_ASSERT_MSG(sndActive != 0, "Sound system is not initialized.");
hwDisableIrq(); hwDisableIrq();
ret = synthSendKeyOff(vid); ret = synthSendKeyOff(vid);
hwEnableIrq(); hwEnableIrq();
return ret; return ret;
} }
SND_VOICEID sndFXStartEx(SND_FXID fid, u8 vol, u8 pan, u8 studio) { /*
SND_VOICEID temp_r31;
*/
SND_VOICEID sndFXStartEx(SND_FXID fid, u8 vol, u8 pan, u8 studio) {
SND_VOICEID v;
MUSY_ASSERT_MSG(sndActive != 0, "Sound system is not initialized.");
hwDisableIrq(); hwDisableIrq();
temp_r31 = synthFXStart(fid, vol, pan, studio, synthITDDefault[studio * 2 + 1]); v = synthFXStart(fid, vol, pan, studio, synthITDDefault[studio].sfx);
hwEnableIrq(); hwEnableIrq();
return temp_r31; return v;
} }
SND_VOICEID sndFXCheck(SND_VOICEID arg0) { /*
u32 check;
s32 ret;
check = vidGetInternalId(arg0);
ret = -1;
if (check != -1) {
ret = arg0;
*/
SND_VOICEID sndFXStartPara(SND_FXID fid, u8 vol, u8 pan, u8 studio, u8 numPara, ...) {
u32 vid;
u8 i;
va_list args;
u32 value;
u8 ctrl;
MUSY_ASSERT_MSG(sndActive != 0, "Sound system is not initialized.");
hwDisableIrq();
if ((vid = synthFXStart(fid, vol, pan, studio, synthITDDefault[studio].sfx)) != -1 &&
numPara != 0) {
va_start(args, numPara);
for (i = 0; i < numPara; ++i) {
ctrl = va_arg(args, u32);
value = va_arg(args, u32);
/*
*/
if (ctrl < 0x40 || ctrl == 0x80 || ctrl == 0x84) {
MUSY_ASSERT_MSG(value <= 0x3fff, "Hires MIDI controller value out of range.");
synthFXSetCtrl14(vid, ctrl, (u16)value);
} else {
MUSY_ASSERT_MSG(value <= 0x7f, "Lores MIDI controller value out of range.");
synthFXSetCtrl(vid, ctrl, (u16)value);
}
}
} }
/*
*/
hwEnableIrq();
return vid;
}
/*
*/
SND_VOICEID sndFXStartParaInfo(SND_FXID fid, u8 vol, u8 pan, u8 studio,
SND_PARAMETER_INFO* paraInfo) {
unsigned long vid; // r29
unsigned char i; // r28
SND_PARAMETER* pPtr; // r31
MUSY_ASSERT_MSG(sndActive != 0, "Sound system is not initialized.");
hwDisableIrq();
if ((vid = synthFXStart(fid, vol, pan, studio, synthITDDefault[studio].sfx)) != 0xFFFFFFFF) {
MUSY_ASSERT_MSG(paraInfo != NULL, "Parameter pointer must not be NULL.");
for (pPtr = paraInfo->paraArray, i = 0; i < paraInfo->numPara; ++pPtr, ++i) {
/*
*/
if (pPtr->ctrl < 0x40 || pPtr->ctrl == 0x80 || pPtr->ctrl == 0x84) {
MUSY_ASSERT_MSG(pPtr->paraData.value14 <= 0x3fff,
"Hires MIDI controller value out of range.");
synthFXSetCtrl14(vid, pPtr->ctrl, pPtr->paraData.value14);
} else {
MUSY_ASSERT_MSG(pPtr->paraData.value7 <= 0x7f, "Lores MIDI controller value out of range.");
synthFXSetCtrl(vid, pPtr->ctrl, pPtr->paraData.value7);
}
}
}
hwEnableIrq();
return vid;
}
/*
*/
SND_VOICEID sndFXCheck(SND_VOICEID vid) {
MUSY_ASSERT_MSG(sndActive != NULL, "Sound system is not initialized.");
return vidGetInternalId(vid) != -1 ? vid : -1;
}
/*
*/
bool sndReadFlag(unsigned char num) {
MUSY_ASSERT_MSG(sndActive != NULL, "Sound system is not initialized.");
return synthGlobalVariable[num & 0xf];
}
/*
*/
long sndWriteFlag(unsigned char num, long value) {
long old; // r30
MUSY_ASSERT_MSG(sndActive != NULL, "Sound system is not initialized.");
num &= 0xf;
hwDisableIrq();
old = synthGlobalVariable[num];
synthGlobalVariable[num] = value;
hwEnableIrq();
return old;
}
/*
*/
u32 sndSendMessage(u32 vid, s32 mesg) {
u32 ret; // r31
MUSY_ASSERT_MSG(sndActive != NULL, "Sound system is not initialized.");
hwDisableIrq();
ret = macPostMessage(vid, mesg);
hwEnableIrq();
return ret; return ret;
} }
/*
*/
void sndSetReceiveMessageCallback(void (*callback)(unsigned long, long)) {
MUSY_ASSERT_MSG(sndActive != NULL, "Sound system is not initialized.");
synthMessageCallback = callback;
}
/*
*/
void sndSilence() {
MUSY_ASSERT_MSG(sndActive != NULL, "Sound system is not initialized.");
hwDisableIrq();
seqKillAllInstances();
s3dKillAllEmitter();
synthKillAllVoices(0);
hwEnableIrq();
}
/*
*/
u32 sndIsIdle() {
u32 i; // r31
u8 flag; // r30
MUSY_ASSERT_MSG(sndActive != NULL, "Sound system is not initialized.");
flag = 0;
synthIdleWaitActive = TRUE;
if (!hwGlobalActivity()) {
for (i = 0; i < synthInfo.voiceNum; ++i) {
flag |= hwIsActive(i);
}
} else {
flag = 1;
}
synthIdleWaitActive = FALSE;
return flag == 0;
}
/*
*/
u32 sndFXAssignVolGroup2FXId(SND_FXID fid, u8 vGroup) {
FX_TAB* fx; // r30
u32 ret; // r29
MUSY_ASSERT_MSG(sndActive != NULL, "Sound system is not initialized.");
ret = 0;
hwDisableIrq();
//
//
//
if ((fx = dataGetFX(fid)) != NULL) {
/*
*/
if ((u8)vGroup != 0xFE) {
//
//
fx->vGroup = vGroup;
synthSetMusicVolumeType(vGroup, 3);
} else {
fx->vGroup = 0x1f;
}
ret = 1;
} else {
MUSY_DEBUG("FX ID=%d could not be found in FX table.", fid);
}
hwEnableIrq();
return ret;
}
/*
*/
void sndPauseVolume(u8 volume, u16 time, u8 vGroup) {
MUSY_ASSERT_MSG(sndActive != NULL, "Sound system is not initialized.");
hwDisableIrq();
synthPauseVolume(volume, time, vGroup);
hwEnableIrq();
}
/*
*/
void sndVolume(u8 volume, u16 time, u8 volgroup) { void sndVolume(u8 volume, u16 time, u8 volgroup) {
MUSY_ASSERT_MSG(sndActive != NULL, "Sound system is not initialized.");
hwDisableIrq(); hwDisableIrq();
synthVolume(volume, time, volgroup, 0, -1); synthVolume(volume, time, volgroup, 0, -1);
hwEnableIrq(); hwEnableIrq();
} }
/*
*/
void sndMasterVolume(u8 volume, u16 time, u8 music, u8 fx) { void sndMasterVolume(u8 volume, u16 time, u8 music, u8 fx) {
MUSY_ASSERT_MSG(sndActive != NULL, "Sound system is not initialized.");
hwDisableIrq(); hwDisableIrq();
if (music != 0) { if (music != 0)
synthVolume(volume, time, 0x15, 0, -1); synthVolume(volume, time, 0x15, 0, -1);
}
if (fx != 0) { if (fx != 0)
synthVolume(volume, time, 0x16, 0, -1); synthVolume(volume, time, 0x16, 0, -1);
}
hwEnableIrq(); hwEnableIrq();
} }
/*
*/
void sndOutputMode(SND_OUTPUTMODE output) { void sndOutputMode(SND_OUTPUTMODE output) {
u32 i; u32 i;
u32 oldFlags = synthFlags; u32 oldFlags;
MUSY_ASSERT_MSG(sndActive != NULL, "Sound system is not initialized.");
oldFlags = synthFlags;
switch (output) { switch (output) {
case SND_OUTPUTMODE_MONO: case SND_OUTPUTMODE_MONO:
synthFlags |= 1; synthFlags |= 1;
synthFlags &= ~2; synthFlags &= ~2;
hwDisableHRTF(); hwDisableHRTF();
break; break;
case SND_OUTPUTMODE_STEREO: case SND_OUTPUTMODE_STEREO:
synthFlags &= ~1; synthFlags &= ~1;
synthFlags &= ~2; synthFlags &= ~2;
hwDisableHRTF(); hwDisableHRTF();
break; break;
case SND_OUTPUTMODE_SURROUND: case SND_OUTPUTMODE_SURROUND:
synthFlags &= ~1; synthFlags &= ~1;
synthFlags |= 2; synthFlags |= 2;
hwDisableHRTF(); hwDisableHRTF();
break;
default:
#line 426
MUSY_ASSERT_MSG(FALSE, "Unsupported outputmode selected.");
#line 418
break; break;
} }
@ -94,19 +424,30 @@ void sndOutputMode(SND_OUTPUTMODE output) {
for (i = 0; i < synthInfo.voiceNum; ++i) { for (i = 0; i < synthInfo.voiceNum; ++i) {
synthVoice[i].cFlags |= 0x0000200000000000; synthVoice[i].cFlags |= 0x0000200000000000;
} }
#if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4)
streamOutputModeChanged(); streamOutputModeChanged();
#endif
} }
/*
*/
// clang-format off // clang-format off
void sndSetAuxProcessingCallbacks(u8 studio, void sndSetAuxProcessingCallbacks(u8 studio,
SND_AUX_CALLBACK auxA, void* userA, u8 midiA, SND_SEQID seqIDA, SND_AUX_CALLBACK auxA, void* userA, u8 midiA, SND_SEQID seqIDA,
SND_AUX_CALLBACK auxB, void* userB, u8 midiB, SND_SEQID seqIDB) { SND_AUX_CALLBACK auxB, void* userB, u8 midiB, SND_SEQID seqIDB) {
// clang-format on // clang-format on
MUSY_ASSERT_MSG(sndActive != NULL, "Sound system is not initialized.");
hwDisableIrq(); hwDisableIrq();
if (auxA != NULL) { if (auxA != NULL) {
synthAuxAMIDI[studio] = midiA;
if (midiA != 0xFF) { if ((synthAuxAMIDI[studio] = midiA) != 0xFF) {
synthAuxAMIDISet[studio] = seqGetPrivateId(seqIDA); synthAuxAMIDISet[studio] = seqGetPrivateId(seqIDA);
synthAuxACallback[studio] = auxA; synthAuxACallback[studio] = auxA;
synthAuxAUser[studio] = userA; synthAuxAUser[studio] = userA;
@ -117,8 +458,8 @@ void sndSetAuxProcessingCallbacks(u8 studio,
} }
if (auxB != NULL) { if (auxB != NULL) {
synthAuxBMIDI[studio] = midiB;
if (midiB != 0xFF) { if ((synthAuxBMIDI[studio] = midiB) != 0xFF) {
synthAuxBMIDISet[studio] = seqGetPrivateId(seqIDB); synthAuxBMIDISet[studio] = seqGetPrivateId(seqIDB);
synthAuxBCallback[studio] = auxB; synthAuxBCallback[studio] = auxB;
synthAuxBUser[studio] = userB; synthAuxBUser[studio] = userB;
@ -132,21 +473,103 @@ void sndSetAuxProcessingCallbacks(u8 studio,
hwEnableIrq(); hwEnableIrq();
} }
void synthActivateStudio(u8 studio, u32 arg1, u32 arg2) { /*
*/
void sndUpdateAuxParameter(unsigned char studio, unsigned short* para, unsigned char auxBus) {
struct SND_AUX_INFO info; // r1+0x14
unsigned long i; // r30
MUSY_ASSERT_MSG(sndActive != NULL, "Sound system is not initialized.");
for (i = 0; i < 4; ++i) {
info.data.parameterUpdate.para[i] = para[i];
}
if (auxBus == 0) {
MUSY_ASSERT_MSG(synthAuxACallback[studio] != NULL, "No FX is defined for AuxA.");
synthAuxACallback[studio](1, &info, synthAuxAUser);
} else {
MUSY_ASSERT_MSG(synthAuxBCallback[studio] != NULL, "No FX is defined for AuxB.");
synthAuxBCallback[studio](1, &info, synthAuxBUser);
}
}
/*
*/
void sndSetITDDefault(unsigned char studio, unsigned long musicITD, unsigned long sfxITD) {
synthITDDefault[studio].music = musicITD;
synthITDDefault[studio].sfx = sfxITD;
}
/*
*/
void synthActivateStudio(u8 studio, u32 isMaster, SND_STUDIO_TYPE type) {
MUSY_ASSERT_MSG(sndActive != NULL, "Sound system is not initialized.");
hwDisableIrq(); hwDisableIrq();
synthAuxACallback[studio] = NULL; synthAuxACallback[studio] = NULL;
synthAuxBCallback[studio] = NULL; synthAuxBCallback[studio] = NULL;
synthAuxAMIDI[studio] = 0xFF; synthAuxAMIDI[studio] = 0xFF;
synthAuxBMIDI[studio] = 0xFF; synthAuxBMIDI[studio] = 0xFF;
synthITDDefault[studio * 2 + 1] = 0; synthITDDefault[studio].sfx = 0;
synthITDDefault[studio * 2 + 0] = 0; synthITDDefault[studio].music = 0;
hwActivateStudio(studio, arg1, arg2); hwActivateStudio(studio, isMaster, type);
hwEnableIrq(); hwEnableIrq();
} }
/*
*/
void sndActivateStudioEx(u8 studio, u32 isMaster, SND_STUDIO_TYPE type) {
MUSY_ASSERT_MSG(sndActive != NULL, "Sound system is not initialized.");
MUSY_ASSERT_MSG(studio < synthInfo.studioNum, "Illegal studio index.");
if (studio != 0) {
hwDisableIrq();
synthActivateStudio(studio, isMaster, type);
hwEnableIrq();
} else {
MUSY_DEBUG("The default studio cannot be activated or deactivated.\n");
}
}
/*
*/
void synthDeactivateStudio(u8 studio) { void synthDeactivateStudio(u8 studio) {
u32 i; u32 i;
MUSY_ASSERT_MSG(sndActive != NULL, "Sound system is not initialized.");
for (i = 0; i < synthInfo.voiceNum; ++i) { for (i = 0; i < synthInfo.voiceNum; ++i) {
if (studio == synthVoice[i].studio) { if (studio == synthVoice[i].studio) {
if (synthVoice[i].id != 0xFFFFFFFF) { if (synthVoice[i].id != 0xFFFFFFFF) {
voiceKillSound(synthVoice[i].vidList->vid); voiceKillSound(synthVoice[i].vidList->vid);
@ -155,19 +578,111 @@ void synthDeactivateStudio(u8 studio) {
} }
} }
} }
hwDisableIrq(); hwDisableIrq();
synthAuxACallback[studio] = 0; synthAuxACallback[studio] = 0;
synthAuxBCallback[studio] = 0; synthAuxBCallback[studio] = 0;
synthAuxAMIDI[studio] = 0xFF; synthAuxAMIDI[studio] = 0xFF;
synthAuxBMIDI[studio] = 0xFF; synthAuxBMIDI[studio] = 0xFF;
hwEnableIrq(); hwEnableIrq();
hwDeactivateStudio(studio); hwDeactivateStudio(studio);
} }
bool synthAddStudioInput(u8 studio, SND_STUDIO_INPUT* in_desc) { /*
*/
sndDeactivateStudio(u8 studio) {
MUSY_ASSERT_MSG(sndActive != NULL, "Sound system is not initialized.");
MUSY_ASSERT_MSG(studio < synthInfo.studioNum, "Illegal studio index.");
if (studio != 0) {
hwDisableIrq();
synthDeactivateStudio(studio);
hwEnableIrq();
} else {
MUSY_DEBUG("The default studio cannot be activated or deactivated.\n");
}
}
/*
*/
synthChangeStudioMasterMix(u8 studio, u32 isMaster) {
MUSY_ASSERT_MSG(sndActive != NULL, "Sound system is not initialized.");
hwChangeStudioMix(studio, isMaster);
}
//
void sndChangeStudioMasterMix(unsigned char studio, unsigned long isMaster) {
MUSY_ASSERT_MSG(sndActive != NULL, "Sound system is not initialized.");
if (studio != 0) {
hwDisableIrq();
synthChangeStudioMasterMix(studio, isMaster);
hwEnableIrq();
} else {
MUSY_DEBUG("Default studio's master mix cannot be changed.\n");
}
}
/*
*/
u32 synthAddStudioInput(u8 studio, SND_STUDIO_INPUT* in_desc) {
MUSY_ASSERT_MSG(sndActive != NULL, "Sound system is not initialized.");
return hwAddInput(studio, in_desc); return hwAddInput(studio, in_desc);
} }
bool synthRemoveStudioInput(u8 studio, SND_STUDIO_INPUT* in_desc) { //
u32 sndAddStudioInput(u8 studio, struct SND_STUDIO_INPUT* in_desc) {
u32 ret;
MUSY_ASSERT_MSG(sndActive != NULL, "Sound system is not initialized.");
hwDisableIrq();
ret = synthAddStudioInput(studio, in_desc);
hwEnableIrq();
return ret;
}
/*
*/
u32 synthRemoveStudioInput(u8 studio, SND_STUDIO_INPUT* in_desc) {
MUSY_ASSERT_MSG(sndActive != NULL, "Sound system is not initialized.");
return hwRemoveInput(studio, in_desc); return hwRemoveInput(studio, in_desc);
} }
/*
*/
u32 sndRemoveStudioInput(u8 studio, SND_STUDIO_INPUT* in_desc) {
u32 ret;
MUSY_ASSERT_MSG(sndActive != NULL, "Sound system is not initialized.");
hwDisableIrq();
ret = synthRemoveStudioInput(studio, in_desc);
hwEnableIrq();
return ret;
}
u8 sndDbgGetActiveVoices() {
u8 n; // r31
hwDisableIrq();
n = voiceFxRunning + voiceMusicRunning;
hwEnableIrq();
return n;
}

View File

@ -19,7 +19,7 @@ u8 sndActive = 0;
static u8 synthJobTableIndex = 0; static u8 synthJobTableIndex = 0;
u64 synthRealTime; u64 synthRealTime;
u8 synthIdleWaitActive; u8 synthIdleWaitActive;
SND_MESSAGE_CALLBACK synthMessageCallback; SYNTH_MESSAGE_CALLBACK synthMessageCallback;
SYNTH_VOICE* synthVoice; SYNTH_VOICE* synthVoice;
u32 synthFlags; u32 synthFlags;
u32 synthMasterFaderActiveFlags; u32 synthMasterFaderActiveFlags;

View File

@ -26,7 +26,7 @@ static void DoSetPitch(SYNTH_VOICE* svoice);
3) 0x12340000 & 0x00FFFFFF == 0x00340000 3) 0x12340000 & 0x00FFFFFF == 0x00340000
This behavior could also be matched with a simple mask This behavior could also be matched with a simple mask
0x12345678 & 0x00FF0000 == 0x00340000 0x12345678 & 0x00FF0000 == 0x00340000
But on PPC with CodeWarrior this just produces an improper load: But on PPC with CodeWarrior this just produces an improper load:
@ -35,7 +35,7 @@ static void DoSetPitch(SYNTH_VOICE* svoice);
lwz r0,0(r29) lwz r0,0(r29)
rlwinm r0,r0,0,8,0xf rlwinm r0,r0,0,8,0xf
` `
Instead of the expected Instead of the expected
` `
lwz r3,0(r29) lwz r3,0(r29)
@ -896,7 +896,42 @@ static void mcmdAuxBFXSelect(SYNTH_VOICE* svoice, MSTEP* cstep) {
static void mcmdPortamento(SYNTH_VOICE* svoice, MSTEP* cstep) { static void mcmdPortamento(SYNTH_VOICE* svoice, MSTEP* cstep) {
u32 time; // r1+0x10 u32 time; // r1+0x10
svoice->portType = cstep->para[0] >> 16;
time = cstep->para[1] >> 16;
if ((u8)((cstep->para[1] >> 8) & 1)) {
sndConvertMs(&time);
} else {
sndConvertTicks(&time, svoice);
}
svoice->portDuration = time;
switch ((u8)(cstep->para[0] >> 8)) {
case 0:
if (svoice->midi != 0xFF) {
inpSetMidiCtrl(0x41, svoice->midi, svoice->midiSet, 0);
}
svoice->cFlags &= ~0x400;
return;
case 1:
if (svoice->midi != 0xFF) {
inpSetMidiCtrl(0x41, svoice->midi, svoice->midiSet, 0x7f);
}
init_port:
if (!(svoice->cFlags & 0x400)) {
synthInitPortamento(svoice);
}
svoice->cFlags |= 0x400;
break;
case 2:
if (svoice->midi != 0xFF && inpGetMidiCtrl(0x41, svoice->midi, svoice->midiSet) > 8064) {
goto init_port;
}
break;
}
} }
s32 varGet32(SYNTH_VOICE* svoice, u32 ctrl, u8 index) { s32 varGet32(SYNTH_VOICE* svoice, u32 ctrl, u8 index) {
if (ctrl != 0) { if (ctrl != 0) {
return inpGetExCtrl(svoice, index); return inpGetExCtrl(svoice, index);
@ -931,7 +966,7 @@ void varSet(SYNTH_VOICE* svoice, u32 ctrl, u8 index, s16 v) { varSet32(svoice, c
static void mcmdVarCalculation(SYNTH_VOICE* svoice, MSTEP* cstep, u8 op) { static void mcmdVarCalculation(SYNTH_VOICE* svoice, MSTEP* cstep, u8 op) {
s16 s1 = 0; // r28 s16 s1 = 0; // r28
s16 s2 = 0; // r31 s16 s2 = 0; // r31
s32 t; // r30 s32 t; // r30
s1 = varGet(svoice, (cstep->para[0] >> 24), cstep->para[1]); s1 = varGet(svoice, (cstep->para[0] >> 24), cstep->para[1]);
if (op == 4) { if (op == 4) {