spu: get rid of bStop, clean up
[pcsx_rearmed.git] / plugins / dfsound / adsr.c
index e4873df..a86f461 100644 (file)
@@ -46,6 +46,10 @@ void InitADSR(void)                                    // INIT ADSR
 \r
   RateTableAdd[lcv] = ((7 - (lcv&3)) << 16) / denom;\r
   RateTableSub[lcv] = ((-8 + (lcv&3)) << 16) / denom;\r
+\r
+  // XXX: this is wrong, we need more bits..\r
+  if (RateTableAdd[lcv] == 0)\r
+    RateTableAdd[lcv] = 1;\r
  }\r
 }\r
 \r
@@ -53,26 +57,27 @@ void InitADSR(void)                                    // INIT ADSR
 \r
 INLINE void StartADSR(int ch)                          // MIX ADSR\r
 {\r
- s_chan[ch].ADSRX.State=0;                             // and init some adsr vars\r
+ s_chan[ch].ADSRX.State=ADSR_ATTACK;                   // and init some adsr vars\r
  s_chan[ch].ADSRX.EnvelopeVol=0;\r
 }\r
 \r
 ////////////////////////////////////////////////////////////////////////\r
 \r
-static void MixADSR(int ch, int ns, int ns_to)         // MIX ADSR\r
+static int MixADSR(ADSRInfoEx *adsr, int ns_to)\r
 {\r
- int EnvelopeVol = s_chan[ch].ADSRX.EnvelopeVol;\r
- int val, rto, level;\r
+ int EnvelopeVol = adsr->EnvelopeVol;\r
+ int ns = 0, val, rto, level;\r
+\r
+ if (adsr->State == ADSR_RELEASE)\r
+ {\r
+   val = RateTableSub[adsr->ReleaseRate * 4];\r
 \r
- if (s_chan[ch].bStop)                                 // should be stopped:\r
- {                                                     // do release\r
-   val = RateTableSub[s_chan[ch].ADSRX.ReleaseRate * 4];\r
-   if (s_chan[ch].ADSRX.ReleaseModeExp)\r
+   if (adsr->ReleaseModeExp)\r
    {\r
      for (; ns < ns_to; ns++)\r
      {\r
        EnvelopeVol += ((long long)val * EnvelopeVol) >> (15+16);\r
-       if (EnvelopeVol < 0)\r
+       if (EnvelopeVol <= 0)\r
          break;\r
 \r
        ChanBuf[ns] *= EnvelopeVol >> 21;\r
@@ -84,7 +89,7 @@ static void MixADSR(int ch, int ns, int ns_to)         // MIX ADSR
      for (; ns < ns_to; ns++)\r
      {\r
        EnvelopeVol += val;\r
-       if (EnvelopeVol < 0)\r
+       if (EnvelopeVol <= 0)\r
          break;\r
 \r
        ChanBuf[ns] *= EnvelopeVol >> 21;\r
@@ -92,19 +97,16 @@ static void MixADSR(int ch, int ns, int ns_to)         // MIX ADSR
      }\r
    }\r
 \r
-   if (EnvelopeVol < 0)\r
-     goto stop;\r
-\r
    goto done;\r
  }\r
 \r
- switch (s_chan[ch].ADSRX.State)\r
+ switch (adsr->State)\r
  {\r
-   case 0:                                             // -> attack\r
+   case ADSR_ATTACK:                                   // -> attack\r
      rto = 0;\r
-     if (s_chan[ch].ADSRX.AttackModeExp && EnvelopeVol >= 0x60000000)\r
+     if (adsr->AttackModeExp && EnvelopeVol >= 0x60000000)\r
        rto = 8;\r
-     val = RateTableAdd[s_chan[ch].ADSRX.AttackRate + rto];\r
+     val = RateTableAdd[adsr->AttackRate + rto];\r
 \r
      for (; ns < ns_to; ns++)\r
      {\r
@@ -119,7 +121,7 @@ static void MixADSR(int ch, int ns, int ns_to)         // MIX ADSR
      if (EnvelopeVol < 0) // overflow\r
      {\r
        EnvelopeVol = 0x7fffffff;\r
-       s_chan[ch].ADSRX.State = 1;\r
+       adsr->State = ADSR_DECAY;\r
        ns++; // sample is good already\r
        goto decay;\r
      }\r
@@ -127,9 +129,9 @@ static void MixADSR(int ch, int ns, int ns_to)         // MIX ADSR
 \r
    //--------------------------------------------------//\r
    decay:\r
-   case 1:                                             // -> decay\r
-     val = RateTableSub[s_chan[ch].ADSRX.DecayRate * 4];\r
-     level = s_chan[ch].ADSRX.SustainLevel;\r
+   case ADSR_DECAY:                                    // -> decay\r
+     val = RateTableSub[adsr->DecayRate * 4];\r
+     level = adsr->SustainLevel;\r
 \r
      for (; ns < ns_to; )\r
      {\r
@@ -143,7 +145,7 @@ static void MixADSR(int ch, int ns, int ns_to)         // MIX ADSR
 \r
        if (((EnvelopeVol >> 27) & 0xf) <= level)\r
        {\r
-         s_chan[ch].ADSRX.State = 2;\r
+         adsr->State = ADSR_SUSTAIN;\r
          goto sustain;\r
        }\r
      }\r
@@ -151,16 +153,19 @@ static void MixADSR(int ch, int ns, int ns_to)         // MIX ADSR
 \r
    //--------------------------------------------------//\r
    sustain:\r
-   case 2:                                             // -> sustain\r
-     if (s_chan[ch].ADSRX.SustainIncrease)\r
+   case ADSR_SUSTAIN:                                  // -> sustain\r
+     if (adsr->SustainIncrease)\r
      {\r
        if (EnvelopeVol >= 0x7fff0000)\r
+       {\r
+         ns = ns_to;\r
          break;\r
+       }\r
 \r
        rto = 0;\r
-       if (s_chan[ch].ADSRX.SustainModeExp && EnvelopeVol >= 0x60000000)\r
+       if (adsr->SustainModeExp && EnvelopeVol >= 0x60000000)\r
          rto = 8;\r
-       val = RateTableAdd[s_chan[ch].ADSRX.SustainRate + rto];\r
+       val = RateTableAdd[adsr->SustainRate + rto];\r
 \r
        for (; ns < ns_to; ns++)\r
        {\r
@@ -168,6 +173,7 @@ static void MixADSR(int ch, int ns, int ns_to)         // MIX ADSR
          if ((unsigned int)EnvelopeVol >= 0x7fe00000)\r
          {\r
            EnvelopeVol = 0x7fffffff;\r
+           ns = ns_to;\r
            break;\r
          }\r
 \r
@@ -177,14 +183,14 @@ static void MixADSR(int ch, int ns, int ns_to)         // MIX ADSR
      }\r
      else\r
      {\r
-       val = RateTableSub[s_chan[ch].ADSRX.SustainRate];\r
-       if (s_chan[ch].ADSRX.SustainModeExp)\r
+       val = RateTableSub[adsr->SustainRate];\r
+       if (adsr->SustainModeExp)\r
        {\r
          for (; ns < ns_to; ns++)\r
          {\r
            EnvelopeVol += ((long long)val * EnvelopeVol) >> (15+16);\r
            if (EnvelopeVol < 0) \r
-             goto stop;\r
+             break;\r
 \r
            ChanBuf[ns] *= EnvelopeVol >> 21;\r
            ChanBuf[ns] >>= 10;\r
@@ -196,7 +202,7 @@ static void MixADSR(int ch, int ns, int ns_to)         // MIX ADSR
          {\r
            EnvelopeVol += val;\r
            if (EnvelopeVol < 0) \r
-             goto stop;\r
+             break;\r
 \r
            ChanBuf[ns] *= EnvelopeVol >> 21;\r
            ChanBuf[ns] >>= 10;\r
@@ -207,13 +213,8 @@ static void MixADSR(int ch, int ns, int ns_to)         // MIX ADSR
  }\r
 \r
 done:\r
- s_chan[ch].ADSRX.EnvelopeVol = EnvelopeVol;\r
- return;\r
-\r
-stop:\r
- memset(&ChanBuf[ns], 0, (ns_to - ns) * sizeof(ChanBuf[0]));\r
- s_chan[ch].ADSRX.EnvelopeVol = 0;\r
- dwChannelOn &= ~(1<<ch);\r
+ adsr->EnvelopeVol = EnvelopeVol;\r
+ return ns;\r
 }\r
 \r
 #endif\r