From: notaz Date: Thu, 30 Jan 2025 21:24:18 +0000 (+0200) Subject: spu: try some reverb resample filtering X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0f5a4b3accd38a6352874166504501d3fdc20a49;p=pcsx_rearmed.git spu: try some reverb resample filtering when gauss/cubic interpolation is on libretro/pcsx_rearmed#515 --- diff --git a/plugins/dfsound/externals.h b/plugins/dfsound/externals.h index 6fdef9db..38f66bc8 100644 --- a/plugins/dfsound/externals.h +++ b/plugins/dfsound/externals.h @@ -167,6 +167,8 @@ typedef struct int dirty; // registers changed + // for filtering + int SB[2][4*2]; } REVERBInfo; /////////////////////////////////////////////////////////// diff --git a/plugins/dfsound/freeze.c b/plugins/dfsound/freeze.c index 36b89959..ef06203a 100644 --- a/plugins/dfsound/freeze.c +++ b/plugins/dfsound/freeze.c @@ -15,6 +15,7 @@ * * ***************************************************************************/ +#include #include #include "stdafx.h" @@ -137,6 +138,7 @@ typedef struct uint32_t XARepeat; uint32_t XALastVal; uint32_t last_keyon_cycles; + uint32_t rvb_sb[2][4]; } SPUOSSFreeze_t; @@ -240,7 +242,7 @@ long CALLBACK SPUfreeze(unsigned int ulFreezeMode, SPUFreeze_t * pF, unsigned int cycles) { SPUOSSFreeze_t * pFO = NULL; - int i; + int i, j; if(!pF) return 0; // first check @@ -310,6 +312,8 @@ long CALLBACK SPUfreeze(unsigned int ulFreezeMode, SPUFreeze_t * pF, pFO->XARepeat = spu.XARepeat; pFO->XALastVal = spu.XALastVal; pFO->last_keyon_cycles = spu.last_keyon_cycles; + for (i = 0; i < 2; i++) + memcpy(&pFO->rvb_sb[i], spu.rvb->SB[i], sizeof(pFO->rvb_sb[i])); for(i=0;iulFreezeSize >= sizeof(*pF) + sizeof(*pFO)) { + if (pFO && pF->ulFreezeSize >= sizeof(*pF) + offsetof(SPUOSSFreeze_t, rvb_sb)) { spu.cycles_dma_end = pFO->cycles_dma_end; spu.decode_dirty_ch = pFO->decode_dirty_ch; spu.dwNoiseVal = pFO->dwNoiseVal; @@ -366,6 +370,11 @@ long CALLBACK SPUfreeze(unsigned int ulFreezeMode, SPUFreeze_t * pF, spu.XALastVal = pFO->XALastVal; spu.last_keyon_cycles = pFO->last_keyon_cycles; } + if (pFO && pF->ulFreezeSize >= sizeof(*pF) + sizeof(*pFO)) { + for (i = 0; i < 2; i++) + for (j = 0; j < 2; j++) + memcpy(&spu.rvb->SB[i][j*4], pFO->rvb_sb[i], 4 * sizeof(spu.rvb->SB[i][0])); + } // repair some globals for(i=0;i<=62;i+=2) diff --git a/plugins/dfsound/gauss_i.h b/plugins/dfsound/gauss_i.h index e754347e..00a618a8 100644 --- a/plugins/dfsound/gauss_i.h +++ b/plugins/dfsound/gauss_i.h @@ -49,23 +49,24 @@ for(0) + for(256) + rev(256) + rev(0) // Mednafen's table (PSX) 99-100% -const int gauss[]={ - 0x12c7, 0x59b3, 0x1307, 0xffffffff, - 0x1288, 0x59b2, 0x1347, 0xffffffff, - 0x1249, 0x59b0, 0x1388, 0xffffffff, - 0x120b, 0x59ad, 0x13c9, 0xffffffff, - 0x11cd, 0x59a9, 0x140b, 0xffffffff, - 0x118f, 0x59a4, 0x144d, 0xffffffff, - 0x1153, 0x599e, 0x1490, 0xffffffff, - 0x1116, 0x5997, 0x14d4, 0xffffffff, - 0x10db, 0x598f, 0x1517, 0xffffffff, - 0x109f, 0x5986, 0x155c, 0xffffffff, - 0x1065, 0x597c, 0x15a0, 0xffffffff, - 0x102a, 0x5971, 0x15e6, 0xffffffff, - 0x0ff1, 0x5965, 0x162c, 0xffffffff, - 0x0fb7, 0x5958, 0x1672, 0xffffffff, - 0x0f7f, 0x5949, 0x16b9, 0xffffffff, - 0x0f46, 0x593a, 0x1700, 0xffffffff, +static const signed short gauss[] = +{ + 0x12c7, 0x59b3, 0x1307, 0xffff, + 0x1288, 0x59b2, 0x1347, 0xffff, + 0x1249, 0x59b0, 0x1388, 0xffff, + 0x120b, 0x59ad, 0x13c9, 0xffff, + 0x11cd, 0x59a9, 0x140b, 0xffff, + 0x118f, 0x59a4, 0x144d, 0xffff, + 0x1153, 0x599e, 0x1490, 0xffff, + 0x1116, 0x5997, 0x14d4, 0xffff, + 0x10db, 0x598f, 0x1517, 0xffff, + 0x109f, 0x5986, 0x155c, 0xffff, + 0x1065, 0x597c, 0x15a0, 0xffff, + 0x102a, 0x5971, 0x15e6, 0xffff, + 0x0ff1, 0x5965, 0x162c, 0xffff, + 0x0fb7, 0x5958, 0x1672, 0xffff, + 0x0f7f, 0x5949, 0x16b9, 0xffff, + 0x0f46, 0x593a, 0x1700, 0xffff, 0x0f0f, 0x592a, 0x1747, 0x0000, 0x0ed7, 0x5919, 0x1790, 0x0000, 0x0ea1, 0x5907, 0x17d8, 0x0000, @@ -290,22 +291,22 @@ const int gauss[]={ 0x0000, 0x17d8, 0x5907, 0x0ea1, 0x0000, 0x1790, 0x5919, 0x0ed7, 0x0000, 0x1747, 0x592a, 0x0f0f, - 0xffffffff, 0x1700, 0x593a, 0x0f46, - 0xffffffff, 0x16b9, 0x5949, 0x0f7f, - 0xffffffff, 0x1672, 0x5958, 0x0fb7, - 0xffffffff, 0x162c, 0x5965, 0x0ff1, - 0xffffffff, 0x15e6, 0x5971, 0x102a, - 0xffffffff, 0x15a0, 0x597c, 0x1065, - 0xffffffff, 0x155c, 0x5986, 0x109f, - 0xffffffff, 0x1517, 0x598f, 0x10db, - 0xffffffff, 0x14d4, 0x5997, 0x1116, - 0xffffffff, 0x1490, 0x599e, 0x1153, - 0xffffffff, 0x144d, 0x59a4, 0x118f, - 0xffffffff, 0x140b, 0x59a9, 0x11cd, - 0xffffffff, 0x13c9, 0x59ad, 0x120b, - 0xffffffff, 0x1388, 0x59b0, 0x1249, - 0xffffffff, 0x1347, 0x59b2, 0x1288, - 0xffffffff, 0x1307, 0x59b3, 0x12c7, + 0xffff, 0x1700, 0x593a, 0x0f46, + 0xffff, 0x16b9, 0x5949, 0x0f7f, + 0xffff, 0x1672, 0x5958, 0x0fb7, + 0xffff, 0x162c, 0x5965, 0x0ff1, + 0xffff, 0x15e6, 0x5971, 0x102a, + 0xffff, 0x15a0, 0x597c, 0x1065, + 0xffff, 0x155c, 0x5986, 0x109f, + 0xffff, 0x1517, 0x598f, 0x10db, + 0xffff, 0x14d4, 0x5997, 0x1116, + 0xffff, 0x1490, 0x599e, 0x1153, + 0xffff, 0x144d, 0x59a4, 0x118f, + 0xffff, 0x140b, 0x59a9, 0x11cd, + 0xffff, 0x13c9, 0x59ad, 0x120b, + 0xffff, 0x1388, 0x59b0, 0x1249, + 0xffff, 0x1347, 0x59b2, 0x1288, + 0xffff, 0x1307, 0x59b3, 0x12c7, }; #endif diff --git a/plugins/dfsound/reverb.c b/plugins/dfsound/reverb.c index 8d31c35b..0fcb6a11 100644 --- a/plugins/dfsound/reverb.c +++ b/plugins/dfsound/reverb.c @@ -74,11 +74,31 @@ INLINE int rvb2ram_offs(int curr, int space, int ofs) //////////////////////////////////////////////////////////////////////// -// from nocash psx-spx -static void MixREVERB(int *SSumLR, int *RVB, int ns_to, int curr_addr) +static void reverb_interpolate(REVERBInfo *rvb, int curr_addr, + int out0[2], int out1[2]) +{ + int spos = (curr_addr - 3) & 3; + int dpos = curr_addr & 3; + int i; + + for (i = 0; i < 2; i++) + rvb->SB[i][dpos] = rvb->SB[i][4 | dpos] = out0[i]; + + // mednafen uses some 20 coefs here, we just reuse gauss [0] and [128] + for (i = 0; i < 2; i++) + { + const int *s; + s = &rvb->SB[i][spos]; + out0[i] = (s[0] * 0x12c7 + s[1] * 0x59b3 + s[2] * 0x1307) >> 15; + out1[i] = (s[0] * 0x019c + s[1] * 0x3def + s[2] * 0x3e4c + s[3] * 0x01a8) >> 15; + } +} + +static void MixREVERB(int *SSumLR, int *RVB, int ns_to, int curr_addr, + int do_filter) { unsigned short *spuMem = spu.spuMem; - const REVERBInfo *rvb = spu.rvb; + REVERBInfo *rvb = spu.rvb; int space = 0x40000 - rvb->StartAddr; int mlsame_m2o = rvb->mLSAME + space - 1; int mrsame_m2o = rvb->mRSAME + space - 1; @@ -104,8 +124,9 @@ static void MixREVERB(int *SSumLR, int *RVB, int ns_to, int curr_addr) int mrsame_m2 = g_buffer(mrsame_m2o) << 15; int mldiff_m2 = g_buffer(mldiff_m2o) << 15; int mrdiff_m2 = g_buffer(mrdiff_m2o) << 15; - int Lout, Rout; + int Lout, Rout, out0[2], out1[2]; + // from nocash psx-spx mlsame_m2 += ((Lin + g_buffer(rvb->dLSAME) * vWALL - mlsame_m2) >> 15) * vIIR; mrsame_m2 += ((Rin + g_buffer(rvb->dRSAME) * vWALL - mrsame_m2) >> 15) * vIIR; mldiff_m2 += ((Lin + g_buffer(rvb->dLDIFF) * vWALL - mldiff_m2) >> 15) * vIIR; @@ -138,13 +159,15 @@ static void MixREVERB(int *SSumLR, int *RVB, int ns_to, int curr_addr) Lout = Lout * vAPF2 + (g_buffer(rvb->mLAPF2_dAPF2) << 15); Rout = Rout * vAPF2 + (g_buffer(rvb->mRAPF2_dAPF2) << 15); - Lout = ((Lout >> 15) * rvb->VolLeft) >> 15; - Rout = ((Rout >> 15) * rvb->VolRight) >> 15; + out0[0] = out1[0] = (Lout >> 15) * rvb->VolLeft >> 15; + out0[1] = out1[1] = (Rout >> 15) * rvb->VolRight >> 15; + if (do_filter) + reverb_interpolate(rvb, curr_addr, out0, out1); - SSumLR[ns++] += Lout; - SSumLR[ns++] += Rout; - SSumLR[ns++] += Lout; - SSumLR[ns++] += Rout; + SSumLR[ns++] += out0[0]; + SSumLR[ns++] += out0[1]; + SSumLR[ns++] += out1[0]; + SSumLR[ns++] += out1[1]; curr_addr++; curr_addr = rvb_wrap(curr_addr, space); @@ -240,7 +263,7 @@ INLINE void REVERBDo(int *SSumLR, int *RVB, int ns_to, int curr_addr) { if (spu.spuCtrl & 0x80) // -> reverb on? oki { - MixREVERB(SSumLR, RVB, ns_to, curr_addr); + MixREVERB(SSumLR, RVB, ns_to, curr_addr, spu.interpolation > 1); } else if (spu.rvb->VolLeft || spu.rvb->VolRight) { diff --git a/plugins/dfsound/spu.c b/plugins/dfsound/spu.c index bc9cbf11..0938a34b 100644 --- a/plugins/dfsound/spu.c +++ b/plugins/dfsound/spu.c @@ -333,11 +333,11 @@ INLINE int GetInterpolationGauss(const sample_buf *sb, int spos) int gpos = sb->interp.gauss.pos; int vl = (spos >> 6) & ~3; int vr; - vr = (gauss[vl+0] * gval(0)) >> 15; - vr += (gauss[vl+1] * gval(1)) >> 15; - vr += (gauss[vl+2] * gval(2)) >> 15; - vr += (gauss[vl+3] * gval(3)) >> 15; - return vr; + vr = gauss[vl+0] * gval(0); + vr += gauss[vl+1] * gval(1); + vr += gauss[vl+2] * gval(2); + vr += gauss[vl+3] * gval(3); + return vr >> 15; } static void decode_block_data(int *dest, const unsigned char *src, int predict_nr, int shift_factor)