From 7dde7fec51b43b82ee558e6ca963ce5f1d420754 Mon Sep 17 00:00:00 2001 From: robojumper Date: Wed, 28 May 2025 01:18:53 +0200 Subject: [PATCH] snd_Sound3DEngine OK --- config/SOUE01/symbols.txt | 12 +-- configure.py | 2 +- include/nw4r/snd/snd_Sound3DCalculator.h | 44 ++++++++++ include/nw4r/snd/snd_Sound3DEngine.h | 8 +- include/nw4r/snd/snd_Sound3DListener.h | 4 +- include/nw4r/snd/snd_Sound3DManager.h | 28 ++++-- src/nw4r/snd/snd_Sound3DCalculator.cpp | 2 +- src/nw4r/snd/snd_Sound3DEngine.cpp | 106 +++++++++++++++++++---- src/nw4r/snd/snd_Sound3DListener.cpp | 26 +++--- 9 files changed, 178 insertions(+), 54 deletions(-) create mode 100644 include/nw4r/snd/snd_Sound3DCalculator.h diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index d23c8247..d8b54fc0 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -38610,7 +38610,7 @@ __vt__Q44nw4r3snd6detail8SeqSound = .data:0x8056E088; // type:object size:0x38 __vt__Q54nw4r3snd6detail8SeqSound11SeqLoadTask = .data:0x8056E0C0; // type:object size:0x18 __vt__Q44nw4r3snd6detail8SeqTrack = .data:0x8056E0D8; // type:object size:0x10 lbl_8056E0E8 = .data:0x8056E0E8; // type:object size:0x30 -lbl_8056E118 = .data:0x8056E118; // type:object size:0x20 +__vt__Q34nw4r3snd13Sound3DEngine = .data:0x8056E118; // type:object size:0x1C lbl_8056E138 = .data:0x8056E138; // type:object size:0x38 __vt__Q34nw4r3snd10SoundActor = .data:0x8056E170; // type:object size:0x1C __vt__Q34nw4r3snd12SoundArchive = .data:0x8056E190; // type:object size:0x20 @@ -49733,11 +49733,11 @@ lbl_8057F0F0 = .sdata2:0x8057F0F0; // type:object size:0x4 align:4 data:float lbl_8057F0F4 = .sdata2:0x8057F0F4; // type:object size:0x4 align:4 data:float lbl_8057F0F8 = .sdata2:0x8057F0F8; // type:object size:0x4 align:4 data:float lbl_8057F0FC = .sdata2:0x8057F0FC; // type:object size:0x4 align:4 data:float -lbl_8057F100 = .sdata2:0x8057F100; // type:object size:0x4 align:4 data:float -lbl_8057F104 = .sdata2:0x8057F104; // type:object size:0x4 align:4 data:float -lbl_8057F108 = .sdata2:0x8057F108; // type:object size:0x4 align:4 data:float -lbl_8057F10C = .sdata2:0x8057F10C; // type:object size:0x4 align:4 data:float -lbl_8057F110 = .sdata2:0x8057F110; // type:object size:0x4 align:4 data:float +@2216 = .sdata2:0x8057F100; // type:object size:0x4 scope:local align:4 data:float +@2217 = .sdata2:0x8057F104; // type:object size:0x4 scope:local align:4 data:float +@2218 = .sdata2:0x8057F108; // type:object size:0x4 scope:local align:4 data:float +@2219 = .sdata2:0x8057F10C; // type:object size:0x4 scope:local align:4 data:float +@2392 = .sdata2:0x8057F110; // type:object size:0x4 scope:local align:4 data:float @1266 = .sdata2:0x8057F118; // type:object size:0x4 scope:local align:4 data:float @1267 = .sdata2:0x8057F11C; // type:object size:0x4 scope:local align:4 data:float @1268 = .sdata2:0x8057F120; // type:object size:0x4 scope:local align:4 data:float diff --git a/configure.py b/configure.py index 72596482..d2ca639e 100644 --- a/configure.py +++ b/configure.py @@ -1054,7 +1054,7 @@ config.libs = [ Object(Matching, "nw4r/snd/snd_SeqTrack.cpp"), Object(NonMatching, "nw4r/snd/snd_Sound3DActor.cpp"), Object(NonMatching, "nw4r/snd/snd_Sound3DCalculator.cpp"), - Object(NonMatching, "nw4r/snd/snd_Sound3DEngine.cpp"), + Object(Matching, "nw4r/snd/snd_Sound3DEngine.cpp"), Object(Matching, "nw4r/snd/snd_Sound3DListener.cpp"), Object(NonMatching, "nw4r/snd/snd_Sound3DManager.cpp"), Object(Matching, "nw4r/snd/snd_SoundActor.cpp"), diff --git a/include/nw4r/snd/snd_Sound3DCalculator.h b/include/nw4r/snd/snd_Sound3DCalculator.h new file mode 100644 index 00000000..b2c578d5 --- /dev/null +++ b/include/nw4r/snd/snd_Sound3DCalculator.h @@ -0,0 +1,44 @@ +#ifndef NW4R_SND_SOUND_3D_CALCULATOR_H +#define NW4R_SND_SOUND_3D_CALCULATOR_H + +#include "nw4r/snd/snd_Sound3DManager.h" + +namespace nw4r { +namespace snd { + +class Sound3DCalculator { +public: + struct CalcPanParam { +#if 0 + f32 mSpeakerAngleStereo; // at 0x04 + f32 mFrontSpeakerAngleDpl2; // at 0x08 + f32 mRearSpeakerAngleDpl2; // at 0x0C + f32 mInitPan; // at 0x10 +#endif + f32 field_0x00; + f32 field_0x04; + f32 field_0x08; + f32 field_0x0C; + + CalcPanParam() + : field_0x00(NW4R_MATH_PI / 4), + field_0x04(NW4R_MATH_PI / 6), + field_0x08(2 * NW4R_MATH_PI / 3), + field_0x0C(0.0f) {} + }; + + static void + CalcVolumeAndPriority(const Sound3DManager &, const Sound3DListener &, const Sound3DParam &, float *, int *); + static void + CalcPan(const Sound3DManager &, const Sound3DListener &, const Sound3DParam &, const Sound3DCalculator::CalcPanParam &, float *pan, float *surroundPan); + static void CalcPitch(const Sound3DManager &, const Sound3DListener &, const Sound3DParam &, float *); + static void CalcBiquadFilterValue(const Sound3DManager &, const Sound3DListener &, const Sound3DParam &, float *); + static void CalcPanDpl2(const nw4r::math::VEC3 &, float, float, float, float, float, float, float *, float *); + static void CalcPanStereo(const nw4r::math::VEC3 &, float, float, float, float, float *, float *); + static void CalcAngleAndDistance(const nw4r::math::VEC3 &, float, float, float *, float *); +}; + +} // namespace snd +} // namespace nw4r + +#endif diff --git a/include/nw4r/snd/snd_Sound3DEngine.h b/include/nw4r/snd/snd_Sound3DEngine.h index 3cfd4168..ae15de01 100644 --- a/include/nw4r/snd/snd_Sound3DEngine.h +++ b/include/nw4r/snd/snd_Sound3DEngine.h @@ -4,6 +4,7 @@ #include "nw4r/math.h" #include "nw4r/types_nw4r.h" #include "nw4r/snd/snd_Sound3DManager.h" +#include "nw4r/snd/snd_Sound3DCalculator.h" namespace nw4r { @@ -17,15 +18,12 @@ public: virtual ~Sound3DEngine() {} virtual void UpdateAmbientParam(const Sound3DManager*, const Sound3DParam*, u32, int, SoundAmbientParam*); - virtual void GetAmbientPriority(const Sound3DManager*, const Sound3DParam*, u32); + virtual s32 GetAmbientPriority(const Sound3DManager*, const Sound3DParam*, u32); virtual s32 GetRequiredVoiceOutCount(const Sound3DManager*, const Sound3DParam*, u32); virtual void UpdateAmbientParam(const Sound3DManager*, const Sound3DParam*, u32, u32, SoundAmbientParam*); private: - f32 mSpeakerAngleStereo; // at 0x04 - f32 mFrontSpeakerAngleDpl2; // at 0x08 - f32 mRearSpeakerAngleDpl2; // at 0x0C - f32 mInitPan; // at 0x10 + Sound3DCalculator::CalcPanParam mPanParam; // at 0x04 }; } // namespace snd diff --git a/include/nw4r/snd/snd_Sound3DListener.h b/include/nw4r/snd/snd_Sound3DListener.h index 414343e7..9162cc86 100644 --- a/include/nw4r/snd/snd_Sound3DListener.h +++ b/include/nw4r/snd/snd_Sound3DListener.h @@ -2,6 +2,7 @@ #define NW4R_SND_SOUND_3D_LISTENER_H #include "common.h" #include "nw4r/types_nw4r.h" +#include "nw4r/ut/ut_LinkList.h" #include "nw4r/math.h" @@ -47,8 +48,7 @@ private: u8 mSkipVelocityUpdate; // at 0x58 f32 mUnitBiquadFilterValue; // at 0x5C f32 mUnitBiquadFilterMax; // at 0x60 - UNKWORD field_0x64; // at 0x64 - UNKWORD field_0x68; // at 0x68 + ut::LinkListNode mNode; // at 0x64 }; } // namespace snd diff --git a/include/nw4r/snd/snd_Sound3DManager.h b/include/nw4r/snd/snd_Sound3DManager.h index 8609b453..afcf3b85 100644 --- a/include/nw4r/snd/snd_Sound3DManager.h +++ b/include/nw4r/snd/snd_Sound3DManager.h @@ -1,17 +1,17 @@ #ifndef NW4R_SND_SOUND_3D_MANAGER_H #define NW4R_SND_SOUND_3D_MANAGER_H -#include "nw4r/math.h" #include "nw4r/snd/snd_BasicSound.h" #include "nw4r/snd/snd_InstancePool.h" #include "nw4r/snd/snd_SoundArchive.h" #include "nw4r/types_nw4r.h" +#include "nw4r/ut/ut_LinkList.h" +#include "nw4r/math.h" namespace nw4r { namespace snd { -struct Sound3DParam -{ +struct Sound3DParam { /* 0x00 */ u8 _0x00[0x18]; /* 0x18 */ UNKWORD field_0x18; /* 0x1C */ u8 field_0x1C; @@ -35,6 +35,8 @@ public: }; public: + typedef ut::LinkList ListenerList; + Sound3DManager(); virtual void detail_Update( @@ -53,8 +55,12 @@ public: u32 GetRequiredMemSize(const SoundArchive *pArchive); bool Setup(const SoundArchive *pArchive, void *pBuffer, u32 size); - Sound3DListener *GetListener() const { - return mListener; + const ListenerList &GetListenerList() const { + return mListenerList; + } + + ListenerList &GetListenerList() { + return mListenerList; } int GetMaxPriorityReduction() const { @@ -64,6 +70,10 @@ public: mMaxPriorityReduction = max; } + int GetBiquadFilterType() const { + return biquadFilterType; + } + private: enum ParamDecayCurve { DECAY_CURVE_NONE, @@ -73,9 +83,11 @@ private: private: detail::InstancePool mParamPool; // at 0x8 - Sound3DListener *mListener; // at 0xC - u8 _0x10[0x1C - 0x10]; - s32 mMaxPriorityReduction; // at 0x1C + ListenerList mListenerList; // at 0x0C + u8 _0x18[0x1C - 0x18]; + s32 mMaxPriorityReduction; // at 0x1C + u8 _0x1C[0x28 - 0x20]; + int biquadFilterType; // at 0x28 }; } // namespace snd diff --git a/src/nw4r/snd/snd_Sound3DCalculator.cpp b/src/nw4r/snd/snd_Sound3DCalculator.cpp index e061638f..4812cf46 100644 --- a/src/nw4r/snd/snd_Sound3DCalculator.cpp +++ b/src/nw4r/snd/snd_Sound3DCalculator.cpp @@ -1 +1 @@ -// #include "nw4r/snd/snd_Sound3DCalculator.h" +#include "nw4r/snd/snd_Sound3DCalculator.h" diff --git a/src/nw4r/snd/snd_Sound3DEngine.cpp b/src/nw4r/snd/snd_Sound3DEngine.cpp index f398c5a4..7f4f79e7 100644 --- a/src/nw4r/snd/snd_Sound3DEngine.cpp +++ b/src/nw4r/snd/snd_Sound3DEngine.cpp @@ -1,34 +1,110 @@ #include "nw4r/snd/snd_Sound3DEngine.h" -namespace nw4r { namespace snd { +#include "nw4r/snd/snd_Sound3DCalculator.h" +#include "nw4r/snd/snd_Sound3DListener.h" +#include "nw4r/snd/snd_Sound3DManager.h" +#include "nw4r/snd/snd_global.h" -Sound3DEngine::Sound3DEngine() - : mSpeakerAngleStereo(NW4R_MATH_PI / 4), - mFrontSpeakerAngleDpl2(NW4R_MATH_PI / 6), - mRearSpeakerAngleDpl2(2 * NW4R_MATH_PI / 3), - mInitPan(0.0f) {} +namespace nw4r { +namespace snd { + +Sound3DEngine::Sound3DEngine() {} void Sound3DEngine::UpdateAmbientParam( const Sound3DManager *mgr, const Sound3DParam *pParam, u32, u32 flags, SoundAmbientParam *pAmbientParam ) { - if (flags & 1) + if (flags & 1) { pAmbientParam->volume = 0.0f; + } - if (flags & 8) - pAmbientParam->priority = - mgr->GetMaxPriorityReduction(); + if (flags & 8) { + pAmbientParam->priority = -mgr->GetMaxPriorityReduction(); + } + + if (mgr->GetListenerList().GetSize() > 1) { + flags &= -0x17; + } + + NW4R_RANGE_FOR(it, mgr->GetListenerList()) { + const Sound3DListener &listener = *it; + if (flags & 9) { + f32 volume; + int priority; + Sound3DCalculator::CalcVolumeAndPriority(*mgr, listener, *pParam, &volume, &priority); + if (flags & 1) { + pAmbientParam->volume = ut::Max(volume, pAmbientParam->volume); + } + + if (flags & 8) { + pAmbientParam->priority = ut::Max(priority, pAmbientParam->priority); + } + } + if (flags & 6) { + f32 pan, surroundPan; + Sound3DCalculator::CalcPan(*mgr, listener, *pParam, mPanParam, &pan, &surroundPan); + if (flags & 2) { + pAmbientParam->pan = pan; + } + if (flags & 4) { + pAmbientParam->surroundPan = surroundPan; + } + } + + if (flags & 0x10) { + f32 pitch; + Sound3DCalculator::CalcPitch(*mgr, listener, *pParam, &pitch); + pAmbientParam->pitch = pitch; + } + + if (flags & 0x20) { + f32 biquadFilterValue; + Sound3DCalculator::CalcBiquadFilterValue(*mgr, listener, *pParam, &biquadFilterValue); + pAmbientParam->biquadFilterType = mgr->GetBiquadFilterType(); + pAmbientParam->biquadFilterValue = ut::Min(biquadFilterValue, pAmbientParam->biquadFilterValue); + } + } } -void Sound3DEngine::UpdateAmbientParam(const Sound3DManager* mgr, const Sound3DParam* param, u32, int, SoundAmbientParam*) { - +void Sound3DEngine::UpdateAmbientParam( + const Sound3DManager *mgr, const Sound3DParam *param, u32 unused1, int unused2, SoundAmbientParam *pAmbientParam +) { + u32 flags = 0x1F; + if (param->field_0x18 & 1) { + flags &= ~1; + } + if (param->field_0x18 & 2) { + flags &= ~2; + } + if (param->field_0x18 & 4) { + flags &= ~4; + } + if (param->field_0x18 & 8) { + flags &= ~8; + } + if (!param->field_0x1E) { + flags &= ~0x10; + } + if (param->field_0x18 & 0x10) { + flags |= 0x20; + } + UpdateAmbientParam(mgr, param, unused1, flags, pAmbientParam); } -void Sound3DEngine::GetAmbientPriority(const Sound3DManager*, const Sound3DParam*, u32) { +s32 Sound3DEngine::GetAmbientPriority(const Sound3DManager *mgr, const Sound3DParam *param, u32 arg) { + u32 flags = 0x1000008; + if (param->field_0x18 & 8) { + flags &= ~8; + } + SoundAmbientParam ambientParam; + + UpdateAmbientParam(mgr, param, arg, flags, &ambientParam); + return ambientParam.priority; } -s32 Sound3DEngine::GetRequiredVoiceOutCount(const Sound3DManager*, const Sound3DParam*, u32) { +s32 Sound3DEngine::GetRequiredVoiceOutCount(const Sound3DManager *, const Sound3DParam *, u32) { return 1; } - -}} +} // namespace snd +} // namespace nw4r diff --git a/src/nw4r/snd/snd_Sound3DListener.cpp b/src/nw4r/snd/snd_Sound3DListener.cpp index 08d64440..1ec06b11 100644 --- a/src/nw4r/snd/snd_Sound3DListener.cpp +++ b/src/nw4r/snd/snd_Sound3DListener.cpp @@ -3,22 +3,16 @@ namespace nw4r { namespace snd { -Sound3DListener::Sound3DListener() { - mPosition.x = 0.0f; - mPosition.y = 0.0f; - mPosition.z = 0.0f; - mVelocity.x = 0.0f; - mVelocity.y = 0.0f; - mVelocity.z = 0.0f; - mInteriorSize = 1.0f; - mMaxVolumeDistance = 1.0f; - mUnitDistance = 1.0f; - field_0x54 = 0; - mSkipVelocityUpdate = 1; - mUnitBiquadFilterValue = 0.5f; - mUnitBiquadFilterMax = 1.0f; - field_0x64 = 0; - field_0x68 = 0; +Sound3DListener::Sound3DListener() + : mPosition(0.0f, 0.0f, 0.0f), + mVelocity(0.0f, 0.0f, 0.0f), + mInteriorSize(1.0f), + mMaxVolumeDistance(1.0f), + mUnitDistance(1.0f), + field_0x54(0), + mSkipVelocityUpdate(1), + mUnitBiquadFilterValue(0.5f), + mUnitBiquadFilterMax(1.0f) { math::MTX34Zero(&mMtx); }