From 84a1c44e7743720333f81a1e979f3d0d8e429854 Mon Sep 17 00:00:00 2001 From: Naii-the-Baf Date: Sun, 8 Mar 2026 15:42:46 -0600 Subject: [PATCH] Library/Bgm: Implement `BgmParamsChanger` (#936) --- data/file_list.yml | 80 ++++++----- lib/al/Library/Bgm/BgmParamsChanger.cpp | 173 ++++++++++++++++++++++++ lib/al/Library/Bgm/BgmParamsChanger.h | 115 ++++++++++++++++ lib/al/Library/Bgm/DspValueController.h | 48 +++++++ lib/al/Project/Bgm/BgmInfo.cpp | 21 +++ lib/al/Project/Bgm/BgmInfo.h | 30 +++- 6 files changed, 419 insertions(+), 48 deletions(-) create mode 100644 lib/al/Library/Bgm/BgmParamsChanger.cpp create mode 100644 lib/al/Library/Bgm/BgmParamsChanger.h create mode 100644 lib/al/Library/Bgm/DspValueController.h diff --git a/data/file_list.yml b/data/file_list.yml index 812680de..859d199c 100644 --- a/data/file_list.yml +++ b/data/file_list.yml @@ -226128,147 +226128,147 @@ Library/Bgm/BgmParamsChanger.o: label: - _ZN2al16BgmParamsChangerC1Ev - _ZN2al16BgmParamsChangerC2Ev - status: NotDecompiled + status: Matching - offset: 0x8288a8 size: 156 label: _ZN2al16BgmParamsChanger6updateEv - status: NotDecompiled + status: Matching - offset: 0x828944 size: 212 label: _ZNK2al16BgmParamsChanger28isReachedTargetAllControllerEv - status: NotDecompiled + status: Matching - offset: 0x828a18 size: 20 label: _ZN2al16BgmParamsChanger11resetParamsEv - status: NotDecompiled + status: Matching - offset: 0x828a2c size: 40 label: _ZN2al16BgmParamsChanger8activateEPKcS2_b - status: NotDecompiled + status: Matching - offset: 0x828a54 size: 32 label: _ZN2al16BgmParamsChanger10deactivateEb - status: NotDecompiled + status: Matching - offset: 0x828a74 size: 40 label: _ZN2al16BgmParamsChanger13tryDeactivateEb - status: NotDecompiled + status: Matching - offset: 0x828a9c size: 8 label: _ZN2al16BgmParamsChanger13resetForReuseEv - status: NotDecompiled + status: Matching - offset: 0x828aa4 size: 32 label: _ZN2al16BgmParamsChanger12changeVolumeEfi - status: NotDecompiled + status: Matching - offset: 0x828ac4 size: 32 label: _ZN2al16BgmParamsChanger16changePitchShiftEfi - status: NotDecompiled + status: Matching - offset: 0x828ae4 size: 32 label: _ZN2al16BgmParamsChanger9changeLpfEfi - status: NotDecompiled + status: Matching - offset: 0x828b04 size: 32 label: _ZN2al16BgmParamsChanger18changeBiquadFilterEfi - status: NotDecompiled + status: Matching - offset: 0x828b24 size: 92 label: _ZN2al16BgmParamsChanger26changePitchShiftModulationEffi - status: NotDecompiled + status: Matching - offset: 0x828b80 size: 40 label: _ZN2al16BgmParamsChanger16changeEffectSendEN2nn3atk6AuxBusEfi - status: NotDecompiled + status: Matching - offset: 0x828ba8 size: 40 label: _ZN2al16BgmParamsChanger17changeTrackVolumeEifi - status: NotDecompiled + status: Matching - offset: 0x828bd0 size: 232 label: _ZN2al16BgmParamsChanger19changeDefaultParamsEi - status: NotDecompiled + status: Matching - offset: 0x828cb8 size: 216 label: _ZN2al16BgmParamsChanger15forceDeactivateEv - status: NotDecompiled + status: Matching - offset: 0x828d90 size: 12 label: _ZNK2al16BgmParamsChanger12getCurVolumeEv - status: NotDecompiled + status: Matching - offset: 0x828d9c size: 12 label: _ZNK2al16BgmParamsChanger16getCurPitchShiftEv - status: NotDecompiled + status: Matching - offset: 0x828da8 size: 12 label: _ZNK2al16BgmParamsChanger26getCurPitchShiftModulationEv - status: NotDecompiled + status: Matching - offset: 0x828db4 size: 12 label: _ZNK2al16BgmParamsChanger15getCurLpfCutOffEv - status: NotDecompiled + status: Matching - offset: 0x828dc0 size: 12 label: _ZNK2al16BgmParamsChanger20getBiquadFilterValueEv - status: NotDecompiled + status: Matching - offset: 0x828dcc size: 12 label: _ZNK2al16BgmParamsChanger13getEffectSendEv - status: NotDecompiled + status: Matching - offset: 0x828dd8 size: 8 label: _ZNK2al16BgmParamsChanger14getEffectBusIdEv - status: NotDecompiled + status: Matching - offset: 0x828de0 size: 16 label: _ZNK2al16BgmParamsChanger17getCurTrackVolumeEi - status: NotDecompiled + status: Matching - offset: 0x828df0 size: 8 label: _ZNK2al16BgmParamsChanger10isActivateEv - status: NotDecompiled + status: Matching lazy: true - offset: 0x828df8 size: 8 label: _ZNK2al16BgmParamsChanger8isPausedEv - status: NotDecompiled + status: Matching lazy: true - offset: 0x828e00 size: 8 label: _ZNK2al16BgmParamsChanger20isEnableRegionChangeEv - status: NotDecompiled + status: Matching lazy: true - offset: 0x828e08 size: 16 label: _ZN2al16BgmParamsChanger21setRegionChangeParamsERKNS_21BgmRegionChangeParamsE - status: NotDecompiled + status: Matching lazy: true - offset: 0x828e18 size: 8 label: _ZNK2al16BgmParamsChanger16getSituationNameEv - status: NotDecompiled + status: Matching lazy: true - offset: 0x828e20 size: 8 label: _ZNK2al16BgmParamsChanger19getSubSituationNameEv - status: NotDecompiled + status: Matching lazy: true - offset: 0x828e28 size: 8 label: _ZN2al16BgmParamsChanger16setSituationNameEPKc - status: NotDecompiled + status: Matching lazy: true - offset: 0x828e30 size: 8 label: _ZN2al16BgmParamsChanger19setSubSituationNameEPKc - status: NotDecompiled + status: Matching lazy: true - offset: 0x828e38 size: 8 label: _ZNK2al16BgmParamsChanger21getRegionChangeParamsEv - status: NotDecompiled + status: Matching lazy: true Library/Bgm/BgmPlayInfo.o: '.text': @@ -226964,7 +226964,7 @@ Library/Bgm/BgmSituationDirector.o: size: 52 label: '' status: NotDecompiled -Library/Bgm/DspLinearValueController.o: +Library/Bgm/DspValueController.o: '.text': - offset: 0x82e238 size: 16 @@ -226984,8 +226984,6 @@ Library/Bgm/DspLinearValueController.o: size: 48 label: _ZN2al24DspLinearValueController12changeTargetEfi status: NotDecompiled -Library/Bgm/DspSinValueController.o: - '.text': - offset: 0x82e2dc size: 64 label: @@ -290670,21 +290668,21 @@ Project/Bgm/BgmInfo.o: label: - _ZN2al21BgmRegionChangeParamsC1Ev - _ZN2al21BgmRegionChangeParamsC2Ev - status: NotDecompiled + status: Matching - offset: 0xa47c0c size: 84 label: - _ZN2al21BgmRegionChangeParamsC1ERKS0_ - _ZN2al21BgmRegionChangeParamsC2ERKS0_ - status: NotDecompiled + status: Matching - offset: 0xa47c60 size: 44 label: _ZN2al21BgmRegionChangeParamsaSERKS0_ - status: NotDecompiled + status: Matching - offset: 0xa47c8c size: 96 label: _ZNK2al21BgmRegionChangeParamseqERKS0_ - status: NotDecompiled + status: Matching - offset: 0xa47cec size: 32 label: _ZN24alBgmPlayingTypeFunction21getBgmPlayingTypeNameEi diff --git a/lib/al/Library/Bgm/BgmParamsChanger.cpp b/lib/al/Library/Bgm/BgmParamsChanger.cpp new file mode 100644 index 00000000..9644b3ba --- /dev/null +++ b/lib/al/Library/Bgm/BgmParamsChanger.cpp @@ -0,0 +1,173 @@ +#include "Library/Bgm/BgmParamsChanger.h" + +#include "Library/Bgm/DspValueController.h" + +namespace al { +BgmParamsChanger::BgmParamsChanger() { + mVolume = new DspLinearValueController(1.0f); + mPitchShift = new DspLinearValueController(0.0f); + mLpf = new DspLinearValueController(0.0f); + mBiquadFilter = new DspLinearValueController(0.0f); + mEffectSend = new DspLinearValueController(0.0f); + mPitchShiftModulation = new DspSinValueController(60.0f, 0.0f); + + for (s32 i = 0; i < 6; i++) + mTrackVolume[i] = new DspLinearValueController(i == 0 ? 1.0f : 0.0f); +} + +void BgmParamsChanger::update() { + mVolume->update(); + mPitchShift->update(); + mPitchShiftModulation->update(); + mLpf->update(); + mBiquadFilter->update(); + mEffectSend->update(); + + for (s32 i = 0; i < 6; i++) + mTrackVolume[i]->update(); + + if (mIsReuse && isReachedTargetAllController()) + deactivate(false); +} + +bool BgmParamsChanger::isReachedTargetAllController() const { + if (mVolume->isReachedTarget() && mPitchShift->isReachedTarget() && + mPitchShiftModulation->isReachedTarget() && mLpf->isReachedTarget() && + mBiquadFilter->isReachedTarget() && mEffectSend->isReachedTarget()) { + for (s32 i = 0; i < 6; i++) + if (!mTrackVolume[i]->isReachedTarget()) + return false; + return true; + } + return false; +} + +void BgmParamsChanger::resetParams() { + mIsActivate = false; + mIsPaused = false; + mSubSituationName = nullptr; + mSituationName = nullptr; + _87 = 0; +} + +// TODO: Rename unk +void BgmParamsChanger::activate(const char* situationName, const char* subSituationName, bool unk) { + mIsActivate = true; + mSituationName = situationName; + mSubSituationName = subSituationName; + _87 = unk; + mIsReuse = false; + changeDefaultParams(0); +} + +void BgmParamsChanger::deactivate(bool isReuse) { + mIsReuse = isReuse; + if (!isReuse) + resetParams(); +} + +void BgmParamsChanger::tryDeactivate(bool isReuse) { + if (mIsActivate) + deactivate(isReuse); +} + +void BgmParamsChanger::resetForReuse() { + mIsReuse = false; +} + +void BgmParamsChanger::changeVolume(f32 target, s32 stepCount) { + if (mIsActivate && !mIsPaused) + mVolume->changeTarget(target, stepCount); +} + +void BgmParamsChanger::changePitchShift(f32 target, s32 stepCount) { + if (mIsActivate && !mIsPaused) + mPitchShift->changeTarget(target, stepCount); +} + +void BgmParamsChanger::changeLpf(f32 target, s32 stepCount) { + if (mIsActivate && !mIsPaused) + mLpf->changeTarget(target, stepCount); +} + +void BgmParamsChanger::changeBiquadFilter(f32 target, s32 stepCount) { + if (mIsActivate && !mIsPaused) + mBiquadFilter->changeTarget(target, stepCount); +} + +void BgmParamsChanger::changePitchShiftModulation(f32 target, f32 frequency, s32 stepCount) { + if (mIsActivate && !mIsPaused) { + mPitchShiftModulation->changeTarget(target, stepCount); + mPitchShiftModulation->changeFreq(frequency); + } +} + +void BgmParamsChanger::changeEffectSend(nn::atk::AuxBus bus, f32 target, s32 stepCount) { + if (mIsActivate && !mIsPaused) { + mEffectBus = bus; + mEffectSend->changeTarget(target, stepCount); + } +} + +void BgmParamsChanger::changeTrackVolume(s32 track, f32 target, s32 stepCount) { + if (mIsActivate && !mIsPaused) + mTrackVolume[track]->changeTarget(target, stepCount); +} + +void BgmParamsChanger::changeDefaultParams(s32 stepCount) { + mVolume->changeTarget(1.0f, stepCount); + mPitchShift->changeTarget(0.0f, stepCount); + mLpf->changeTarget(0.0f, stepCount); + mBiquadFilter->changeTarget(0.0f, stepCount); + mEffectSend->changeTarget(0.0f, stepCount); + mPitchShiftModulation->changeTarget(0.0f, stepCount); + + for (s32 i = 0; i < 6; i++) + mTrackVolume[i]->changeTarget(i == 0 ? 1.0f : 0.0f, stepCount); +} + +void BgmParamsChanger::forceDeactivate() { + mVolume->changeTarget(mVolume->getCurrent(), 0); + mPitchShift->changeTarget(mPitchShift->getCurrent(), 0); + mPitchShiftModulation->changeTarget(mPitchShiftModulation->getAmplitude(), 0); + mLpf->changeTarget(mLpf->getCurrent(), 0); + mBiquadFilter->changeTarget(mBiquadFilter->getCurrent(), 0); + mEffectSend->changeTarget(mEffectSend->getCurrent(), 0); + + for (s32 i = 0; i < 6; i++) + mTrackVolume[i]->changeTarget(mTrackVolume[i]->getCurrent(), 0); +} + +f32 BgmParamsChanger::getCurVolume() const { + return mVolume->getCurrent(); +} + +f32 BgmParamsChanger::getCurPitchShift() const { + return mPitchShift->getCurrent(); +} + +f32 BgmParamsChanger::getCurPitchShiftModulation() const { + return mPitchShiftModulation->getAmplitude(); +} + +f32 BgmParamsChanger::getCurLpfCutOff() const { + return mLpf->getCurrent(); +} + +f32 BgmParamsChanger::getBiquadFilterValue() const { + return mBiquadFilter->getCurrent(); +} + +f32 BgmParamsChanger::getEffectSend() const { + return mEffectSend->getCurrent(); +} + +nn::atk::AuxBus BgmParamsChanger::getEffectBusId() const { + return mEffectBus; +} + +f32 BgmParamsChanger::getCurTrackVolume(s32 track) const { + return mTrackVolume[track]->getCurrent(); +} + +} // namespace al diff --git a/lib/al/Library/Bgm/BgmParamsChanger.h b/lib/al/Library/Bgm/BgmParamsChanger.h new file mode 100644 index 00000000..cc304d47 --- /dev/null +++ b/lib/al/Library/Bgm/BgmParamsChanger.h @@ -0,0 +1,115 @@ +#pragma once + +#include +#include + +#include "Project/Bgm/BgmInfo.h" + +namespace al { +class DspLinearValueController; +class DspSinValueController; +struct BgmRegionChangeParams; + +class IBgmParamsChanger { +public: + virtual void resetForReuse() = 0; + virtual bool isActivate() const = 0; + virtual bool isPaused() const = 0; + virtual void changeVolume(f32 target, s32 stepCount) = 0; + virtual void changePitchShift(f32 target, s32 stepCount) = 0; + virtual void changePitchShiftModulation(f32 target, f32 frequency, s32 stepCount) = 0; + virtual void changeLpf(f32 target, s32 stepCount) = 0; + virtual void changeBiquadFilter(f32 target, s32 stepCount) = 0; + virtual void changeEffectSend(nn::atk::AuxBus bus, f32 target, s32 stepCount) = 0; + virtual void changeTrackVolume(s32 track, f32 target, s32 stepCount) = 0; + virtual void changeDefaultParams(s32 stepCount) = 0; + virtual bool isEnableRegionChange() const = 0; + virtual void setRegionChangeParams(const BgmRegionChangeParams& params) = 0; + virtual const char* getSituationName() const = 0; + virtual const char* getSubSituationName() const = 0; + virtual void setSituationName(const char* name) = 0; + virtual void setSubSituationName(const char* name) = 0; + virtual f32 getCurVolume() const = 0; + virtual f32 getCurPitchShift() const = 0; + virtual f32 getCurPitchShiftModulation() const = 0; + virtual f32 getCurLpfCutOff() const = 0; + virtual f32 getBiquadFilterValue() const = 0; + virtual f32 getEffectSend() const = 0; + virtual nn::atk::AuxBus getEffectBusId() const = 0; + virtual f32 getCurTrackVolume(s32 track) const = 0; + virtual const BgmRegionChangeParams& getRegionChangeParams() const = 0; +}; + +class BgmParamsChanger : public IBgmParamsChanger { +public: + BgmParamsChanger(); + void update(); + bool isReachedTargetAllController() const; + void resetParams(); + void activate(const char* situationName, const char* subSituationName, bool unk); + void deactivate(bool isReuse); + void tryDeactivate(bool isReuse); + void resetForReuse() override; + void changeVolume(f32 target, s32 stepCount) override; + void changePitchShift(f32 target, s32 stepCount) override; + void changeLpf(f32 target, s32 stepCount) override; + void changeBiquadFilter(f32 target, s32 stepCount) override; + void changePitchShiftModulation(f32 target, f32 frequency, s32 stepCount) override; + void changeEffectSend(nn::atk::AuxBus bus, f32 target, s32 stepCount) override; + void changeTrackVolume(s32 track, f32 target, s32 stepCount) override; + void changeDefaultParams(s32 stepCount) override; + void forceDeactivate(); + f32 getCurVolume() const override; + f32 getCurPitchShift() const override; + f32 getCurPitchShiftModulation() const override; + f32 getCurLpfCutOff() const override; + f32 getBiquadFilterValue() const override; + f32 getEffectSend() const override; + nn::atk::AuxBus getEffectBusId() const override; + f32 getCurTrackVolume(s32 track) const override; + + bool isActivate() const override { return mIsActivate; } + + bool isPaused() const override { return mIsPaused; } + + bool isEnableRegionChange() const override { return mIsEnableRegionChange; } + + void setRegionChangeParams(const BgmRegionChangeParams& params) override { + mIsEnableRegionChange = true; + mRegionChangeParams = params; + } + + const char* getSituationName() const override { return mSituationName; } + + const char* getSubSituationName() const override { return mSubSituationName; } + + void setSituationName(const char* name) override { mSituationName = name; } + + void setSubSituationName(const char* name) override { mSubSituationName = name; } + + const BgmRegionChangeParams& getRegionChangeParams() const override { + return mRegionChangeParams; + } + +private: + DspLinearValueController* mVolume = nullptr; + DspLinearValueController* mPitchShift = nullptr; + DspLinearValueController* mLpf = nullptr; + DspLinearValueController* mBiquadFilter = nullptr; + DspLinearValueController* mEffectSend = nullptr; + DspSinValueController* mPitchShiftModulation = nullptr; + nn::atk::AuxBus mEffectBus = nn::atk::AuxBus::AuxBus_A; + DspLinearValueController* mTrackVolume[6]; + bool mIsEnableRegionChange = false; + BgmRegionChangeParams mRegionChangeParams; + bool mIsActivate = false; + bool mIsPaused = false; + bool mIsReuse = false; + bool _87 = false; + const char* mSituationName = nullptr; + const char* mSubSituationName = nullptr; +}; + +static_assert(sizeof(BgmParamsChanger) == 0x98); + +} // namespace al diff --git a/lib/al/Library/Bgm/DspValueController.h b/lib/al/Library/Bgm/DspValueController.h new file mode 100644 index 00000000..cb96f0f6 --- /dev/null +++ b/lib/al/Library/Bgm/DspValueController.h @@ -0,0 +1,48 @@ +#pragma once + +#include + +namespace al { +class DspLinearValueController { +public: + DspLinearValueController(f32 value); + void init(f32 value); + void update(); + void changeTarget(f32 target, s32 stepCount); + + bool isReachedTarget() const { return mTarget == mCurrent; } + + f32 getCurrent() const { return mCurrent; } + +private: + f32 mCurrent = 0.0f; + f32 mTarget = 0.0f; + f32 mStep = 0.0f; +}; + +static_assert(sizeof(DspLinearValueController) == 0xc); + +class DspSinValueController { +public: + DspSinValueController(f32 shift, f32 amplitude); + void init(f32); + void update(); + void changeTarget(f32, s32); + void changeFreq(f32); + + bool isReachedTarget() const { return mLinearValue->isReachedTarget(); } + + f32 getAmplitude() const { return mAmplitude; } + +private: + f32 mShift; + f32 mFreq; + f32 mDelta; + f32 mAngle; + f32 mAmplitude; + DspLinearValueController* mLinearValue; +}; + +static_assert(sizeof(DspSinValueController) == 0x20); + +} // namespace al diff --git a/lib/al/Project/Bgm/BgmInfo.cpp b/lib/al/Project/Bgm/BgmInfo.cpp index 4a53569e..367dba0b 100644 --- a/lib/al/Project/Bgm/BgmInfo.cpp +++ b/lib/al/Project/Bgm/BgmInfo.cpp @@ -24,6 +24,27 @@ void BgmChangeableParams::operator=(const BgmChangeableParams& value) { mTrackVolume5 = value.mTrackVolume5; } +BgmRegionChangeParams::BgmRegionChangeParams() {} + +BgmRegionChangeParams::BgmRegionChangeParams(const BgmRegionChangeParams& other) + : _0(other._0), _4(other._4), _8(other._8), _c(other._c), _d(other._d) { + *this = other; +} + +void BgmRegionChangeParams::operator=(const BgmRegionChangeParams& other) { + _0 = other._0; + _4 = other._4; + _8 = other._8; + _c = other._c; + _d = other._d; +} + +bool BgmRegionChangeParams::operator==(const BgmRegionChangeParams& other) const { + if (_0 == other._0 && _4 == other._4 && _8 == other._8 && _c == other._c && _d == other._d) + return true; + return false; +} + BgmUserInfo::BgmUserInfo() = default; s32 BgmUserInfo::compareInfo(const BgmUserInfo* info_1, const BgmUserInfo* info_2) { diff --git a/lib/al/Project/Bgm/BgmInfo.h b/lib/al/Project/Bgm/BgmInfo.h index 69f878a0..73f944b8 100644 --- a/lib/al/Project/Bgm/BgmInfo.h +++ b/lib/al/Project/Bgm/BgmInfo.h @@ -4,6 +4,14 @@ namespace al { +struct BgmUserInfo; +class ByamlIter; +class SafeString; +template +class AudioInfoListWithParts; +class BgmActionInfo; +class BgmSourceInfo; + class BgmChangeableParams { public: BgmChangeableParams(); @@ -27,13 +35,21 @@ private: f32 mTrackVolume5 = 0; }; -struct BgmUserInfo; -class ByamlIter; -class SafeString; -template -class AudioInfoListWithParts; -class BgmActionInfo; -class BgmSourceInfo; +struct BgmRegionChangeParams { + BgmRegionChangeParams(); + + BgmRegionChangeParams(const BgmRegionChangeParams& other); + + void operator=(const BgmRegionChangeParams& other); + + bool operator==(const BgmRegionChangeParams& other) const; + + s32 _0 = 0; + s32 _4 = 0; + s32 _8 = 0; + bool _c = false; + bool _d = false; +}; struct BgmUserInfo { static BgmUserInfo* createInfo(const ByamlIter&, const sead::SafeString&);