cdrom: change pause timing again
[pcsx_rearmed.git] / plugins / dfsound / adsr.c
index a86f461..23ff3df 100644 (file)
@@ -57,15 +57,15 @@ void InitADSR(void)                                    // INIT ADSR
 \r
 INLINE void StartADSR(int ch)                          // MIX ADSR\r
 {\r
- s_chan[ch].ADSRX.State=ADSR_ATTACK;                   // and init some adsr vars\r
- s_chan[ch].ADSRX.EnvelopeVol=0;\r
+ spu.s_chan[ch].ADSRX.State = ADSR_ATTACK;             // and init some adsr vars\r
+ spu.s_chan[ch].ADSRX.EnvelopeVol = 0;\r
 }\r
 \r
 ////////////////////////////////////////////////////////////////////////\r
 \r
-static int MixADSR(ADSRInfoEx *adsr, int ns_to)\r
+static int MixADSR(int *samples, ADSRInfoEx *adsr, int ns_to)\r
 {\r
- int EnvelopeVol = adsr->EnvelopeVol;\r
unsigned int EnvelopeVol = adsr->EnvelopeVol;\r
  int ns = 0, val, rto, level;\r
 \r
  if (adsr->State == ADSR_RELEASE)\r
@@ -77,11 +77,11 @@ static int MixADSR(ADSRInfoEx *adsr, int ns_to)
      for (; ns < ns_to; ns++)\r
      {\r
        EnvelopeVol += ((long long)val * EnvelopeVol) >> (15+16);\r
-       if (EnvelopeVol <= 0)\r
+       if ((signed int)EnvelopeVol <= 0)\r
          break;\r
 \r
-       ChanBuf[ns] *= EnvelopeVol >> 21;\r
-       ChanBuf[ns] >>= 10;\r
+       samples[ns] *= (signed int)EnvelopeVol >> 21;\r
+       samples[ns] >>= 10;\r
      }\r
    }\r
    else\r
@@ -89,11 +89,11 @@ static int MixADSR(ADSRInfoEx *adsr, int ns_to)
      for (; ns < ns_to; ns++)\r
      {\r
        EnvelopeVol += val;\r
-       if (EnvelopeVol <= 0)\r
+       if ((signed int)EnvelopeVol <= 0)\r
          break;\r
 \r
-       ChanBuf[ns] *= EnvelopeVol >> 21;\r
-       ChanBuf[ns] >>= 10;\r
+       samples[ns] *= (signed int)EnvelopeVol >> 21;\r
+       samples[ns] >>= 10;\r
      }\r
    }\r
 \r
@@ -111,14 +111,14 @@ static int MixADSR(ADSRInfoEx *adsr, int ns_to)
      for (; ns < ns_to; ns++)\r
      {\r
        EnvelopeVol += val;\r
-       if (EnvelopeVol < 0)\r
+       if ((signed int)EnvelopeVol < 0) // overflow\r
         break;\r
 \r
-       ChanBuf[ns] *= EnvelopeVol >> 21;\r
-       ChanBuf[ns] >>= 10;\r
+       samples[ns] *= (signed int)EnvelopeVol >> 21;\r
+       samples[ns] >>= 10;\r
      }\r
 \r
-     if (EnvelopeVol < 0) // overflow\r
+     if ((signed int)EnvelopeVol < 0) // overflow\r
      {\r
        EnvelopeVol = 0x7fffffff;\r
        adsr->State = ADSR_DECAY;\r
@@ -136,11 +136,11 @@ static int MixADSR(ADSRInfoEx *adsr, int ns_to)
      for (; ns < ns_to; )\r
      {\r
        EnvelopeVol += ((long long)val * EnvelopeVol) >> (15+16);\r
-       if (EnvelopeVol < 0)\r
+       if ((signed int)EnvelopeVol < 0)\r
          EnvelopeVol = 0;\r
 \r
-       ChanBuf[ns] *= EnvelopeVol >> 21;\r
-       ChanBuf[ns] >>= 10;\r
+       samples[ns] *= EnvelopeVol >> 21;\r
+       samples[ns] >>= 10;\r
        ns++;\r
 \r
        if (((EnvelopeVol >> 27) & 0xf) <= level)\r
@@ -170,15 +170,15 @@ static int MixADSR(ADSRInfoEx *adsr, int ns_to)
        for (; ns < ns_to; ns++)\r
        {\r
          EnvelopeVol += val;\r
-         if ((unsigned int)EnvelopeVol >= 0x7fe00000)\r
+         if (EnvelopeVol >= 0x7fe00000)\r
          {\r
            EnvelopeVol = 0x7fffffff;\r
            ns = ns_to;\r
            break;\r
          }\r
 \r
-         ChanBuf[ns] *= EnvelopeVol >> 21;\r
-         ChanBuf[ns] >>= 10;\r
+         samples[ns] *= (signed int)EnvelopeVol >> 21;\r
+         samples[ns] >>= 10;\r
        }\r
      }\r
      else\r
@@ -189,11 +189,11 @@ static int MixADSR(ADSRInfoEx *adsr, int ns_to)
          for (; ns < ns_to; ns++)\r
          {\r
            EnvelopeVol += ((long long)val * EnvelopeVol) >> (15+16);\r
-           if (EnvelopeVol < 0) \r
+           if ((signed int)EnvelopeVol < 0)\r
              break;\r
 \r
-           ChanBuf[ns] *= EnvelopeVol >> 21;\r
-           ChanBuf[ns] >>= 10;\r
+           samples[ns] *= (signed int)EnvelopeVol >> 21;\r
+           samples[ns] >>= 10;\r
          }\r
        }\r
        else\r
@@ -201,11 +201,11 @@ static int MixADSR(ADSRInfoEx *adsr, int ns_to)
          for (; ns < ns_to; ns++)\r
          {\r
            EnvelopeVol += val;\r
-           if (EnvelopeVol < 0) \r
+           if ((signed int)EnvelopeVol < 0)\r
              break;\r
 \r
-           ChanBuf[ns] *= EnvelopeVol >> 21;\r
-           ChanBuf[ns] >>= 10;\r
+           samples[ns] *= (signed int)EnvelopeVol >> 21;\r
+           samples[ns] >>= 10;\r
          }\r
        }\r
      }\r
@@ -217,6 +217,130 @@ done:
  return ns;\r
 }\r
 \r
+static int SkipADSR(ADSRInfoEx *adsr, int ns_to)\r
+{\r
+ unsigned int EnvelopeVol = adsr->EnvelopeVol;\r
+ int ns = 0, val, rto, level;\r
+ int64_t v64;\r
+\r
+ if (adsr->State == ADSR_RELEASE)\r
+ {\r
+   val = RateTableSub[adsr->ReleaseRate * 4];\r
+   if (adsr->ReleaseModeExp)\r
+   {\r
+     for (; ns < ns_to; ns++)\r
+     {\r
+       EnvelopeVol += ((long long)val * EnvelopeVol) >> (15+16);\r
+       if ((signed int)EnvelopeVol <= 0)\r
+         break;\r
+     }\r
+   }\r
+   else\r
+   {\r
+     v64 = EnvelopeVol;\r
+     v64 += (int64_t)val * ns_to;\r
+     EnvelopeVol = (int)v64;\r
+     if (v64 > 0)\r
+       ns = ns_to;\r
+   }\r
+   goto done;\r
+ }\r
+\r
+ switch (adsr->State)\r
+ {\r
+   case ADSR_ATTACK:                                   // -> attack\r
+     rto = 0;\r
+     if (adsr->AttackModeExp && EnvelopeVol >= 0x60000000)\r
+       rto = 8;\r
+     val = RateTableAdd[adsr->AttackRate + rto];\r
+\r
+     for (; ns < ns_to; ns++)\r
+     {\r
+       EnvelopeVol += val;\r
+       if ((signed int)EnvelopeVol < 0)\r
+        break;\r
+     }\r
+     if ((signed int)EnvelopeVol < 0) // overflow\r
+     {\r
+       EnvelopeVol = 0x7fffffff;\r
+       adsr->State = ADSR_DECAY;\r
+       ns++;\r
+       goto decay;\r
+     }\r
+     break;\r
+\r
+   //--------------------------------------------------//\r
+   decay:\r
+   case ADSR_DECAY:                                    // -> decay\r
+     val = RateTableSub[adsr->DecayRate * 4];\r
+     level = adsr->SustainLevel;\r
+\r
+     for (; ns < ns_to; )\r
+     {\r
+       EnvelopeVol += ((long long)val * EnvelopeVol) >> (15+16);\r
+       if ((signed int)EnvelopeVol < 0)\r
+         EnvelopeVol = 0;\r
+\r
+       ns++;\r
+\r
+       if (((EnvelopeVol >> 27) & 0xf) <= level)\r
+       {\r
+         adsr->State = ADSR_SUSTAIN;\r
+         goto sustain;\r
+       }\r
+     }\r
+     break;\r
+\r
+   //--------------------------------------------------//\r
+   sustain:\r
+   case ADSR_SUSTAIN:                                  // -> sustain\r
+     if (adsr->SustainIncrease)\r
+     {\r
+       ns = ns_to;\r
+\r
+       if (EnvelopeVol >= 0x7fff0000)\r
+         break;\r
+\r
+       rto = 0;\r
+       if (adsr->SustainModeExp && EnvelopeVol >= 0x60000000)\r
+         rto = 8;\r
+       val = RateTableAdd[adsr->SustainRate + rto];\r
+\r
+       v64 = EnvelopeVol;\r
+       v64 += (int64_t)val * (ns_to - ns);\r
+       EnvelopeVol = (int)v64;\r
+       if (v64 >= 0x7fe00000ll)\r
+         EnvelopeVol = 0x7fffffff;\r
+     }\r
+     else\r
+     {\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 ((signed int)EnvelopeVol < 0)\r
+             break;\r
+         }\r
+       }\r
+       else\r
+       {\r
+         v64 = EnvelopeVol;\r
+         v64 += (int64_t)val * (ns_to - ns);\r
+         EnvelopeVol = (int)v64;\r
+         if (v64 > 0)\r
+           ns = ns_to;\r
+       }\r
+     }\r
+     break;\r
+ }\r
+\r
+done:\r
+ adsr->EnvelopeVol = EnvelopeVol;\r
+ return ns;\r
+}\r
+\r
 #endif\r
 \r
 /*\r