Skip to content

Commit

Permalink
spu: try some reverb resample filtering
Browse files Browse the repository at this point in the history
when gauss/cubic interpolation is on
libretro#515
  • Loading branch information
notaz committed Jan 30, 2025
1 parent 9c0bfd9 commit 0f5a4b3
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 51 deletions.
2 changes: 2 additions & 0 deletions plugins/dfsound/externals.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ typedef struct

int dirty; // registers changed

// for filtering
int SB[2][4*2];
} REVERBInfo;

///////////////////////////////////////////////////////////
Expand Down
13 changes: 11 additions & 2 deletions plugins/dfsound/freeze.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* *
***************************************************************************/

#include <stddef.h>
#include <assert.h>
#include "stdafx.h"

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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;i<MAXCHAN;i++)
{
Expand Down Expand Up @@ -357,7 +361,7 @@ long CALLBACK SPUfreeze(unsigned int ulFreezeMode, SPUFreeze_t * pF,
spu.XARepeat = 0;
spu.XALastVal = 0;
spu.last_keyon_cycles = cycles - 16*786u;
if (pFO && pF->ulFreezeSize >= 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;
Expand All @@ -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)
Expand Down
67 changes: 34 additions & 33 deletions plugins/dfsound/gauss_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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
45 changes: 34 additions & 11 deletions plugins/dfsound/reverb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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)
{
Expand Down
10 changes: 5 additions & 5 deletions plugins/dfsound/spu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 0f5a4b3

Please sign in to comment.