\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
\r
////////////////////////////////////////////////////////////////////////\r
\r
-static void MixADSR(int ch, int ns, int ns_to) // MIX ADSR\r
+static int MixADSR(int ch, int ns_to) // MIX ADSR\r
{\r
int EnvelopeVol = s_chan[ch].ADSRX.EnvelopeVol;\r
- int val, rto, level;\r
+ int ns = 0, val, rto, level;\r
\r
if (s_chan[ch].bStop) // should be stopped:\r
{ // do release\r
val = RateTableSub[s_chan[ch].ADSRX.ReleaseRate * 4];\r
+\r
if (s_chan[ch].ADSRX.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
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
}\r
}\r
\r
- if (EnvelopeVol < 0)\r
- goto stop;\r
-\r
goto done;\r
}\r
\r
if (s_chan[ch].ADSRX.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 ((unsigned int)EnvelopeVol >= 0x7fe00000)\r
{\r
EnvelopeVol = 0x7fffffff;\r
+ ns = ns_to;\r
break;\r
}\r
\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
{\r
EnvelopeVol += val;\r
if (EnvelopeVol < 0) \r
- goto stop;\r
+ break;\r
\r
ChanBuf[ns] *= EnvelopeVol >> 21;\r
ChanBuf[ns] >>= 10;\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
+ return ns;\r
}\r
\r
#endif\r