From 771ee00fc78a1f1fb83b93672307033269a04aee Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Mon, 23 Oct 2023 12:22:07 -0700 Subject: [PATCH] Nearly match streamHandle, minor fixes Former-commit-id: 685734b22e068de22c536c13e3cff2c92054c918 --- configure.py | 10 ++- include/musyx/assert.h | 2 +- include/musyx/musyx_priv.h | 2 +- src/musyx/runtime/stream.c | 141 +++++++++++++++++++++++++++++--- src/musyx/runtime/synthmacros.c | 39 ++++----- 5 files changed, 161 insertions(+), 33 deletions(-) diff --git a/configure.py b/configure.py index e493bd54..4227b34f 100755 --- a/configure.py +++ b/configure.py @@ -189,7 +189,15 @@ cflags_retro = [ ] cflags_musyx = [ - *cflags_base, + "-proc gekko", + "-nodefaults", + "-nosyspath", + "-i include", + "-i libc", + "-inline auto", + "-O4,p", + "-fp hard", + "-Cpp_exceptions off", "-str reuse,pool,readonly", "-fp_contract off", ] diff --git a/include/musyx/assert.h b/include/musyx/assert.h index 69753f5a..7ce9a86d 100644 --- a/include/musyx/assert.h +++ b/include/musyx/assert.h @@ -27,7 +27,7 @@ static inline void __SOME_ASSERT_DERP() { __SOME_ASSERT_DERP2() != 0; } #ifndef MUSY_ASSERT_MSG #ifdef _DEBUG -#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 1) +#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 0) #define MUSY_ASSERT_MSG(cond, msg) \ do { \ s32 tmp = 1; \ diff --git a/include/musyx/musyx_priv.h b/include/musyx/musyx_priv.h index f28df748..a0120de8 100644 --- a/include/musyx/musyx_priv.h +++ b/include/musyx/musyx_priv.h @@ -1013,7 +1013,7 @@ extern u8 salNumVoices; /* Stream */ typedef s32 (*SND_STREAM_UPDATE_CALLBACK)(void* buffer1, u32 len1, void* buffer2, u32 len2, - void* user); + u32 user); typedef struct SNDADPCMinfo { // total size: 0x28 u16 numCoef; // offset 0x0, size 0x2 diff --git a/src/musyx/runtime/stream.c b/src/musyx/runtime/stream.c index 876fb20a..41b89ec8 100644 --- a/src/musyx/runtime/stream.c +++ b/src/musyx/runtime/stream.c @@ -40,8 +40,7 @@ void streamHandle() { return; } streamCallCnt = streamCallDelay; - si = streamInfo; - for (i = 0; i < synthInfo.voiceNum; ++i) { + for (si = &streamInfo[0], i = 0; i < synthInfo.voiceNum; ++i) { switch (si->state) { case 1: newsmp.info = si->frq | 0x40000000; @@ -72,7 +71,7 @@ void streamHandle() { } hwInitSamplePlayback(si->voice, -1, &newsmp, 1, -1, synthVoice[si->voice].id, 1, 1); - hwSetPitch(si->voice, ((float)si->frq / (float)synthInfo.mixFrq) * 4096.f); + hwSetPitch(si->voice, (si->frq / (float)synthInfo.mixFrq) * 4096.f); #if MUSY_VERSION <= MUSY_VERSION_CHECK(1, 5, 3) hwSetVolume(si->voice, 0, si->vol * (1 / 127.f), (si->pan << 16), (si->span << 16), si->auxa * (1 / 127.f), si->auxb * (1 / 127.f)); @@ -96,13 +95,134 @@ void streamHandle() { if (si->last != cpos) { if (si->last < cpos) { switch (si->type) { - case 0: + case 0: { if ((len = si->updateFunction(si->buffer + si->last, cpos - si->last, NULL, 0, - &si->user)) != 0 && + si->user)) != 0 && si->state == 2) { + cpos = (si->last + len) % si->size; + if (!(si->flags & 0x20000)) { + if (cpos != 0) { + hwFlushStream(si->buffer, si->size * 2, (cpos - si->last) * 2, si->hwStreamHandle, + NULL, 0); + } else { + hwFlushStream(si->buffer, si->size * 2, (si->size - si->last) * 2, + si->hwStreamHandle, NULL, 0); + } + } + + si->last = cpos; + } + } break; + case 1: { + u32 off = (si->last / 14); + if ((len = si->updateFunction(si->buffer + si->last * 4, cpos - si->last, NULL, 0, + si->user)) != 0 && + si->state == 2) { + cpos = (si->last + len) % si->size; + + if (!(si->flags & 0x20000)) { + if (cpos != 0) { + hwFlushStream(si->buffer, off * 8, (si->bytes + si->last) * -8, + si->hwStreamHandle, NULL, 0); + } else { + hwFlushStream(si->buffer, off * 8, ((cpos + 13) / 14) * 8 + off * -8, + si->hwStreamHandle, NULL, 0); + } + } + si->last = cpos; + } + } break; + } + } else if (cpos == 0) { + switch (si->type) { + case 0: + if ((len = si->updateFunction(si->buffer + cpos * 4, si->size - si->last, NULL, 0, + si->user)) && + si->state == 2) { + cpos = (si->last + len) % si->size; + if (!(si->flags & 0x20000)) { + if (cpos == 0) { + hwFlushStream(si->buffer, si->last * 2, si->bytes + si->last * -2, + si->hwStreamHandle, NULL, 0); + } else { + hwFlushStream(si->buffer, si->last * 2, (cpos - si->last) * 2, si->hwStreamHandle, + NULL, 0); + } + } + si->last = cpos; + } + break; + case 1: + cpos = si->last / 14; + if ((len = si->updateFunction(si->buffer + cpos * 4, si->size - si->last, NULL, 0, + si->user)) && + si->state == 2) { + u32 off = (si->last + len) % si->size; + if (!(si->flags & 0x20000)) { + if (off == 0) { + hwFlushStream(si->buffer, cpos * 8, si->bytes + cpos * -8, si->hwStreamHandle, + NULL, 0); + } else { + hwFlushStream(si->buffer, si->last * 2, ((off + 13) / 14) * 8, si->hwStreamHandle, + NULL, 0); + } + } + + si->last = off; } break; } + } else { + switch (si->type) { + case 0: + if ((len = si->updateFunction(si->buffer + cpos * 4, si->size - si->last, NULL, 0, + si->user)) && + si->state == 2) { + cpos = (si->last + len) % si->size; + + if (!(si->flags & 0x20000)) { + if (si->size - si->last > len) { + hwFlushStream(si->buffer, si->last * 2, si->bytes + si->last * -2, + si->hwStreamHandle, NULL, 0); + hwFlushStream(si->buffer, 0, cpos * 2, si->hwStreamHandle, NULL, 0); + } else if (cpos == 0) { + hwFlushStream(si->buffer, si->last * 2, si->bytes + si->last * -2, + si->hwStreamHandle, NULL, 0); + } else { + hwFlushStream(si->buffer, si->last * 2, (cpos - si->last) * 2, si->hwStreamHandle, + NULL, 0); + } + } + } + break; + case 1: { + u32 off = (si->last / 14) * 8; + if ((len = si->updateFunction(si->buffer + cpos * 4, si->size - si->last, NULL, 0, + si->user)) && + si->state == 2) { + cpos = (si->last + len) % si->size; + + if (!(si->flags & 0x20000)) { + if (si->size - si->last > len) { + hwFlushStream(si->buffer, off, ((cpos + 13) / 14) * 8, si->hwStreamHandle, NULL, + 0); + } else if (cpos == 0) { + hwFlushStream(si->buffer, off, si->bytes + off * -8, si->hwStreamHandle, NULL, 0); + } else { + hwFlushStream(si->buffer, off, si->bytes + (si->last / 14) * -8, + si->hwStreamHandle, NULL, 0); + hwFlushStream(si->buffer, 0, (cpos / 14) << 3, si->hwStreamHandle, NULL, 0); + } + } + } + si->last = cpos; + } break; + } + } + + if (si->state == 2 && !(si->flags & 0x20000) && si->type == 1) { + hwSetStreamLoopPS(si->voice, + (si->lastPSFromBuffer = *(u32*)OSCachedToUncached(si->buffer) >> 24)); } } break; @@ -122,7 +242,7 @@ void streamKill(u32 voice) { voiceUnblock(si->voice); } si->state = 3; - si->updateFunction(NULL, 0, NULL, 0, (void*)si->user); + si->updateFunction(NULL, 0, NULL, 0, si->user); break; default: break; @@ -362,6 +482,7 @@ u32 sndStreamAllocStereo(u8 prio, void* lBuffer, void* rBuffer, u32 samples, u32 hwEnableIrq(); return stid[0]; } + u32 sndStreamAllocLength(u32 num, u32 flags) { if (flags & 1) { return (((num + 13) / 14) * 8 + 31) & ~31; @@ -461,7 +582,7 @@ void sndStreamFrq(u32 stid, u32 frq) { MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized."); hwDisableIrq(); - (i = GetPrivateIndex(stid)); + i = GetPrivateIndex(stid); if (i != -1) { streamInfo[i].frq = frq; if (streamInfo[i].state == 2) { @@ -500,11 +621,9 @@ void sndStreamFree(u32 stid) { } u32 sndStreamActivate(u32 stid) { - u32 i; // r31 - u32 ret; // r28 + u32 i; // r31 + bool ret = 0; // r28 MUSY_ASSERT_MSG(sndActive, "Sound system is not initialized."); - i = 0; - ret = 0; hwDisableIrq(); i = GetPrivateIndex(stid); if (i != -1) { diff --git a/src/musyx/runtime/synthmacros.c b/src/musyx/runtime/synthmacros.c index cd73fa2c..df5e7a09 100644 --- a/src/musyx/runtime/synthmacros.c +++ b/src/musyx/runtime/synthmacros.c @@ -94,7 +94,7 @@ static u32 mcmdWait(SYNTH_VOICE* svoice, MSTEP* cstep) { u32 w; // r1+0x10 u32 ms; // r29 - if ((ms = cstep->para[1] >> 0x10)) { + if ((ms = (u16)(cstep->para[1] >> 0x10))) { if (((u8)(cstep->para[0] >> 8) & 1)) { if (svoice->cFlags & 8) { if (!(svoice->cFlags & 0x10000000000)) { @@ -128,13 +128,13 @@ static u32 mcmdWait(SYNTH_VOICE* svoice, MSTEP* cstep) { } if (w != 0) { - if (cstep->para[1] & 1) { + if ((u8)cstep->para[1] & 1) { svoice->wait = svoice->macStartTime + ms; } else { svoice->wait = macRealTime + ms; } } else { - if (cstep->para[1] & 1) { + if ((u8)cstep->para[1] & 1) { svoice->wait = ms; } else { svoice->wait = svoice->waitTime + ms; @@ -298,7 +298,7 @@ static void mcmdLoop(SYNTH_VOICE* svoice, MSTEP* cstep) { if (svoice->loop == 0) { if ((u8)(cstep->para[0] >> 16) & 1) { - svoice->loop = sndRand() % (s32)(cstep->para[1] >> 16); + svoice->loop = sndRand() % (u16)(cstep->para[1] >> 16); } else { svoice->loop = (cstep->para[1] >> 16); } @@ -407,7 +407,7 @@ static void mcmdSetAgeCounterSpeed(SYNTH_VOICE* svoice, MSTEP* cstep) { static void mcmdSetAgeCounterByVolume(SYNTH_VOICE* svoice, MSTEP* cstep) { u32 age; // r30 - age = (((u8)(svoice->volume >> 16) * (u16)cstep->para[1]) >> 7) + (cstep->para[0] >> 16); + age = (((u8)(svoice->volume >> 16) * (u16)cstep->para[1]) >> 7) + (u16)(cstep->para[0] >> 16); svoice->age = age > 60000 ? 0x75300000 : age * 0x8000; hwSetPriority(svoice->id & 0xff, (u32)svoice->prio << 0x18 | svoice->age >> 0xf); } @@ -436,7 +436,7 @@ static void mcmdSetPitchWheelRange(SYNTH_VOICE* svoice, MSTEP* cstep) { } static u32 mcmdSetKey(SYNTH_VOICE* svoice, MSTEP* cstep) { - svoice->curNote = (u16)(cstep->para[0] >> 8) & 0x7f; + svoice->curNote = (u8)(cstep->para[0] >> 8) & 0x7f; svoice->curDetune = (s8)(cstep->para[0] >> 0x10); if (voiceIsLastStarted(svoice) != 0) { inpSetMidiLastNote(svoice->midi, svoice->midiSet, svoice->curNote & 0xff); @@ -446,8 +446,8 @@ static u32 mcmdSetKey(SYNTH_VOICE* svoice, MSTEP* cstep) { } static u32 mcmdAddKey(SYNTH_VOICE* svoice, MSTEP* cstep) { - if (cstep->para[0] >> 0x18 == 0) { - svoice->curNote = svoice->curNote + (s16)(s8)(u8)(cstep->para[0] >> 8); + if ((u8)(cstep->para[0] >> 0x18) == 0) { + svoice->curNote += (s8)(u8)(cstep->para[0] >> 8); } else { svoice->curNote = (u16)svoice->orgNote + (s16)(s8)(u8)(cstep->para[0] >> 8); } @@ -482,7 +482,7 @@ static void mcmdStartSample(SYNTH_VOICE* svoice, MSTEP* cstep) { if (dataGetSample(smp, &newsmp) != 0) { return; } - switch (cstep->para[0] >> 0x18) { + switch ((u8)(cstep->para[0] >> 0x18)) { case 0: newsmp.offset = cstep->para[1]; break; @@ -543,7 +543,7 @@ static void mcmdVibrato(SYNTH_VOICE* svoice, MSTEP* cstep) { } time = (u16)(cstep->para[1] >> 0x10); - if ((u16)(cstep->para[1] >> 8) & 1) { + if ((u8)(cstep->para[1] >> 8) & 1) { sndConvertMs(&time); } else { sndConvertTicks(&time, svoice); @@ -592,7 +592,7 @@ static void mcmdSetupLFO(SYNTH_VOICE* svoice, MSTEP* cstep) { u8 n; // r31 n = (u8)(cstep->para[0] >> 8); - time = cstep->para[0] >> 0x10; + time = (u16)(cstep->para[0] >> 0x10); sndConvertMs(&time); if (svoice->lfo[n].period != 0) { phase = (u16)cstep->para[1]; @@ -629,7 +629,6 @@ static void DoSetPitch(SYNTH_VOICE* svoice) { f /= (1 << (no & 0x3f)); for (i = 11; f <= kf[i]; i--) { - } svoice->curNote = (svoice->sInfo >> 24) + no * 12 + i; @@ -704,10 +703,10 @@ static u32 mcmdPitchSweep(SYNTH_VOICE* svoice, MSTEP* cstep, int num) { static void DoPanningSetup(SYNTH_VOICE* svoice, MSTEP* cstep, u8 pi) { s32 width; // r29 u32 mstime; // r27 - svoice->panTime[pi] = width = (cstep->para[0] >> 16); + svoice->panTime[pi] = width = (u16)(cstep->para[0] >> 16); sndConvertMs(&svoice->panTime[pi]); mstime = (s8)(cstep->para[1]); - svoice->panning[pi] = (cstep->para[0] & 0xFF00) << 8; + svoice->panning[pi] = ((u8)(cstep->para[0] >> 8)) << 16; svoice->panTarget[pi] = svoice->panning[pi] + mstime * 0x10000; if (svoice->panTime[pi] != 0) { svoice->panDelta[pi] = (s32)(mstime << 16) / width; @@ -752,7 +751,7 @@ static u32 TranslateVolume(u32 volume, u16 curve) { if (vhigh < 0x7f) { d = vlow * (ptr[vhigh + 1] - ptr[vhigh]); - volume = d + ((u8)ptr[vhigh] << 16); + volume = d + (ptr[vhigh] << 16); } else { volume = ptr[vhigh] << 16; } @@ -772,9 +771,11 @@ static void mcmdScaleVolume(SYNTH_VOICE* svoice, MSTEP* cstep) { } else { svoice->volume = (svoice->orgVolume * scale) / 0x7f; } - +#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 0) + svoice->volume += (u8)(cstep->para[0] >> 16) << 16; +#else svoice->volume += EXTRACT_3RDNYBBLE(cstep->para[0]); - +#endif if (svoice->volume > 0x7f0000) { svoice->volume = 0x7f0000; } @@ -789,8 +790,8 @@ static void mcmdScaleVolume(SYNTH_VOICE* svoice, MSTEP* cstep) { static void mcmdScaleVolumeDLS(SYNTH_VOICE* svoice, MSTEP* cstep) { u16 scale; // r31 - scale = (u16)(cstep->para[0] >> 8); - if (cstep->para[0] >> 0x18 == 0) { + scale = (cstep->para[0] >> 8); + if ((u8)(cstep->para[0] >> 0x18) == 0) { svoice->volume = ((svoice->volume >> 5) * scale) >> 7; } else { svoice->volume = ((svoice->orgVolume >> 5) * scale) >> 7;