From 215ff9e69c0b845f24e7a3aa9faeef06d9276145 Mon Sep 17 00:00:00 2001 From: notaz Date: Sat, 27 Dec 2014 23:24:15 +0200 Subject: spu: handle stop better, split main func more --- plugins/dfsound/adsr.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) (limited to 'plugins/dfsound/adsr.c') diff --git a/plugins/dfsound/adsr.c b/plugins/dfsound/adsr.c index c1e98b3..976315d 100644 --- a/plugins/dfsound/adsr.c +++ b/plugins/dfsound/adsr.c @@ -63,10 +63,10 @@ INLINE void StartADSR(int ch) // MIX ADSR //////////////////////////////////////////////////////////////////////// -static void MixADSR(int ch, int ns, int ns_to) // MIX ADSR +static int MixADSR(int ch, int ns_to) // MIX ADSR { int EnvelopeVol = s_chan[ch].ADSRX.EnvelopeVol; - int val, rto, level; + int ns = 0, val, rto, level; if (s_chan[ch].bStop) // should be stopped: { // do release @@ -97,9 +97,6 @@ static void MixADSR(int ch, int ns, int ns_to) // MIX ADSR } } - if (EnvelopeVol <= 0) - goto stop; - goto done; } @@ -160,7 +157,10 @@ static void MixADSR(int ch, int ns, int ns_to) // MIX ADSR if (s_chan[ch].ADSRX.SustainIncrease) { if (EnvelopeVol >= 0x7fff0000) + { + ns = ns_to; break; + } rto = 0; if (s_chan[ch].ADSRX.SustainModeExp && EnvelopeVol >= 0x60000000) @@ -173,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; } @@ -189,7 +190,7 @@ static void MixADSR(int ch, int ns, int ns_to) // MIX ADSR { EnvelopeVol += ((long long)val * EnvelopeVol) >> (15+16); if (EnvelopeVol < 0) - goto stop; + break; ChanBuf[ns] *= EnvelopeVol >> 21; ChanBuf[ns] >>= 10; @@ -201,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; @@ -213,12 +214,7 @@ 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; - spu.dwChannelOn &= ~(1<EnvelopeVol; int ns = 0, val, rto, level; - if (s_chan[ch].bStop) // should be stopped: - { // do release - val = RateTableSub[s_chan[ch].ADSRX.ReleaseRate * 4]; + if (adsr->State == ADSR_RELEASE) + { + val = RateTableSub[adsr->ReleaseRate * 4]; - if (s_chan[ch].ADSRX.ReleaseModeExp) + if (adsr->ReleaseModeExp) { for (; ns < ns_to; ns++) { @@ -100,13 +100,13 @@ static int MixADSR(int ch, int ns_to) // MIX ADSR 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++) { @@ -121,7 +121,7 @@ static int MixADSR(int ch, 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; } @@ -129,9 +129,9 @@ static int MixADSR(int ch, 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; ) { @@ -145,7 +145,7 @@ static int MixADSR(int ch, int ns_to) // MIX ADSR if (((EnvelopeVol >> 27) & 0xf) <= level) { - s_chan[ch].ADSRX.State = 2; + adsr->State = ADSR_SUSTAIN; goto sustain; } } @@ -153,8 +153,8 @@ static int MixADSR(int ch, 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) { @@ -163,9 +163,9 @@ static int MixADSR(int ch, int ns_to) // MIX ADSR } 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++) { @@ -183,8 +183,8 @@ static int MixADSR(int ch, 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++) { @@ -213,7 +213,7 @@ static int MixADSR(int ch, int ns_to) // MIX ADSR } done: - s_chan[ch].ADSRX.EnvelopeVol = EnvelopeVol; + adsr->EnvelopeVol = EnvelopeVol; return ns; } -- cgit v1.2.3 From 5514a050f4e936f5c333fa1271b11bf5a6a9ea39 Mon Sep 17 00:00:00 2001 From: notaz Date: Sun, 4 Jan 2015 01:43:23 +0200 Subject: spu: start offload code to TI C64x DSP --- plugins/dfsound/adsr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'plugins/dfsound/adsr.c') diff --git a/plugins/dfsound/adsr.c b/plugins/dfsound/adsr.c index a86f461..836fdbb 100644 --- a/plugins/dfsound/adsr.c +++ b/plugins/dfsound/adsr.c @@ -57,8 +57,8 @@ void InitADSR(void) // INIT ADSR INLINE void StartADSR(int ch) // MIX ADSR { - s_chan[ch].ADSRX.State=ADSR_ATTACK; // and init some adsr vars - s_chan[ch].ADSRX.EnvelopeVol=0; + spu.s_chan[ch].ADSRX.State = ADSR_ATTACK; // and init some adsr vars + spu.s_chan[ch].ADSRX.EnvelopeVol = 0; } //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 3bd31caf9e9f5ddab2bf4fbdb5a129f4972c45f3 Mon Sep 17 00:00:00 2001 From: notaz Date: Sat, 10 Jan 2015 01:55:24 +0200 Subject: spu: support multiple pending buffers for threaded implementation --- plugins/dfsound/adsr.c | 125 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) (limited to 'plugins/dfsound/adsr.c') diff --git a/plugins/dfsound/adsr.c b/plugins/dfsound/adsr.c index 836fdbb..69e55bd 100644 --- a/plugins/dfsound/adsr.c +++ b/plugins/dfsound/adsr.c @@ -217,6 +217,131 @@ done: return ns; } +static int SkipADSR(ADSRInfoEx *adsr, int ns_to) +{ + int EnvelopeVol = adsr->EnvelopeVol; + int ns = 0, val, rto, level; + + if (adsr->State == ADSR_RELEASE) + { + val = RateTableSub[adsr->ReleaseRate * 4]; + if (adsr->ReleaseModeExp) + { + for (; ns < ns_to; ns++) + { + EnvelopeVol += ((long long)val * EnvelopeVol) >> (15+16); + if (EnvelopeVol <= 0) + break; + } + } + else + { + EnvelopeVol += val * ns_to; + if (EnvelopeVol > 0) + ns = ns_to; + } + goto done; + } + + switch (adsr->State) + { + case ADSR_ATTACK: // -> attack + rto = 0; + if (adsr->AttackModeExp && EnvelopeVol >= 0x60000000) + rto = 8; + val = RateTableAdd[adsr->AttackRate + rto]; + + for (; ns < ns_to; ns++) + { + EnvelopeVol += val; + if (EnvelopeVol < 0) + break; + } + if (EnvelopeVol < 0) // overflow + { + EnvelopeVol = 0x7fffffff; + adsr->State = ADSR_DECAY; + ns++; + goto decay; + } + break; + + //--------------------------------------------------// + decay: + case ADSR_DECAY: // -> decay + val = RateTableSub[adsr->DecayRate * 4]; + level = adsr->SustainLevel; + + for (; ns < ns_to; ) + { + EnvelopeVol += ((long long)val * EnvelopeVol) >> (15+16); + if (EnvelopeVol < 0) + EnvelopeVol = 0; + + ns++; + + if (((EnvelopeVol >> 27) & 0xf) <= level) + { + adsr->State = ADSR_SUSTAIN; + goto sustain; + } + } + break; + + //--------------------------------------------------// + sustain: + case ADSR_SUSTAIN: // -> sustain + if (adsr->SustainIncrease) + { + if (EnvelopeVol >= 0x7fff0000) + { + ns = ns_to; + break; + } + + rto = 0; + if (adsr->SustainModeExp && EnvelopeVol >= 0x60000000) + rto = 8; + val = RateTableAdd[adsr->SustainRate + rto]; + + EnvelopeVol += val * (ns_to - ns); + if ((unsigned int)EnvelopeVol >= 0x7fe00000) + { + EnvelopeVol = 0x7fffffff; + ns = ns_to; + break; + } + } + else + { + val = RateTableSub[adsr->SustainRate]; + if (adsr->SustainModeExp) + { + for (; ns < ns_to; ns++) + { + EnvelopeVol += ((long long)val * EnvelopeVol) >> (15+16); + if (EnvelopeVol < 0) + break; + } + } + else + { + EnvelopeVol += val * (ns_to - ns); + if (EnvelopeVol > 0) + { + ns = ns_to; + break; + } + } + } + break; + } + +done: + adsr->EnvelopeVol = EnvelopeVol; + return ns; +} + #endif /* -- cgit v1.2.3 From c632283d5c48d7731ec5704c3d5eef54951fec20 Mon Sep 17 00:00:00 2001 From: notaz Date: Mon, 12 Jan 2015 03:00:12 +0200 Subject: spu: fix some skip accuracy issues --- plugins/dfsound/adsr.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'plugins/dfsound/adsr.c') diff --git a/plugins/dfsound/adsr.c b/plugins/dfsound/adsr.c index 69e55bd..9e32862 100644 --- a/plugins/dfsound/adsr.c +++ b/plugins/dfsound/adsr.c @@ -221,6 +221,7 @@ static int SkipADSR(ADSRInfoEx *adsr, int ns_to) { int EnvelopeVol = adsr->EnvelopeVol; int ns = 0, val, rto, level; + int64_t v64; if (adsr->State == ADSR_RELEASE) { @@ -236,8 +237,10 @@ static int SkipADSR(ADSRInfoEx *adsr, int ns_to) } else { - EnvelopeVol += val * ns_to; - if (EnvelopeVol > 0) + v64 = EnvelopeVol; + v64 += (int64_t)val * ns_to; + EnvelopeVol = (int)v64; + if (v64 > 0) ns = ns_to; } goto done; @@ -293,24 +296,21 @@ static int SkipADSR(ADSRInfoEx *adsr, int ns_to) case ADSR_SUSTAIN: // -> sustain if (adsr->SustainIncrease) { + ns = ns_to; + if (EnvelopeVol >= 0x7fff0000) - { - ns = ns_to; break; - } rto = 0; if (adsr->SustainModeExp && EnvelopeVol >= 0x60000000) rto = 8; val = RateTableAdd[adsr->SustainRate + rto]; - EnvelopeVol += val * (ns_to - ns); - if ((unsigned int)EnvelopeVol >= 0x7fe00000) - { + v64 = EnvelopeVol; + v64 += (int64_t)val * (ns_to - ns); + EnvelopeVol = (int)v64; + if (v64 >= 0x7fe00000ll) EnvelopeVol = 0x7fffffff; - ns = ns_to; - break; - } } else { @@ -326,8 +326,10 @@ static int SkipADSR(ADSRInfoEx *adsr, int ns_to) } else { - EnvelopeVol += val * (ns_to - ns); - if (EnvelopeVol > 0) + v64 = EnvelopeVol; + v64 += (int64_t)val * (ns_to - ns); + EnvelopeVol = (int)v64; + if (v64 > 0) { ns = ns_to; break; -- cgit v1.2.3