spu: refactor adsr (simplify code)
authornotaz <notasas@gmail.com>
Mon, 28 Feb 2011 00:13:23 +0000 (02:13 +0200)
committernotaz <notasas@gmail.com>
Tue, 1 Mar 2011 15:35:10 +0000 (17:35 +0200)
plugins/dfsound/adsr.c

index 1e397af..47eccb3 100644 (file)
 // ADSR func\r
 ////////////////////////////////////////////////////////////////////////\r
 \r
-unsigned long RateTable[160];\r
+unsigned int RateTable[160];\r
 \r
 void InitADSR(void)                                    // INIT ADSR\r
 {\r
- unsigned long r,rs,rd;int i;\r
+ unsigned int r,rs,rd;int i;\r
 \r
  memset(RateTable,0,sizeof(unsigned long)*160);        // build the rate table according to Neill's rules (see at bottom of file)\r
 \r
@@ -61,26 +61,20 @@ INLINE void StartADSR(int ch)                          // MIX ADSR
 \r
 INLINE int MixADSR(int ch)                             // MIX ADSR\r
 {    \r
+ static const char ratetable_offset[8] = { 0, 4, 6, 8, 9, 10, 11, 12 };\r
+ int rto;\r
+\r
  if(s_chan[ch].bStop)                                  // should be stopped:\r
   {                                                    // do release\r
    if(s_chan[ch].ADSRX.ReleaseModeExp)\r
     {\r
-     switch((s_chan[ch].ADSRX.EnvelopeVol>>28)&0x7)\r
-      {\r
-       case 0: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +0 + 32]; break;\r
-       case 1: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +4 + 32]; break;\r
-       case 2: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +6 + 32]; break;\r
-       case 3: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +8 + 32]; break;\r
-       case 4: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +9 + 32]; break;\r
-       case 5: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +10+ 32]; break;\r
-       case 6: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +11+ 32]; break;\r
-       case 7: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 +12+ 32]; break;\r
-      }\r
+     rto=ratetable_offset[(s_chan[ch].ADSRX.EnvelopeVol>>28)&0x7];\r
     }\r
    else\r
     {\r
-     s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x0C + 32];\r
+     rto=12;\r
     }\r
+   s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18 + rto + 32];\r
 \r
    if(s_chan[ch].ADSRX.EnvelopeVol<0) \r
     {\r
@@ -93,107 +87,72 @@ INLINE int MixADSR(int ch)                             // MIX ADSR
      //s_chan[ch].bNoise=0;\r
     }\r
 \r
-   return s_chan[ch].ADSRX.EnvelopeVol>>21;\r
+   goto done;\r
   }\r
- else                                                  // not stopped yet?\r
-  {\r
-   if(s_chan[ch].ADSRX.State==0)                       // -> attack\r
-    {\r
-     if(s_chan[ch].ADSRX.AttackModeExp)\r
-      {\r
-       if(s_chan[ch].ADSRX.EnvelopeVol<0x60000000) \r
-        s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.AttackRate^0x7F)-0x10 + 32];\r
-       else\r
-        s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.AttackRate^0x7F)-0x18 + 32];\r
-      }\r
-     else\r
-      {\r
-       s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.AttackRate^0x7F)-0x10 + 32];\r
-      }\r
 \r
-     if(s_chan[ch].ADSRX.EnvelopeVol<0) \r
-      {\r
-       s_chan[ch].ADSRX.EnvelopeVol=0x7FFFFFFF;\r
-       s_chan[ch].ADSRX.State=1;\r
-      }\r
+  switch(s_chan[ch].ADSRX.State)                       // not stopped yet\r
+  {\r
+   case 0:                                             // -> attack\r
+    rto=8;\r
+    if(s_chan[ch].ADSRX.AttackModeExp&&s_chan[ch].ADSRX.EnvelopeVol>=0x60000000)\r
+     rto = 0;\r
+    s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.AttackRate^0x7F)-0x18 + rto + 32];\r
+\r
+    if(s_chan[ch].ADSRX.EnvelopeVol<0) \r
+     {\r
+      s_chan[ch].ADSRX.EnvelopeVol=0x7FFFFFFF;\r
+      s_chan[ch].ADSRX.State=1;\r
+     }\r
+    break;\r
 \r
-     return s_chan[ch].ADSRX.EnvelopeVol>>21;\r
-    }\r
    //--------------------------------------------------//\r
-   if(s_chan[ch].ADSRX.State==1)                       // -> decay\r
-    {\r
-     switch((s_chan[ch].ADSRX.EnvelopeVol>>28)&0x7)\r
-      {\r
-       case 0: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+0 + 32]; break;\r
-       case 1: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+4 + 32]; break;\r
-       case 2: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+6 + 32]; break;\r
-       case 3: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+8 + 32]; break;\r
-       case 4: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+9 + 32]; break;\r
-       case 5: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+10+ 32]; break;\r
-       case 6: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+11+ 32]; break;\r
-       case 7: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+12+ 32]; break;\r
-      }\r
+   case 1:                                             // -> decay\r
+    rto=ratetable_offset[(s_chan[ch].ADSRX.EnvelopeVol>>28)&0x7];\r
+    s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+ rto + 32];\r
 \r
-     if(s_chan[ch].ADSRX.EnvelopeVol<0) s_chan[ch].ADSRX.EnvelopeVol=0;\r
-     if(((s_chan[ch].ADSRX.EnvelopeVol>>27)&0xF) <= s_chan[ch].ADSRX.SustainLevel)\r
-      {\r
-       s_chan[ch].ADSRX.State=2;\r
-      }\r
+    if(s_chan[ch].ADSRX.EnvelopeVol<0) s_chan[ch].ADSRX.EnvelopeVol=0;\r
+    if(((s_chan[ch].ADSRX.EnvelopeVol>>27)&0xF) <= s_chan[ch].ADSRX.SustainLevel)\r
+     {\r
+      s_chan[ch].ADSRX.State=2;\r
+     }\r
+    break;\r
 \r
-     return s_chan[ch].ADSRX.EnvelopeVol>>21;\r
-    }\r
    //--------------------------------------------------//\r
-   if(s_chan[ch].ADSRX.State==2)                       // -> sustain\r
-    {\r
-     if(s_chan[ch].ADSRX.SustainIncrease)\r
-      {\r
-       if(s_chan[ch].ADSRX.SustainModeExp)\r
-        {\r
-         if(s_chan[ch].ADSRX.EnvelopeVol<0x60000000) \r
-          s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.SustainRate^0x7F)-0x10 + 32];\r
-         else\r
-          s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.SustainRate^0x7F)-0x18 + 32];\r
-        }\r
-       else\r
-        {\r
-         s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.SustainRate^0x7F)-0x10 + 32];\r
-        }\r
-\r
-       if(s_chan[ch].ADSRX.EnvelopeVol<0) \r
-        {\r
-         s_chan[ch].ADSRX.EnvelopeVol=0x7FFFFFFF;\r
-        }\r
-      }\r
-     else\r
-      {\r
-       if(s_chan[ch].ADSRX.SustainModeExp)\r
-        {\r
-         switch((s_chan[ch].ADSRX.EnvelopeVol>>28)&0x7)\r
-          {\r
-           case 0: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +0 + 32];break;\r
-           case 1: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +4 + 32];break;\r
-           case 2: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +6 + 32];break;\r
-           case 3: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +8 + 32];break;\r
-           case 4: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +9 + 32];break;\r
-           case 5: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +10+ 32];break;\r
-           case 6: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +11+ 32];break;\r
-           case 7: s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B +12+ 32];break;\r
-          }\r
-        }\r
-       else\r
-        {\r
-         s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x0F + 32];\r
-        }\r
-\r
-       if(s_chan[ch].ADSRX.EnvelopeVol<0) \r
-        {\r
-         s_chan[ch].ADSRX.EnvelopeVol=0;\r
-        }\r
-      }\r
-     return s_chan[ch].ADSRX.EnvelopeVol>>21;\r
-    }\r
+   case 2:                                             // -> sustain\r
+    if(s_chan[ch].ADSRX.SustainIncrease)\r
+     {\r
+      rto=8;\r
+      if(s_chan[ch].ADSRX.SustainModeExp&&s_chan[ch].ADSRX.EnvelopeVol>=0x60000000)\r
+       rto=0;\r
+      s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.SustainRate^0x7F)-0x18 + rto + 32];\r
+\r
+      if(s_chan[ch].ADSRX.EnvelopeVol<0) \r
+       {\r
+        s_chan[ch].ADSRX.EnvelopeVol=0x7FFFFFFF;\r
+       }\r
+     }\r
+    else\r
+     {\r
+      if(s_chan[ch].ADSRX.SustainModeExp)\r
+       {\r
+        rto=ratetable_offset[(s_chan[ch].ADSRX.EnvelopeVol>>28)&0x7];\r
+       }\r
+      else\r
+       {\r
+        rto=12;\r
+       }\r
+      s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B + rto + 32];\r
+\r
+      if(s_chan[ch].ADSRX.EnvelopeVol<0) \r
+       {\r
+        s_chan[ch].ADSRX.EnvelopeVol=0;\r
+       }\r
+     }\r
+    break;\r
   }\r
- return 0;\r
+\r
+done:\r
+ return s_chan[ch].ADSRX.EnvelopeVol>>21;\r
 }\r
 \r
 #endif\r
@@ -637,3 +596,4 @@ Logarithmic release mode:
 -----------------------------------------------------------------------------\r
 */\r
 \r
+// vim:shiftwidth=1:expandtab\r