diff --git a/src/deluge/dsp/compressor/compressor.cpp b/src/deluge/dsp/compressor/compressor.cpp index c75669db05..6460a9bd89 100644 --- a/src/deluge/dsp/compressor/compressor.cpp +++ b/src/deluge/dsp/compressor/compressor.cpp @@ -25,9 +25,7 @@ Compressor::Compressor() { status = EnvelopeStage::OFF; lastValue = 2147483647; - envelopeOffset = ONE_Q31; pos = 0; - attack = getParamFromUserValue(Param::Static::COMPRESSOR_ATTACK, 7); release = getParamFromUserValue(Param::Static::COMPRESSOR_RELEASE, 28); pendingHitStrength = 0; @@ -82,14 +80,11 @@ void Compressor::registerHitRetrospectively(int32_t strength, uint32_t numSample // If we're still in the release stage... if (numSamplesSinceRelease < releaseStageLengthInSamples) { pos = numSamplesSinceRelease * alteredRelease; - envelopeHeight = ONE_Q31 - envelopeOffset; - envelopeOffset = ONE_Q31; status = EnvelopeStage::RELEASE; } // Or if we're past the release stage... else { - envelopeOffset = ONE_Q31; status = EnvelopeStage::OFF; } } @@ -133,23 +128,19 @@ int32_t Compressor::render(uint16_t numSamples, int32_t shapeValue) { int32_t newOffset = ONE_Q31 - pendingHitStrength; pendingHitStrength = 0; - //envelope offset is the value we're attack/decaying to + // Only actually do anything if this hit is going to cause a bigger dip than we're already currently experiencing if (newOffset < lastValue) { envelopeOffset = newOffset; // If attack is all the way down, jump directly to release stage if (attack == attackRateTable[0] << 2) { - envelopeHeight = ONE_Q31 - envelopeOffset; - envelopeOffset = ONE_Q31; - pos = 0; - status = EnvelopeStage::RELEASE; + goto prepareForRelease; } - else { - status = EnvelopeStage::ATTACK; - pos = 0; - } + status = EnvelopeStage::ATTACK; + envelopeHeight = lastValue - envelopeOffset; + pos = 0; } } @@ -157,14 +148,10 @@ int32_t Compressor::render(uint16_t numSamples, int32_t shapeValue) { pos += numSamples * getActualAttackRate(); if (pos >= 8388608) { - //if we're in follower mode then we just hold the value - - envelopeHeight = ONE_Q31 - envelopeOffset; - envelopeOffset = ONE_Q31; prepareForRelease: pos = 0; status = EnvelopeStage::RELEASE; - + envelopeHeight = ONE_Q31 - envelopeOffset; goto doRelease; } //lastValue = (multiply_32x32_rshift32(envelopeHeight, decayTable4[pos >> 13]) << 1) + envelopeOffset; // Goes down quickly at first. Bad @@ -204,110 +191,15 @@ int32_t Compressor::render(uint16_t numSamples, int32_t shapeValue) { preValue = straightness * (pos >> 8) + (getDecay8(8388608 - pos, 23) >> 16) * curvedness16; } - lastValue = envelopeOffset - envelopeHeight + (multiply_32x32_rshift32(preValue, envelopeHeight) << 1); + lastValue = ONE_Q31 - envelopeHeight + (multiply_32x32_rshift32(preValue, envelopeHeight) << 1); //lastValue = 2147483647 - (multiply_32x32_rshift32(decayTable8[pos >> 13], envelopeHeight) << 1); // Upside down exponential curve //lastValue = 2147483647 - (((int64_t)((sineWave[((pos >> 14) + 256) & 1023] >> 1) + 1073741824) * (int64_t)envelopeHeight) >> 31); // Sine wave. Not great //lastValue = (multiply_32x32_rshift32(pos * (pos >> 15), envelopeHeight) << 1); // Parabola. Doesn't "punch". } - - else { // Off or hold - -doOff: - lastValue = envelopeOffset; - } - - return lastValue - ONE_Q31; -} - -int32_t Compressor::renderFollower(uint16_t numSamples, int32_t shapeValue) { - - int32_t newOffset = ONE_Q31 - pendingHitStrength; - - pendingHitStrength = 0; - //envelope offset is the value we're attack/decaying to - // Only actually do anything if this hit is going to cause a bigger dip than we're already currently experiencing - if (newOffset < lastValue) { - envelopeOffset = newOffset; - envelopeHeight = lastValue - envelopeOffset; - pos = 0; - if (status == EnvelopeStage::HOLD) { - status = EnvelopeStage::ATTACK; - } - else if (status != EnvelopeStage::ATTACK) { - status = EnvelopeStage::HOLD; - } - } - //or if we're working in follower mode, in which case we want to start releasing whenever the current hit strength is below the envelope level - else if (newOffset > envelopeOffset) { - envelopeOffset = newOffset; - envelopeHeight = newOffset - lastValue; - pos = 0; - - if (status == EnvelopeStage::HOLD) { - - status = EnvelopeStage::RELEASE; - } - else if (status != EnvelopeStage::RELEASE) { - status = EnvelopeStage::HOLD; - } - } - - if (status == EnvelopeStage::ATTACK) { - pos += numSamples * getActualAttackRate(); - - if (pos >= 8388608) { - //if we're in follower mode then we just hold the value - status = EnvelopeStage::HOLD; - goto doOff; - } - //lastValue = (multiply_32x32_rshift32(envelopeHeight, decayTable4[pos >> 13]) << 1) + envelopeOffset; // Goes down quickly at first. Bad - //lastValue = (multiply_32x32_rshift32(envelopeHeight, 2147483647 - (pos << 8)) << 1) + envelopeOffset; // Straight line - lastValue = (multiply_32x32_rshift32(envelopeHeight, (ONE_Q31 - getDecay4(8388608 - pos, 23))) << 1) - + envelopeOffset; // Goes down slowly at first. Great squishiness - //lastValue = (multiply_32x32_rshift32(envelopeHeight, (2147483647 - decayTable8[1023 - (pos >> 13)])) << 1) + envelopeOffset; // Even slower to accelerate. Loses punch slightly - //lastValue = (multiply_32x32_rshift32(envelopeHeight, (sineWave[((pos >> 14) + 256) & 1023] >> 1) + 1073741824) << 1) + envelopeOffset; // Sine wave. Sounds a bit flat - //lastValue = (multiply_32x32_rshift32(envelopeHeight, 2147483647 - pos * (pos >> 15)) << 1) + envelopeOffset; // Parabola. Not bad, but doesn't quite have punchiness - } - else if (status == EnvelopeStage::RELEASE) { -doRelease: - pos += numSamples * getActualReleaseRate(); - - if (pos >= 8388608) { - status = EnvelopeStage::HOLD; - goto doOff; - } - - uint32_t positiveShapeValue = (uint32_t)shapeValue + 2147483648; - - int32_t preValue; - - // This would be the super simple case - // int32_t curvedness16 = (uint32_t)(positiveShapeValue + 32768) >> 16; - - // And this is the better, more complicated case - int32_t curvedness16 = (positiveShapeValue >> 15) - (pos >> 7); - if (curvedness16 < 0) { - preValue = pos << 8; - } - else { - if (curvedness16 > 65536) { - curvedness16 = 65536; - } - int32_t straightness = 65536 - curvedness16; - preValue = straightness * (pos >> 8) + (getDecay8(8388608 - pos, 23) >> 16) * curvedness16; - } - - lastValue = envelopeOffset - envelopeHeight + (multiply_32x32_rshift32(preValue, envelopeHeight) << 1); - - lastValue = - envelopeOffset - (multiply_32x32_rshift32(envelopeHeight, (ONE_Q31 - getDecay4(8388608 - pos, 23))) << 1); - } - - else { // Off or hold - + else { // Off doOff: - lastValue = envelopeOffset; + lastValue = ONE_Q31; } return lastValue - ONE_Q31; diff --git a/src/deluge/dsp/compressor/compressor.h b/src/deluge/dsp/compressor/compressor.h index 78470afcc8..c48cc96040 100644 --- a/src/deluge/dsp/compressor/compressor.h +++ b/src/deluge/dsp/compressor/compressor.h @@ -26,6 +26,7 @@ class Compressor { public: Compressor(); void cloneFrom(Compressor* other); + EnvelopeStage status; uint32_t pos; int32_t lastValue; @@ -41,7 +42,6 @@ class Compressor { SyncLevel syncLevel; // Basically, 0 is off, max value is 9. Higher numbers are shorter intervals (higher speed). int32_t render(uint16_t numSamples, int32_t shapeValue); - int32_t renderFollower(uint16_t numSamples, int32_t shapeValue); void registerHit(int32_t strength); void registerHitRetrospectively(int32_t strength, uint32_t numSamplesAgo);