diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 5887703a..28496ea4 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -2901,6 +2901,7 @@ nw4r/snd/snd_AxManager.cpp: nw4r/snd/snd_AxVoice.cpp: .text start:0x80464880 end:0x80467634 align:16 + .sdata2 start:0x8057EF30 end:0x8057EF58 nw4r/snd/snd_AxVoiceManager.cpp: .text start:0x80467640 end:0x80467DC8 align:16 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 508ef954..f4433999 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -49646,14 +49646,14 @@ lbl_8057EF14 = .sdata2:0x8057EF14; // type:object size:0x4 align:4 data:float @2523 = .sdata2:0x8057EF20; // type:object size:0x8 scope:local align:8 data:double @2626 = .sdata2:0x8057EF28; // type:object size:0x4 scope:local align:4 data:float @3157 = .sdata2:0x8057EF2C; // type:object size:0x4 scope:local align:4 data:float -lbl_8057EF30 = .sdata2:0x8057EF30; // type:object size:0x4 align:4 data:float -lbl_8057EF34 = .sdata2:0x8057EF34; // type:object size:0x4 align:4 data:float -lbl_8057EF38 = .sdata2:0x8057EF38; // type:object size:0x4 align:4 data:float -lbl_8057EF40 = .sdata2:0x8057EF40; // type:object size:0x8 align:8 data:double -lbl_8057EF48 = .sdata2:0x8057EF48; // type:object size:0x4 align:4 data:float -lbl_8057EF4C = .sdata2:0x8057EF4C; // type:object size:0x4 align:4 data:float -lbl_8057EF50 = .sdata2:0x8057EF50; // type:object size:0x4 align:4 data:float -lbl_8057EF54 = .sdata2:0x8057EF54; // type:object size:0x4 align:4 data:float +@5196 = .sdata2:0x8057EF30; // type:object size:0x4 scope:local align:4 data:float +@5197 = .sdata2:0x8057EF34; // type:object size:0x4 scope:local align:4 data:float +@5198 = .sdata2:0x8057EF38; // type:object size:0x4 scope:local align:4 data:float +@5201 = .sdata2:0x8057EF40; // type:object size:0x8 scope:local align:8 data:double +@5425 = .sdata2:0x8057EF48; // type:object size:0x4 scope:local align:4 data:float +@5426 = .sdata2:0x8057EF4C; // type:object size:0x4 scope:local align:4 data:float +@5427 = .sdata2:0x8057EF50; // type:object size:0x4 scope:local align:4 data:float +@5467 = .sdata2:0x8057EF54; // type:object size:0x4 scope:local align:4 data:float @1517 = .sdata2:0x8057EF58; // type:object size:0x4 scope:local align:4 data:float @1518 = .sdata2:0x8057EF5C; // type:object size:0x4 scope:local align:4 data:float @1519 = .sdata2:0x8057EF60; // type:object size:0x4 scope:local align:4 data:float diff --git a/configure.py b/configure.py index 86b595c0..02e791cb 100644 --- a/configure.py +++ b/configure.py @@ -1014,7 +1014,7 @@ config.libs = [ [ Object(NonMatching, "nw4r/snd/snd_AnimSound.cpp"), Object(Matching, "nw4r/snd/snd_AxManager.cpp"), - Object(NonMatching, "nw4r/snd/snd_AxVoice.cpp"), + Object(Matching, "nw4r/snd/snd_AxVoice.cpp"), Object(Matching, "nw4r/snd/snd_AxVoiceManager.cpp"), Object(Matching, "nw4r/snd/snd_AxfxImpl.cpp"), Object(Matching, "nw4r/snd/snd_Bank.cpp"), diff --git a/include/nw4r/snd/snd_AxVoice.h b/include/nw4r/snd/snd_AxVoice.h index 4e6d34b7..0b709c4b 100644 --- a/include/nw4r/snd/snd_AxVoice.h +++ b/include/nw4r/snd/snd_AxVoice.h @@ -121,6 +121,8 @@ namespace nw4r { namespace snd { namespace detail void SetVoiceBiquad(AXPBBIQUAD const &biquad); void SetVoiceBiquadCoefs(u16 b0, u16 b1, u16 b2, u16 a1, u16 a2); void SetVoiceRmtIIR(__AXPBRMTIIR const &iir); + void SetVoiceRmtOn(u16 on); + void SetVoiceRmtMix(_AXPBRMTMIX const &iir); void SetVoiceRmtIIRCoefs(u16 type, ...); void Set(AXVPB *vpb); @@ -243,7 +245,7 @@ namespace nw4r { namespace snd { namespace detail void SetAdpcm(AdpcmParam const *param); void SetAdpcmLoop(AdpcmLoopParam const *param); bool SetMix(MixParam const ¶m); - bool SetRmtMix(const RemoteMixParam ¶m); + void SetRmtMix(const RemoteMixParam ¶m); void SetSrc(f32 ratio, bool initialUpdate); void SetVe(f32 volume, f32 initVolume); void SetLpf(u16 freq); diff --git a/src/nw4r/snd/snd_AxVoice.cpp b/src/nw4r/snd/snd_AxVoice.cpp index 81d8213d..656786d6 100644 --- a/src/nw4r/snd/snd_AxVoice.cpp +++ b/src/nw4r/snd/snd_AxVoice.cpp @@ -302,6 +302,10 @@ void AxVoice::SetVoiceType(VoiceType type) mVpb.SetVoiceType(type); } +void AxVoice::EnableRemote(bool enable) { + mVpb.SetVoiceRmtOn(enable); +} + void AxVoice::ResetDelta() { ut::AutoInterruptLock lock; @@ -674,6 +678,37 @@ bool AxVoice::SetMix(MixParam const ¶m) return needUpdateFlag; } +void AxVoice::SetRmtMix(const RemoteMixParam& rParam) { + AXPBRMTMIX mix; + + mix.vMain0 = rParam.vMain0; + mix.vDeltaMain0 = 0; + + mix.vAux0 = rParam.vAux0; + mix.vDeltaAux0 = 0; + + mix.vMain1 = rParam.vMain1; + mix.vDeltaMain1 = 0; + + mix.vAux1 = rParam.vAux1; + mix.vDeltaAux1 = 0; + + mix.vMain2 = rParam.vMain2; + mix.vDeltaMain2 = 0; + + mix.vAux2 = rParam.vAux2; + mix.vDeltaAux2 = 0; + + mix.vMain3 = rParam.vMain3; + mix.vDeltaMain3 = 0; + + mix.vAux3 = rParam.vAux3; + mix.vDeltaAux3 = 0; + + mVpb.SetVoiceRmtMix(mix); +} + + void AxVoice::SetSrc(f32 ratio, bool initialUpdate) { ut::AutoInterruptLock lock; @@ -713,8 +748,12 @@ void AxVoice::SetVe(f32 volume, f32 initVolume) if (!mVpb.IsAvailable()) return; - mVpb.SetVoiceVe(volume * (AX_MAX_VOLUME - 1), - initVolume * (AX_MAX_VOLUME - 1)); + int v = volume * (AX_MAX_VOLUME - 1); + int iv = initVolume * (AX_MAX_VOLUME - 1); + v = ut::Clamp(v, 0, 0xFFFF); + iv = ut::Clamp(iv, 0, 0xFFFF); + + mVpb.SetVoiceVe(v, iv); } void AxVoice::SetLpf(u16 freq) @@ -1277,6 +1316,102 @@ void AxVoiceParamBlock::SetVoiceBiquadCoefs(u16 b0, u16 b1, u16 b2, u16 a1, mSync |= AX_VPB_SYNC_FLAG_BIQUAD_COEFS; } +void AxVoiceParamBlock::SetVoiceRmtOn(u16 on) { + ut::AutoInterruptLock lock; + + if (!IsAvailable()) { + return; + } + + mVpb->pb.remote = on; + mSync |= AX_VPB_SYNC_FLAG_RMT_ON; +} + +void AxVoiceParamBlock::SetVoiceRmtMix(_AXPBRMTMIX const &rMix) +{ + ut::AutoInterruptLock lock; + + if (!IsAvailable()) { + return; + } + + u16* pDst = reinterpret_cast(&mVpb->pb.rmtMix); + const u16* pSrc = reinterpret_cast(&rMix); + + u16 ctrl = 0; + + // vMain0 + if ((*pDst++ = *pSrc++) != 0) { + ctrl |= AX_MIXER_CTRL_RMT_M0; + } + // vDeltaMain0 + if ((*pDst++ = *pSrc++) != 0) { + ctrl |= AX_MIXER_CTRL_RMT_DELTA_M0; + } + // vAux0 + if ((*pDst++ = *pSrc++) != 0) { + ctrl |= AX_MIXER_CTRL_RMT_A0; + } + // vDeltaAux0 + if ((*pDst++ = *pSrc++) != 0) { + ctrl |= AX_MIXER_CTRL_RMT_DELTA_A0; + } + + // vMain1 + if ((*pDst++ = *pSrc++) != 0) { + ctrl |= AX_MIXER_CTRL_RMT_M1; + } + // vDeltaMain1 + if ((*pDst++ = *pSrc++) != 0) { + ctrl |= AX_MIXER_CTRL_RMT_DELTA_M1; + } + // vAux1 + if ((*pDst++ = *pSrc++) != 0) { + ctrl |= AX_MIXER_CTRL_RMT_A1; + } + // vDeltaAux1 + if ((*pDst++ = *pSrc++) != 0) { + ctrl |= AX_MIXER_CTRL_RMT_DELTA_A1; + } + + // vMain2 + if ((*pDst++ = *pSrc++) != 0) { + ctrl |= AX_MIXER_CTRL_RMT_M2; + } + // vDeltaMain2 + if ((*pDst++ = *pSrc++) != 0) { + ctrl |= AX_MIXER_CTRL_RMT_DELTA_M2; + } + // vAux2 + if ((*pDst++ = *pSrc++) != 0) { + ctrl |= AX_MIXER_CTRL_RMT_A2; + } + // vDeltaAux2 + if ((*pDst++ = *pSrc++) != 0) { + ctrl |= AX_MIXER_CTRL_RMT_DELTA_A2; + } + + // vMain3 + if ((*pDst++ = *pSrc++) != 0) { + ctrl |= AX_MIXER_CTRL_RMT_M3; + } + // vDeltaMain3 + if ((*pDst++ = *pSrc++) != 0) { + ctrl |= AX_MIXER_CTRL_RMT_DELTA_M3; + } + // vAux3 + if ((*pDst++ = *pSrc++) != 0) { + ctrl |= AX_MIXER_CTRL_RMT_A3; + } + // vDeltaAux3 + if ((*pDst++ = *pSrc++) != 0) { + ctrl |= AX_MIXER_CTRL_RMT_DELTA_A3; + } + + mVpb->pb.rmtMixerCtrl = ctrl; + mSync |= AX_VPB_SYNC_FLAG_RMT_MIXER_CTRL | AX_VPB_SYNC_FLAG_RMT_MIX; +} + void AxVoiceParamBlock::SetVoiceRmtIIR(__AXPBRMTIIR const &iir) { ut::AutoInterruptLock lock;