mirror of https://github.com/PCSX2/pcsx2.git
SPU2: Get rid of 32bit volumes [SAVEVERSION+]
This commit is contained in:
parent
07d4a65a45
commit
16a11b75a8
|
@ -28,24 +28,6 @@ static const s32 tbl_XA_Factor[16][2] =
|
|||
{98, -55},
|
||||
{122, -60}};
|
||||
|
||||
// Performs a 64-bit multiplication between two values and returns the
|
||||
// high 32 bits as a result (discarding the fractional 32 bits).
|
||||
// The combined fractional bits of both inputs must be 32 bits for this
|
||||
// to work properly.
|
||||
//
|
||||
// This is meant to be a drop-in replacement for times when the 'div' part
|
||||
// of a MulDiv is a constant. (example: 1<<8, or 4096, etc)
|
||||
//
|
||||
// [Air] Performance breakdown: This is over 10 times faster than MulDiv in
|
||||
// a *worst case* scenario. It's also more accurate since it forces the
|
||||
// caller to extend the inputs so that they make use of all 32 bits of
|
||||
// precision.
|
||||
//
|
||||
static __forceinline s32 MulShr32(s32 srcval, s32 mulval)
|
||||
{
|
||||
return static_cast<s64>(srcval) * mulval >> 32;
|
||||
}
|
||||
|
||||
__forceinline s32 clamp_mix(s32 x)
|
||||
{
|
||||
return std::clamp(x, -0x8000, 0x7fff);
|
||||
|
@ -278,16 +260,7 @@ static __forceinline void GetNextDataDummy(V_Core& thiscore, uint voiceidx)
|
|||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
|
||||
// Data is expected to be 16 bit signed (typical stuff!).
|
||||
// volume is expected to be 32 bit signed (31 bits with reverse phase)
|
||||
// Data is shifted up by 1 bit to give the output an effective 16 bit range.
|
||||
static __forceinline s32 ApplyVolume(s32 data, s32 volume)
|
||||
{
|
||||
//return (volume * data) >> 15;
|
||||
return MulShr32(data << 1, volume);
|
||||
}
|
||||
|
||||
static __forceinline s32 ApplyVolume16(s32 data, s32 volume)
|
||||
{
|
||||
return (volume * data) >> 15;
|
||||
}
|
||||
|
@ -302,8 +275,8 @@ static __forceinline StereoOut32 ApplyVolume(const StereoOut32& data, const V_Vo
|
|||
static __forceinline StereoOut32 ApplyVolume(const StereoOut32& data, const V_VolumeSlideLR& volume)
|
||||
{
|
||||
return StereoOut32(
|
||||
ApplyVolume16(data.Left, volume.Left.Value),
|
||||
ApplyVolume16(data.Right, volume.Right.Value));
|
||||
ApplyVolume(data.Left, volume.Left.Value),
|
||||
ApplyVolume(data.Right, volume.Right.Value));
|
||||
}
|
||||
|
||||
static void __forceinline UpdatePitch(uint coreidx, uint voiceidx)
|
||||
|
@ -485,7 +458,7 @@ static __forceinline StereoOut32 MixVoice(uint coreidx, uint voiceidx)
|
|||
// use a full 64-bit multiply/result here.
|
||||
|
||||
CalculateADSR(thiscore, voiceidx);
|
||||
Value = ApplyVolume16(Value, vc.ADSR.Value);
|
||||
Value = ApplyVolume(Value, vc.ADSR.Value);
|
||||
vc.OutX = Value;
|
||||
|
||||
if (IsDevBuild)
|
||||
|
@ -684,8 +657,8 @@ __forceinline
|
|||
}
|
||||
else
|
||||
{
|
||||
Out.Left = ApplyVolume16(Out.Left, Cores[1].MasterVol.Left.Value);
|
||||
Out.Right = ApplyVolume16(Out.Right, Cores[1].MasterVol.Right.Value);
|
||||
Out.Left = ApplyVolume(Out.Left, Cores[1].MasterVol.Left.Value);
|
||||
Out.Right = ApplyVolume(Out.Right, Cores[1].MasterVol.Right.Value);
|
||||
}
|
||||
|
||||
// Final Clamp!
|
||||
|
|
|
@ -243,14 +243,14 @@ static std::array<u16*, 0x401> ComputeRegTable()
|
|||
//0x760: weird area
|
||||
PCORE(0, MasterVol.Left.Reg_VOL),
|
||||
PCORE(0, MasterVol.Right.Reg_VOL),
|
||||
PCORE(0, FxVol.Left) + 1,
|
||||
PCORE(0, FxVol.Right) + 1,
|
||||
PCORE(0, ExtVol.Left) + 1,
|
||||
PCORE(0, ExtVol.Right) + 1,
|
||||
PCORE(0, InpVol.Left) + 1,
|
||||
PCORE(0, InpVol.Right) + 1,
|
||||
PCORE(0, MasterVol.Left.Value) + 1,
|
||||
PCORE(0, MasterVol.Right.Value) + 1,
|
||||
PCORE(0, FxVol.Left),
|
||||
PCORE(0, FxVol.Right),
|
||||
PCORE(0, ExtVol.Left),
|
||||
PCORE(0, ExtVol.Right),
|
||||
PCORE(0, InpVol.Left),
|
||||
PCORE(0, InpVol.Right),
|
||||
PCORE(0, MasterVol.Left.Value),
|
||||
PCORE(0, MasterVol.Right.Value),
|
||||
PCORE(0, Revb.IIR_VOL),
|
||||
PCORE(0, Revb.COMB1_VOL),
|
||||
PCORE(0, Revb.COMB2_VOL),
|
||||
|
@ -264,14 +264,14 @@ static std::array<u16*, 0x401> ComputeRegTable()
|
|||
|
||||
PCORE(1, MasterVol.Left.Reg_VOL),
|
||||
PCORE(1, MasterVol.Right.Reg_VOL),
|
||||
PCORE(1, FxVol.Left) + 1,
|
||||
PCORE(1, FxVol.Right) + 1,
|
||||
PCORE(1, ExtVol.Left) + 1,
|
||||
PCORE(1, ExtVol.Right) + 1,
|
||||
PCORE(1, InpVol.Left) + 1,
|
||||
PCORE(1, InpVol.Right) + 1,
|
||||
PCORE(1, MasterVol.Left.Value) + 1,
|
||||
PCORE(1, MasterVol.Right.Value) + 1,
|
||||
PCORE(1, FxVol.Left),
|
||||
PCORE(1, FxVol.Right),
|
||||
PCORE(1, ExtVol.Left),
|
||||
PCORE(1, ExtVol.Right),
|
||||
PCORE(1, InpVol.Left),
|
||||
PCORE(1, InpVol.Right),
|
||||
PCORE(1, MasterVol.Left.Value),
|
||||
PCORE(1, MasterVol.Right.Value),
|
||||
PCORE(1, Revb.IIR_VOL),
|
||||
PCORE(1, Revb.COMB1_VOL),
|
||||
PCORE(1, Revb.COMB2_VOL),
|
||||
|
|
|
@ -103,7 +103,7 @@ __forceinline void spu2M_Write(u32 addr, u16 value)
|
|||
spu2M_Write(addr, (s16)value);
|
||||
}
|
||||
|
||||
V_VolumeLR V_VolumeLR::Max(0x7FFFFFFF);
|
||||
V_VolumeLR V_VolumeLR::Max(0x7FFF);
|
||||
V_VolumeSlideLR V_VolumeSlideLR::Max(0x3FFF, 0x7FFF);
|
||||
|
||||
V_Core::V_Core(int coreidx)
|
||||
|
@ -478,13 +478,6 @@ __forceinline void UpdateSpdifMode()
|
|||
}
|
||||
}
|
||||
|
||||
// Converts an SPU2 register volume write into a 32 bit SPU2 volume. The value is extended
|
||||
// properly into the lower 16 bits of the value to provide a full spectrum of volumes.
|
||||
static s32 GetVol32(u16 src)
|
||||
{
|
||||
return ((static_cast<s32>(src)) << 16) | ((src << 1) & 0xffff);
|
||||
}
|
||||
|
||||
static u32 map_spu1to2(u32 addr)
|
||||
{
|
||||
return addr * 4 + (addr >= 0x200 ? 0xc0000 : 0);
|
||||
|
@ -565,11 +558,11 @@ void V_Core::WriteRegPS1(u32 mem, u16 value)
|
|||
break;
|
||||
|
||||
case 0x1d84: // Reverberation depth left
|
||||
FxVol.Left = GetVol32(value);
|
||||
FxVol.Left = SignExtend16(value);
|
||||
break;
|
||||
|
||||
case 0x1d86: // Reverberation depth right
|
||||
FxVol.Right = GetVol32(value);
|
||||
FxVol.Right = SignExtend16(value);
|
||||
break;
|
||||
|
||||
case 0x1d88: // Voice ON (0-15)
|
||||
|
@ -875,10 +868,10 @@ u16 V_Core::ReadRegPS1(u32 mem)
|
|||
value = MasterVol.Right.Value;
|
||||
break;
|
||||
case 0x1d84:
|
||||
value = FxVol.Left >> 16;
|
||||
value = FxVol.Left;
|
||||
break;
|
||||
case 0x1d86:
|
||||
value = FxVol.Right >> 16;
|
||||
value = FxVol.Right;
|
||||
break;
|
||||
|
||||
case 0x1d88:
|
||||
|
@ -1389,27 +1382,27 @@ static void RegWrite_CoreExt(u16 value)
|
|||
break;
|
||||
|
||||
case REG_P_EVOLL:
|
||||
thiscore.FxVol.Left = GetVol32(value);
|
||||
thiscore.FxVol.Left = SignExtend16(value);
|
||||
break;
|
||||
|
||||
case REG_P_EVOLR:
|
||||
thiscore.FxVol.Right = GetVol32(value);
|
||||
thiscore.FxVol.Right = SignExtend16(value);
|
||||
break;
|
||||
|
||||
case REG_P_AVOLL:
|
||||
thiscore.ExtVol.Left = GetVol32(value);
|
||||
thiscore.ExtVol.Left = SignExtend16(value);
|
||||
break;
|
||||
|
||||
case REG_P_AVOLR:
|
||||
thiscore.ExtVol.Right = GetVol32(value);
|
||||
thiscore.ExtVol.Right = SignExtend16(value);
|
||||
break;
|
||||
|
||||
case REG_P_BVOLL:
|
||||
thiscore.InpVol.Left = GetVol32(value);
|
||||
thiscore.InpVol.Left = SignExtend16(value);
|
||||
break;
|
||||
|
||||
case REG_P_BVOLR:
|
||||
thiscore.InpVol.Right = GetVol32(value);
|
||||
thiscore.InpVol.Right = SignExtend16(value);
|
||||
break;
|
||||
|
||||
// MVOLX has been confirmed to not be allowed to be written to, so cases have been added as a no-op.
|
||||
|
|
|
@ -37,7 +37,7 @@ enum class FreezeAction
|
|||
// [SAVEVERSION+]
|
||||
// This informs the auto updater that the users savestates will be invalidated.
|
||||
|
||||
static const u32 g_SaveVersion = (0x9A45 << 16) | 0x0000;
|
||||
static const u32 g_SaveVersion = (0x9A46 << 16) | 0x0000;
|
||||
|
||||
|
||||
// the freezing data between submodules and core
|
||||
|
|
Loading…
Reference in New Issue