spu: save/restore decode_pos
[pcsx_rearmed.git] / plugins / dfsound / spu.c
index 8681d35..b0b083d 100644 (file)
@@ -35,7 +35,7 @@
 #include "arm_features.h"
 #endif
 
-#ifdef __ARM_ARCH_7A__
+#ifdef HAVE_ARMV7
  #define ssat32_to_16(v) \
   asm("ssat %0,#16,%1" : "=r" (v) : "r" (v))
 #else
@@ -247,6 +247,8 @@ static void StartSoundMain(int ch)
  s_chan->iSBPos=27;
  s_chan->spos=0;
 
+ s_chan->pCurr = spu.spuMemC+((regAreaGet(ch,6)&~1)<<3);
+
  spu.dwNewChannel&=~(1<<ch);                           // clear new channel bit
  spu.dwChannelOn|=1<<ch;
  spu.dwChannelDead&=~(1<<ch);
@@ -433,7 +435,7 @@ static int decode_block(void *unused, int ch, int *SB)
  decode_block_data(SB, start + 2, predict_nr, shift_factor);
 
  flags = start[1];
- if (flags & 4)
+ if (flags & 4 && (!s_chan->bIgnoreLoop))
   s_chan->pLoop = start;                   // loop adress
 
  start += 16;
@@ -818,12 +820,8 @@ static void do_channels(int ns_to)
   }
 
   if (spu.rvb->StartAddr) {
-   if (do_rvb) {
-    if (unlikely(spu.rvb->dirty))
-     REVERBPrep();
-
+   if (do_rvb)
     REVERBDo(spu.SSumLR, RVB, ns_to, spu.rvb->CurrAddr);
-   }
 
    spu.rvb->CurrAddr += ns_to / 2;
    while (spu.rvb->CurrAddr >= 0x40000)
@@ -846,6 +844,7 @@ static struct spu_worker {
    unsigned int i_ready;
    unsigned int i_reaped;
    unsigned int last_boot_cnt; // dsp
+   unsigned int ram_dirty;
   };
   // aligning for C64X_DSP
   unsigned int _pad0[128/4];
@@ -970,11 +969,8 @@ static void queue_channel_work(int ns_to, unsigned int silentch)
 
  work->rvb_addr = 0;
  if (spu.rvb->StartAddr) {
-  if (spu_config.iUseReverb) {
-   if (unlikely(spu.rvb->dirty))
-    REVERBPrep();
+  if (spu_config.iUseReverb)
    work->rvb_addr = spu.rvb->CurrAddr;
-  }
 
   spu.rvb->CurrAddr += ns_to / 2;
   while (spu.rvb->CurrAddr >= 0x40000)
@@ -989,9 +985,9 @@ static void do_channel_work(struct work_item *work)
 {
  unsigned int mask;
  unsigned int decode_dirty_ch = 0;
+ const SPUCHAN *s_chan;
  int *SB, sinc, spos, sbpos;
  int d, ch, ns_to;
- SPUCHAN *s_chan;
 
  ns_to = work->ns_to;
 
@@ -1057,8 +1053,12 @@ static void sync_worker_thread(int force)
  struct work_item *work;
  int done, used_space;
 
+ // rvb offsets will change, thread may be using them
+ force |= spu.rvb->dirty && spu.rvb->StartAddr;
+
  done = thread_get_i_done() - worker->i_reaped;
  used_space = worker->i_ready - worker->i_reaped;
+
  //printf("done: %d use: %d dsp: %u/%u\n", done, used_space,
  //  worker->boot_cnt, worker->i_done);
 
@@ -1150,6 +1150,9 @@ void do_samples(unsigned int cycles_to, int do_direct)
      }
    }
 
+  if (unlikely(spu.rvb->dirty))
+   REVERBPrep();
+
   if (do_direct || worker == NULL || !spu_config.iUseThread) {
    do_channels(ns_to);
    do_samples_finish(spu.SSumLR, ns_to, silentch, spu.decode_pos);
@@ -1252,7 +1255,7 @@ void schedule_next_irq(void)
 
 void CALLBACK SPUasync(unsigned int cycle, unsigned int flags)
 {
- do_samples(cycle, 0);
+ do_samples(cycle, spu_config.iUseFixedUpdates);
 
  if (spu.spuCtrl & CTRL_IRQ)
   schedule_next_irq();
@@ -1315,14 +1318,12 @@ static void SetupStreams(void)
  spu.pSpuBuffer = (unsigned char *)malloc(32768);      // alloc mixing buffer
  spu.SSumLR = calloc(NSSIZE * 2, sizeof(spu.SSumLR[0]));
 
- spu.XAStart =                                         // alloc xa buffer
-  (uint32_t *)malloc(44100 * sizeof(uint32_t));
+ spu.XAStart = malloc(44100 * sizeof(uint32_t));       // alloc xa buffer
  spu.XAEnd   = spu.XAStart + 44100;
  spu.XAPlay  = spu.XAStart;
  spu.XAFeed  = spu.XAStart;
 
- spu.CDDAStart =                                       // alloc cdda buffer
-  (uint32_t *)malloc(CDDA_BUFFER_SIZE);
+ spu.CDDAStart = malloc(CDDA_BUFFER_SIZE);             // alloc cdda buffer
  spu.CDDAEnd   = spu.CDDAStart + 16384;
  spu.CDDAPlay  = spu.CDDAStart;
  spu.CDDAFeed  = spu.CDDAStart;
@@ -1488,6 +1489,7 @@ long CALLBACK SPUinit(void)
    spu.s_chan[i].ADSRX.SustainIncrease = 1;
    spu.s_chan[i].pLoop = spu.spuMemC;
    spu.s_chan[i].pCurr = spu.spuMemC;
+   spu.s_chan[i].bIgnoreLoop = 0;
   }
 
  spu.bSpuInit=1;                                       // flag: we are inited
@@ -1576,7 +1578,7 @@ void CALLBACK SPUregisterCallback(void (CALLBACK *callback)(void))
  spu.irqCallback = callback;
 }
 
-void CALLBACK SPUregisterCDDAVolume(void (CALLBACK *CDDAVcallback)(unsigned short,unsigned short))
+void CALLBACK SPUregisterCDDAVolume(void (CALLBACK *CDDAVcallback)(short, short))
 {
  spu.cddavCallback = CDDAVcallback;
 }