spu: deal with some reverb overflows
authornotaz <notasas@gmail.com>
Tue, 20 May 2025 23:00:40 +0000 (02:00 +0300)
committernotaz <notasas@gmail.com>
Tue, 20 May 2025 23:56:41 +0000 (02:56 +0300)
still possible but hopefully won't happen in practice
libretro/pcsx_rearmed#890

plugins/dfsound/reverb.c

index 081369c..c736c1c 100644 (file)
@@ -105,11 +105,12 @@ static void MixREVERB(int *SSumLR, int *RVB, int ns_to, int curr_addr,
  int mrsame_m2o = rvb->mRSAME + space - 1;\r
  int mldiff_m2o = rvb->mLDIFF + space - 1;\r
  int mrdiff_m2o = rvb->mRDIFF + space - 1;\r
- int vCOMB1 = rvb->vCOMB1, vCOMB2 = rvb->vCOMB2;\r
- int vCOMB3 = rvb->vCOMB3, vCOMB4 = rvb->vCOMB4;\r
- int vAPF1 = rvb->vAPF1, vAPF2 = rvb->vAPF2;\r
+ int vCOMB1 = rvb->vCOMB1 >> 1, vCOMB2 = rvb->vCOMB2 >> 1;\r
+ int vCOMB3 = rvb->vCOMB3 >> 1, vCOMB4 = rvb->vCOMB4 >> 1;\r
+ int vAPF1 = rvb->vAPF1 >> 1, vAPF2 = rvb->vAPF2 >> 1;\r
+ int vLIN = rvb->vLIN >> 1, vRIN = rvb->vRIN >> 1;\r
+ int vWALL = rvb->vWALL >> 1;\r
  int vIIR = rvb->vIIR;\r
- int vWALL = rvb->vWALL;\r
  int ns;\r
 \r
 #if P_HAVE_PTHREAD || defined(WANT_THREAD_CODE)\r
@@ -122,23 +123,26 @@ static void MixREVERB(int *SSumLR, int *RVB, int ns_to, int curr_addr,
 \r
  for (ns = 0; ns < ns_to * 2; )\r
   {\r
-   int Lin = RVB[ns]   * rvb->vLIN;\r
-   int Rin = RVB[ns+1] * rvb->vRIN;\r
-   int mlsame_m2 = g_buffer(mlsame_m2o) << 15; // -1\r
-   int mrsame_m2 = g_buffer(mrsame_m2o) << 15;\r
-   int mldiff_m2 = g_buffer(mldiff_m2o) << 15;\r
-   int mrdiff_m2 = g_buffer(mrdiff_m2o) << 15;\r
+   int Lin = RVB[ns];\r
+   int Rin = RVB[ns+1];\r
+   int mlsame_m2 = g_buffer(mlsame_m2o) << (15-1);\r
+   int mrsame_m2 = g_buffer(mrsame_m2o) << (15-1);\r
+   int mldiff_m2 = g_buffer(mldiff_m2o) << (15-1);\r
+   int mrdiff_m2 = g_buffer(mrdiff_m2o) << (15-1);\r
    int Lout, Rout, out0[2], out1[2];\r
 \r
+   ssat32_to_16(Lin); Lin *= vLIN;\r
+   ssat32_to_16(Rin); Rin *= vRIN;\r
+\r
    // from nocash psx-spx\r
    mlsame_m2 += ((Lin + g_buffer(rvb->dLSAME) * vWALL - mlsame_m2) >> 15) * vIIR;\r
    mrsame_m2 += ((Rin + g_buffer(rvb->dRSAME) * vWALL - mrsame_m2) >> 15) * vIIR;\r
    mldiff_m2 += ((Lin + g_buffer(rvb->dLDIFF) * vWALL - mldiff_m2) >> 15) * vIIR;\r
    mrdiff_m2 += ((Rin + g_buffer(rvb->dRDIFF) * vWALL - mrdiff_m2) >> 15) * vIIR;\r
-   mlsame_m2 >>= 15; s_buffer_w(rvb->mLSAME, mlsame_m2);\r
-   mrsame_m2 >>= 15; s_buffer_w(rvb->mRSAME, mrsame_m2);\r
-   mldiff_m2 >>= 15; s_buffer_w(rvb->mLDIFF, mldiff_m2);\r
-   mrdiff_m2 >>= 15; s_buffer_w(rvb->mRDIFF, mrdiff_m2);\r
+   mlsame_m2 >>= (15-1); s_buffer_w(rvb->mLSAME, mlsame_m2);\r
+   mrsame_m2 >>= (15-1); s_buffer_w(rvb->mRSAME, mrsame_m2);\r
+   mldiff_m2 >>= (15-1); s_buffer_w(rvb->mLDIFF, mldiff_m2);\r
+   mrdiff_m2 >>= (15-1); s_buffer_w(rvb->mRDIFF, mrdiff_m2);\r
 \r
    Lout = vCOMB1 * g_buffer(rvb->mLCOMB1) + vCOMB2 * g_buffer(rvb->mLCOMB2)\r
         + vCOMB3 * g_buffer(rvb->mLCOMB3) + vCOMB4 * g_buffer(rvb->mLCOMB4);\r
@@ -147,24 +151,24 @@ static void MixREVERB(int *SSumLR, int *RVB, int ns_to, int curr_addr,
 \r
    preload(SSumLR + ns + 64*2/4 - 4);\r
 \r
-   Lout -= vAPF1 * g_buffer(rvb->mLAPF1_dAPF1); Lout >>= 15;\r
-   Rout -= vAPF1 * g_buffer(rvb->mRAPF1_dAPF1); Rout >>= 15;\r
+   Lout -= vAPF1 * g_buffer(rvb->mLAPF1_dAPF1); Lout >>= (15-1);\r
+   Rout -= vAPF1 * g_buffer(rvb->mRAPF1_dAPF1); Rout >>= (15-1);\r
    s_buffer_w(rvb->mLAPF1, Lout);\r
    s_buffer_w(rvb->mRAPF1, Rout);\r
-   Lout = Lout * vAPF1 + (g_buffer(rvb->mLAPF1_dAPF1) << 15);\r
-   Rout = Rout * vAPF1 + (g_buffer(rvb->mRAPF1_dAPF1) << 15);\r
+   Lout = Lout * vAPF1 + (g_buffer(rvb->mLAPF1_dAPF1) << (15-1));\r
+   Rout = Rout * vAPF1 + (g_buffer(rvb->mRAPF1_dAPF1) << (15-1));\r
 \r
    preload(RVB + ns + 64*2/4 - 4);\r
 \r
-   Lout -= vAPF2 * g_buffer(rvb->mLAPF2_dAPF2); Lout >>= 15;\r
-   Rout -= vAPF2 * g_buffer(rvb->mRAPF2_dAPF2); Rout >>= 15;\r
+   Lout -= vAPF2 * g_buffer(rvb->mLAPF2_dAPF2); Lout >>= (15-1);\r
+   Rout -= vAPF2 * g_buffer(rvb->mRAPF2_dAPF2); Rout >>= (15-1);\r
    s_buffer_w(rvb->mLAPF2, Lout);\r
    s_buffer_w(rvb->mRAPF2, Rout);\r
-   Lout = Lout * vAPF2 + (g_buffer(rvb->mLAPF2_dAPF2) << 15);\r
-   Rout = Rout * vAPF2 + (g_buffer(rvb->mRAPF2_dAPF2) << 15);\r
+   Lout = Lout * vAPF2 + (g_buffer(rvb->mLAPF2_dAPF2) << (15-1));\r
+   Rout = Rout * vAPF2 + (g_buffer(rvb->mRAPF2_dAPF2) << (15-1));\r
 \r
-   out0[0] = out1[0] = (Lout >> 15) * rvb->VolLeft  >> 15;\r
-   out0[1] = out1[1] = (Rout >> 15) * rvb->VolRight >> 15;\r
+   out0[0] = out1[0] = (Lout >> (15-1)) * rvb->VolLeft  >> 15;\r
+   out0[1] = out1[1] = (Rout >> (15-1)) * rvb->VolRight >> 15;\r
    if (do_filter)\r
     reverb_interpolate(sb, curr_addr, out0, out1);\r
 \r