X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=pcsx_rearmed.git;a=blobdiff_plain;f=plugins%2Fdfsound%2Fadsr.c;h=a86f461c69c2d3401d9b3afffa694f5c9c5ae802;hp=e4873dfd418cdf203b0a9beabd7f4b96fbeda27c;hb=9ad8abfa940cd5c13eb0653639ea86736b65a2c4;hpb=1ab7621a76d1ef82fde77322c12d4076889bed01 diff --git a/plugins/dfsound/adsr.c b/plugins/dfsound/adsr.c index e4873dfd..a86f461c 100644 --- a/plugins/dfsound/adsr.c +++ b/plugins/dfsound/adsr.c @@ -46,6 +46,10 @@ void InitADSR(void) // INIT ADSR RateTableAdd[lcv] = ((7 - (lcv&3)) << 16) / denom; RateTableSub[lcv] = ((-8 + (lcv&3)) << 16) / denom; + + // XXX: this is wrong, we need more bits.. + if (RateTableAdd[lcv] == 0) + RateTableAdd[lcv] = 1; } } @@ -53,26 +57,27 @@ void InitADSR(void) // INIT ADSR INLINE void StartADSR(int ch) // MIX ADSR { - s_chan[ch].ADSRX.State=0; // and init some adsr vars + s_chan[ch].ADSRX.State=ADSR_ATTACK; // and init some adsr vars s_chan[ch].ADSRX.EnvelopeVol=0; } //////////////////////////////////////////////////////////////////////// -static void MixADSR(int ch, int ns, int ns_to) // MIX ADSR +static int MixADSR(ADSRInfoEx *adsr, int ns_to) { - int EnvelopeVol = s_chan[ch].ADSRX.EnvelopeVol; - int val, rto, level; + int EnvelopeVol = adsr->EnvelopeVol; + int ns = 0, val, rto, level; + + if (adsr->State == ADSR_RELEASE) + { + val = RateTableSub[adsr->ReleaseRate * 4]; - if (s_chan[ch].bStop) // should be stopped: - { // do release - val = RateTableSub[s_chan[ch].ADSRX.ReleaseRate * 4]; - if (s_chan[ch].ADSRX.ReleaseModeExp) + if (adsr->ReleaseModeExp) { for (; ns < ns_to; ns++) { EnvelopeVol += ((long long)val * EnvelopeVol) >> (15+16); - if (EnvelopeVol < 0) + if (EnvelopeVol <= 0) break; ChanBuf[ns] *= EnvelopeVol >> 21; @@ -84,7 +89,7 @@ static void MixADSR(int ch, int ns, int ns_to) // MIX ADSR for (; ns < ns_to; ns++) { EnvelopeVol += val; - if (EnvelopeVol < 0) + if (EnvelopeVol <= 0) break; ChanBuf[ns] *= EnvelopeVol >> 21; @@ -92,19 +97,16 @@ static void MixADSR(int ch, int ns, int ns_to) // MIX ADSR } } - if (EnvelopeVol < 0) - goto stop; - goto done; } - switch (s_chan[ch].ADSRX.State) + switch (adsr->State) { - case 0: // -> attack + case ADSR_ATTACK: // -> attack rto = 0; - if (s_chan[ch].ADSRX.AttackModeExp && EnvelopeVol >= 0x60000000) + if (adsr->AttackModeExp && EnvelopeVol >= 0x60000000) rto = 8; - val = RateTableAdd[s_chan[ch].ADSRX.AttackRate + rto]; + val = RateTableAdd[adsr->AttackRate + rto]; for (; ns < ns_to; ns++) { @@ -119,7 +121,7 @@ static void MixADSR(int ch, int ns, int ns_to) // MIX ADSR if (EnvelopeVol < 0) // overflow { EnvelopeVol = 0x7fffffff; - s_chan[ch].ADSRX.State = 1; + adsr->State = ADSR_DECAY; ns++; // sample is good already goto decay; } @@ -127,9 +129,9 @@ static void MixADSR(int ch, int ns, int ns_to) // MIX ADSR //--------------------------------------------------// decay: - case 1: // -> decay - val = RateTableSub[s_chan[ch].ADSRX.DecayRate * 4]; - level = s_chan[ch].ADSRX.SustainLevel; + case ADSR_DECAY: // -> decay + val = RateTableSub[adsr->DecayRate * 4]; + level = adsr->SustainLevel; for (; ns < ns_to; ) { @@ -143,7 +145,7 @@ static void MixADSR(int ch, int ns, int ns_to) // MIX ADSR if (((EnvelopeVol >> 27) & 0xf) <= level) { - s_chan[ch].ADSRX.State = 2; + adsr->State = ADSR_SUSTAIN; goto sustain; } } @@ -151,16 +153,19 @@ static void MixADSR(int ch, int ns, int ns_to) // MIX ADSR //--------------------------------------------------// sustain: - case 2: // -> sustain - if (s_chan[ch].ADSRX.SustainIncrease) + case ADSR_SUSTAIN: // -> sustain + if (adsr->SustainIncrease) { if (EnvelopeVol >= 0x7fff0000) + { + ns = ns_to; break; + } rto = 0; - if (s_chan[ch].ADSRX.SustainModeExp && EnvelopeVol >= 0x60000000) + if (adsr->SustainModeExp && EnvelopeVol >= 0x60000000) rto = 8; - val = RateTableAdd[s_chan[ch].ADSRX.SustainRate + rto]; + val = RateTableAdd[adsr->SustainRate + rto]; for (; ns < ns_to; ns++) { @@ -168,6 +173,7 @@ static void MixADSR(int ch, int ns, int ns_to) // MIX ADSR if ((unsigned int)EnvelopeVol >= 0x7fe00000) { EnvelopeVol = 0x7fffffff; + ns = ns_to; break; } @@ -177,14 +183,14 @@ static void MixADSR(int ch, int ns, int ns_to) // MIX ADSR } else { - val = RateTableSub[s_chan[ch].ADSRX.SustainRate]; - if (s_chan[ch].ADSRX.SustainModeExp) + val = RateTableSub[adsr->SustainRate]; + if (adsr->SustainModeExp) { for (; ns < ns_to; ns++) { EnvelopeVol += ((long long)val * EnvelopeVol) >> (15+16); if (EnvelopeVol < 0) - goto stop; + break; ChanBuf[ns] *= EnvelopeVol >> 21; ChanBuf[ns] >>= 10; @@ -196,7 +202,7 @@ static void MixADSR(int ch, int ns, int ns_to) // MIX ADSR { EnvelopeVol += val; if (EnvelopeVol < 0) - goto stop; + break; ChanBuf[ns] *= EnvelopeVol >> 21; ChanBuf[ns] >>= 10; @@ -207,13 +213,8 @@ static void MixADSR(int ch, int ns, int ns_to) // MIX ADSR } done: - s_chan[ch].ADSRX.EnvelopeVol = EnvelopeVol; - return; - -stop: - memset(&ChanBuf[ns], 0, (ns_to - ns) * sizeof(ChanBuf[0])); - s_chan[ch].ADSRX.EnvelopeVol = 0; - dwChannelOn &= ~(1<EnvelopeVol = EnvelopeVol; + return ns; } #endif