From a29290780bd2eb6e9997aeb46f9a3e8f62908972 Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Sat, 21 Oct 2023 10:29:58 -0700 Subject: [PATCH] Match and link snd3d.c Former-commit-id: 0c0fecfb797ed42f5e50d43fd5149eff7d4bcba0 --- configure.py | 2 +- include/musyx/hardware.h | 4 ++ include/musyx/musyx_priv.h | 78 +++++++++++++++++++++++------------- include/musyx/synth.h | 5 +++ src/musyx/runtime/snd3d.c | 8 ++-- src/musyx/runtime/snd_init.c | 27 +++++++++++-- src/musyx/runtime/synth.c | 74 +++++++++++++++++++++++++++++----- 7 files changed, 151 insertions(+), 47 deletions(-) diff --git a/configure.py b/configure.py index 35e1e073..8b8eda8f 100755 --- a/configure.py +++ b/configure.py @@ -1184,7 +1184,7 @@ config.libs = [ Object(Matching, "musyx/runtime/s_data.c"), Object(NonMatching, "musyx/runtime/hw_dspctrl.c"), Object(Matching, "musyx/runtime/hw_volconv.c"), - Object(NonMatching, "musyx/runtime/snd3d.c"), + Object(Matching, "musyx/runtime/snd3d.c"), Object(Matching, "musyx/runtime/snd_init.c"), Object(Matching, "musyx/runtime/snd_math.c"), Object(NonMatching, "musyx/runtime/snd_midictrl.c"), diff --git a/include/musyx/hardware.h b/include/musyx/hardware.h index 2700a665..da88f97d 100644 --- a/include/musyx/hardware.h +++ b/include/musyx/hardware.h @@ -30,6 +30,10 @@ void hwSetVirtualSampleLoopBuffer(u32 voice, void* addr, u32 len); u16 hwGetSampleID(u32 voice); u8 hwGetSampleType(u32 voice); void hwChangeStudioMix(u8 studio, u32 isMaster); +#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 3) +void hwSetFilter(unsigned long v, unsigned char mode, unsigned short coefA, unsigned short coefB); +void hwLowPassFrqToCoef(unsigned long frq, unsigned short* _a0, unsigned short* _b1); +#endif #ifdef __cplusplus } diff --git a/include/musyx/musyx_priv.h b/include/musyx/musyx_priv.h index ebd02a6c..5fc82e2b 100644 --- a/include/musyx/musyx_priv.h +++ b/include/musyx/musyx_priv.h @@ -513,27 +513,34 @@ typedef struct SYNTH_VOICE { u32 id; // offset 0xF4, size 0x4 VID_LIST* vidList; // offset 0xF8, size 0x4 VID_LIST* vidMasterList; // offset 0xFC, size 0x4 - u16 allocId; // offset 0x100, size 0x2 - u16 macroId; // offset 0x102, size 0x2 - u8 keyGroup; // offset 0x104, size 0x1 - u32 lastVID; // offset 0x108, size 0x4 - u8 prio; // offset 0x10C, size 0x1 - u16 ageSpeed; // offset 0x10E, size 0x2 - u32 age; // offset 0x110, size 0x4 - u64 cFlags; // offset 0x114, size 0x8 - u8 block; // offset 0x11C, size 0x1 - u8 fxFlag; // offset 0x11D, size 0x1 - u8 vGroup; // offset 0x11E, size 0x1 - u8 studio; // offset 0x11F, size 0x1 - u8 track; // offset 0x120, size 0x1 - u8 midi; // offset 0x121, size 0x1 - u8 midiSet; // offset 0x122, size 0x1 - u8 section; // offset 0x123, size 0x1 +#if MUSY_VERSION <= MUSY_VERSION_CHECK(2, 0, 0) + u16 allocId; // offset 0x100, size 0x2 +#else + u32 allocId; +#endif + u16 macroId; // offset 0x102, size 0x2 + u8 keyGroup; // offset 0x104, size 0x1 + u32 lastVID; // offset 0x108, size 0x4 + u8 prio; // offset 0x10C, size 0x1 + u16 ageSpeed; // offset 0x10E, size 0x2 + u32 age; // offset 0x110, size 0x4 + u64 cFlags; // offset 0x114, size 0x8 + u8 block; // offset 0x11C, size 0x1 + u8 fxFlag; // offset 0x11D, size 0x1 + u8 vGroup; // offset 0x11E, size 0x1 + u8 studio; // offset 0x11F, size 0x1 + u8 track; // offset 0x120, size 0x1 + u8 midi; // offset 0x121, size 0x1 + u8 midiSet; // offset 0x122, size 0x1 + u8 section; // offset 0x123, size 0x1 #if MUSY_VERSION <= MUSY_VERSION_CHECK(1, 5, 0) void* sAddr; #endif - u32 sInfo; // offset 0x124, size 0x4 - u32 playFrq; // offset 0x128, size 0x4 + u32 sInfo; // offset 0x124, size 0x4 + u32 playFrq; // offset 0x128, size 0x4 +#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 3) + u16 sampleId; +#endif u16 curNote; // offset 0x12C, size 0x2 s8 curDetune; // offset 0x12E, size 0x1 u8 orgNote; // offset 0x12F, size 0x1 @@ -577,9 +584,13 @@ typedef struct SYNTH_VOICE { u8 pbLowerKeyRange; // offset 0x1D6, size 0x1 u8 pbUpperKeyRange; // offset 0x1D7, size 0x1 u16 pbLast; // offset 0x1D8, size 0x2 - ADSR_VARS pitchADSR; // offset 0x1DC, size 0x28 - s16 pitchADSRRange; // offset 0x204, size 0x2 - u16 curPitch; // offset 0x206, size 0x2 +#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 3) + u32 lpfLowerFrqBoundary; + u32 lpfUpperFrqBoundary; +#endif + ADSR_VARS pitchADSR; // offset 0x1DC, size 0x28 + s16 pitchADSRRange; // offset 0x204, size 0x2 + u16 curPitch; // offset 0x206, size 0x2 struct setup { // total size: 0x9 u8 vol; // offset 0x0, size 0x1 @@ -606,11 +617,15 @@ typedef struct SYNTH_VOICE { CTRL_DEST inpPreAuxB; // offset 0x380, size 0x24 CTRL_DEST inpPostAuxB; // offset 0x3A4, size 0x24 CTRL_DEST inpTremolo; // offset 0x3C8, size 0x24 - u8 mesgNum; // offset 0x3EC, size 0x1 - u8 mesgRead; // offset 0x3ED, size 0x1 - u8 mesgWrite; // offset 0x3EE, size 0x1 - s32 mesgQueue[4]; // offset 0x3F0, size 0x10 - u16 curOutputVolume; // offset 0x400, size 0x2 +#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 3) + CTRL_DEST inpFilterSwitch; // offset 0x3F8, size 0x24 + CTRL_DEST inpFilterParameter; // offset 0x41C, size 0x24 +#endif + u8 mesgNum; // offset 0x3EC, size 0x1 + u8 mesgRead; // offset 0x3ED, size 0x1 + u8 mesgWrite; // offset 0x3EE, size 0x1 + s32 mesgQueue[4]; // offset 0x3F0, size 0x10 + u16 curOutputVolume; // offset 0x400, size 0x2 } SYNTH_VOICE; typedef struct synthITDInfo { @@ -855,7 +870,11 @@ typedef struct ADSR_INFO { } ADSR_INFO; void dataInit(u32, u32); /* extern */ -void dataInitStack(); /* extern */ +#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 3) +void dataInitStack(unsigned long aramBase, unsigned long aramSize); +#else +void dataInitStack(); /* extern */ +#endif u32 dataInsertSDir(SDIR_DATA* sdir, void* smp_data); u32 dataRemoveSDir(SDIR_DATA* sdir); u32 dataInsertMacro(u16 mid, void* macroaddr); @@ -1058,6 +1077,11 @@ void inpSetMidiCtrl(u8 ctrl, u8 channel, u8 set, u8 value); void inpSetMidiCtrl14(u8 ctrl, u8 channel, u8 set, u16 value); void inpSetExCtrl(SYNTH_VOICE* svoice, u8 ctrl, s16 v); CHANNEL_DEFAULTS* inpGetChannelDefaults(u8 midi, u8 midiSet); +#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 3) +unsigned short inpGetFilterSwitch(struct SYNTH_VOICE* svoice); +unsigned short inpGetFilterParameter(struct SYNTH_VOICE* svoice); +void inpSetLPFDefaultRange(u32 lowFrq, u32 highFrq); +#endif extern CTRL_DEST inpAuxA[8][4]; extern CTRL_DEST inpAuxB[8][4]; void inpSetMidiLastNote(u8 midi, u8 midiSet, u8 key); diff --git a/include/musyx/synth.h b/include/musyx/synth.h index 0d93690a..7a8c7e74 100644 --- a/include/musyx/synth.h +++ b/include/musyx/synth.h @@ -40,6 +40,11 @@ void hwSetAUXProcessingCallbacks(u8 studio, SND_AUX_CALLBACK auxA, void* userA, MSTEP* dataGetMacro(u16 mid); u32 voiceAllocate(u8 priority, u8 maxVoices, u16 allocId, u8 fxFlag); + +#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 3) +int voiceAllocatePeek(u8 priority, u8 maxVoices, u32 allocId, u8 fxFlag, u32 * currentAllocId); +#endif + void voiceFree(SYNTH_VOICE* svoice); void synthActivateStudio(u8 studio, u32 isMaster, SND_STUDIO_TYPE type); void synthDeactivateStudio(u8 studio); diff --git a/src/musyx/runtime/snd3d.c b/src/musyx/runtime/snd3d.c index 8ed4685f..97fb7391 100644 --- a/src/musyx/runtime/snd3d.c +++ b/src/musyx/runtime/snd3d.c @@ -125,7 +125,7 @@ static void CheckRoomStatus() { room->distance = distance; room->curMVol = has_listener ? 0x7f0000 : 0; - if (room->curMVol * 1.201479e-07f >= 0.5) { + if (room->curMVol * 1.2014794e-07f >= 0.5) { synthActivateStudio(room->studio, TRUE, SND_STUDIO_TYPE_STD); } else { synthActivateStudio(room->studio, FALSE, SND_STUDIO_TYPE_STD); @@ -142,7 +142,7 @@ static void CheckRoomStatus() { room->flags &= ~0x80000000; } - if (room->curMVol * 1.201479e-07f >= 0.5) { + if (room->curMVol * 1.2014794e-07f >= 0.5) { synthActivateStudio(room->studio, TRUE, SND_STUDIO_TYPE_STD); } else { synthActivateStudio(room->studio, FALSE, SND_STUDIO_TYPE_STD); @@ -155,7 +155,7 @@ static void CheckRoomStatus() { room->curMVol = 0; room->flags &= ~0x40000000; } - if (room->curMVol * 1.201479e-07f >= 0.5) { + if (room->curMVol * 1.2014794e-07f >= 0.5) { synthActivateStudio(room->studio, TRUE, SND_STUDIO_TYPE_STD); } else { synthActivateStudio(room->studio, FALSE, SND_STUDIO_TYPE_STD); @@ -444,7 +444,7 @@ static u16 clip3FFF(u32 v) { return v; } -static void SetFXParameters(SND_EMITTER* em, f32 vol, f32 xPan, f32 yPan, f32 zPan, f32 doppler) { +static void SetFXParameters(SND_EMITTER* const em, f32 vol, f32 xPan, f32 yPan, f32 zPan, f32 doppler) { SND_VOICEID vid; // r30 u8 i; // r28 SND_PARAMETER* pPtr; // r31 diff --git a/src/musyx/runtime/snd_init.c b/src/musyx/runtime/snd_init.c index d494291c..3637eff4 100644 --- a/src/musyx/runtime/snd_init.c +++ b/src/musyx/runtime/snd_init.c @@ -26,21 +26,29 @@ */ -static s32 DoInit(u32 rate, u32 aramSize, u32 voices, u32 flags) { +#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 3) +long DoInit(u32 mixFrq, u32 numVoices, u32 flags, u32 aramBase, u32 aramSize) +#else +static s32 DoInit(u32 mixFrq, u32 aramSize, u32 numVoices, u32 flags) +#endif +{ bool ret; - MUSY_DEBUG("\nMusyX software initialization...\nBuild Date: %s %s\n\n", __DATE__, __TIME__); + MUSY_DEBUG("\nMusyX software initialization...\nBuild Date: %s %s\n\n", "Dec 17 2003", "20:32:41"); ret = FALSE; +#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 3) + dataInitStack(aramBase, aramGetUserBytes(aramSize)); +#else dataInitStack(); - +#endif dataInit(0, aramSize); seqInit(); synthIdleWaitActive = 0; - synthInit(rate, voices); + synthInit(mixFrq, numVoices); streamInit(); @@ -72,6 +80,7 @@ s32 sndInit(u8 voices, u8 music, u8 sfx, u8 studios, u32 flags, u32 aramSize) { u32 frq; // r1+0x14 MUSY_DEBUG("Entering sndInit()\n\n"); + ret = 0; sndActive = 0; if (voices <= 64) { synthInfo.voiceNum = voices; @@ -88,7 +97,11 @@ s32 sndInit(u8 voices, u8 music, u8 sfx, u8 studios, u32 flags, u32 aramSize) { synthInfo.maxSFX = sfx; frq = 32000; if ((ret = hwInit(&frq, synthInfo.voiceNum, synthInfo.studioNum, flags)) == 0) { +#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 3) + ret = DoInit(32000, synthInfo.voiceNum, flags, aramGetFirstUserAddress(), aramSize); +#else ret = DoInit(32000, aramSize, synthInfo.voiceNum, flags); +#endif } MUSY_DEBUG("Leaving sndInit().\n\n"); @@ -145,3 +158,9 @@ SND_PLAYBACKINFO* sndGetPlayBackInfo() { return NULL; } + +#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 3) +void sndSetLowPassFilterDefaultRange(unsigned long lowFrq, unsigned long highFrq) { + inpSetLPFDefaultRange(lowFrq, highFrq); +} +#endif diff --git a/src/musyx/runtime/synth.c b/src/musyx/runtime/synth.c index 75413c0d..27dac3a7 100644 --- a/src/musyx/runtime/synth.c +++ b/src/musyx/runtime/synth.c @@ -1,5 +1,6 @@ #include "musyx/synth.h" +#include "musyx/hardware.h" #include "musyx/musyx_priv.h" static u32 synthTicksPerSecond[9][16]; @@ -315,7 +316,6 @@ static void unblockAllAllocatedVoices(u32 vid) { u32 id; // r31 id = vidGetInternalId(vid); -#line 501 MUSY_ASSERT_MSG(id != SND_ID_ERROR, "*** Alloc unblock: ID is illegal"); while (id != SND_ID_ERROR) { synthVoice[id & 0xff].block = 0; @@ -393,7 +393,11 @@ static void UpdateTimeMIDICtrl(SYNTH_VOICE* sv) { } sv->timeUsedByInput = 0; +#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 3) + sv->midiDirtyFlags = 0x7fff; +#else sv->midiDirtyFlags = 0x1fff; +#endif } static void LowPrecisionHandler(u32 i) { @@ -430,7 +434,11 @@ static void LowPrecisionHandler(u32 i) { sv->lfo[j].lastValue = sv->lfo[j].value; if (sv->lfoUsedByInput[j]) { sv->lfoUsedByInput[j] = 0; +#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 3) + sv->midiDirtyFlags |= 0x7fff; +#else sv->midiDirtyFlags |= 0x1fff; +#endif } } } @@ -441,8 +449,13 @@ static void LowPrecisionHandler(u32 i) { } if (sv->sweepNum[0] | sv->sweepNum[1]) { +#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 3) + cntDelta = (lowDeltaTime << 8) >> 4; + addFactor = (lowDeltaTime << 4) >> 4; +#else cntDelta = (lowDeltaTime & 0x00ffffff) << 4; addFactor = lowDeltaTime & 0x0fffffff; +#endif for (j = 0; j < 2; ++j) { if (sv->sweepNum[j] == 0) { continue; @@ -508,14 +521,18 @@ static void LowPrecisionHandler(u32 i) { Modulation = inpGetModulation(sv); vrange = sv->vibKeyRange * 256 + (sv->vibCentRange * 256) / 100; if (sv->vibModAddScale != 0) { -#if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4) +#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 3) + vrange += (sv->vibModAddScale * (Modulation >> 7)) >> 7; +#elif MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4) vrange += (sv->vibModAddScale * ((Modulation & 0x1ffff) >> 7)) >> 7; #else vrange += (sv->vibModAddScale * ((Modulation >> 7) & 0x1ff)) >> 7; #endif } if ((sv->cFlags & 0x4000) != 0) { -#if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4) +#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 3) + voff = (sv->vibCurOffset * (Modulation >> 7)) >> 7; +#elif MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4) voff = (sv->vibCurOffset * ((Modulation & 0x1ffff) >> 7)) >> 7; #else voff = (sv->vibCurOffset * ((Modulation >> 7) & 0x1ff)) >> 7; @@ -575,6 +592,12 @@ static void ZeroOffsetHandler(u32 i) { s32 pan; // r28 f32 preVol; // f26 f32 postVol; // f29 +#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 3) + unsigned short para; // r22 + unsigned short a0; // r1+0xA + unsigned short b0; // r1+0x8 + unsigned long frq; // r21 +#endif sv = &synthVoice[i]; if (!hwIsActive(i) && sv->addr == NULL) { @@ -664,17 +687,28 @@ static void ZeroOffsetHandler(u32 i) { if (volUpdate || (sv->midiDirtyFlags & 0xf01) != 0) { preVol = voiceVol; - postVol = voiceVol * vol * (f32)inpGetVolume(sv) * 0.00006103888f /* 1/16384? */; + postVol = voiceVol * vol * (f32)inpGetVolume(sv) * (1.f/16383.f) /* 1/16384? */; auxa = ((f32)sv->revVolOffset * (1.f / 127.f)) + - ((preVol * (f32)inpGetPreAuxA(sv) * 0.00006103888f /* 1/16384? */) + + ((preVol * (f32)inpGetPreAuxA(sv) * (1.f/16383.f) /* 1/16384? */) + ((f32)sv->revVolScale * - (postVol * (f32)inpGetReverb(sv) * 0.00006103888f /* 1/16384? */) * (1.f / 127.f))); - auxb = (preVol * (f32)inpGetPreAuxB(sv) * 0.00006103888f /* 1/16384? */) + - (postVol * (f32)inpGetPostAuxB(sv) * 0.00006103888f /* 1/16384? */); + (postVol * (f32)inpGetReverb(sv) * (1.f/16383.f) /* 1/16384? */) * (1.f / 127.f))); + auxb = (preVol * (f32)inpGetPreAuxB(sv) * (1.f/16383.f) /* 1/16384? */) + + (postVol * (f32)inpGetPostAuxB(sv) * (1.f/16383.f) /* 1/16384? */); sv->curOutputVolume = (u16)(postVol * 32767.f); hwSetVolume(i, sv->volTable, postVol, sv->lastPan, sv->lastSPan, auxa, auxb); } - +#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 3) + if (sv->midiDirtyFlags & 0x6000) { + if (inpGetFilterSwitch(sv) > 0x1FFF) { + para = inpGetFilterParameter(sv); + frq = sv->lpfLowerFrqBoundary + (u32)((1.f - ((1.f/16383.f) * para)) * (sv->lpfUpperFrqBoundary - sv->lpfLowerFrqBoundary)); + hwLowPassFrqToCoef(frq, &a0, &b0); + hwSetFilter(i, 1, a0, b0); + } else { + hwSetFilter(i, 0, 0, 0); + } + } +#endif if (sv->age != 0) { if ((s32)(sv->age -= sv->ageSpeed * lowDeltaTime) < 0) { sv->age = 0; @@ -943,6 +977,26 @@ u32 synthFXStart(u16 fid, u8 vol, u8 pan, u8 studio, u32 itd) { return v; } +#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 3) +int synthCheckFXRealloc(unsigned short fid) { + struct FX_TAB* fx; // r31 + unsigned long allocId; // r30 + unsigned long currentAllocId; // r1+0x8 + + fx = dataGetFX(fid); + if (fx == NULL) { + return 0; + } + + allocId = fid | 0x80000000; + + if (!voiceAllocatePeek(fx->priority, fx->maxVoices, allocId, TRUE, ¤tAllocId)) { + return 0; + } + return allocId == currentAllocId; +} +#endif + bool synthFXSetCtrl(u32 vid, u8 ctrl, u8 value) { u32 i; // r31 u32 ret; // r29 @@ -1264,7 +1318,6 @@ static u32 synthHWMessageHandler(u32 mesg, u32 voiceID) { break; default: -#line 1975 MUSY_ASSERT(FALSE); break; } @@ -1283,7 +1336,6 @@ void synthInit(u32 mixFrq, u32 numVoices) { synthVoice = salMalloc(numVoices * sizeof(SYNTH_VOICE)); if (synthVoice == NULL) { -#line 2135 MUSY_FATAL("Fatal: Could not allocate synthesizer voice array."); } memset(synthVoice, 0, numVoices * sizeof(SYNTH_VOICE));