From d91e3f568b4a39140ce1bd542d72799bac136857 Mon Sep 17 00:00:00 2001 From: Ziemas Date: Sat, 23 Sep 2023 16:47:40 +0200 Subject: [PATCH] SPU: DC filter output Some games leave paused voices hanging with volume turned on which results in dc offset. Filter it out. --- pcsx2/SPU2/Mixer.cpp | 15 ++++++++++++++- pcsx2/SPU2/defs.h | 2 ++ pcsx2/SPU2/spu2sys.cpp | 3 +++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/pcsx2/SPU2/Mixer.cpp b/pcsx2/SPU2/Mixer.cpp index 509ac0b452..f88e79f610 100644 --- a/pcsx2/SPU2/Mixer.cpp +++ b/pcsx2/SPU2/Mixer.cpp @@ -603,6 +603,19 @@ StereoOut32 V_Core::Mix(const VoiceMixSet& inVoices, const StereoOut32& Input, c return TD + ApplyVolume(RV, FxVol); } +static StereoOut32 DCFilter(StereoOut32 input) { + // A simple DC blocking high-pass filter + // Implementation from http://peabody.sapp.org/class/dmp2/lab/dcblock/ + // The magic number 0x7f5c is ceil(INT16_MAX * 0.995) + StereoOut32 output; + output.Left = (input.Left - DCFilterIn.Left + clamp_mix((0x7f5c * DCFilterOut.Left) >> 15)); + output.Right = (input.Right - DCFilterIn.Right + clamp_mix((0x7f5c * DCFilterOut.Right) >> 15)); + + DCFilterIn = input; + DCFilterOut = output; + return output; +} + // used to throttle the output rate of cache stat reports static int p_cachestat_counter = 0; @@ -679,7 +692,7 @@ __forceinline // output by design. // Good thing though that this code gets the volume exactly right, as per tests :) Out = clamp_mix(Out); - + Out = DCFilter(Out); SndBuffer::Write(StereoOut16(Out)); // Update AutoDMA output positioning diff --git a/pcsx2/SPU2/defs.h b/pcsx2/SPU2/defs.h index 21108dd337..528a5ad5fb 100644 --- a/pcsx2/SPU2/defs.h +++ b/pcsx2/SPU2/defs.h @@ -513,6 +513,8 @@ extern u16 OutPos; extern u16 InputPos; // SPU Mixing Cycles ("Ticks mixed" counter) extern u32 Cycles; +// DC Filter state +extern StereoOut16 DCFilterIn, DCFilterOut; extern s16 spu2regs[0x010000 / sizeof(s16)]; extern s16 _spu2mem[0x200000 / sizeof(s16)]; diff --git a/pcsx2/SPU2/spu2sys.cpp b/pcsx2/SPU2/spu2sys.cpp index 7e77f8d7b2..1fbf0d6f44 100644 --- a/pcsx2/SPU2/spu2sys.cpp +++ b/pcsx2/SPU2/spu2sys.cpp @@ -37,6 +37,7 @@ V_CoreDebug DebugCores[2]; V_Core Cores[2]; V_SPDIF Spdif; +StereoOut16 DCFilterIn, DCFilterOut; u16 OutPos; u16 InputPos; u32 Cycles; @@ -149,6 +150,8 @@ void V_Core::Init(int index) DMAPtr = nullptr; KeyOn = 0; OutPos = 0; + DCFilterIn = {}; + DCFilterOut = {}; psxmode = false; psxSoundDataTransferControl = 0;