spu: drop unused mono code
[pcsx_rearmed.git] / plugins / dfsound / spu.c
index 7e6cfb2..dc0f584 100644 (file)
@@ -34,6 +34,7 @@
 #define N_(x) (x)
 #endif
 
+/*
 #if defined (USEMACOSX)
 static char * libraryName     = N_("Mac OS X Sound");
 #elif defined (USEALSA)
@@ -49,6 +50,7 @@ static char * libraryName     = N_("NULL Sound");
 #endif
 
 static char * libraryInfo     = N_("P.E.Op.S. Sound Driver V1.7\nCoded by Pete Bernert and the P.E.Op.S. team\n");
+*/
 
 // globals
 
@@ -71,7 +73,6 @@ int             iDebugMode=0;
 int             iRecordMode=0;
 int             iUseReverb=2;
 int             iUseInterpolation=2;
-int             iDisStereo=0;
 
 // MAIN infos struct for each channel
 
@@ -93,19 +94,19 @@ int             bSPUIsOpen=0;
 static pthread_t thread = (pthread_t)-1;               // thread id (linux)
 
 unsigned long dwNewChannel=0;                          // flags for faster testing, if new channel starts
+unsigned long dwChannelOn=0;
 
 void (CALLBACK *irqCallback)(void)=0;                  // func of main emu, called on spu irq
 void (CALLBACK *cddavCallback)(unsigned short,unsigned short)=0;
 
 // certain globals (were local before, but with the new timeproc I need em global)
 
-static const int f[5][2] = {   {    0,  0  },
+static const int f[8][2] = {   {    0,  0  },
                         {   60,  0  },
                         {  115, -52 },
                         {   98, -55 },
                         {  122, -60 } };
-int SSumR[NSSIZE];
-int SSumL[NSSIZE];
+int SSumLR[NSSIZE*2];
 int iFMod[NSSIZE];
 int iCycle = 0;
 short * pS;
@@ -245,16 +246,15 @@ INLINE void StartSound(int ch)
  StartADSR(ch);
  StartREVERB(ch);
 
- s_chan[ch].pCurr=s_chan[ch].pStart;                   // set sample start
+ // fussy timing issues - do in VoiceOn
+ //s_chan[ch].pCurr=s_chan[ch].pStart;                   // set sample start
+ //s_chan[ch].bStop=0;
+ //s_chan[ch].bOn=1;
 
  s_chan[ch].s_1=0;                                     // init mixing vars
  s_chan[ch].s_2=0;
  s_chan[ch].iSBPos=28;
 
- s_chan[ch].bNew=0;                                    // init channel flags
- s_chan[ch].bStop=0;
- s_chan[ch].bOn=1;
-
  s_chan[ch].SB[29]=0;                                  // init our interpolation helpers
  s_chan[ch].SB[30]=0;
 
@@ -440,7 +440,7 @@ INLINE int iGetInterpolationVal(int ch)
 
 static void *MAINThread(void *arg)
 {
- int s_1,s_2,fa,ns;
+ int s_1,s_2,fa,ns,ns_from,ns_to;
 #if !defined(_MACOSX) && !defined(__arm__)
  int voldiv = iVolume;
 #else
@@ -479,27 +479,30 @@ static void *MAINThread(void *arg)
 
    //--------------------------------------------------// continue from irq handling in timer mode? 
 
+   ns_from=0;
+   ns_to=NSSIZE;
+   ch=0;
    if(lastch>=0)                                       // will be -1 if no continue is pending
     {
-     ch=lastch; ns=lastns; lastch=-1;                  // -> setup all kind of vars to continue
-     goto GOON;                                        // -> directly jump to the continue point
+     ch=lastch; ns_from=lastns+1; lastch=-1;           // -> setup all kind of vars to continue
     }
 
    //--------------------------------------------------//
    //- main channel loop                              -// 
    //--------------------------------------------------//
     {
-     for(ch=0;ch<MAXCHAN;ch++)                         // loop em all... we will collect 1 ms of sound of each playing channel
+     for(;ch<MAXCHAN;ch++)                             // loop em all... we will collect 1 ms of sound of each playing channel
       {
-       if(s_chan[ch].bNew) StartSound(ch);             // start new sound
-       if(!s_chan[ch].bOn) continue;                   // channel not playing? next
+       if(dwNewChannel&(1<<ch)) StartSound(ch);        // start new sound
+       if(!(dwChannelOn&(1<<ch))) continue;            // channel not playing? next
 
        if(s_chan[ch].iActFreq!=s_chan[ch].iUsedFreq)   // new psx frequency?
         VoiceChangeFrequency(ch);
 
-       ns=0;
-       while(ns<NSSIZE)                                // loop until 1 ms of data is reached
+       for(ns=ns_from;ns<ns_to;ns++)                   // loop until 1 ms of data is reached
         {
+         int sval;
+
          if(s_chan[ch].bFMod==1 && iFMod[ns])          // fmod freq channel
           FModChangeFrequency(ch,ns);
 
@@ -511,8 +514,7 @@ static void *MAINThread(void *arg)
 
              if (start == (unsigned char*)-1)          // special "stop" sign
               {
-               s_chan[ch].bOn=0;                       // -> turn everything off
-               s_chan[ch].ADSRX.lVolume=0;
+               dwChannelOn&=~(1<<ch);                  // -> turn everything off
                s_chan[ch].ADSRX.EnvelopeVol=0;
                goto ENDX;                              // -> and done for this channel
               }
@@ -562,13 +564,15 @@ static void *MAINThread(void *arg)
                    (pSpuIrq >  s_chan[ch].pLoop-16 &&
                     pSpuIrq <= s_chan[ch].pLoop)))
                {
-                 s_chan[ch].iIrqDone=1;                // -> debug flag
                  irqCallback();                        // -> call main emu
 
                  if(iSPUIRQWait)                       // -> option: wait after irq for main emu
                   {
                    iSpuAsyncWait=1;
                    bIRQReturn=1;
+                   lastch=ch; 
+                   lastns=ns;
+                   ns_to=ns+1;
                   }
                 }
               }
@@ -595,28 +599,6 @@ static void *MAINThread(void *arg)
              s_chan[ch].pCurr=start;                   // store values for next cycle
              s_chan[ch].s_1=s_1;
              s_chan[ch].s_2=s_2;
-
-             if(bIRQReturn)                            // special return for "spu irq - wait for cpu action"
-              {
-               bIRQReturn=0;
-               if(iUseTimer!=2)
-                { 
-                 DWORD dwWatchTime=timeGetTime_spu()+2500;
-
-                 while(iSpuAsyncWait && !bEndThread && 
-                       timeGetTime_spu()<dwWatchTime)
-                     usleep(1000L);
-                }
-               else
-                {
-                 lastch=ch; 
-                 lastns=ns;
-
-                 return 0;
-                }
-              }
-
-GOON: ;
             }
 
            fa=s_chan[ch].SB[s_chan[ch].iSBPos++];      // get sample data
@@ -630,40 +612,52 @@ GOON: ;
               fa=iGetNoiseVal(ch);                     // get noise val
          else fa=iGetInterpolationVal(ch);             // get sample val
 
-         s_chan[ch].sval = (MixADSR(ch) * fa) / 1023;  // mix adsr
+         sval = (MixADSR(ch) * fa) / 1023;  // mix adsr
 
          if(s_chan[ch].bFMod==2)                       // fmod freq channel
-          iFMod[ns]=s_chan[ch].sval;                   // -> store 1T sample data, use that to do fmod on next channel
+          iFMod[ns]=sval;                              // -> store 1T sample data, use that to do fmod on next channel
          else                                          // no fmod freq channel
           {
            //////////////////////////////////////////////
            // ok, left/right sound volume (psx volume goes from 0 ... 0x3fff)
 
-           if(s_chan[ch].iMute) 
-            s_chan[ch].sval=0;                         // debug mute
-           else
-            {
-             SSumL[ns]+=(s_chan[ch].sval*s_chan[ch].iLeftVolume)/0x4000L;
-             SSumR[ns]+=(s_chan[ch].sval*s_chan[ch].iRightVolume)/0x4000L;
-            }
+           SSumLR[ns*2]  +=(sval*s_chan[ch].iLeftVolume)/0x4000L;
+           SSumLR[ns*2+1]+=(sval*s_chan[ch].iRightVolume)/0x4000L;
 
            //////////////////////////////////////////////
            // now let us store sound data for reverb    
 
-           if(s_chan[ch].bRVBActive) StoreREVERB(ch,ns);
+           if(s_chan[ch].bRVBActive) StoreREVERB(ch,ns,sval);
           }
 
          ////////////////////////////////////////////////
          // ok, go on until 1 ms data of this channel is collected
 
-         ns++;
          s_chan[ch].spos += s_chan[ch].sinc;
-
         }
 ENDX:   ;
       }
     }
 
+    if(bIRQReturn)                            // special return for "spu irq - wait for cpu action"
+     {
+      bIRQReturn=0;
+      if(iUseTimer!=2)
+       { 
+        DWORD dwWatchTime=timeGetTime_spu()+2500;
+
+        while(iSpuAsyncWait && !bEndThread && 
+              timeGetTime_spu()<dwWatchTime)
+            usleep(1000L);
+       continue;
+       }
+      else
+       {
+        return 0;
+       }
+     }
+
+
   //---------------------------------------------------//
   //- here we have another 1 ms of sound data
   //---------------------------------------------------//
@@ -674,37 +668,21 @@ ENDX:   ;
   ///////////////////////////////////////////////////////
   // mix all channels (including reverb) into one buffer
 
-  if(iDisStereo)                                       // no stereo?
-   {
-    int dl, dr;
-    for (ns = 0; ns < NSSIZE; ns++)
-     {
-      SSumL[ns] += MixREVERBLeft(ns);
-
-      dl = SSumL[ns] / voldiv; SSumL[ns] = 0;
-      if (dl < -32767) dl = -32767; if (dl > 32767) dl = 32767;
-
-      SSumR[ns] += MixREVERBRight();
-
-      dr = SSumR[ns] / voldiv; SSumR[ns] = 0;
-      if (dr < -32767) dr = -32767; if (dr > 32767) dr = 32767;
-      *pS++ = (dl + dr) / 2;
-     }
-   }
-  else                                                 // stereo:
-  for (ns = 0; ns < NSSIZE; ns++)
+  for (ns = 0; ns < NSSIZE*2; )
    {
-    SSumL[ns] += MixREVERBLeft(ns);
+    SSumLR[ns] += MixREVERBLeft(ns/2);
 
-    d = SSumL[ns] / voldiv; SSumL[ns] = 0;
+    d = SSumLR[ns] / voldiv; SSumLR[ns] = 0;
     if (d < -32767) d = -32767; if (d > 32767) d = 32767;
     *pS++ = d;
+    ns++;
 
-    SSumR[ns] += MixREVERBRight();
+    SSumLR[ns] += MixREVERBRight();
 
-    d = SSumR[ns] / voldiv; SSumR[ns] = 0;
+    d = SSumLR[ns] / voldiv; SSumLR[ns] = 0;
     if(d < -32767) d = -32767; if(d > 32767) d = 32767;
     *pS++ = d;
+    ns++;
    }
 
   //////////////////////////////////////////////////////                   
@@ -734,7 +712,7 @@ ENDX:   ;
         for(ch=0;ch<4;ch++)
          {
           if(pSpuIrq>=pMixIrq+(ch*0x400) && pSpuIrq<pMixIrq+(ch*0x400)+2)
-           {irqCallback();s_chan[ch].iIrqDone=1;}
+           irqCallback();
          }
        }
       pMixIrq+=2;if(pMixIrq>spuMemC+0x3ff) pMixIrq=spuMemC;
@@ -769,7 +747,7 @@ void CALLBACK SPUasync(unsigned long cycle)
  if(iSpuAsyncWait)
   {
    iSpuAsyncWait++;
-   if(iSpuAsyncWait<=64) return;
+   if(iSpuAsyncWait<=16) return;
    iSpuAsyncWait=0;
   }
 
@@ -778,6 +756,11 @@ void CALLBACK SPUasync(unsigned long cycle)
    if(!bSpuInit) return;                               // -> no init, no call
 
    MAINThread(0);                                      // -> linux high-compat mode
+
+   // abuse iSpuAsyncWait mechanism to reduce calls to above function
+   // to make it do larger chunks
+   // note: doing it less often than once per frame causes skips
+   iSpuAsyncWait=1;
   }
 }
 
@@ -817,8 +800,7 @@ void CALLBACK SPUplayCDDAchannel(short *pcm, int nbytes)
 // SETUPTIMER: init of certain buffers and threads/timers
 void SetupTimer(void)
 {
- memset(SSumR,0,NSSIZE*sizeof(int));                   // init some mixing buffers
- memset(SSumL,0,NSSIZE*sizeof(int));
+ memset(SSumLR,0,sizeof(SSumLR));                      // init some mixing buffers
  memset(iFMod,0,NSSIZE*sizeof(int));
  pS=(short *)pSpuBuffer;                               // setup soundbuffer pointer
 
@@ -880,9 +862,7 @@ void SetupStreams(void)
 // we don't use mutex sync... not needed, would only 
 // slow us down:
 //   s_chan[i].hMutex=CreateMutex(NULL,FALSE,NULL);
-   s_chan[i].ADSRX.SustainLevel = 1024;                // -> init sustain
-   s_chan[i].iMute=0;
-   s_chan[i].iIrqDone=0;
+   s_chan[i].ADSRX.SustainLevel = 0xf;                 // -> init sustain
    s_chan[i].pLoop=spuMemC;
    s_chan[i].pStart=spuMemC;
    s_chan[i].pCurr=spuMemC;
@@ -923,7 +903,7 @@ long CALLBACK SPUinit(void)
  pMixIrq = 0;
  memset((void *)s_chan, 0, (MAXCHAN + 1) * sizeof(SPUCHAN));
  pSpuIrq = 0;
- iSPUIRQWait = 0;
//iSPUIRQWait = 0;
  lastch = -1;
 
  //ReadConfigSPU();                                      // read user stuff
@@ -1029,3 +1009,5 @@ char * SPUgetLibInfos(void)
  return _(libraryInfo);
 }
 */
+
+// vim:shiftwidth=1:expandtab