spu: some cdda/xa reverb support
authornotaz <notasas@gmail.com>
Wed, 9 Aug 2023 23:29:53 +0000 (02:29 +0300)
committernotaz <notasas@gmail.com>
Thu, 10 Aug 2023 18:02:39 +0000 (21:02 +0300)
not for threaded spu as it'd race with writes and I don't want to use a
mutex or do extra copying there

libretro/pcsx_rearmed#733

plugins/dfsound/registers.h
plugins/dfsound/spu.c
plugins/dfsound/xa.c
plugins/dfsound/xa.h [deleted file]

index 28641b8..a296431 100644 (file)
 #define H_SPU_ADSRLevel22  0x0d68\r
 #define H_SPU_ADSRLevel23  0x0d78\r
 \r
-#define CTRL_IRQ                0x40\r
-#define CTRL_REVERB             0x80\r
+#define CTRL_CD                 0x0001\r
+#define CTRL_CDREVERB           0x0004\r
+#define CTRL_IRQ                0x0040\r
+#define CTRL_REVERB             0x0080\r
 #define CTRL_NOISE              0x3f00\r
 #define CTRL_MUTE               0x4000\r
 #define CTRL_ON                 0x8000\r
index f6730d6..038f946 100644 (file)
@@ -814,6 +814,8 @@ static void do_channels(int ns_to)
     mix_chan(spu.SSumLR, ns_to, s_chan->iLeftVolume, s_chan->iRightVolume);
   }
 
+  MixXA(spu.SSumLR, RVB, ns_to, spu.decode_pos);
+
   if (spu.rvb->StartAddr) {
    if (do_rvb)
     REVERBDo(spu.SSumLR, RVB, ns_to, spu.rvb->CurrAddr);
@@ -1066,6 +1068,7 @@ static void sync_worker_thread(int force)
   work = &worker->i[worker->i_reaped & WORK_I_MASK];
   thread_work_wait_sync(work, force);
 
+  MixXA(work->SSumLR, RVB, work->ns_to, work->decode_pos);
   do_samples_finish(work->SSumLR, work->ns_to,
    work->channels_silent, work->decode_pos);
 
@@ -1192,12 +1195,10 @@ static void do_samples_finish(int *SSumLR, int ns_to,
     spu.decode_dirty_ch &= ~(1<<3);
    }
 
-  MixXA(SSumLR, ns_to, decode_pos);
-
   vol_l = vol_l * spu_config.iVolume >> 10;
   vol_r = vol_r * spu_config.iVolume >> 10;
 
-  if (!(spu.spuCtrl & 0x4000) || !(vol_l | vol_r))
+  if (!(spu.spuCtrl & CTRL_MUTE) || !(vol_l | vol_r))
    {
     // muted? (rare)
     memset(spu.pS, 0, ns_to * 2 * sizeof(spu.pS[0]));
index 397ed59..23924d3 100644 (file)
@@ -39,7 +39,7 @@ static int gauss_window[8] = {0, 0, 0, 0, 0, 0, 0, 0};
 // MIX XA & CDDA
 ////////////////////////////////////////////////////////////////////////
 
-INLINE void MixXA(int *SSumLR, int ns_to, int decode_pos)
+INLINE void MixXA(int *SSumLR, int *RVB, int ns_to, int decode_pos)
 {
  int cursor = decode_pos;
  int ns;
@@ -51,15 +51,23 @@ INLINE void MixXA(int *SSumLR, int ns_to, int decode_pos)
   if(spu.XAPlay == spu.XAFeed)
    spu.XARepeat--;
 
-  for(ns = 0; ns < ns_to*2; )
+  for(ns = 0; ns < ns_to*2; ns += 2)
    {
     if(spu.XAPlay != spu.XAFeed) v=*spu.XAPlay++;
     if(spu.XAPlay == spu.XAEnd) spu.XAPlay=spu.XAStart;
 
     l = ((int)(short)v * spu.iLeftXAVol) >> 15;
     r = ((int)(short)(v >> 16) * spu.iLeftXAVol) >> 15;
-    SSumLR[ns++] += l;
-    SSumLR[ns++] += r;
+    if (spu.spuCtrl & CTRL_CD)
+    {
+     SSumLR[ns+0] += l;
+     SSumLR[ns+1] += r;
+    }
+    if (unlikely(spu.spuCtrl & CTRL_CDREVERB))
+    {
+     RVB[ns+0] += l;
+     RVB[ns+1] += r;
+    }
 
     spu.spuMem[cursor] = HTOLE16(v);
     spu.spuMem[cursor + 0x400/2] = HTOLE16(v >> 16);
@@ -71,15 +79,23 @@ INLINE void MixXA(int *SSumLR, int ns_to, int decode_pos)
  // hence this 'ns_to < 8'
  else if(spu.CDDAPlay != spu.CDDAFeed || ns_to < 8)
  {
-  for(ns = 0; ns < ns_to*2; )
+  for(ns = 0; ns < ns_to*2; ns += 2)
    {
     if(spu.CDDAPlay != spu.CDDAFeed) v=*spu.CDDAPlay++;
     if(spu.CDDAPlay == spu.CDDAEnd) spu.CDDAPlay=spu.CDDAStart;
 
     l = ((int)(short)v * spu.iLeftXAVol) >> 15;
     r = ((int)(short)(v >> 16) * spu.iLeftXAVol) >> 15;
-    SSumLR[ns++] += l;
-    SSumLR[ns++] += r;
+    if (spu.spuCtrl & CTRL_CD)
+    {
+     SSumLR[ns+0] += l;
+     SSumLR[ns+1] += r;
+    }
+    if (unlikely(spu.spuCtrl & CTRL_CDREVERB))
+    {
+     RVB[ns+0] += l;
+     RVB[ns+1] += r;
+    }
 
     spu.spuMem[cursor] = HTOLE16(v);
     spu.spuMem[cursor + 0x400/2] = HTOLE16(v >> 16);
@@ -420,3 +436,4 @@ INLINE int FeedCDDA(unsigned char *pcm, int nBytes)
 }
 
 #endif
+// vim:shiftwidth=1:expandtab
diff --git a/plugins/dfsound/xa.h b/plugins/dfsound/xa.h
deleted file mode 100644 (file)
index 137fe43..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/***************************************************************************\r
-                            xa.h  -  description\r
-                             -------------------\r
-    begin                : Wed May 15 2002\r
-    copyright            : (C) 2002 by Pete Bernert\r
-    email                : BlackDove@addcom.de\r
- ***************************************************************************/\r
-/***************************************************************************\r
- *                                                                         *\r
- *   This program is free software; you can redistribute it and/or modify  *\r
- *   it under the terms of the GNU General Public License as published by  *\r
- *   the Free Software Foundation; either version 2 of the License, or     *\r
- *   (at your option) any later version. See also the license.txt file for *\r
- *   additional informations.                                              *\r
- *                                                                         *\r
- ***************************************************************************/\r
-\r
-#ifndef __P_XA_H__\r
-#define __P_XA_H__\r
-\r
-INLINE void MixXA(void);\r
-INLINE void FeedXA(xa_decode_t *xap);\r
-INLINE int  FeedCDDA(unsigned char *pcm, int nBytes);\r
-\r
-#endif /* __P_XA_H__ */\r