summaryrefslogtreecommitdiff
path: root/src/nw4r
diff options
context:
space:
mode:
authorrobojumper <robojumper@gmail.com>2025-05-28 22:19:53 +0200
committerrobojumper <robojumper@gmail.com>2025-05-28 22:21:32 +0200
commitbd2adcab70991550f79ba76e035381e03ce89f60 (patch)
tree476b7b4722d1ff05501cfeb752985999c8fc26c5 /src/nw4r
parentd004459b3c8af2e5ada3b44093feff260c8d9e35 (diff)
snd_Sound3DManager OK
Diffstat (limited to 'src/nw4r')
-rw-r--r--src/nw4r/snd/snd_BasicSound.cpp10
-rw-r--r--src/nw4r/snd/snd_Sound3DManager.cpp246
2 files changed, 33 insertions, 223 deletions
diff --git a/src/nw4r/snd/snd_BasicSound.cpp b/src/nw4r/snd/snd_BasicSound.cpp
index db6b61fc..d6e29c09 100644
--- a/src/nw4r/snd/snd_BasicSound.cpp
+++ b/src/nw4r/snd/snd_BasicSound.cpp
@@ -322,7 +322,7 @@ void BasicSound::Update()
for (int i = 0; i < mVoiceOutCount; i++)
ambientParam.voiceOutParam[i] = basicPlayer.GetVoiceOutParam(i);
- mAmbientInfo.paramUpdateCallback->at_0x0c(
+ mAmbientInfo.paramUpdateCallback->detail_UpdateAmbientParam(
mAmbientInfo.arg, mId, mVoiceOutCount, &ambientParam);
mAmbientParam.volume = ambientParam.volume;
@@ -519,7 +519,7 @@ void BasicSound::Shutdown()
if (mAmbientInfo.argAllocaterCallback)
{
- mAmbientInfo.argAllocaterCallback->at_0x10(mAmbientInfo.arg, this);
+ mAmbientInfo.argAllocaterCallback->detail_FreeAmbientArg(mAmbientInfo.arg, this);
mAmbientInfo.arg = nullptr;
}
@@ -691,7 +691,7 @@ void BasicSound::SetAmbientInfo(AmbientInfo const &ambientArgInfo)
NW4RAssertPointerNonnull_Line(1090, ambientArgInfo.argAllocaterCallback);
void *ambientArg =
- ambientArgInfo.argAllocaterCallback->at_0x0c(ambientArgInfo.argSize);
+ ambientArgInfo.argAllocaterCallback->detail_AllocAmbientArg(ambientArgInfo.argSize);
if (!ambientArg)
{
NW4RCheckMessage_Line(1093, ambientArg, "Failed to alloc AmbientArg.");
@@ -705,7 +705,7 @@ void BasicSound::SetAmbientInfo(AmbientInfo const &ambientArgInfo)
if (ambientArgInfo.paramUpdateCallback)
{
int voiceOutCount =
- mAmbientInfo.paramUpdateCallback->at_0x14(mAmbientInfo.arg, mId);
+ mAmbientInfo.paramUpdateCallback->detail_GetRequiredVoiceOutCount(mAmbientInfo.arg, mId);
if (voiceOutCount > 4)
voiceOutCount = 4;
@@ -720,7 +720,7 @@ int BasicSound::GetAmbientPriority(AmbientInfo const &ambientInfo, u32 soundId)
return PRIORITY_MIN;
int priority =
- ambientInfo.paramUpdateCallback->at_0x10(ambientInfo.arg, soundId);
+ ambientInfo.paramUpdateCallback->detail_GetAmbientPriority(ambientInfo.arg, soundId);
return priority;
}
diff --git a/src/nw4r/snd/snd_Sound3DManager.cpp b/src/nw4r/snd/snd_Sound3DManager.cpp
index ebd0771c..1c8172e7 100644
--- a/src/nw4r/snd/snd_Sound3DManager.cpp
+++ b/src/nw4r/snd/snd_Sound3DManager.cpp
@@ -15,30 +15,10 @@ namespace {
static Sound3DEngine sEngine;
-/**
- * Solves the linear equation:
- * a*x + b*y + c = d
- *
- * Where:
- * a = dFactor - cFactor
- * b = dAngle - cAngle
- * c = cAngle * cFactor
- * d = dAngle * dFactor
- */
-inline f32 SolveLinerFunction(f32 x, f32 dAngle, f32 cAngle, f32 dFactor,
- f32 cFactor) { // @typo
- if (dAngle == cAngle) {
- return (dFactor + cFactor) / 2;
- }
-
- f32 b = dAngle - cAngle;
-
- return x * (cFactor - dFactor) / b + (dAngle * dFactor - cAngle * cFactor) / b;
-}
-
} // namespace
-Sound3DManager::Sound3DManager() : mpEngine(&sEngine), mMaxPriorityReduction(32), field_0x20(0.9f), field_0x24(0.0f), biquadFilterType(0) {}
+Sound3DManager::Sound3DManager()
+ : mpEngine(&sEngine), mMaxPriorityReduction(32), field_0x20(0.9f), field_0x24(0.0f), mBiquadFilterType(0) {}
u32 Sound3DManager::GetRequiredMemSize(const SoundArchive *pArchive) {
u32 numParam = 0;
@@ -60,209 +40,35 @@ bool Sound3DManager::Setup(const SoundArchive *pArchive, void *pBuffer, u32 size
return true;
}
-void Sound3DManager::detail_Update(
- SoundParam *pParam, u32 id, detail::BasicSound *pSound, const void *pArg, u32 flags
-) {
- SoundHandle handle;
- if (pSound != NULL) {
- handle.detail_AttachSoundAsTempHandle(pSound);
- }
-
- Update(pParam, id, pSound != NULL ? &handle : NULL, pArg, flags);
+void Sound3DManager::SetEngine(Sound3DEngine *engine) {
+ mpEngine = engine;
}
-void Sound3DManager::Update(SoundParam *pParam, u32 id, SoundHandle *pHandle, const void *pArg, u32 flags) {
-#pragma unused(id)
-#pragma unused(pHandle)
-
- f32 angle;
- f32 panLR, panFR;
- f32 pan, surroundPan;
-#if 0
- const Sound3DActorParam* pActorParam =
- static_cast<const Sound3DActorParam*>(pArg);
-
- Sound3DListener* pListener = GetListener();
- if (pListener == NULL) {
- pParam->volume = 0.0f;
- return;
- }
-
- math::VEC3 relativePos;
- VEC3Transform(&relativePos, &pListener->GetMatrix(),
- &pActorParam->position);
-
- f32 distance = VEC3Len(&relativePos);
- f32 volume = 1.0f;
-
- if ((flags & (PARAM_UPDATE_VOLUME | PARAM_UPDATE_PRIORITY)) &&
- distance > pListener->GetMaxVolumeDistance()) {
-
- switch (pActorParam->soundParam.decayCurve) {
- case DECAY_CURVE_LOGARITHMIC: {
- f32 units = (distance - pListener->GetMaxVolumeDistance()) /
- pListener->GetUnitDistance();
-
- volume =
- std::pow(pActorParam->soundParam.decayRatio / 256.0f, units);
- break;
- }
-
- case DECAY_CURVE_LINEAR: {
- f32 units = (distance - pListener->GetMaxVolumeDistance()) /
- pListener->GetUnitDistance() *
- pActorParam->soundParam.decayRatio;
-
- units = units / 256.0f;
- volume = ut::Max(0.0f, 1.0f - units);
- break;
- }
- }
- }
-
- if ((flags & PARAM_UPDATE_VOLUME) &&
- !(pActorParam->soundParam.flags & PARAM_UPDATE_VOLUME)) {
-
- pParam->volume = volume;
- }
-
- if (flags & (PARAM_UPDATE_PAN | PARAM_UPDATE_SURROUND_PAN)) {
- math::VEC3 adjustedPos;
-
- if (0.0f == distance) {
- adjustedPos.z = 0.0f;
- adjustedPos.y = 0.0f;
- adjustedPos.x = 0.0f;
- } else {
- math::VEC3 relativeXZ(relativePos.x, 0.0f, relativePos.z);
-
- f32 distanceXZ = VEC3Len(&relativeXZ);
- if (distanceXZ > pListener->GetInteriorSize()) {
- relativeXZ.x *= pListener->GetInteriorSize() / distanceXZ;
- relativeXZ.z *= pListener->GetInteriorSize() / distanceXZ;
- }
-
- f32 ratioXZ = VEC3Len(&relativeXZ);
- adjustedPos.x = relativePos.x * ratioXZ / distance;
- adjustedPos.y = 0.0f;
- adjustedPos.z = relativePos.z * ratioXZ / distance;
- }
-
- angle = atan2(adjustedPos.x, -adjustedPos.z);
- f32 distanceNrm = VEC3Len(&adjustedPos) / pListener->GetInteriorSize();
-
- switch (detail::AxManager::GetInstance().GetOutputMode()) {
- case OUTPUT_MODE_SURROUND:
- case OUTPUT_MODE_DPL2: {
- static f32 angleRearLeft = -mRearSpeakerAngleDpl2;
- static f32 angleFrontLeft = -mFrontSpeakerAngleDpl2;
- static f32 angleFrontRight = mFrontSpeakerAngleDpl2;
- static f32 angleRearRight = mRearSpeakerAngleDpl2;
-
- // clang-format off
- if (angle < angleRearLeft) {
- panLR = SolveLinerFunction(angle, -NW4R_MATH_PI, angleRearLeft, -1.0f, 0.0f);
- panFR = 1.0f;
- } else if (angle < -NW4R_MATH_PI / 2) {
- panLR = -1.0f;
- panFR = SolveLinerFunction(angle, angleRearLeft, -NW4R_MATH_PI / 2, 0.0f, 1.0f);
- } else if (angle < angleFrontLeft) {
- panLR = -1.0f;
- panFR = SolveLinerFunction(angle, -NW4R_MATH_PI / 2, angleFrontLeft, -1.0f, 0.0f);
- } else if (angle < angleFrontRight) {
- panLR = SolveLinerFunction(angle, angleFrontLeft, angleFrontRight, 1.0f, -1.0f);
- panFR = -1.0f;
- } else if (angle < NW4R_MATH_PI / 2) {
- panLR = 1.0f;
- panFR = SolveLinerFunction(angle, angleFrontRight, NW4R_MATH_PI / 2, 0.0f, -1.0f);
- } else if (angle < angleRearRight) {
- panLR = 1.0f;
- panFR = SolveLinerFunction(angle, NW4R_MATH_PI / 2, angleRearRight, 1.0f, 0.0f);
- } else {
- panLR = SolveLinerFunction(angle, angleRearRight, NW4R_MATH_PI, 0.0f, 1.0f);
- panFR = 1.0f;
- }
- // clang-format on
-
- f32 cosAvg = (std::cosf(mFrontSpeakerAngleDpl2) +
- std::cosf(mRearSpeakerAngleDpl2)) /
- 2.0f;
-
- f32 rearFactor =
- cosAvg / (cosAvg + -std::cosf(mRearSpeakerAngleDpl2));
-
- panLR *= mPanRange;
- panFR *= mPanRange;
-
- pan = panLR * distanceNrm;
-
- surroundPan =
- mInitPan + (1.0f + (panFR * distanceNrm +
- rearFactor * (1.0f - distanceNrm)));
- break;
- }
-
- case OUTPUT_MODE_STEREO: {
- static f32 angleRearLeft = -NW4R_MATH_PI + mSpeakerAngleStereo;
- static f32 angleFrontLeft = -mSpeakerAngleStereo;
- static f32 angleFrontRight = mSpeakerAngleStereo;
- static f32 angleRearRight = NW4R_MATH_PI - mSpeakerAngleStereo;
-
- // clang-format off
- if (angle < angleRearLeft) {
- panLR = SolveLinerFunction(angle, -NW4R_MATH_PI, angleRearLeft, -1.0f, 0.0f);
- panFR = 1.0f;
- } else if (angle < angleFrontLeft) {
- panLR = -1.0f;
- panFR = SolveLinerFunction(angle, angleRearLeft, angleFrontLeft, -1.0f, 1.0f);
- } else if (angle < angleFrontRight) {
- panLR = SolveLinerFunction(angle, angleFrontLeft, angleFrontRight, 1.0f, -1.0f);
- panFR = -1.0f;
- } else if (angle < angleRearRight) {
- panLR = 1.0f;
- panFR = SolveLinerFunction(angle, angleFrontRight, angleRearRight, 1.0f, -1.0f);
- } else {
- panLR = SolveLinerFunction(angle, angleRearRight, NW4R_MATH_PI, 0.0f, 1.0f);
- panFR = 1.0f;
- }
- // clang-format on
-
- panLR *= mPanRange;
- panFR *= mPanRange;
-
- surroundPan = 1.0f + panFR * distanceNrm;
- pan = panLR * distanceNrm;
- break;
- }
-
- case OUTPUT_MODE_MONO:
- default: {
- pan = 0.0f;
- surroundPan = 0.0f;
- break;
- }
- }
- }
-
- if ((flags & PARAM_UPDATE_PAN) &&
- !(pActorParam->soundParam.flags & PARAM_UPDATE_PAN)) {
-
- pParam->pan = pan;
+void Sound3DManager::detail_UpdateAmbientParam(
+ const void *param, u32 unused1, int unused2, SoundAmbientParam *ambientParam
+) {
+ const Sound3DParam *p = static_cast<const Sound3DParam *>(param);
+ if (mpEngine != NULL) {
+ mpEngine->UpdateAmbientParam(this, p, unused1, unused2, ambientParam);
}
+}
- if ((flags & PARAM_UPDATE_SURROUND_PAN) &&
- !(pActorParam->soundParam.flags & PARAM_UPDATE_SURROUND_PAN)) {
-
- pParam->surroundPan = surroundPan;
+int Sound3DManager::detail_GetAmbientPriority(const void *param, u32 arg) {
+ int result = 0;
+ if (mpEngine != NULL) {
+ const Sound3DParam *p = static_cast<const Sound3DParam *>(param);
+ result = mpEngine->GetAmbientPriority(this, p, arg);
}
+ return result;
+}
- if ((flags & PARAM_UPDATE_PRIORITY) &&
- !(pActorParam->soundParam.flags & PARAM_UPDATE_PRIORITY)) {
-
- pParam->priority =
- -static_cast<int>((1.0f - volume) * GetMaxPriorityReduction());
+int Sound3DManager::detail_GetRequiredVoiceOutCount(const void *param, u32 arg) {
+ int result = 1;
+ if (mpEngine != NULL) {
+ const Sound3DParam *p = static_cast<const Sound3DParam *>(param);
+ result = mpEngine->GetRequiredVoiceOutCount(this, p, arg);
}
-#endif
+ return result;
}
void *Sound3DManager::detail_AllocAmbientArg(u32 size) {
@@ -279,6 +85,10 @@ void Sound3DManager::detail_FreeAmbientArg(void *pArg, const detail::BasicSound
mParamPool.Free(static_cast<Sound3DParam *>(pArg));
}
+void Sound3DManager::SetBiquadFilterType(int type) {
+ mBiquadFilterType = type;
+}
+
Sound3DParam::Sound3DParam() {
field_0x18 = 0;
decayCurve = Sound3DManager::DECAY_CURVE_LOGARITHMIC;