From 1416c39e0f2878db34a7381a74ff5175dec56885 Mon Sep 17 00:00:00 2001 From: escape209 Date: Sat, 1 Aug 2026 15:24:13 +0100 Subject: [PATCH 1/4] iSnd work --- src/SB/Core/gc/iSnd.cpp | 191 +++++++++++++++++++++++++++++++++++++--- src/SB/Core/gc/iSnd.h | 6 +- 2 files changed, 184 insertions(+), 13 deletions(-) diff --git a/src/SB/Core/gc/iSnd.cpp b/src/SB/Core/gc/iSnd.cpp index 642ab8c0c..ce145b9c4 100644 --- a/src/SB/Core/gc/iSnd.cpp +++ b/src/SB/Core/gc/iSnd.cpp @@ -613,16 +613,20 @@ bool iSndIsPlaying(U32 assetID) { if (gSnd.voice[i].assetID == assetID) { - if(streams[i].vinf.flags & 0xC000 && (streams[i].vinf.flags & 0x82) == 0) { + if (streams[i].vinf.flags & 0xC000 && (streams[i].vinf.flags & 0x82) == 0) + { return true; } return false; } } - for(S32 i = 0; i < 0x3a; i++) { - if(gSnd.voice[i+6].assetID == assetID) { - if(voices[i].flags & 0x4 && (voices[i].flags & 0x8) == 0) { + for (S32 i = 0; i < 0x3a; i++) + { + if (gSnd.voice[i + 6].assetID == assetID) + { + if (voices[i].flags & 0x4 && (voices[i].flags & 0x8) == 0) + { return true; } return false; @@ -633,10 +637,12 @@ bool iSndIsPlaying(U32 assetID) bool iSndIsPlaying(U32 assetID, U32 parid) { - for(U32 i = 0; i < 0x40; i++) { - if((assetID == 0 || gSnd.voice[i].assetID == assetID) && gSnd.voice[i].parentID == parid) + for (U32 i = 0; i < 0x40; i++) + { + if ((assetID == 0 || gSnd.voice[i].assetID == assetID) && gSnd.voice[i].parentID == parid) { - if(iSndIsPlaying(gSnd.voice[i].assetID)) { + if (iSndIsPlaying(gSnd.voice[i].assetID)) + { return true; }; } @@ -646,7 +652,6 @@ bool iSndIsPlaying(U32 assetID, U32 parid) bool iSndIsPlayingByHandle(U32 handle) { - if (handle == 0) { return false; @@ -656,17 +661,18 @@ bool iSndIsPlayingByHandle(U32 handle) { if (gSnd.voice[i].sndID == handle) { - return (streams[i].vinf.flags & 0xC000 && (streams[i].vinf.flags & 0x82) == 0); + return (streams[i].vinf.flags & 0xC000 && (streams[i].vinf.flags & 0x82) == 0); } } - for(S32 i = 0; i < 0x3a; i++) { - if(gSnd.voice[i+6].sndID == handle) { + for (S32 i = 0; i < 0x3a; i++) + { + if (gSnd.voice[i + 6].sndID == handle) + { return (voices[i].flags & 0x4 && (voices[i].flags & 0x8) == 0); } } return false; - } U32 iVolFromX(F32 param1) @@ -686,6 +692,18 @@ U32 iVolFromX(F32 param1) } } +void iSndCalcVol(xSndVoiceInfo* vp, vinfo* info) +{ + S32 vol = iVolFromX(vp->vol * gSnd.categoryVolFader[vp->category]); + + info->x10 = vol; + info->x14 = vol; + info->x18 = 0x40; + info->x1c = 0x40; + MIXAdjustFader(info->voice, vol - MIXGetFader(info->voice)); + MIXAdjustPan(info->voice, 0x40 - MIXGetPan(info->voice)); +} + void iSndVolUpdate(xSndVoiceInfo* info, vinfo* vinfo) { MIXUnMute(vinfo->voice); @@ -716,6 +734,42 @@ void iSndUpdateSounds() } } +S32 iSndPlay(xSndVoiceInfo* vp) +{ + U32 ret; + + S32 offset = (S32)vp - (S32)gSnd.voice; + S32 div = offset / 100; + + xSTAssetName(vp->assetID); + + if ((div < 0) || (div >= 64)) + { + ret = 0; + } + else if (div < 6) + { + ret = iSndPrepStream(vp); + if (ret < 0x3a) + { + if (vp->flags & 0x200) + { + ret = iSndPlayMemStream(vp); + } + else + { + ret = iSndPlayStream(vp); + } + } + } + else + { + ret = iSndPlaySound(vp); + } + + return ret; +} + void iSndStartStereo(U32 id1, U32 id2, F32 pitch) { } @@ -779,6 +833,44 @@ void sndloadcb(tag_xFile* tag) SoundFlags = 0; } +void iSndDIEDIEDIE() +{ + if (!soundInited) + { + return; + } + + OSDisableInterrupts(); + soundInited = 0; + + for (S32 i = 0; i < (S32)(sizeof(streams) / (sizeof(UNK_STREAM))); i++) + { + UNK_STREAM* pv = &streams[i]; + + if (pv->vinf.voice != NULL) + { + MIXReleaseChannel(pv->vinf.voice); + AXSetVoiceState(pv->vinf.voice, 0); + iSndMyAXFree(&pv->vinf.voice); + } + pv++; + } + + for (S32 i = 0; i < (S32)(sizeof(voices) / (sizeof(vinfo))); i++) + { + vinfo* v = &voices[i]; + + if ((v->voice != NULL)) + { + MIXReleaseChannel(v->voice); + AXSetVoiceState(v->voice, 0); + iSndMyAXFree(&v->voice); + } + } + + AXQuit(); +} + void iSndSetExternalCallback(iSndExternalCallback callback) { } @@ -791,3 +883,78 @@ void iSndMyAXFree(_AXVPB** param1) *param1 = NULL; } } + +void iSndSuspend() +{ + AXRegisterCallback(0); + + for (S32 i = 0; i < (S32)(sizeof(streams) / (sizeof(UNK_STREAM))); i++) + { + UNK_STREAM* pv = &streams[i]; + + if (pv->vinf.voice != NULL) + { + AXSetVoiceState(pv->vinf.voice, 0); + } + pv++; + } + + for (S32 i = 0; i < (S32)(sizeof(voices) / (sizeof(vinfo))); i++) + { + vinfo* v = &voices[i]; + + if ((v->voice != NULL)) + { + AXSetVoiceState(v->voice, 0); + } + } +} + +void iSndResume() +{ + for (S32 i = 0; i < (S32)(sizeof(streams) / (sizeof(UNK_STREAM))); i++) + { + UNK_STREAM* pv = &streams[i]; + + if ((pv->vinf.voice != NULL) && !(pv->vinf.flags & 2)) + { + AXSetVoiceState(pv->vinf.voice, 1); + } + pv++; + } + + for (S32 i = 0; i < (S32)(sizeof(voices) / (sizeof(vinfo))); i++) + { + vinfo* v = &voices[i]; + + if ((v->voice != NULL) && !(v->flags & 8)) + { + AXSetVoiceState(v->voice, 1); + } + } + + AXRegisterCallback(fcb); +} + +F32 iSndGetVol(U32 snd) +{ + xSndVoiceInfo* vp = &gSnd.voice[0]; + + for (int i = 0; i < 0x40; i++) + { + if (vp->flags & 1) + { + if (vp->sndID == snd) + { + if (gSnd.categoryVolFader[vp->category] <= 0.0f) + { + return 0.0f; + } + return (vp->vol / gSnd.categoryVolFader[vp->category]); + } + } + vp++; + } + + return 0.0f; +} \ No newline at end of file diff --git a/src/SB/Core/gc/iSnd.h b/src/SB/Core/gc/iSnd.h index 8fd42e336..c658a8e88 100644 --- a/src/SB/Core/gc/iSnd.h +++ b/src/SB/Core/gc/iSnd.h @@ -78,7 +78,11 @@ void iSndUpdate(); void iSndFindFreeVoice(U32 priority, U32 flags, U32 owner); -void iSndPlay(xSndVoiceInfo* vp); +S32 iSndPlay(xSndVoiceInfo* vp); +S32 iSndPrepStream(xSndVoiceInfo *); +S32 iSndPlayStream(xSndVoiceInfo *); +S32 iSndPlayMemStream(xSndVoiceInfo *); +S32 iSndPlaySound(xSndVoiceInfo *); void iSndSetVol(U32 snd, F32 vol); void iSndSetPitch(U32 snd, F32 pitch); void iSndStartStereo(U32 id1, U32 id2, F32 pitch); From 24f60ed6184b02ac9ada791fb2eaaf1cc19e5d9b Mon Sep 17 00:00:00 2001 From: escape209 Date: Sun, 2 Aug 2026 12:09:03 +0100 Subject: [PATCH 2/4] Match iSndSetVol and fix iSndPlay --- src/SB/Core/gc/iSnd.cpp | 51 ++++++++++++++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 8 deletions(-) diff --git a/src/SB/Core/gc/iSnd.cpp b/src/SB/Core/gc/iSnd.cpp index ce145b9c4..2ad25292e 100644 --- a/src/SB/Core/gc/iSnd.cpp +++ b/src/SB/Core/gc/iSnd.cpp @@ -736,8 +736,6 @@ void iSndUpdateSounds() S32 iSndPlay(xSndVoiceInfo* vp) { - U32 ret; - S32 offset = (S32)vp - (S32)gSnd.voice; S32 div = offset / 100; @@ -745,29 +743,66 @@ S32 iSndPlay(xSndVoiceInfo* vp) if ((div < 0) || (div >= 64)) { - ret = 0; + return 0; } else if (div < 6) { - ret = iSndPrepStream(vp); + U32 ret = iSndPrepStream(vp); if (ret < 0x3a) { if (vp->flags & 0x200) { - ret = iSndPlayMemStream(vp); + return iSndPlayMemStream(vp); } else { - ret = iSndPlayStream(vp); + return iSndPlayStream(vp); } } + return ret; } else { - ret = iSndPlaySound(vp); + return iSndPlaySound(vp); + } +} + +void iSndSetVol(U32 snd, F32 vol) +{ + xSndVoiceInfo* vp = &gSnd.voice[0]; + + S32 i = 0; + for (; i < 64;) + { + if (vp->sndID == snd) + break; + i++; + vp++; } - return ret; + if (i != 64) + { + vp->vol = vol; + S32 adj = iVolFromX(vol * gSnd.categoryVolFader[vp->category]); + vinfo* info; + if (i < 6) + { + info = &streams[i].vinf; + } + else + { + info = &voices[i - 6]; + } + if (info->voice != 0) + { + info->x10 = adj; + info->x14 = adj; + info->x18 = 0x40; + info->x1c = 0x40; + MIXAdjustFader(info->voice, adj - MIXGetFader(info->voice)); + MIXAdjustPan(info->voice, 0x40 - MIXGetPan(info->voice)); + } + } } void iSndStartStereo(U32 id1, U32 id2, F32 pitch) From 7a9ebcf982534ae0626050c0a82a61d6a6240ad7 Mon Sep 17 00:00:00 2001 From: escape209 Date: Sun, 2 Aug 2026 13:01:57 +0100 Subject: [PATCH 3/4] Save iSndDIEDIEDIE for a Part 2 PR --- src/SB/Core/gc/iSnd.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SB/Core/gc/iSnd.cpp b/src/SB/Core/gc/iSnd.cpp index 2ad25292e..3bf9b264b 100644 --- a/src/SB/Core/gc/iSnd.cpp +++ b/src/SB/Core/gc/iSnd.cpp @@ -867,7 +867,7 @@ void sndloadcb(tag_xFile* tag) { SoundFlags = 0; } - +/* Matching void iSndDIEDIEDIE() { if (!soundInited) @@ -905,7 +905,7 @@ void iSndDIEDIEDIE() AXQuit(); } - +*/ void iSndSetExternalCallback(iSndExternalCallback callback) { } From 69249a4f80d53097634c54ddf17d2344178f4366 Mon Sep 17 00:00:00 2001 From: escape209 Date: Sun, 2 Aug 2026 21:12:26 +0100 Subject: [PATCH 4/4] Move iterator incrementation to loop head --- src/SB/Core/gc/iSnd.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/SB/Core/gc/iSnd.cpp b/src/SB/Core/gc/iSnd.cpp index 3bf9b264b..a5ecbc1f0 100644 --- a/src/SB/Core/gc/iSnd.cpp +++ b/src/SB/Core/gc/iSnd.cpp @@ -772,12 +772,10 @@ void iSndSetVol(U32 snd, F32 vol) xSndVoiceInfo* vp = &gSnd.voice[0]; S32 i = 0; - for (; i < 64;) + for (; i < 64; i++, vp++) { if (vp->sndID == snd) break; - i++; - vp++; } if (i != 64)