From 30af769202fd24f076a1caec059283a4abe2a457 Mon Sep 17 00:00:00 2001 From: Sergey Date: Tue, 7 Nov 2023 21:56:28 +0400 Subject: [PATCH 01/37] Add compressor effect --- CMakeLists.txt | 1 + .../backends/builtin/builtinbackend.cpp | 2 + .../backends/builtin/compressoreffect.cpp | 280 ++++++++++++++++++ .../backends/builtin/compressoreffect.h | 64 ++++ 4 files changed, 347 insertions(+) create mode 100644 src/effects/backends/builtin/compressoreffect.cpp create mode 100644 src/effects/backends/builtin/compressoreffect.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 2061926f158..f5db15cdb67 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -797,6 +797,7 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL src/effects/backends/builtin/loudnesscontoureffect.cpp src/effects/backends/builtin/metronomeeffect.cpp src/effects/backends/builtin/moogladder4filtereffect.cpp + src/effects/backends/builtin/compressoreffect.cpp src/effects/backends/builtin/parametriceqeffect.cpp src/effects/backends/builtin/phasereffect.cpp src/effects/backends/builtin/reverbeffect.cpp diff --git a/src/effects/backends/builtin/builtinbackend.cpp b/src/effects/backends/builtin/builtinbackend.cpp index a2497e39bc7..cd2b548b566 100644 --- a/src/effects/backends/builtin/builtinbackend.cpp +++ b/src/effects/backends/builtin/builtinbackend.cpp @@ -18,6 +18,7 @@ #endif #include "effects/backends/builtin/autopaneffect.h" #include "effects/backends/builtin/distortioneffect.h" +#include "effects/backends/builtin/compressoreffect.h" #include "effects/backends/builtin/echoeffect.h" #include "effects/backends/builtin/glitcheffect.h" #include "effects/backends/builtin/loudnesscontoureffect.h" @@ -62,6 +63,7 @@ BuiltInBackend::BuiltInBackend() { #endif registerEffect(); registerEffect(); + registerEffect(); } std::unique_ptr BuiltInBackend::createProcessor( diff --git a/src/effects/backends/builtin/compressoreffect.cpp b/src/effects/backends/builtin/compressoreffect.cpp new file mode 100644 index 00000000000..8d955b570c6 --- /dev/null +++ b/src/effects/backends/builtin/compressoreffect.cpp @@ -0,0 +1,280 @@ +#include "effects/backends/builtin/compressoreffect.h" +#include + +// static +QString CompressorEffect::getId() { + return "org.mixxx.effects.compressor"; +} + +//static +EffectManifestPointer CompressorEffect::getManifest() { + EffectManifestPointer pManifest(new EffectManifest); + pManifest->setId(getId()); + pManifest->setName(QObject::tr("Compressor")); + pManifest->setShortName(QObject::tr("Compressor")); + pManifest->setAuthor("The Mixxx Team"); + pManifest->setVersion("1.0"); + pManifest->setDescription( + "A single-band compressor effect"); + pManifest->setEffectRampsFromDry(true); + pManifest->setMetaknobDefault(0.0); + + EffectManifestParameterPointer clipping = pManifest->addParameter(); + clipping->setId("clipping"); + clipping->setName(QObject::tr("Clipping")); + clipping->setShortName(QObject::tr("Clipping")); + clipping->setDescription(QObject::tr("Hard limiter to 0 db")); + clipping->setValueScaler(EffectManifestParameter::ValueScaler::Toggle); + clipping->setRange(0, 1, 1); + clipping->appendStep(qMakePair(QObject::tr("Off"), Clipping::ClippingOff)); + clipping->appendStep(qMakePair(QObject::tr("On"), Clipping::ClippingOn)); + + EffectManifestParameterPointer autoMakeUp = pManifest->addParameter(); + autoMakeUp->setId("automakeup"); + autoMakeUp->setName(QObject::tr("Auto Make Up Gain")); + autoMakeUp->setShortName(QObject::tr("Make Up")); + autoMakeUp->setDescription(QObject::tr( + "Auto make up gain to 0 db level")); + autoMakeUp->setValueScaler(EffectManifestParameter::ValueScaler::Toggle); + autoMakeUp->setRange(0, 1, 1); + autoMakeUp->appendStep(qMakePair(QObject::tr("Off"), AutoMakeUp::AutoMakeUpOff)); + autoMakeUp->appendStep(qMakePair(QObject::tr("On"), AutoMakeUp::AutoMakeUpOn)); + + + //TODO description + EffectManifestParameterPointer threshold = pManifest->addParameter(); + threshold->setId("threshold"); + threshold->setName(QObject::tr("Threshold (dB)")); + threshold->setShortName(QObject::tr("Threshold")); + threshold->setDescription(QObject::tr( + "The amount of amplification " + "applied to the audio signal. At higher levels the audio will be more distored.")); + threshold->setValueScaler(EffectManifestParameter::ValueScaler::Linear); + //threshold->setDefaultLinkType(EffectManifestParameter::LinkType::Linked); + threshold->setUnitsHint(EffectManifestParameter::UnitsHint::Decibel); + threshold->setNeutralPointOnScale(0); + threshold->setRange(-50, -20, 0); + + EffectManifestParameterPointer ratio = pManifest->addParameter(); + ratio->setId("ratio"); + ratio->setName(QObject::tr("Ratio (:1)")); + ratio->setShortName(QObject::tr("Ratio")); + ratio->setDescription(QObject::tr( + "The amount of ratio.")); + ratio->setValueScaler(EffectManifestParameter::ValueScaler::Linear); + //ratio->setDefaultLinkType(EffectManifestParameter::LinkType::Linked); + ratio->setUnitsHint(EffectManifestParameter::UnitsHint::Coefficient); + ratio->setNeutralPointOnScale(0); + ratio->setRange(1.0, 4.0, 20); + + EffectManifestParameterPointer knee = pManifest->addParameter(); + knee->setId("knee"); + knee->setName(QObject::tr("Knee (dB)")); + knee->setShortName(QObject::tr("Knee")); + knee->setDescription(QObject::tr( + "The amount of knee.")); + knee->setValueScaler(EffectManifestParameter::ValueScaler::Linear); + //knee->setDefaultLinkType(EffectManifestParameter::LinkType::Linked); + knee->setUnitsHint(EffectManifestParameter::UnitsHint::Coefficient); + knee->setNeutralPointOnScale(0); + knee->setRange(0.0, 4.0, 24); + + EffectManifestParameterPointer attack = pManifest->addParameter(); + attack->setId("attack"); + attack->setName(QObject::tr("Attack (ms)")); + attack->setShortName(QObject::tr("Attack")); + attack->setDescription(QObject::tr( + "Attack")); + attack->setValueScaler(EffectManifestParameter::ValueScaler::Integral); + attack->setUnitsHint(EffectManifestParameter::UnitsHint::Millisecond); + attack->setRange(0, 30, 250); + + EffectManifestParameterPointer release = pManifest->addParameter(); + release->setId("release"); + release->setName(QObject::tr("Release (ms)")); + release->setShortName(QObject::tr("Release")); + release->setDescription(QObject::tr( + "Release")); + release->setValueScaler(EffectManifestParameter::ValueScaler::Integral); + release->setUnitsHint(EffectManifestParameter::UnitsHint::Millisecond); + release->setRange(0, 150, 2000); + + EffectManifestParameterPointer gain = pManifest->addParameter(); + gain->setId("gain"); + gain->setName(QObject::tr("Make up gain")); + gain->setShortName(QObject::tr("Gain")); + gain->setDescription(QObject::tr( + "Gain")); + gain->setValueScaler(EffectManifestParameter::ValueScaler::Linear); + gain->setUnitsHint(EffectManifestParameter::UnitsHint::Decibel); + gain->setRange(-25, 0, 25); + + return pManifest; +} + +CompressorGroupState::CompressorGroupState( + const mixxx::EngineParameters& engineParameters) + : EffectState(engineParameters), + samplerate(engineParameters.sampleRate()), + previousMakeUpGain(-1), + previousStateDB(0) { +} + +void CompressorEffect::loadEngineEffectParameters( + const QMap& parameters) { + m_pThreshold = parameters.value("threshold"); + m_pRatio = parameters.value("ratio"); + m_pKnee = parameters.value("knee"); + m_pAttack = parameters.value("attack"); + m_pRelease = parameters.value("release"); + m_pGain = parameters.value("gain"); + m_pAutoMakeUp = parameters.value("automakeup"); + m_pClipping = parameters.value("clipping"); +} + +void CompressorEffect::processChannel( + CompressorGroupState* pState, + const CSAMPLE* pInput, + CSAMPLE* pOutput, + const mixxx::EngineParameters& engineParameters, + const EffectEnableState enableState, + const GroupFeatureState& groupFeatures) { + Q_UNUSED(groupFeatures); + Q_UNUSED(enableState); + + // TODO test: Marc Benjamin, Zana - Edge of Paradise; Cassette - Tell Me Why; Adele - Skyfall + // url: https://github.com/p-hlp/CTAGDRC + + SINT numSamples = engineParameters.samplesPerBuffer(); + int channelCount = engineParameters.channelCount(); + SINT numFrames = engineParameters.framesPerBuffer(); + + //CSAMPLE max = SampleUtil::maxAbsAmplitude(pInput, numSamples); + //if (max == CSAMPLE_ZERO) { + // SampleUtil::copy(pOutput, pInput, numSamples); + // return; + //} + + CSAMPLE thresholdParam = static_cast(m_pThreshold->value()); + CSAMPLE ratioParam = static_cast(m_pRatio->value()); + //CSAMPLE kneeParam = static_cast(m_pKnee->value()); + //CSAMPLE kneeHalf = kneeParam / 2.0f; + CSAMPLE gainParamDB = static_cast(m_pGain->value()); + CSAMPLE attackParam = m_pAttack->value(); + CSAMPLE releaseParam = m_pRelease->value(); + CSAMPLE attackCoeff = exp(-1000.0 / (attackParam * pState->samplerate)); + CSAMPLE releaseCoeff = exp(-1000.0 / (releaseParam * pState->samplerate)); + CSAMPLE makeUpCoeff = 0.03; + + CSAMPLE stateDB = pState->previousStateDB; + CSAMPLE makeUpStateDB = pState->previousMakeUpGain; + + std::vector gains(numFrames); + CSAMPLE maxGain = thresholdParam; + for (SINT i = 0; i < numSamples; i += channelCount) { + CSAMPLE maxSample = std::max(fabs(pInput[i]), fabs(pInput[i + 1])); + if (maxSample == CSAMPLE_ZERO) { + gains[i / channelCount] = 0.0; + continue; + } + + CSAMPLE maxSampleDB = ratio2db(maxSample); + CSAMPLE overDB = maxSampleDB - thresholdParam; + //if (overDB <= kneeHalf) { + // overDB = 0.0f; + //} else if (overDB > -kneeHalf && overDB <= kneeHalf) { + // overDB = 0.5f * (overDB + kneeHalf) * (overDB + kneeHalf) / kneeParam; + //} + + // atack/release + if (overDB > stateDB) { + stateDB = overDB + attackCoeff * (stateDB - overDB); + } else { + stateDB = overDB + releaseCoeff * (stateDB - overDB); + } + + + overDB = stateDB; + CSAMPLE gainReductionDB = overDB * (1.0 / ratioParam - 1.0); + gains[i / channelCount] = gainReductionDB; + CSAMPLE totalGain = maxSampleDB + gainReductionDB; + if (totalGain > maxGain) { + maxGain = totalGain; + } + } + + CSAMPLE autoMakeUp = 0; + if (m_pAutoMakeUp->toInt() == AutoMakeUpOn) { + CSAMPLE minGainReductionDB = -maxGain - 3.0; + if (makeUpStateDB == -1) { + //std::string msg2 = std::string("makeUpStateDB: ") + std::to_string(makeUpStateDB) + std::string(" minGainReductionDB: ") + std::to_string(minGainReductionDB) + std::string("\n"); + //OutputDebugStringA(msg2.c_str()); + makeUpStateDB = minGainReductionDB; + } + makeUpStateDB = makeUpCoeff * minGainReductionDB + (1 - makeUpCoeff) * makeUpStateDB; + autoMakeUp = makeUpStateDB; + } + + for (SINT i = 0; i < numSamples; i += channelCount) { + CSAMPLE gain = db2ratio(gains[i / channelCount] + gainParamDB + autoMakeUp); + pOutput[i] = pInput[i] * gain; + pOutput[i + 1] = pInput[i + 1] * gain; + } + + if (m_pClipping->toInt() == ClippingOn) { + SampleUtil::copyClampBuffer(pOutput, pOutput, numSamples); + } + + + pState->previousStateDB = stateDB; + pState->previousMakeUpGain = makeUpStateDB; + //std::string msg2 = std::string("makeUpStateDB: ") + std::to_string(makeUpStateDB) + std::string(" stateDB: ") + std::to_string(stateDB) + std::string("\n"); + //OutputDebugStringA(msg2.c_str()); + + /* + if (m_pAutoMakeUp->toInt() == On) { + CSAMPLE sum = CSAMPLE_ZERO; + for (SINT i = 0; i < numSamples; i += channelCount) { + sum += std::max(fabs(pInput[i]), fabs(pInput[i + 1])); + } + CSAMPLE max = SampleUtil::maxAbsAmplitude(pOutput, numSamples); + if (max != CSAMPLE_ZERO) { + CSAMPLE averageDB = -ratio2db(max) - 2; + CSAMPLE makeUpSatetDB = pState->previousMakeUpGain; + + makeUpSatetDB = averageDB + makeUpCoeff * (makeUpSatetDB - averageDB); + std::string msg = std::string("makeUpCoeff: ") + std::to_string(makeUpCoeff) + std::string(" averageDB: ") + std::to_string(averageDB) + std::string(" makeUpSatetDB: ") + std::to_string(makeUpSatetDB) + std::string("\n"); + OutputDebugStringA(msg.c_str()); + + gainParamDB += averageDB; + pState->previousMakeUpGain = makeUpSatetDB; + } + } + + + SampleUtil::applyGain(pOutput, db2ratio(gainParamDB), numSamples); + */ + + + /* if (thresholdParam < 0.01) { + SampleUtil::copy(pOutput, pInput, numSamples); + return; + } + + switch (m_pAutoMakeUp->toInt()) { + case Off: + processCompressor( + thresholdParam, pState, pOutput, pInput, engineParameters); + break; + + case On: + processCompressor( + thresholdParam, pState, pOutput, pInput, engineParameters); + break; + + default: + // We should never enter here, but we act as a noop effect just in case. + SampleUtil::copy(pOutput, pInput, numSamples); + return; + }*/ +} diff --git a/src/effects/backends/builtin/compressoreffect.h b/src/effects/backends/builtin/compressoreffect.h new file mode 100644 index 00000000000..caf8ca13d9d --- /dev/null +++ b/src/effects/backends/builtin/compressoreffect.h @@ -0,0 +1,64 @@ +#pragma once + +#include "effects/backends/effectprocessor.h" +#include "engine/effects/engineeffect.h" +#include "engine/effects/engineeffectparameter.h" +#include "util/class.h" +#include "util/defs.h" +#include "util/sample.h" +#include "util/types.h" + +class CompressorGroupState : public EffectState { + public: + CompressorGroupState(const mixxx::EngineParameters& engineParameters); + + double samplerate; + CSAMPLE previousStateDB; + CSAMPLE previousMakeUpGain; +}; + +class CompressorEffect : public EffectProcessorImpl { + public: + CompressorEffect() = default; + + static QString getId(); + static EffectManifestPointer getManifest(); + + void loadEngineEffectParameters( + const QMap& parameters) override; + + void processChannel( + CompressorGroupState* pState, + const CSAMPLE* pInput, + CSAMPLE* pOutput, + const mixxx::EngineParameters& engineParameters, + const EffectEnableState enableState, + const GroupFeatureState& groupFeatures) override; + + private: + + enum AutoMakeUp { + AutoMakeUpOff = 0, + AutoMakeUpOn = 1, + }; + + enum Clipping { + ClippingOff = 0, + ClippingOn = 1, + }; + + QString debugString() const { + return getId(); + } + + EngineEffectParameterPointer m_pClipping; + EngineEffectParameterPointer m_pAutoMakeUp; + EngineEffectParameterPointer m_pThreshold; + EngineEffectParameterPointer m_pRatio; + EngineEffectParameterPointer m_pKnee; + EngineEffectParameterPointer m_pAttack; + EngineEffectParameterPointer m_pRelease; + EngineEffectParameterPointer m_pGain; + + DISALLOW_COPY_AND_ASSIGN(CompressorEffect); +}; From bf0bf062e7edefeb053decbab4568acd85513d9d Mon Sep 17 00:00:00 2001 From: Sergey Date: Tue, 7 Nov 2023 22:50:19 +0400 Subject: [PATCH 02/37] Auto make up refactoring --- .../backends/builtin/compressoreffect.cpp | 70 +++++-------------- .../backends/builtin/compressoreffect.h | 4 ++ 2 files changed, 21 insertions(+), 53 deletions(-) diff --git a/src/effects/backends/builtin/compressoreffect.cpp b/src/effects/backends/builtin/compressoreffect.cpp index 8d955b570c6..a0dea5a6a3a 100644 --- a/src/effects/backends/builtin/compressoreffect.cpp +++ b/src/effects/backends/builtin/compressoreffect.cpp @@ -116,7 +116,7 @@ CompressorGroupState::CompressorGroupState( const mixxx::EngineParameters& engineParameters) : EffectState(engineParameters), samplerate(engineParameters.sampleRate()), - previousMakeUpGain(-1), + previousMakeUpGain(0), previousStateDB(0) { } @@ -149,32 +149,22 @@ void CompressorEffect::processChannel( int channelCount = engineParameters.channelCount(); SINT numFrames = engineParameters.framesPerBuffer(); - //CSAMPLE max = SampleUtil::maxAbsAmplitude(pInput, numSamples); - //if (max == CSAMPLE_ZERO) { - // SampleUtil::copy(pOutput, pInput, numSamples); - // return; - //} - CSAMPLE thresholdParam = static_cast(m_pThreshold->value()); CSAMPLE ratioParam = static_cast(m_pRatio->value()); //CSAMPLE kneeParam = static_cast(m_pKnee->value()); //CSAMPLE kneeHalf = kneeParam / 2.0f; CSAMPLE gainParamDB = static_cast(m_pGain->value()); - CSAMPLE attackParam = m_pAttack->value(); - CSAMPLE releaseParam = m_pRelease->value(); - CSAMPLE attackCoeff = exp(-1000.0 / (attackParam * pState->samplerate)); - CSAMPLE releaseCoeff = exp(-1000.0 / (releaseParam * pState->samplerate)); - CSAMPLE makeUpCoeff = 0.03; + CSAMPLE attackCoeff = exp(-1000.0 / (m_pAttack->value() * pState->samplerate)); + CSAMPLE releaseCoeff = exp(-1000.0 / (m_pRelease->value() * pState->samplerate)); CSAMPLE stateDB = pState->previousStateDB; - CSAMPLE makeUpStateDB = pState->previousMakeUpGain; - std::vector gains(numFrames); CSAMPLE maxGain = thresholdParam; for (SINT i = 0; i < numSamples; i += channelCount) { CSAMPLE maxSample = std::max(fabs(pInput[i]), fabs(pInput[i + 1])); if (maxSample == CSAMPLE_ZERO) { - gains[i / channelCount] = 0.0; + pOutput[i] = CSAMPLE_ZERO; + pOutput[i + 1] = CSAMPLE_ZERO; continue; } @@ -196,38 +186,35 @@ void CompressorEffect::processChannel( overDB = stateDB; CSAMPLE gainReductionDB = overDB * (1.0 / ratioParam - 1.0); - gains[i / channelCount] = gainReductionDB; + CSAMPLE gain = db2ratio(gainReductionDB + gainParamDB); + pOutput[i] = pInput[i] * gain; + pOutput[i + 1] = pInput[i + 1] * gain; + CSAMPLE totalGain = maxSampleDB + gainReductionDB; if (totalGain > maxGain) { maxGain = totalGain; } } + pState->previousStateDB = stateDB; - CSAMPLE autoMakeUp = 0; if (m_pAutoMakeUp->toInt() == AutoMakeUpOn) { + CSAMPLE makeUpStateDB = pState->previousMakeUpGain; CSAMPLE minGainReductionDB = -maxGain - 3.0; - if (makeUpStateDB == -1) { - //std::string msg2 = std::string("makeUpStateDB: ") + std::to_string(makeUpStateDB) + std::string(" minGainReductionDB: ") + std::to_string(minGainReductionDB) + std::string("\n"); - //OutputDebugStringA(msg2.c_str()); - makeUpStateDB = minGainReductionDB; - } makeUpStateDB = makeUpCoeff * minGainReductionDB + (1 - makeUpCoeff) * makeUpStateDB; - autoMakeUp = makeUpStateDB; + for (SINT i = 0; i < numSamples; i += channelCount) { + CSAMPLE gain = db2ratio(makeUpStateDB); + pOutput[i] = pOutput[i] * gain; + pOutput[i + 1] = pOutput[i + 1] * gain; + } + pState->previousMakeUpGain = makeUpStateDB; } - for (SINT i = 0; i < numSamples; i += channelCount) { - CSAMPLE gain = db2ratio(gains[i / channelCount] + gainParamDB + autoMakeUp); - pOutput[i] = pInput[i] * gain; - pOutput[i + 1] = pInput[i + 1] * gain; - } if (m_pClipping->toInt() == ClippingOn) { SampleUtil::copyClampBuffer(pOutput, pOutput, numSamples); } - pState->previousStateDB = stateDB; - pState->previousMakeUpGain = makeUpStateDB; //std::string msg2 = std::string("makeUpStateDB: ") + std::to_string(makeUpStateDB) + std::string(" stateDB: ") + std::to_string(stateDB) + std::string("\n"); //OutputDebugStringA(msg2.c_str()); @@ -254,27 +241,4 @@ void CompressorEffect::processChannel( SampleUtil::applyGain(pOutput, db2ratio(gainParamDB), numSamples); */ - - - /* if (thresholdParam < 0.01) { - SampleUtil::copy(pOutput, pInput, numSamples); - return; - } - - switch (m_pAutoMakeUp->toInt()) { - case Off: - processCompressor( - thresholdParam, pState, pOutput, pInput, engineParameters); - break; - - case On: - processCompressor( - thresholdParam, pState, pOutput, pInput, engineParameters); - break; - - default: - // We should never enter here, but we act as a noop effect just in case. - SampleUtil::copy(pOutput, pInput, numSamples); - return; - }*/ } diff --git a/src/effects/backends/builtin/compressoreffect.h b/src/effects/backends/builtin/compressoreffect.h index caf8ca13d9d..bc4edc05de2 100644 --- a/src/effects/backends/builtin/compressoreffect.h +++ b/src/effects/backends/builtin/compressoreffect.h @@ -8,6 +8,10 @@ #include "util/sample.h" #include "util/types.h" +namespace { +constexpr double makeUpCoeff = 0.03; +} // anonymous namespace + class CompressorGroupState : public EffectState { public: CompressorGroupState(const mixxx::EngineParameters& engineParameters); From b5e8049dd866cd71a1a5afda8662a4faccde0630 Mon Sep 17 00:00:00 2001 From: Sergey Date: Tue, 7 Nov 2023 23:39:24 +0400 Subject: [PATCH 03/37] Split compressor logic and make up logic --- .../backends/builtin/compressoreffect.cpp | 29 ++++++++----------- .../backends/builtin/compressoreffect.h | 3 +- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/effects/backends/builtin/compressoreffect.cpp b/src/effects/backends/builtin/compressoreffect.cpp index a0dea5a6a3a..7604a7954b2 100644 --- a/src/effects/backends/builtin/compressoreffect.cpp +++ b/src/effects/backends/builtin/compressoreffect.cpp @@ -153,13 +153,11 @@ void CompressorEffect::processChannel( CSAMPLE ratioParam = static_cast(m_pRatio->value()); //CSAMPLE kneeParam = static_cast(m_pKnee->value()); //CSAMPLE kneeHalf = kneeParam / 2.0f; - CSAMPLE gainParamDB = static_cast(m_pGain->value()); CSAMPLE attackCoeff = exp(-1000.0 / (m_pAttack->value() * pState->samplerate)); CSAMPLE releaseCoeff = exp(-1000.0 / (m_pRelease->value() * pState->samplerate)); CSAMPLE stateDB = pState->previousStateDB; - CSAMPLE maxGain = thresholdParam; for (SINT i = 0; i < numSamples; i += channelCount) { CSAMPLE maxSample = std::max(fabs(pInput[i]), fabs(pInput[i + 1])); if (maxSample == CSAMPLE_ZERO) { @@ -185,30 +183,27 @@ void CompressorEffect::processChannel( overDB = stateDB; - CSAMPLE gainReductionDB = overDB * (1.0 / ratioParam - 1.0); - CSAMPLE gain = db2ratio(gainReductionDB + gainParamDB); + CSAMPLE gain = db2ratio(overDB * (1.0 / ratioParam - 1.0)); pOutput[i] = pInput[i] * gain; pOutput[i + 1] = pInput[i + 1] * gain; - - CSAMPLE totalGain = maxSampleDB + gainReductionDB; - if (totalGain > maxGain) { - maxGain = totalGain; - } } pState->previousStateDB = stateDB; if (m_pAutoMakeUp->toInt() == AutoMakeUpOn) { - CSAMPLE makeUpStateDB = pState->previousMakeUpGain; - CSAMPLE minGainReductionDB = -maxGain - 3.0; - makeUpStateDB = makeUpCoeff * minGainReductionDB + (1 - makeUpCoeff) * makeUpStateDB; - for (SINT i = 0; i < numSamples; i += channelCount) { - CSAMPLE gain = db2ratio(makeUpStateDB); - pOutput[i] = pOutput[i] * gain; - pOutput[i + 1] = pOutput[i + 1] * gain; + CSAMPLE makeUpState = pState->previousMakeUpGain; + CSAMPLE maxSample = SampleUtil::maxAbsAmplitude(pOutput, numSamples); + if (maxSample > CSAMPLE_ZERO) { + CSAMPLE minGainReduction = (1 / maxSample) * makeUpCoeff; + makeUpState = makeUpAttackCoeff * minGainReduction + (1 - makeUpAttackCoeff) * makeUpState; + pState->previousMakeUpGain = makeUpState; + + SampleUtil::applyGain(pOutput, makeUpState, numSamples); } - pState->previousMakeUpGain = makeUpStateDB; } + CSAMPLE gainParamDB = static_cast(m_pGain->value()); + SampleUtil::applyGain(pOutput, db2ratio(gainParamDB), numSamples); + if (m_pClipping->toInt() == ClippingOn) { SampleUtil::copyClampBuffer(pOutput, pOutput, numSamples); diff --git a/src/effects/backends/builtin/compressoreffect.h b/src/effects/backends/builtin/compressoreffect.h index bc4edc05de2..4280a4e91bd 100644 --- a/src/effects/backends/builtin/compressoreffect.h +++ b/src/effects/backends/builtin/compressoreffect.h @@ -9,7 +9,8 @@ #include "util/types.h" namespace { -constexpr double makeUpCoeff = 0.03; +constexpr double makeUpAttackCoeff = 0.03; +const double makeUpCoeff = 1 / pow(10, 0.15); } // anonymous namespace class CompressorGroupState : public EffectState { From b5fa5bdf057553460befe1bdc3ecdb1b07c4cb6b Mon Sep 17 00:00:00 2001 From: Sergey Date: Mon, 13 Nov 2023 22:42:28 +0400 Subject: [PATCH 04/37] Compression refactoring --- .../backends/builtin/compressoreffect.cpp | 103 ++++++------------ .../backends/builtin/compressoreffect.h | 2 + 2 files changed, 37 insertions(+), 68 deletions(-) diff --git a/src/effects/backends/builtin/compressoreffect.cpp b/src/effects/backends/builtin/compressoreffect.cpp index 7604a7954b2..18a96601b55 100644 --- a/src/effects/backends/builtin/compressoreffect.cpp +++ b/src/effects/backends/builtin/compressoreffect.cpp @@ -14,8 +14,7 @@ EffectManifestPointer CompressorEffect::getManifest() { pManifest->setShortName(QObject::tr("Compressor")); pManifest->setAuthor("The Mixxx Team"); pManifest->setVersion("1.0"); - pManifest->setDescription( - "A single-band compressor effect"); + pManifest->setDescription("A single-band compressor effect"); pManifest->setEffectRampsFromDry(true); pManifest->setMetaknobDefault(0.0); @@ -59,8 +58,7 @@ EffectManifestPointer CompressorEffect::getManifest() { ratio->setId("ratio"); ratio->setName(QObject::tr("Ratio (:1)")); ratio->setShortName(QObject::tr("Ratio")); - ratio->setDescription(QObject::tr( - "The amount of ratio.")); + ratio->setDescription(QObject::tr("The amount of ratio.")); ratio->setValueScaler(EffectManifestParameter::ValueScaler::Linear); //ratio->setDefaultLinkType(EffectManifestParameter::LinkType::Linked); ratio->setUnitsHint(EffectManifestParameter::UnitsHint::Coefficient); @@ -71,8 +69,7 @@ EffectManifestPointer CompressorEffect::getManifest() { knee->setId("knee"); knee->setName(QObject::tr("Knee (dB)")); knee->setShortName(QObject::tr("Knee")); - knee->setDescription(QObject::tr( - "The amount of knee.")); + knee->setDescription(QObject::tr("The amount of knee.")); knee->setValueScaler(EffectManifestParameter::ValueScaler::Linear); //knee->setDefaultLinkType(EffectManifestParameter::LinkType::Linked); knee->setUnitsHint(EffectManifestParameter::UnitsHint::Coefficient); @@ -83,8 +80,7 @@ EffectManifestPointer CompressorEffect::getManifest() { attack->setId("attack"); attack->setName(QObject::tr("Attack (ms)")); attack->setShortName(QObject::tr("Attack")); - attack->setDescription(QObject::tr( - "Attack")); + attack->setDescription(QObject::tr("Attack")); attack->setValueScaler(EffectManifestParameter::ValueScaler::Integral); attack->setUnitsHint(EffectManifestParameter::UnitsHint::Millisecond); attack->setRange(0, 30, 250); @@ -93,18 +89,16 @@ EffectManifestPointer CompressorEffect::getManifest() { release->setId("release"); release->setName(QObject::tr("Release (ms)")); release->setShortName(QObject::tr("Release")); - release->setDescription(QObject::tr( - "Release")); + release->setDescription(QObject::tr("Release")); release->setValueScaler(EffectManifestParameter::ValueScaler::Integral); release->setUnitsHint(EffectManifestParameter::UnitsHint::Millisecond); release->setRange(0, 150, 2000); EffectManifestParameterPointer gain = pManifest->addParameter(); gain->setId("gain"); - gain->setName(QObject::tr("Make up gain")); + gain->setName(QObject::tr("Output gain")); gain->setShortName(QObject::tr("Gain")); - gain->setDescription(QObject::tr( - "Gain")); + gain->setDescription(QObject::tr("Gain")); gain->setValueScaler(EffectManifestParameter::ValueScaler::Linear); gain->setUnitsHint(EffectManifestParameter::UnitsHint::Decibel); gain->setRange(-25, 0, 25); @@ -142,13 +136,36 @@ void CompressorEffect::processChannel( Q_UNUSED(groupFeatures); Q_UNUSED(enableState); - // TODO test: Marc Benjamin, Zana - Edge of Paradise; Cassette - Tell Me Why; Adele - Skyfall - // url: https://github.com/p-hlp/CTAGDRC - SINT numSamples = engineParameters.samplesPerBuffer(); int channelCount = engineParameters.channelCount(); - SINT numFrames = engineParameters.framesPerBuffer(); + // Compression + applyCompression(pState, numSamples, channelCount, pInput, pOutput); + + // Auto make up + if (m_pAutoMakeUp->toInt() == AutoMakeUpOn) { + CSAMPLE makeUpState = pState->previousMakeUpGain; + CSAMPLE maxSample = SampleUtil::maxAbsAmplitude(pOutput, numSamples); + if (maxSample > CSAMPLE_ZERO) { + CSAMPLE minGainReduction = (1 / maxSample) * makeUpCoeff; + makeUpState = makeUpAttackCoeff * minGainReduction + (1 - makeUpAttackCoeff) * makeUpState; + pState->previousMakeUpGain = makeUpState; + + SampleUtil::applyGain(pOutput, makeUpState, numSamples); + } + } + + // Output gain + CSAMPLE gainParamDB = static_cast(m_pGain->value()); + SampleUtil::applyGain(pOutput, db2ratio(gainParamDB), numSamples); + + // Clipping + if (m_pClipping->toInt() == ClippingOn) { + SampleUtil::copyClampBuffer(pOutput, pOutput, numSamples); + } +} + +void CompressorEffect::applyCompression(CompressorGroupState* pState, const SINT& numSamples, int channelCount, const CSAMPLE* pInput, CSAMPLE* pOutput) { CSAMPLE thresholdParam = static_cast(m_pThreshold->value()); CSAMPLE ratioParam = static_cast(m_pRatio->value()); //CSAMPLE kneeParam = static_cast(m_pKnee->value()); @@ -157,7 +174,6 @@ void CompressorEffect::processChannel( CSAMPLE releaseCoeff = exp(-1000.0 / (m_pRelease->value() * pState->samplerate)); CSAMPLE stateDB = pState->previousStateDB; - for (SINT i = 0; i < numSamples; i += channelCount) { CSAMPLE maxSample = std::max(fabs(pInput[i]), fabs(pInput[i + 1])); if (maxSample == CSAMPLE_ZERO) { @@ -181,59 +197,10 @@ void CompressorEffect::processChannel( stateDB = overDB + releaseCoeff * (stateDB - overDB); } - overDB = stateDB; CSAMPLE gain = db2ratio(overDB * (1.0 / ratioParam - 1.0)); pOutput[i] = pInput[i] * gain; pOutput[i + 1] = pInput[i + 1] * gain; } pState->previousStateDB = stateDB; - - if (m_pAutoMakeUp->toInt() == AutoMakeUpOn) { - CSAMPLE makeUpState = pState->previousMakeUpGain; - CSAMPLE maxSample = SampleUtil::maxAbsAmplitude(pOutput, numSamples); - if (maxSample > CSAMPLE_ZERO) { - CSAMPLE minGainReduction = (1 / maxSample) * makeUpCoeff; - makeUpState = makeUpAttackCoeff * minGainReduction + (1 - makeUpAttackCoeff) * makeUpState; - pState->previousMakeUpGain = makeUpState; - - SampleUtil::applyGain(pOutput, makeUpState, numSamples); - } - } - - CSAMPLE gainParamDB = static_cast(m_pGain->value()); - SampleUtil::applyGain(pOutput, db2ratio(gainParamDB), numSamples); - - - if (m_pClipping->toInt() == ClippingOn) { - SampleUtil::copyClampBuffer(pOutput, pOutput, numSamples); - } - - - //std::string msg2 = std::string("makeUpStateDB: ") + std::to_string(makeUpStateDB) + std::string(" stateDB: ") + std::to_string(stateDB) + std::string("\n"); - //OutputDebugStringA(msg2.c_str()); - - /* - if (m_pAutoMakeUp->toInt() == On) { - CSAMPLE sum = CSAMPLE_ZERO; - for (SINT i = 0; i < numSamples; i += channelCount) { - sum += std::max(fabs(pInput[i]), fabs(pInput[i + 1])); - } - CSAMPLE max = SampleUtil::maxAbsAmplitude(pOutput, numSamples); - if (max != CSAMPLE_ZERO) { - CSAMPLE averageDB = -ratio2db(max) - 2; - CSAMPLE makeUpSatetDB = pState->previousMakeUpGain; - - makeUpSatetDB = averageDB + makeUpCoeff * (makeUpSatetDB - averageDB); - std::string msg = std::string("makeUpCoeff: ") + std::to_string(makeUpCoeff) + std::string(" averageDB: ") + std::to_string(averageDB) + std::string(" makeUpSatetDB: ") + std::to_string(makeUpSatetDB) + std::string("\n"); - OutputDebugStringA(msg.c_str()); - - gainParamDB += averageDB; - pState->previousMakeUpGain = makeUpSatetDB; - } - } - - - SampleUtil::applyGain(pOutput, db2ratio(gainParamDB), numSamples); - */ -} +} \ No newline at end of file diff --git a/src/effects/backends/builtin/compressoreffect.h b/src/effects/backends/builtin/compressoreffect.h index 4280a4e91bd..30d2a409ae9 100644 --- a/src/effects/backends/builtin/compressoreffect.h +++ b/src/effects/backends/builtin/compressoreffect.h @@ -66,4 +66,6 @@ class CompressorEffect : public EffectProcessorImpl { EngineEffectParameterPointer m_pGain; DISALLOW_COPY_AND_ASSIGN(CompressorEffect); + + void applyCompression(CompressorGroupState* pState, const SINT& numSamples, int channelCount, const CSAMPLE* pInput, CSAMPLE* pOutput); }; From a2b70a425184ba328c28e651ae136b4c698ea038 Mon Sep 17 00:00:00 2001 From: Sergey Date: Mon, 13 Nov 2023 23:54:31 +0400 Subject: [PATCH 05/37] Add knee param + fixes --- .../backends/builtin/compressoreffect.cpp | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/effects/backends/builtin/compressoreffect.cpp b/src/effects/backends/builtin/compressoreffect.cpp index 18a96601b55..48b42860a1b 100644 --- a/src/effects/backends/builtin/compressoreffect.cpp +++ b/src/effects/backends/builtin/compressoreffect.cpp @@ -168,8 +168,8 @@ void CompressorEffect::processChannel( void CompressorEffect::applyCompression(CompressorGroupState* pState, const SINT& numSamples, int channelCount, const CSAMPLE* pInput, CSAMPLE* pOutput) { CSAMPLE thresholdParam = static_cast(m_pThreshold->value()); CSAMPLE ratioParam = static_cast(m_pRatio->value()); - //CSAMPLE kneeParam = static_cast(m_pKnee->value()); - //CSAMPLE kneeHalf = kneeParam / 2.0f; + CSAMPLE kneeParam = static_cast(m_pKnee->value()); + CSAMPLE kneeHalf = kneeParam / 2.0f; CSAMPLE attackCoeff = exp(-1000.0 / (m_pAttack->value() * pState->samplerate)); CSAMPLE releaseCoeff = exp(-1000.0 / (m_pRelease->value() * pState->samplerate)); @@ -184,21 +184,21 @@ void CompressorEffect::applyCompression(CompressorGroupState* pState, const SINT CSAMPLE maxSampleDB = ratio2db(maxSample); CSAMPLE overDB = maxSampleDB - thresholdParam; - //if (overDB <= kneeHalf) { - // overDB = 0.0f; - //} else if (overDB > -kneeHalf && overDB <= kneeHalf) { - // overDB = 0.5f * (overDB + kneeHalf) * (overDB + kneeHalf) / kneeParam; - //} + if (overDB <= -kneeHalf) { + overDB = 0.0f; + } else if (overDB > -kneeHalf && overDB <= kneeHalf) { + overDB = 0.5f * (overDB + kneeHalf) * (overDB + kneeHalf) / kneeParam; + } + CSAMPLE compressedDB = overDB * (1.0 / ratioParam - 1.0); // atack/release - if (overDB > stateDB) { - stateDB = overDB + attackCoeff * (stateDB - overDB); + if (compressedDB > stateDB) { + stateDB = compressedDB + attackCoeff * (stateDB - compressedDB); } else { - stateDB = overDB + releaseCoeff * (stateDB - overDB); + stateDB = compressedDB + releaseCoeff * (stateDB - compressedDB); } - overDB = stateDB; - CSAMPLE gain = db2ratio(overDB * (1.0 / ratioParam - 1.0)); + CSAMPLE gain = db2ratio(stateDB); pOutput[i] = pInput[i] * gain; pOutput[i + 1] = pInput[i + 1] * gain; } From 75a73b34f32dc6877e7131d1f0715238c4d0f75a Mon Sep 17 00:00:00 2001 From: Sergey Date: Sun, 26 Nov 2023 16:16:24 +0400 Subject: [PATCH 06/37] Auto make up fixes --- .../backends/builtin/compressoreffect.cpp | 28 +++++++++++++------ .../backends/builtin/compressoreffect.h | 6 ++-- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/effects/backends/builtin/compressoreffect.cpp b/src/effects/backends/builtin/compressoreffect.cpp index 48b42860a1b..7ddc6641466 100644 --- a/src/effects/backends/builtin/compressoreffect.cpp +++ b/src/effects/backends/builtin/compressoreffect.cpp @@ -144,15 +144,7 @@ void CompressorEffect::processChannel( // Auto make up if (m_pAutoMakeUp->toInt() == AutoMakeUpOn) { - CSAMPLE makeUpState = pState->previousMakeUpGain; - CSAMPLE maxSample = SampleUtil::maxAbsAmplitude(pOutput, numSamples); - if (maxSample > CSAMPLE_ZERO) { - CSAMPLE minGainReduction = (1 / maxSample) * makeUpCoeff; - makeUpState = makeUpAttackCoeff * minGainReduction + (1 - makeUpAttackCoeff) * makeUpState; - pState->previousMakeUpGain = makeUpState; - - SampleUtil::applyGain(pOutput, makeUpState, numSamples); - } + applyAutoMakeUp(pState, pOutput, numSamples); } // Output gain @@ -165,6 +157,24 @@ void CompressorEffect::processChannel( } } +void CompressorEffect::applyAutoMakeUp(CompressorGroupState* pState, CSAMPLE* pOutput, const SINT& numSamples) { + CSAMPLE makeUpStateDB = pState->previousMakeUpGain; + CSAMPLE maxSample = SampleUtil::maxAbsAmplitude(pOutput, numSamples); + if (maxSample > 0) { + CSAMPLE maxSampleDB = ratio2db(maxSample); + CSAMPLE minGainReductionDB = -maxSampleDB + makeUpTarget; + makeUpStateDB = makeUpAttackCoeff * minGainReductionDB + (1 - makeUpAttackCoeff) * makeUpStateDB; + CSAMPLE levelDB = makeUpStateDB + maxSampleDB; + // logarithmic smoothing + if (levelDB > -1.0) { + makeUpStateDB = log10(levelDB + 2) - 1 - maxSampleDB; + } + + pState->previousMakeUpGain = makeUpStateDB; + SampleUtil::applyGain(pOutput, db2ratio(makeUpStateDB), numSamples); + } +} + void CompressorEffect::applyCompression(CompressorGroupState* pState, const SINT& numSamples, int channelCount, const CSAMPLE* pInput, CSAMPLE* pOutput) { CSAMPLE thresholdParam = static_cast(m_pThreshold->value()); CSAMPLE ratioParam = static_cast(m_pRatio->value()); diff --git a/src/effects/backends/builtin/compressoreffect.h b/src/effects/backends/builtin/compressoreffect.h index 30d2a409ae9..828ac83cf18 100644 --- a/src/effects/backends/builtin/compressoreffect.h +++ b/src/effects/backends/builtin/compressoreffect.h @@ -9,8 +9,8 @@ #include "util/types.h" namespace { -constexpr double makeUpAttackCoeff = 0.03; -const double makeUpCoeff = 1 / pow(10, 0.15); + constexpr double makeUpAttackCoeff = 0.03; + constexpr double makeUpTarget = -3.0; } // anonymous namespace class CompressorGroupState : public EffectState { @@ -68,4 +68,6 @@ class CompressorEffect : public EffectProcessorImpl { DISALLOW_COPY_AND_ASSIGN(CompressorEffect); void applyCompression(CompressorGroupState* pState, const SINT& numSamples, int channelCount, const CSAMPLE* pInput, CSAMPLE* pOutput); + + void applyAutoMakeUp(CompressorGroupState* pState, CSAMPLE* pOutput, const SINT& numSamples); }; From 1c1adda9630e83ec5e22dbd5f6d24536ccbeec32 Mon Sep 17 00:00:00 2001 From: Sergey Date: Mon, 18 Dec 2023 19:36:04 +0100 Subject: [PATCH 07/37] Fix attack & release --- src/effects/backends/builtin/compressoreffect.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/effects/backends/builtin/compressoreffect.cpp b/src/effects/backends/builtin/compressoreffect.cpp index 7ddc6641466..7865cf16e51 100644 --- a/src/effects/backends/builtin/compressoreffect.cpp +++ b/src/effects/backends/builtin/compressoreffect.cpp @@ -83,7 +83,7 @@ EffectManifestPointer CompressorEffect::getManifest() { attack->setDescription(QObject::tr("Attack")); attack->setValueScaler(EffectManifestParameter::ValueScaler::Integral); attack->setUnitsHint(EffectManifestParameter::UnitsHint::Millisecond); - attack->setRange(0, 30, 250); + attack->setRange(0, 10, 100); EffectManifestParameterPointer release = pManifest->addParameter(); release->setId("release"); @@ -92,7 +92,7 @@ EffectManifestPointer CompressorEffect::getManifest() { release->setDescription(QObject::tr("Release")); release->setValueScaler(EffectManifestParameter::ValueScaler::Integral); release->setUnitsHint(EffectManifestParameter::UnitsHint::Millisecond); - release->setRange(0, 150, 2000); + release->setRange(0, 150, 1500); EffectManifestParameterPointer gain = pManifest->addParameter(); gain->setId("gain"); @@ -202,7 +202,7 @@ void CompressorEffect::applyCompression(CompressorGroupState* pState, const SINT CSAMPLE compressedDB = overDB * (1.0 / ratioParam - 1.0); // atack/release - if (compressedDB > stateDB) { + if (compressedDB < stateDB) { stateDB = compressedDB + attackCoeff * (stateDB - compressedDB); } else { stateDB = compressedDB + releaseCoeff * (stateDB - compressedDB); From 247624b4f378781b2dc21fc585a38b0550a8a601 Mon Sep 17 00:00:00 2001 From: Sergey Date: Wed, 20 Dec 2023 11:10:00 +0100 Subject: [PATCH 08/37] Attack & release fix --- src/effects/backends/builtin/compressoreffect.cpp | 12 ++++++------ src/effects/backends/builtin/compressoreffect.h | 3 +-- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/effects/backends/builtin/compressoreffect.cpp b/src/effects/backends/builtin/compressoreffect.cpp index 7865cf16e51..e20b7722def 100644 --- a/src/effects/backends/builtin/compressoreffect.cpp +++ b/src/effects/backends/builtin/compressoreffect.cpp @@ -109,7 +109,6 @@ EffectManifestPointer CompressorEffect::getManifest() { CompressorGroupState::CompressorGroupState( const mixxx::EngineParameters& engineParameters) : EffectState(engineParameters), - samplerate(engineParameters.sampleRate()), previousMakeUpGain(0), previousStateDB(0) { } @@ -137,10 +136,9 @@ void CompressorEffect::processChannel( Q_UNUSED(enableState); SINT numSamples = engineParameters.samplesPerBuffer(); - int channelCount = engineParameters.channelCount(); // Compression - applyCompression(pState, numSamples, channelCount, pInput, pOutput); + applyCompression(pState, engineParameters, pInput, pOutput); // Auto make up if (m_pAutoMakeUp->toInt() == AutoMakeUpOn) { @@ -175,15 +173,17 @@ void CompressorEffect::applyAutoMakeUp(CompressorGroupState* pState, CSAMPLE* pO } } -void CompressorEffect::applyCompression(CompressorGroupState* pState, const SINT& numSamples, int channelCount, const CSAMPLE* pInput, CSAMPLE* pOutput) { +void CompressorEffect::applyCompression(CompressorGroupState* pState, const mixxx::EngineParameters& engineParameters, const CSAMPLE* pInput, CSAMPLE* pOutput) { CSAMPLE thresholdParam = static_cast(m_pThreshold->value()); CSAMPLE ratioParam = static_cast(m_pRatio->value()); CSAMPLE kneeParam = static_cast(m_pKnee->value()); CSAMPLE kneeHalf = kneeParam / 2.0f; - CSAMPLE attackCoeff = exp(-1000.0 / (m_pAttack->value() * pState->samplerate)); - CSAMPLE releaseCoeff = exp(-1000.0 / (m_pRelease->value() * pState->samplerate)); + CSAMPLE attackCoeff = exp(-1000.0 / (m_pAttack->value() * engineParameters.sampleRate())); + CSAMPLE releaseCoeff = exp(-1000.0 / (m_pRelease->value() * engineParameters.sampleRate())); CSAMPLE stateDB = pState->previousStateDB; + SINT numSamples = engineParameters.samplesPerBuffer(); + int channelCount = engineParameters.channelCount(); for (SINT i = 0; i < numSamples; i += channelCount) { CSAMPLE maxSample = std::max(fabs(pInput[i]), fabs(pInput[i + 1])); if (maxSample == CSAMPLE_ZERO) { diff --git a/src/effects/backends/builtin/compressoreffect.h b/src/effects/backends/builtin/compressoreffect.h index 828ac83cf18..9e65ac4a2ca 100644 --- a/src/effects/backends/builtin/compressoreffect.h +++ b/src/effects/backends/builtin/compressoreffect.h @@ -17,7 +17,6 @@ class CompressorGroupState : public EffectState { public: CompressorGroupState(const mixxx::EngineParameters& engineParameters); - double samplerate; CSAMPLE previousStateDB; CSAMPLE previousMakeUpGain; }; @@ -67,7 +66,7 @@ class CompressorEffect : public EffectProcessorImpl { DISALLOW_COPY_AND_ASSIGN(CompressorEffect); - void applyCompression(CompressorGroupState* pState, const SINT& numSamples, int channelCount, const CSAMPLE* pInput, CSAMPLE* pOutput); + void applyCompression(CompressorGroupState* pState, const mixxx::EngineParameters& engineParameters, const CSAMPLE* pInput, CSAMPLE* pOutput); void applyAutoMakeUp(CompressorGroupState* pState, CSAMPLE* pOutput, const SINT& numSamples); }; From 92f231fee977d35d617649ac3a76e29efe534602 Mon Sep 17 00:00:00 2001 From: Sergey Date: Sat, 6 Jan 2024 18:26:47 +0100 Subject: [PATCH 09/37] Add descriptions + change Attack knob to logarithmic --- .../backends/builtin/compressoreffect.cpp | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/effects/backends/builtin/compressoreffect.cpp b/src/effects/backends/builtin/compressoreffect.cpp index e20b7722def..d74401fae8d 100644 --- a/src/effects/backends/builtin/compressoreffect.cpp +++ b/src/effects/backends/builtin/compressoreffect.cpp @@ -30,26 +30,23 @@ EffectManifestPointer CompressorEffect::getManifest() { EffectManifestParameterPointer autoMakeUp = pManifest->addParameter(); autoMakeUp->setId("automakeup"); - autoMakeUp->setName(QObject::tr("Auto Make Up Gain")); - autoMakeUp->setShortName(QObject::tr("Make Up")); + autoMakeUp->setName(QObject::tr("Auto Makeup Gain")); + autoMakeUp->setShortName(QObject::tr("Makeup")); autoMakeUp->setDescription(QObject::tr( - "Auto make up gain to 0 db level")); + "The AutoMakeup button enables automatic makeup gain to 0 db level")); autoMakeUp->setValueScaler(EffectManifestParameter::ValueScaler::Toggle); autoMakeUp->setRange(0, 1, 1); autoMakeUp->appendStep(qMakePair(QObject::tr("Off"), AutoMakeUp::AutoMakeUpOff)); autoMakeUp->appendStep(qMakePair(QObject::tr("On"), AutoMakeUp::AutoMakeUpOn)); - //TODO description EffectManifestParameterPointer threshold = pManifest->addParameter(); threshold->setId("threshold"); threshold->setName(QObject::tr("Threshold (dB)")); threshold->setShortName(QObject::tr("Threshold")); threshold->setDescription(QObject::tr( - "The amount of amplification " - "applied to the audio signal. At higher levels the audio will be more distored.")); + "The Threshold knob adjusts the level above which the compressor starts attenuating the input signal")); threshold->setValueScaler(EffectManifestParameter::ValueScaler::Linear); - //threshold->setDefaultLinkType(EffectManifestParameter::LinkType::Linked); threshold->setUnitsHint(EffectManifestParameter::UnitsHint::Decibel); threshold->setNeutralPointOnScale(0); threshold->setRange(-50, -20, 0); @@ -58,20 +55,20 @@ EffectManifestPointer CompressorEffect::getManifest() { ratio->setId("ratio"); ratio->setName(QObject::tr("Ratio (:1)")); ratio->setShortName(QObject::tr("Ratio")); - ratio->setDescription(QObject::tr("The amount of ratio.")); - ratio->setValueScaler(EffectManifestParameter::ValueScaler::Linear); - //ratio->setDefaultLinkType(EffectManifestParameter::LinkType::Linked); + ratio->setDescription(QObject::tr("The Ratio knob determines how much the signal is attenuated above the chosen threshold. " + "For a ratio of 4:1, one dB remains for every 4dB of input signal above the threshold. " + "At a ratio of 1:1 no compression is happening, as the input is exactly the output")); + ratio->setValueScaler(EffectManifestParameter::ValueScaler::Logarithmic); ratio->setUnitsHint(EffectManifestParameter::UnitsHint::Coefficient); ratio->setNeutralPointOnScale(0); - ratio->setRange(1.0, 4.0, 20); + ratio->setRange(1.0, 4.0, 1000); EffectManifestParameterPointer knee = pManifest->addParameter(); knee->setId("knee"); knee->setName(QObject::tr("Knee (dB)")); knee->setShortName(QObject::tr("Knee")); - knee->setDescription(QObject::tr("The amount of knee.")); + knee->setDescription(QObject::tr("The Knee knob is used to achieve a rounder compression curve")); knee->setValueScaler(EffectManifestParameter::ValueScaler::Linear); - //knee->setDefaultLinkType(EffectManifestParameter::LinkType::Linked); knee->setUnitsHint(EffectManifestParameter::UnitsHint::Coefficient); knee->setNeutralPointOnScale(0); knee->setRange(0.0, 4.0, 24); @@ -80,16 +77,19 @@ EffectManifestPointer CompressorEffect::getManifest() { attack->setId("attack"); attack->setName(QObject::tr("Attack (ms)")); attack->setShortName(QObject::tr("Attack")); - attack->setDescription(QObject::tr("Attack")); - attack->setValueScaler(EffectManifestParameter::ValueScaler::Integral); + attack->setDescription(QObject::tr( + "The Attack knob sets the time that determines how fast the compression will set in once the signal exceeds the threshold")); + attack->setValueScaler(EffectManifestParameter::ValueScaler::Logarithmic); attack->setUnitsHint(EffectManifestParameter::UnitsHint::Millisecond); - attack->setRange(0, 10, 100); + attack->setRange(0, 10, 250); EffectManifestParameterPointer release = pManifest->addParameter(); release->setId("release"); release->setName(QObject::tr("Release (ms)")); release->setShortName(QObject::tr("Release")); - release->setDescription(QObject::tr("Release")); + release->setDescription(QObject::tr( + "The Release knob sets the time that determines how fast the compressor will recover from the gain reduction once the signal falls under the threshold. " + "Depending on the input signal, short release times may introduce a 'pumping' effect and/or distortion")); release->setValueScaler(EffectManifestParameter::ValueScaler::Integral); release->setUnitsHint(EffectManifestParameter::UnitsHint::Millisecond); release->setRange(0, 150, 1500); @@ -98,7 +98,7 @@ EffectManifestPointer CompressorEffect::getManifest() { gain->setId("gain"); gain->setName(QObject::tr("Output gain")); gain->setShortName(QObject::tr("Gain")); - gain->setDescription(QObject::tr("Gain")); + gain->setDescription(QObject::tr("The Output gain knob adjusts the level of the output signal after the compression was applied")); gain->setValueScaler(EffectManifestParameter::ValueScaler::Linear); gain->setUnitsHint(EffectManifestParameter::UnitsHint::Decibel); gain->setRange(-25, 0, 25); From 6e3c846fd2aeea7d91791b43d0d3007d507558d1 Mon Sep 17 00:00:00 2001 From: Sergey Date: Sat, 6 Jan 2024 18:36:51 +0100 Subject: [PATCH 10/37] Remove unnecessary include --- src/effects/backends/builtin/compressoreffect.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/effects/backends/builtin/compressoreffect.cpp b/src/effects/backends/builtin/compressoreffect.cpp index d74401fae8d..98744f2c199 100644 --- a/src/effects/backends/builtin/compressoreffect.cpp +++ b/src/effects/backends/builtin/compressoreffect.cpp @@ -1,5 +1,4 @@ #include "effects/backends/builtin/compressoreffect.h" -#include // static QString CompressorEffect::getId() { From c8dba6af6ed54c8cd17e44c9dec2b923bb24771a Mon Sep 17 00:00:00 2001 From: Sergey Date: Sat, 13 Jan 2024 17:23:03 +0400 Subject: [PATCH 11/37] Update src/effects/backends/builtin/compressoreffect.h Co-authored-by: Swiftb0y <12380386+Swiftb0y@users.noreply.github.com> --- src/effects/backends/builtin/compressoreffect.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/effects/backends/builtin/compressoreffect.h b/src/effects/backends/builtin/compressoreffect.h index 9e65ac4a2ca..3e97ff725b6 100644 --- a/src/effects/backends/builtin/compressoreffect.h +++ b/src/effects/backends/builtin/compressoreffect.h @@ -9,8 +9,8 @@ #include "util/types.h" namespace { - constexpr double makeUpAttackCoeff = 0.03; - constexpr double makeUpTarget = -3.0; + constexpr CSAMPLE_GAIN kMakeUpAttackCoeff = 0.03; + constexpr CSAMPLE_GAIN kMakeUpTarget = -3.0; } // anonymous namespace class CompressorGroupState : public EffectState { From 3b6f3694f025dacf79c30d1e5127ed87d64656b5 Mon Sep 17 00:00:00 2001 From: Sergey Date: Sat, 13 Jan 2024 17:23:41 +0400 Subject: [PATCH 12/37] Update src/effects/backends/builtin/compressoreffect.h Co-authored-by: Swiftb0y <12380386+Swiftb0y@users.noreply.github.com> --- src/effects/backends/builtin/compressoreffect.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/effects/backends/builtin/compressoreffect.h b/src/effects/backends/builtin/compressoreffect.h index 3e97ff725b6..ad8ab7b6234 100644 --- a/src/effects/backends/builtin/compressoreffect.h +++ b/src/effects/backends/builtin/compressoreffect.h @@ -41,12 +41,12 @@ class CompressorEffect : public EffectProcessorImpl { private: - enum AutoMakeUp { + enum class AutoMakeUp { AutoMakeUpOff = 0, AutoMakeUpOn = 1, }; - enum Clipping { + enum class Clipping { ClippingOff = 0, ClippingOn = 1, }; From 3c9cebe83e09ee6bce8d05c4d3bca93dee438b1d Mon Sep 17 00:00:00 2001 From: Sergey Date: Sat, 13 Jan 2024 17:23:59 +0400 Subject: [PATCH 13/37] Update src/effects/backends/builtin/compressoreffect.cpp Co-authored-by: Swiftb0y <12380386+Swiftb0y@users.noreply.github.com> --- src/effects/backends/builtin/compressoreffect.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/effects/backends/builtin/compressoreffect.cpp b/src/effects/backends/builtin/compressoreffect.cpp index 98744f2c199..29582721961 100644 --- a/src/effects/backends/builtin/compressoreffect.cpp +++ b/src/effects/backends/builtin/compressoreffect.cpp @@ -7,7 +7,7 @@ QString CompressorEffect::getId() { //static EffectManifestPointer CompressorEffect::getManifest() { - EffectManifestPointer pManifest(new EffectManifest); + auto pManifest = EffectManifestPointer::create(); pManifest->setId(getId()); pManifest->setName(QObject::tr("Compressor")); pManifest->setShortName(QObject::tr("Compressor")); From 503fc79c8e775b3f96c4f6a121c6ea43305133f0 Mon Sep 17 00:00:00 2001 From: Sergey Date: Sat, 13 Jan 2024 17:24:22 +0400 Subject: [PATCH 14/37] Update src/effects/backends/builtin/compressoreffect.cpp Co-authored-by: Swiftb0y <12380386+Swiftb0y@users.noreply.github.com> --- src/effects/backends/builtin/compressoreffect.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/effects/backends/builtin/compressoreffect.cpp b/src/effects/backends/builtin/compressoreffect.cpp index 29582721961..8f654f8110b 100644 --- a/src/effects/backends/builtin/compressoreffect.cpp +++ b/src/effects/backends/builtin/compressoreffect.cpp @@ -108,8 +108,8 @@ EffectManifestPointer CompressorEffect::getManifest() { CompressorGroupState::CompressorGroupState( const mixxx::EngineParameters& engineParameters) : EffectState(engineParameters), - previousMakeUpGain(0), - previousStateDB(0) { + previousStateDB(0), + previousMakeUpGain(0) { } void CompressorEffect::loadEngineEffectParameters( From 68cb60a9acb809c20bf258d555efdf2ef0a1764b Mon Sep 17 00:00:00 2001 From: Sergey Date: Sat, 13 Jan 2024 17:54:22 +0400 Subject: [PATCH 15/37] Update src/effects/backends/builtin/compressoreffect.cpp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Daniel Schürmann --- src/effects/backends/builtin/compressoreffect.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/effects/backends/builtin/compressoreffect.cpp b/src/effects/backends/builtin/compressoreffect.cpp index 8f654f8110b..d9aeefa1cd0 100644 --- a/src/effects/backends/builtin/compressoreffect.cpp +++ b/src/effects/backends/builtin/compressoreffect.cpp @@ -21,7 +21,7 @@ EffectManifestPointer CompressorEffect::getManifest() { clipping->setId("clipping"); clipping->setName(QObject::tr("Clipping")); clipping->setShortName(QObject::tr("Clipping")); - clipping->setDescription(QObject::tr("Hard limiter to 0 db")); + clipping->setDescription(QObject::tr("Hard limiter to full scale")); clipping->setValueScaler(EffectManifestParameter::ValueScaler::Toggle); clipping->setRange(0, 1, 1); clipping->appendStep(qMakePair(QObject::tr("Off"), Clipping::ClippingOff)); From 3494bffedd0b78e672d75cf2dc8eeaae643d0486 Mon Sep 17 00:00:00 2001 From: Sergey Date: Sat, 13 Jan 2024 18:00:27 +0400 Subject: [PATCH 16/37] Update src/effects/backends/builtin/compressoreffect.cpp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Daniel Schürmann --- src/effects/backends/builtin/compressoreffect.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/effects/backends/builtin/compressoreffect.cpp b/src/effects/backends/builtin/compressoreffect.cpp index d9aeefa1cd0..92af925ab53 100644 --- a/src/effects/backends/builtin/compressoreffect.cpp +++ b/src/effects/backends/builtin/compressoreffect.cpp @@ -41,7 +41,7 @@ EffectManifestPointer CompressorEffect::getManifest() { EffectManifestParameterPointer threshold = pManifest->addParameter(); threshold->setId("threshold"); - threshold->setName(QObject::tr("Threshold (dB)")); + threshold->setName(QObject::tr("Threshold (dBFS)")); threshold->setShortName(QObject::tr("Threshold")); threshold->setDescription(QObject::tr( "The Threshold knob adjusts the level above which the compressor starts attenuating the input signal")); From fee6e99d36f4151c371b6fbe4c5cf609e24c844b Mon Sep 17 00:00:00 2001 From: Sergey Date: Sat, 13 Jan 2024 15:57:06 +0100 Subject: [PATCH 17/37] AutoMakeUp & Clipping enum fixes --- .../backends/builtin/compressoreffect.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/effects/backends/builtin/compressoreffect.cpp b/src/effects/backends/builtin/compressoreffect.cpp index 92af925ab53..9246871679d 100644 --- a/src/effects/backends/builtin/compressoreffect.cpp +++ b/src/effects/backends/builtin/compressoreffect.cpp @@ -24,8 +24,8 @@ EffectManifestPointer CompressorEffect::getManifest() { clipping->setDescription(QObject::tr("Hard limiter to full scale")); clipping->setValueScaler(EffectManifestParameter::ValueScaler::Toggle); clipping->setRange(0, 1, 1); - clipping->appendStep(qMakePair(QObject::tr("Off"), Clipping::ClippingOff)); - clipping->appendStep(qMakePair(QObject::tr("On"), Clipping::ClippingOn)); + clipping->appendStep(qMakePair(QObject::tr("Off"), static_cast(Clipping::ClippingOff))); + clipping->appendStep(qMakePair(QObject::tr("On"), static_cast(Clipping::ClippingOn))); EffectManifestParameterPointer autoMakeUp = pManifest->addParameter(); autoMakeUp->setId("automakeup"); @@ -35,8 +35,8 @@ EffectManifestPointer CompressorEffect::getManifest() { "The AutoMakeup button enables automatic makeup gain to 0 db level")); autoMakeUp->setValueScaler(EffectManifestParameter::ValueScaler::Toggle); autoMakeUp->setRange(0, 1, 1); - autoMakeUp->appendStep(qMakePair(QObject::tr("Off"), AutoMakeUp::AutoMakeUpOff)); - autoMakeUp->appendStep(qMakePair(QObject::tr("On"), AutoMakeUp::AutoMakeUpOn)); + autoMakeUp->appendStep(qMakePair(QObject::tr("Off"), static_cast(AutoMakeUp::AutoMakeUpOff))); + autoMakeUp->appendStep(qMakePair(QObject::tr("On"), static_cast(AutoMakeUp::AutoMakeUpOn))); EffectManifestParameterPointer threshold = pManifest->addParameter(); @@ -140,7 +140,7 @@ void CompressorEffect::processChannel( applyCompression(pState, engineParameters, pInput, pOutput); // Auto make up - if (m_pAutoMakeUp->toInt() == AutoMakeUpOn) { + if (m_pAutoMakeUp->toInt() == static_cast(AutoMakeUp::AutoMakeUpOn)) { applyAutoMakeUp(pState, pOutput, numSamples); } @@ -149,7 +149,7 @@ void CompressorEffect::processChannel( SampleUtil::applyGain(pOutput, db2ratio(gainParamDB), numSamples); // Clipping - if (m_pClipping->toInt() == ClippingOn) { + if (m_pClipping->toInt() == static_cast(Clipping::ClippingOn)) { SampleUtil::copyClampBuffer(pOutput, pOutput, numSamples); } } @@ -159,8 +159,8 @@ void CompressorEffect::applyAutoMakeUp(CompressorGroupState* pState, CSAMPLE* pO CSAMPLE maxSample = SampleUtil::maxAbsAmplitude(pOutput, numSamples); if (maxSample > 0) { CSAMPLE maxSampleDB = ratio2db(maxSample); - CSAMPLE minGainReductionDB = -maxSampleDB + makeUpTarget; - makeUpStateDB = makeUpAttackCoeff * minGainReductionDB + (1 - makeUpAttackCoeff) * makeUpStateDB; + CSAMPLE minGainReductionDB = -maxSampleDB + kMakeUpTarget; + makeUpStateDB = kMakeUpAttackCoeff * minGainReductionDB + (1 - kMakeUpAttackCoeff) * makeUpStateDB; CSAMPLE levelDB = makeUpStateDB + maxSampleDB; // logarithmic smoothing if (levelDB > -1.0) { From 0c337ab709afb30e920057b74393f1df38459e33 Mon Sep 17 00:00:00 2001 From: Sergey Date: Sat, 13 Jan 2024 16:33:47 +0100 Subject: [PATCH 18/37] Fix formatting --- src/effects/backends/builtin/compressoreffect.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/effects/backends/builtin/compressoreffect.cpp b/src/effects/backends/builtin/compressoreffect.cpp index 9246871679d..1b7808bbb69 100644 --- a/src/effects/backends/builtin/compressoreffect.cpp +++ b/src/effects/backends/builtin/compressoreffect.cpp @@ -200,7 +200,7 @@ void CompressorEffect::applyCompression(CompressorGroupState* pState, const mixx } CSAMPLE compressedDB = overDB * (1.0 / ratioParam - 1.0); - // atack/release + // attack/release if (compressedDB < stateDB) { stateDB = compressedDB + attackCoeff * (stateDB - compressedDB); } else { @@ -212,4 +212,4 @@ void CompressorEffect::applyCompression(CompressorGroupState* pState, const mixx pOutput[i + 1] = pInput[i + 1] * gain; } pState->previousStateDB = stateDB; -} \ No newline at end of file +} From f519762955375314f32bcc94df5f341abae9a2db Mon Sep 17 00:00:00 2001 From: Sergey Date: Sat, 13 Jan 2024 16:59:07 +0100 Subject: [PATCH 19/37] Add applyClamp function to SampleUtil --- src/effects/backends/builtin/compressoreffect.cpp | 4 ++-- src/util/sample.cpp | 8 ++++++++ src/util/sample.h | 3 +++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/effects/backends/builtin/compressoreffect.cpp b/src/effects/backends/builtin/compressoreffect.cpp index 1b7808bbb69..23cf0ee5e30 100644 --- a/src/effects/backends/builtin/compressoreffect.cpp +++ b/src/effects/backends/builtin/compressoreffect.cpp @@ -64,7 +64,7 @@ EffectManifestPointer CompressorEffect::getManifest() { EffectManifestParameterPointer knee = pManifest->addParameter(); knee->setId("knee"); - knee->setName(QObject::tr("Knee (dB)")); + knee->setName(QObject::tr("Knee (dBFS)")); knee->setShortName(QObject::tr("Knee")); knee->setDescription(QObject::tr("The Knee knob is used to achieve a rounder compression curve")); knee->setValueScaler(EffectManifestParameter::ValueScaler::Linear); @@ -150,7 +150,7 @@ void CompressorEffect::processChannel( // Clipping if (m_pClipping->toInt() == static_cast(Clipping::ClippingOn)) { - SampleUtil::copyClampBuffer(pOutput, pOutput, numSamples); + SampleUtil::applyClamp(pOutput, numSamples); } } diff --git a/src/util/sample.cpp b/src/util/sample.cpp index 56bf630c728..dd8ea766553 100644 --- a/src/util/sample.cpp +++ b/src/util/sample.cpp @@ -480,6 +480,14 @@ void SampleUtil::copyClampBuffer(CSAMPLE* M_RESTRICT pDest, } } +// static +void SampleUtil::applyClamp(CSAMPLE* pBuffer, SINT iNumSamples) { + // note: LOOP VECTORIZED. + for (SINT i = 0; i < iNumSamples; ++i) { + pBuffer[i] = clampSample(pBuffer[i]); + } +} + // static void SampleUtil::interleaveBuffer(CSAMPLE* M_RESTRICT pDest, const CSAMPLE* M_RESTRICT pSrc1, diff --git a/src/util/sample.h b/src/util/sample.h index f94c87ca4fb..6ba8f6b3964 100644 --- a/src/util/sample.h +++ b/src/util/sample.h @@ -235,6 +235,9 @@ class SampleUtil { static void copyClampBuffer(CSAMPLE* pDest, const CSAMPLE* pSrc, SINT numSamples); + // Limiting every value in pBuffer to the valid range of CSAMPLE + static void applyClamp(CSAMPLE* pBuffer, SINT iNumSamples); + // Interleave the samples in pSrc1 and pSrc2 into pDest. iNumSamples must be // the number of samples in pSrc1 and pSrc2, and pDest must have at least // space for iNumSamples*2 samples. pDest must not be an alias of pSrc1 or From 97aafcb69e1aeea703ee29ac9006b0422ee75738 Mon Sep 17 00:00:00 2001 From: Sergey Date: Sat, 13 Jan 2024 20:12:47 +0100 Subject: [PATCH 20/37] Fix formatting 2 --- .../backends/builtin/builtinbackend.cpp | 2 +- .../backends/builtin/compressoreffect.cpp | 50 +++++++++++++------ .../backends/builtin/compressoreffect.h | 7 ++- 3 files changed, 38 insertions(+), 21 deletions(-) diff --git a/src/effects/backends/builtin/builtinbackend.cpp b/src/effects/backends/builtin/builtinbackend.cpp index cd2b548b566..b4b71425301 100644 --- a/src/effects/backends/builtin/builtinbackend.cpp +++ b/src/effects/backends/builtin/builtinbackend.cpp @@ -17,8 +17,8 @@ #include "effects/backends/builtin/reverbeffect.h" #endif #include "effects/backends/builtin/autopaneffect.h" -#include "effects/backends/builtin/distortioneffect.h" #include "effects/backends/builtin/compressoreffect.h" +#include "effects/backends/builtin/distortioneffect.h" #include "effects/backends/builtin/echoeffect.h" #include "effects/backends/builtin/glitcheffect.h" #include "effects/backends/builtin/loudnesscontoureffect.h" diff --git a/src/effects/backends/builtin/compressoreffect.cpp b/src/effects/backends/builtin/compressoreffect.cpp index 23cf0ee5e30..d376f5d4472 100644 --- a/src/effects/backends/builtin/compressoreffect.cpp +++ b/src/effects/backends/builtin/compressoreffect.cpp @@ -5,7 +5,7 @@ QString CompressorEffect::getId() { return "org.mixxx.effects.compressor"; } -//static +// static EffectManifestPointer CompressorEffect::getManifest() { auto pManifest = EffectManifestPointer::create(); pManifest->setId(getId()); @@ -35,9 +35,10 @@ EffectManifestPointer CompressorEffect::getManifest() { "The AutoMakeup button enables automatic makeup gain to 0 db level")); autoMakeUp->setValueScaler(EffectManifestParameter::ValueScaler::Toggle); autoMakeUp->setRange(0, 1, 1); - autoMakeUp->appendStep(qMakePair(QObject::tr("Off"), static_cast(AutoMakeUp::AutoMakeUpOff))); - autoMakeUp->appendStep(qMakePair(QObject::tr("On"), static_cast(AutoMakeUp::AutoMakeUpOn))); - + autoMakeUp->appendStep(qMakePair( + QObject::tr("Off"), static_cast(AutoMakeUp::AutoMakeUpOff))); + autoMakeUp->appendStep(qMakePair( + QObject::tr("On"), static_cast(AutoMakeUp::AutoMakeUpOn))); EffectManifestParameterPointer threshold = pManifest->addParameter(); threshold->setId("threshold"); @@ -54,9 +55,13 @@ EffectManifestPointer CompressorEffect::getManifest() { ratio->setId("ratio"); ratio->setName(QObject::tr("Ratio (:1)")); ratio->setShortName(QObject::tr("Ratio")); - ratio->setDescription(QObject::tr("The Ratio knob determines how much the signal is attenuated above the chosen threshold. " - "For a ratio of 4:1, one dB remains for every 4dB of input signal above the threshold. " - "At a ratio of 1:1 no compression is happening, as the input is exactly the output")); + ratio->setDescription( + QObject::tr("The Ratio knob determines how much the signal is " + "attenuated above the chosen threshold. " + "For a ratio of 4:1, one dB remains for every 4dB of " + "input signal above the threshold. " + "At a ratio of 1:1 no compression is happening, as the " + "input is exactly the output")); ratio->setValueScaler(EffectManifestParameter::ValueScaler::Logarithmic); ratio->setUnitsHint(EffectManifestParameter::UnitsHint::Coefficient); ratio->setNeutralPointOnScale(0); @@ -66,7 +71,8 @@ EffectManifestPointer CompressorEffect::getManifest() { knee->setId("knee"); knee->setName(QObject::tr("Knee (dBFS)")); knee->setShortName(QObject::tr("Knee")); - knee->setDescription(QObject::tr("The Knee knob is used to achieve a rounder compression curve")); + knee->setDescription(QObject::tr( + "The Knee knob is used to achieve a rounder compression curve")); knee->setValueScaler(EffectManifestParameter::ValueScaler::Linear); knee->setUnitsHint(EffectManifestParameter::UnitsHint::Coefficient); knee->setNeutralPointOnScale(0); @@ -77,7 +83,8 @@ EffectManifestPointer CompressorEffect::getManifest() { attack->setName(QObject::tr("Attack (ms)")); attack->setShortName(QObject::tr("Attack")); attack->setDescription(QObject::tr( - "The Attack knob sets the time that determines how fast the compression will set in once the signal exceeds the threshold")); + "The Attack knob sets the time that determines how fast the " + "compression will set in once the signal exceeds the threshold")); attack->setValueScaler(EffectManifestParameter::ValueScaler::Logarithmic); attack->setUnitsHint(EffectManifestParameter::UnitsHint::Millisecond); attack->setRange(0, 10, 250); @@ -86,9 +93,12 @@ EffectManifestPointer CompressorEffect::getManifest() { release->setId("release"); release->setName(QObject::tr("Release (ms)")); release->setShortName(QObject::tr("Release")); - release->setDescription(QObject::tr( - "The Release knob sets the time that determines how fast the compressor will recover from the gain reduction once the signal falls under the threshold. " - "Depending on the input signal, short release times may introduce a 'pumping' effect and/or distortion")); + release->setDescription( + QObject::tr("The Release knob sets the time that determines how " + "fast the compressor will recover from the gain " + "reduction once the signal falls under the threshold. " + "Depending on the input signal, short release times " + "may introduce a 'pumping' effect and/or distortion")); release->setValueScaler(EffectManifestParameter::ValueScaler::Integral); release->setUnitsHint(EffectManifestParameter::UnitsHint::Millisecond); release->setRange(0, 150, 1500); @@ -97,7 +107,9 @@ EffectManifestPointer CompressorEffect::getManifest() { gain->setId("gain"); gain->setName(QObject::tr("Output gain")); gain->setShortName(QObject::tr("Gain")); - gain->setDescription(QObject::tr("The Output gain knob adjusts the level of the output signal after the compression was applied")); + gain->setDescription( + QObject::tr("The Output gain knob adjusts the level of the output " + "signal after the compression was applied")); gain->setValueScaler(EffectManifestParameter::ValueScaler::Linear); gain->setUnitsHint(EffectManifestParameter::UnitsHint::Decibel); gain->setRange(-25, 0, 25); @@ -154,13 +166,16 @@ void CompressorEffect::processChannel( } } -void CompressorEffect::applyAutoMakeUp(CompressorGroupState* pState, CSAMPLE* pOutput, const SINT& numSamples) { +void CompressorEffect::applyAutoMakeUp(CompressorGroupState* pState, + CSAMPLE* pOutput, + const SINT& numSamples) { CSAMPLE makeUpStateDB = pState->previousMakeUpGain; CSAMPLE maxSample = SampleUtil::maxAbsAmplitude(pOutput, numSamples); if (maxSample > 0) { CSAMPLE maxSampleDB = ratio2db(maxSample); CSAMPLE minGainReductionDB = -maxSampleDB + kMakeUpTarget; - makeUpStateDB = kMakeUpAttackCoeff * minGainReductionDB + (1 - kMakeUpAttackCoeff) * makeUpStateDB; + makeUpStateDB = kMakeUpAttackCoeff * minGainReductionDB + + (1 - kMakeUpAttackCoeff) * makeUpStateDB; CSAMPLE levelDB = makeUpStateDB + maxSampleDB; // logarithmic smoothing if (levelDB > -1.0) { @@ -172,7 +187,10 @@ void CompressorEffect::applyAutoMakeUp(CompressorGroupState* pState, CSAMPLE* pO } } -void CompressorEffect::applyCompression(CompressorGroupState* pState, const mixxx::EngineParameters& engineParameters, const CSAMPLE* pInput, CSAMPLE* pOutput) { +void CompressorEffect::applyCompression(CompressorGroupState* pState, + const mixxx::EngineParameters& engineParameters, + const CSAMPLE* pInput, + CSAMPLE* pOutput) { CSAMPLE thresholdParam = static_cast(m_pThreshold->value()); CSAMPLE ratioParam = static_cast(m_pRatio->value()); CSAMPLE kneeParam = static_cast(m_pKnee->value()); diff --git a/src/effects/backends/builtin/compressoreffect.h b/src/effects/backends/builtin/compressoreffect.h index ad8ab7b6234..fdbae215f44 100644 --- a/src/effects/backends/builtin/compressoreffect.h +++ b/src/effects/backends/builtin/compressoreffect.h @@ -9,8 +9,8 @@ #include "util/types.h" namespace { - constexpr CSAMPLE_GAIN kMakeUpAttackCoeff = 0.03; - constexpr CSAMPLE_GAIN kMakeUpTarget = -3.0; +constexpr CSAMPLE_GAIN kMakeUpAttackCoeff = 0.03; +constexpr CSAMPLE_GAIN kMakeUpTarget = -3.0; } // anonymous namespace class CompressorGroupState : public EffectState { @@ -39,8 +39,7 @@ class CompressorEffect : public EffectProcessorImpl { const EffectEnableState enableState, const GroupFeatureState& groupFeatures) override; - private: - + private: enum class AutoMakeUp { AutoMakeUpOff = 0, AutoMakeUpOn = 1, From 5f624ea3e231bbe0a38dc9af926f609dee401254 Mon Sep 17 00:00:00 2001 From: Sergey Date: Sat, 13 Jan 2024 20:13:37 +0100 Subject: [PATCH 21/37] Fix compile error - float instead of double --- src/effects/backends/builtin/compressoreffect.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/effects/backends/builtin/compressoreffect.h b/src/effects/backends/builtin/compressoreffect.h index fdbae215f44..a1abce3e342 100644 --- a/src/effects/backends/builtin/compressoreffect.h +++ b/src/effects/backends/builtin/compressoreffect.h @@ -9,8 +9,8 @@ #include "util/types.h" namespace { -constexpr CSAMPLE_GAIN kMakeUpAttackCoeff = 0.03; -constexpr CSAMPLE_GAIN kMakeUpTarget = -3.0; +constexpr CSAMPLE_GAIN kMakeUpAttackCoeff = 0.03f; +constexpr CSAMPLE_GAIN kMakeUpTarget = -3.0f; } // anonymous namespace class CompressorGroupState : public EffectState { From 82f4915b642fab5a5dd77d5fd4492be248e215da Mon Sep 17 00:00:00 2001 From: Sergey Date: Sun, 14 Jan 2024 11:08:24 +0100 Subject: [PATCH 22/37] Fix formatting 3 --- src/effects/backends/builtin/compressoreffect.cpp | 5 +++-- src/effects/backends/builtin/compressoreffect.h | 5 ++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/effects/backends/builtin/compressoreffect.cpp b/src/effects/backends/builtin/compressoreffect.cpp index d376f5d4472..58f6dc6ff4e 100644 --- a/src/effects/backends/builtin/compressoreffect.cpp +++ b/src/effects/backends/builtin/compressoreffect.cpp @@ -44,8 +44,9 @@ EffectManifestPointer CompressorEffect::getManifest() { threshold->setId("threshold"); threshold->setName(QObject::tr("Threshold (dBFS)")); threshold->setShortName(QObject::tr("Threshold")); - threshold->setDescription(QObject::tr( - "The Threshold knob adjusts the level above which the compressor starts attenuating the input signal")); + threshold->setDescription( + QObject::tr("The Threshold knob adjusts the level above which the " + "compressor starts attenuating the input signal")); threshold->setValueScaler(EffectManifestParameter::ValueScaler::Linear); threshold->setUnitsHint(EffectManifestParameter::UnitsHint::Decibel); threshold->setNeutralPointOnScale(0); diff --git a/src/effects/backends/builtin/compressoreffect.h b/src/effects/backends/builtin/compressoreffect.h index a1abce3e342..588498a93c0 100644 --- a/src/effects/backends/builtin/compressoreffect.h +++ b/src/effects/backends/builtin/compressoreffect.h @@ -65,7 +65,10 @@ class CompressorEffect : public EffectProcessorImpl { DISALLOW_COPY_AND_ASSIGN(CompressorEffect); - void applyCompression(CompressorGroupState* pState, const mixxx::EngineParameters& engineParameters, const CSAMPLE* pInput, CSAMPLE* pOutput); + void applyCompression(CompressorGroupState* pState, + const mixxx::EngineParameters& engineParameters, + const CSAMPLE* pInput, + CSAMPLE* pOutput); void applyAutoMakeUp(CompressorGroupState* pState, CSAMPLE* pOutput, const SINT& numSamples); }; From 923c1eab68d47a34f5d0d07ad9e363ac0e2366f5 Mon Sep 17 00:00:00 2001 From: Sergey Date: Sun, 14 Jan 2024 11:23:29 +0100 Subject: [PATCH 23/37] Fix compile errors --- src/effects/backends/builtin/compressoreffect.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/effects/backends/builtin/compressoreffect.cpp b/src/effects/backends/builtin/compressoreffect.cpp index 58f6dc6ff4e..9762d2ad231 100644 --- a/src/effects/backends/builtin/compressoreffect.cpp +++ b/src/effects/backends/builtin/compressoreffect.cpp @@ -180,7 +180,7 @@ void CompressorEffect::applyAutoMakeUp(CompressorGroupState* pState, CSAMPLE levelDB = makeUpStateDB + maxSampleDB; // logarithmic smoothing if (levelDB > -1.0) { - makeUpStateDB = log10(levelDB + 2) - 1 - maxSampleDB; + makeUpStateDB = log10(levelDB + 2.0f) - 1.0f - maxSampleDB; } pState->previousMakeUpGain = makeUpStateDB; @@ -196,8 +196,10 @@ void CompressorEffect::applyCompression(CompressorGroupState* pState, CSAMPLE ratioParam = static_cast(m_pRatio->value()); CSAMPLE kneeParam = static_cast(m_pKnee->value()); CSAMPLE kneeHalf = kneeParam / 2.0f; - CSAMPLE attackCoeff = exp(-1000.0 / (m_pAttack->value() * engineParameters.sampleRate())); - CSAMPLE releaseCoeff = exp(-1000.0 / (m_pRelease->value() * engineParameters.sampleRate())); + CSAMPLE attackCoeff = (float)exp( + -1000.0 / (m_pAttack->value() * engineParameters.sampleRate())); + CSAMPLE releaseCoeff = (float)exp( + -1000.0 / (m_pRelease->value() * engineParameters.sampleRate())); CSAMPLE stateDB = pState->previousStateDB; SINT numSamples = engineParameters.samplesPerBuffer(); @@ -217,7 +219,7 @@ void CompressorEffect::applyCompression(CompressorGroupState* pState, } else if (overDB > -kneeHalf && overDB <= kneeHalf) { overDB = 0.5f * (overDB + kneeHalf) * (overDB + kneeHalf) / kneeParam; } - CSAMPLE compressedDB = overDB * (1.0 / ratioParam - 1.0); + CSAMPLE compressedDB = overDB * (1.0f / ratioParam - 1.0f); // attack/release if (compressedDB < stateDB) { From 85f13cc342a61c487f87a87b148d784e7abb6816 Mon Sep 17 00:00:00 2001 From: Sergey Date: Sat, 3 Feb 2024 15:31:14 +0100 Subject: [PATCH 24/37] Update src/effects/backends/builtin/compressoreffect.cpp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Daniel Schürmann --- src/effects/backends/builtin/compressoreffect.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/effects/backends/builtin/compressoreffect.cpp b/src/effects/backends/builtin/compressoreffect.cpp index 9762d2ad231..e538579ac72 100644 --- a/src/effects/backends/builtin/compressoreffect.cpp +++ b/src/effects/backends/builtin/compressoreffect.cpp @@ -59,7 +59,7 @@ EffectManifestPointer CompressorEffect::getManifest() { ratio->setDescription( QObject::tr("The Ratio knob determines how much the signal is " "attenuated above the chosen threshold. " - "For a ratio of 4:1, one dB remains for every 4dB of " + "For a ratio of 4:1, one dB remains for every four dB of " "input signal above the threshold. " "At a ratio of 1:1 no compression is happening, as the " "input is exactly the output")); From 552d05c2e0cfaa347015c75f0f9a2398e569a97e Mon Sep 17 00:00:00 2001 From: Sergey Date: Sat, 3 Feb 2024 16:12:35 +0100 Subject: [PATCH 25/37] Change makeup description + remove vectorized note --- src/effects/backends/builtin/compressoreffect.cpp | 7 ++++--- src/util/sample.cpp | 1 - 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/effects/backends/builtin/compressoreffect.cpp b/src/effects/backends/builtin/compressoreffect.cpp index e538579ac72..759a101bcac 100644 --- a/src/effects/backends/builtin/compressoreffect.cpp +++ b/src/effects/backends/builtin/compressoreffect.cpp @@ -31,8 +31,9 @@ EffectManifestPointer CompressorEffect::getManifest() { autoMakeUp->setId("automakeup"); autoMakeUp->setName(QObject::tr("Auto Makeup Gain")); autoMakeUp->setShortName(QObject::tr("Makeup")); - autoMakeUp->setDescription(QObject::tr( - "The AutoMakeup button enables automatic makeup gain to 0 db level")); + autoMakeUp->setDescription( + QObject::tr("The Auto Makeup button enables automatic gain " + "adjustment to almost 0 dBFS volume level")); autoMakeUp->setValueScaler(EffectManifestParameter::ValueScaler::Toggle); autoMakeUp->setRange(0, 1, 1); autoMakeUp->appendStep(qMakePair( @@ -180,7 +181,7 @@ void CompressorEffect::applyAutoMakeUp(CompressorGroupState* pState, CSAMPLE levelDB = makeUpStateDB + maxSampleDB; // logarithmic smoothing if (levelDB > -1.0) { - makeUpStateDB = log10(levelDB + 2.0f) - 1.0f - maxSampleDB; + makeUpStateDB = log10f(levelDB + 2.0f) - 1.0f - maxSampleDB; } pState->previousMakeUpGain = makeUpStateDB; diff --git a/src/util/sample.cpp b/src/util/sample.cpp index dd8ea766553..f4f335ceeba 100644 --- a/src/util/sample.cpp +++ b/src/util/sample.cpp @@ -482,7 +482,6 @@ void SampleUtil::copyClampBuffer(CSAMPLE* M_RESTRICT pDest, // static void SampleUtil::applyClamp(CSAMPLE* pBuffer, SINT iNumSamples) { - // note: LOOP VECTORIZED. for (SINT i = 0; i < iNumSamples; ++i) { pBuffer[i] = clampSample(pBuffer[i]); } From 1956ab24706fefd8cbdff004df949fb3ffb5d63e Mon Sep 17 00:00:00 2001 From: Sergey Date: Sat, 3 Feb 2024 17:04:04 +0100 Subject: [PATCH 26/37] Change variables to double --- .../backends/builtin/compressoreffect.cpp | 47 +++++++++---------- .../backends/builtin/compressoreffect.h | 4 +- 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/src/effects/backends/builtin/compressoreffect.cpp b/src/effects/backends/builtin/compressoreffect.cpp index 759a101bcac..490ae97098f 100644 --- a/src/effects/backends/builtin/compressoreffect.cpp +++ b/src/effects/backends/builtin/compressoreffect.cpp @@ -159,8 +159,8 @@ void CompressorEffect::processChannel( } // Output gain - CSAMPLE gainParamDB = static_cast(m_pGain->value()); - SampleUtil::applyGain(pOutput, db2ratio(gainParamDB), numSamples); + CSAMPLE gain = static_cast(db2ratio(m_pGain->value())); + SampleUtil::applyGain(pOutput, gain, numSamples); // Clipping if (m_pClipping->toInt() == static_cast(Clipping::ClippingOn)) { @@ -171,21 +171,22 @@ void CompressorEffect::processChannel( void CompressorEffect::applyAutoMakeUp(CompressorGroupState* pState, CSAMPLE* pOutput, const SINT& numSamples) { - CSAMPLE makeUpStateDB = pState->previousMakeUpGain; + double makeUpStateDB = pState->previousMakeUpGain; CSAMPLE maxSample = SampleUtil::maxAbsAmplitude(pOutput, numSamples); if (maxSample > 0) { - CSAMPLE maxSampleDB = ratio2db(maxSample); - CSAMPLE minGainReductionDB = -maxSampleDB + kMakeUpTarget; + double maxSampleDB = ratio2db(maxSample); + double minGainReductionDB = -maxSampleDB + kMakeUpTarget; makeUpStateDB = kMakeUpAttackCoeff * minGainReductionDB + (1 - kMakeUpAttackCoeff) * makeUpStateDB; - CSAMPLE levelDB = makeUpStateDB + maxSampleDB; + double levelDB = makeUpStateDB + maxSampleDB; // logarithmic smoothing if (levelDB > -1.0) { - makeUpStateDB = log10f(levelDB + 2.0f) - 1.0f - maxSampleDB; + makeUpStateDB = log10(levelDB + 2.0) - 1.0 - maxSampleDB; } pState->previousMakeUpGain = makeUpStateDB; - SampleUtil::applyGain(pOutput, db2ratio(makeUpStateDB), numSamples); + CSAMPLE gain = static_cast(db2ratio(makeUpStateDB)); + SampleUtil::applyGain(pOutput, gain, numSamples); } } @@ -193,16 +194,14 @@ void CompressorEffect::applyCompression(CompressorGroupState* pState, const mixxx::EngineParameters& engineParameters, const CSAMPLE* pInput, CSAMPLE* pOutput) { - CSAMPLE thresholdParam = static_cast(m_pThreshold->value()); - CSAMPLE ratioParam = static_cast(m_pRatio->value()); - CSAMPLE kneeParam = static_cast(m_pKnee->value()); - CSAMPLE kneeHalf = kneeParam / 2.0f; - CSAMPLE attackCoeff = (float)exp( - -1000.0 / (m_pAttack->value() * engineParameters.sampleRate())); - CSAMPLE releaseCoeff = (float)exp( - -1000.0 / (m_pRelease->value() * engineParameters.sampleRate())); - - CSAMPLE stateDB = pState->previousStateDB; + double thresholdParam = m_pThreshold->value(); + double ratioParam = m_pRatio->value(); + double kneeParam = m_pKnee->value(); + double kneeHalf = kneeParam / 2.0f; + double attackCoeff = exp(-1000.0 / (m_pAttack->value() * engineParameters.sampleRate())); + double releaseCoeff = exp(-1000.0 / (m_pRelease->value() * engineParameters.sampleRate())); + + double stateDB = pState->previousStateDB; SINT numSamples = engineParameters.samplesPerBuffer(); int channelCount = engineParameters.channelCount(); for (SINT i = 0; i < numSamples; i += channelCount) { @@ -213,14 +212,14 @@ void CompressorEffect::applyCompression(CompressorGroupState* pState, continue; } - CSAMPLE maxSampleDB = ratio2db(maxSample); - CSAMPLE overDB = maxSampleDB - thresholdParam; + double maxSampleDB = ratio2db(maxSample); + double overDB = maxSampleDB - thresholdParam; if (overDB <= -kneeHalf) { - overDB = 0.0f; + overDB = 0.0; } else if (overDB > -kneeHalf && overDB <= kneeHalf) { - overDB = 0.5f * (overDB + kneeHalf) * (overDB + kneeHalf) / kneeParam; + overDB = 0.5 * (overDB + kneeHalf) * (overDB + kneeHalf) / kneeParam; } - CSAMPLE compressedDB = overDB * (1.0f / ratioParam - 1.0f); + double compressedDB = overDB * (1.0 / ratioParam - 1.0); // attack/release if (compressedDB < stateDB) { @@ -229,7 +228,7 @@ void CompressorEffect::applyCompression(CompressorGroupState* pState, stateDB = compressedDB + releaseCoeff * (stateDB - compressedDB); } - CSAMPLE gain = db2ratio(stateDB); + CSAMPLE gain = static_cast(db2ratio(stateDB)); pOutput[i] = pInput[i] * gain; pOutput[i + 1] = pInput[i + 1] * gain; } diff --git a/src/effects/backends/builtin/compressoreffect.h b/src/effects/backends/builtin/compressoreffect.h index 588498a93c0..37e35638b7d 100644 --- a/src/effects/backends/builtin/compressoreffect.h +++ b/src/effects/backends/builtin/compressoreffect.h @@ -17,8 +17,8 @@ class CompressorGroupState : public EffectState { public: CompressorGroupState(const mixxx::EngineParameters& engineParameters); - CSAMPLE previousStateDB; - CSAMPLE previousMakeUpGain; + double previousStateDB; + double previousMakeUpGain; }; class CompressorEffect : public EffectProcessorImpl { From 3530873fc05978784e7bdd6bb1f8b066f099a499 Mon Sep 17 00:00:00 2001 From: Sergey Date: Sat, 3 Feb 2024 17:49:04 +0100 Subject: [PATCH 27/37] Calculate ballistics only if params were changed --- .../backends/builtin/compressoreffect.cpp | 22 +++++++++++++++++-- .../backends/builtin/compressoreffect.h | 9 ++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/effects/backends/builtin/compressoreffect.cpp b/src/effects/backends/builtin/compressoreffect.cpp index 490ae97098f..3bb1e1c189e 100644 --- a/src/effects/backends/builtin/compressoreffect.cpp +++ b/src/effects/backends/builtin/compressoreffect.cpp @@ -123,6 +123,10 @@ CompressorGroupState::CompressorGroupState( const mixxx::EngineParameters& engineParameters) : EffectState(engineParameters), previousStateDB(0), + previousAttackParamMs(10), + previousAttackCoeff(calculateBallistics(10, engineParameters)), + previousReleaseParamMs(150), + previousReleaseCoeff(calculateBallistics(150, engineParameters)), previousMakeUpGain(0) { } @@ -198,8 +202,22 @@ void CompressorEffect::applyCompression(CompressorGroupState* pState, double ratioParam = m_pRatio->value(); double kneeParam = m_pKnee->value(); double kneeHalf = kneeParam / 2.0f; - double attackCoeff = exp(-1000.0 / (m_pAttack->value() * engineParameters.sampleRate())); - double releaseCoeff = exp(-1000.0 / (m_pRelease->value() * engineParameters.sampleRate())); + + double attackParamMs = m_pAttack->value(); + double attackCoeff = pState->previousAttackCoeff; + if (attackParamMs != pState->previousAttackParamMs) { + attackCoeff = calculateBallistics(attackParamMs, engineParameters); + pState->previousAttackParamMs = attackParamMs; + pState->previousAttackCoeff = attackCoeff; + } + + double releaseParamMs = m_pRelease->value(); + double releaseCoeff = pState->previousReleaseCoeff; + if (releaseParamMs != pState->previousReleaseParamMs) { + releaseCoeff = calculateBallistics(releaseParamMs, engineParameters); + pState->previousReleaseParamMs = releaseParamMs; + pState->previousReleaseCoeff = releaseCoeff; + } double stateDB = pState->previousStateDB; SINT numSamples = engineParameters.samplesPerBuffer(); diff --git a/src/effects/backends/builtin/compressoreffect.h b/src/effects/backends/builtin/compressoreffect.h index 37e35638b7d..c0dae0e34a6 100644 --- a/src/effects/backends/builtin/compressoreffect.h +++ b/src/effects/backends/builtin/compressoreffect.h @@ -11,6 +11,11 @@ namespace { constexpr CSAMPLE_GAIN kMakeUpAttackCoeff = 0.03f; constexpr CSAMPLE_GAIN kMakeUpTarget = -3.0f; + +double calculateBallistics(double paramMs, const mixxx::EngineParameters& engineParameters) { + return exp(-1000.0 / (paramMs * engineParameters.sampleRate())); +} + } // anonymous namespace class CompressorGroupState : public EffectState { @@ -18,6 +23,10 @@ class CompressorGroupState : public EffectState { CompressorGroupState(const mixxx::EngineParameters& engineParameters); double previousStateDB; + double previousAttackParamMs; + double previousAttackCoeff; + double previousReleaseParamMs; + double previousReleaseCoeff; double previousMakeUpGain; }; From 86216da0fab4ff9b6d978a9e2d39f4e0d2928bcd Mon Sep 17 00:00:00 2001 From: Sergey Date: Sat, 3 Feb 2024 18:00:03 +0100 Subject: [PATCH 28/37] Remove clipping --- .../backends/builtin/compressoreffect.cpp | 16 ---------------- src/effects/backends/builtin/compressoreffect.h | 6 ------ src/util/sample.cpp | 7 ------- src/util/sample.h | 3 --- 4 files changed, 32 deletions(-) diff --git a/src/effects/backends/builtin/compressoreffect.cpp b/src/effects/backends/builtin/compressoreffect.cpp index 3bb1e1c189e..7bc4d5da853 100644 --- a/src/effects/backends/builtin/compressoreffect.cpp +++ b/src/effects/backends/builtin/compressoreffect.cpp @@ -17,16 +17,6 @@ EffectManifestPointer CompressorEffect::getManifest() { pManifest->setEffectRampsFromDry(true); pManifest->setMetaknobDefault(0.0); - EffectManifestParameterPointer clipping = pManifest->addParameter(); - clipping->setId("clipping"); - clipping->setName(QObject::tr("Clipping")); - clipping->setShortName(QObject::tr("Clipping")); - clipping->setDescription(QObject::tr("Hard limiter to full scale")); - clipping->setValueScaler(EffectManifestParameter::ValueScaler::Toggle); - clipping->setRange(0, 1, 1); - clipping->appendStep(qMakePair(QObject::tr("Off"), static_cast(Clipping::ClippingOff))); - clipping->appendStep(qMakePair(QObject::tr("On"), static_cast(Clipping::ClippingOn))); - EffectManifestParameterPointer autoMakeUp = pManifest->addParameter(); autoMakeUp->setId("automakeup"); autoMakeUp->setName(QObject::tr("Auto Makeup Gain")); @@ -139,7 +129,6 @@ void CompressorEffect::loadEngineEffectParameters( m_pRelease = parameters.value("release"); m_pGain = parameters.value("gain"); m_pAutoMakeUp = parameters.value("automakeup"); - m_pClipping = parameters.value("clipping"); } void CompressorEffect::processChannel( @@ -165,11 +154,6 @@ void CompressorEffect::processChannel( // Output gain CSAMPLE gain = static_cast(db2ratio(m_pGain->value())); SampleUtil::applyGain(pOutput, gain, numSamples); - - // Clipping - if (m_pClipping->toInt() == static_cast(Clipping::ClippingOn)) { - SampleUtil::applyClamp(pOutput, numSamples); - } } void CompressorEffect::applyAutoMakeUp(CompressorGroupState* pState, diff --git a/src/effects/backends/builtin/compressoreffect.h b/src/effects/backends/builtin/compressoreffect.h index c0dae0e34a6..7617ccad5c2 100644 --- a/src/effects/backends/builtin/compressoreffect.h +++ b/src/effects/backends/builtin/compressoreffect.h @@ -54,16 +54,10 @@ class CompressorEffect : public EffectProcessorImpl { AutoMakeUpOn = 1, }; - enum class Clipping { - ClippingOff = 0, - ClippingOn = 1, - }; - QString debugString() const { return getId(); } - EngineEffectParameterPointer m_pClipping; EngineEffectParameterPointer m_pAutoMakeUp; EngineEffectParameterPointer m_pThreshold; EngineEffectParameterPointer m_pRatio; diff --git a/src/util/sample.cpp b/src/util/sample.cpp index f4f335ceeba..56bf630c728 100644 --- a/src/util/sample.cpp +++ b/src/util/sample.cpp @@ -480,13 +480,6 @@ void SampleUtil::copyClampBuffer(CSAMPLE* M_RESTRICT pDest, } } -// static -void SampleUtil::applyClamp(CSAMPLE* pBuffer, SINT iNumSamples) { - for (SINT i = 0; i < iNumSamples; ++i) { - pBuffer[i] = clampSample(pBuffer[i]); - } -} - // static void SampleUtil::interleaveBuffer(CSAMPLE* M_RESTRICT pDest, const CSAMPLE* M_RESTRICT pSrc1, diff --git a/src/util/sample.h b/src/util/sample.h index 6ba8f6b3964..f94c87ca4fb 100644 --- a/src/util/sample.h +++ b/src/util/sample.h @@ -235,9 +235,6 @@ class SampleUtil { static void copyClampBuffer(CSAMPLE* pDest, const CSAMPLE* pSrc, SINT numSamples); - // Limiting every value in pBuffer to the valid range of CSAMPLE - static void applyClamp(CSAMPLE* pBuffer, SINT iNumSamples); - // Interleave the samples in pSrc1 and pSrc2 into pDest. iNumSamples must be // the number of samples in pSrc1 and pSrc2, and pDest must have at least // space for iNumSamples*2 samples. pDest must not be an alias of pSrc1 or From cadd4e308517aebcb2e708066b438d27f1dd3076 Mon Sep 17 00:00:00 2001 From: Sergey Date: Mon, 19 Feb 2024 21:02:51 +0100 Subject: [PATCH 29/37] remove applyMakeUp DB round trip --- .../backends/builtin/compressoreffect.cpp | 39 ++++++++++++------- .../backends/builtin/compressoreffect.h | 5 ++- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/src/effects/backends/builtin/compressoreffect.cpp b/src/effects/backends/builtin/compressoreffect.cpp index 7bc4d5da853..9cffab119ad 100644 --- a/src/effects/backends/builtin/compressoreffect.cpp +++ b/src/effects/backends/builtin/compressoreffect.cpp @@ -117,7 +117,10 @@ CompressorGroupState::CompressorGroupState( previousAttackCoeff(calculateBallistics(10, engineParameters)), previousReleaseParamMs(150), previousReleaseCoeff(calculateBallistics(150, engineParameters)), - previousMakeUpGain(0) { + previousMakeUpGain(1), + previousThresholdParam(-20), + previousThresholdParamRatio(db2ratio(-20.0f * 2)), + kMakeUpTargetRatio(db2ratio(kMakeUpTarget)) { } void CompressorEffect::loadEngineEffectParameters( @@ -159,22 +162,30 @@ void CompressorEffect::processChannel( void CompressorEffect::applyAutoMakeUp(CompressorGroupState* pState, CSAMPLE* pOutput, const SINT& numSamples) { - double makeUpStateDB = pState->previousMakeUpGain; + double thresholdParam = m_pThreshold->value(); + double thresholdRatio = pState->previousThresholdParamRatio; + if (thresholdParam != pState->previousThresholdParam) { + thresholdRatio = db2ratio(thresholdParam * 2); + pState->previousThresholdParam = thresholdParam; + pState->previousThresholdParamRatio = thresholdRatio; + } + CSAMPLE maxSample = SampleUtil::maxAbsAmplitude(pOutput, numSamples); - if (maxSample > 0) { - double maxSampleDB = ratio2db(maxSample); - double minGainReductionDB = -maxSampleDB + kMakeUpTarget; - makeUpStateDB = kMakeUpAttackCoeff * minGainReductionDB + - (1 - kMakeUpAttackCoeff) * makeUpStateDB; - double levelDB = makeUpStateDB + maxSampleDB; - // logarithmic smoothing - if (levelDB > -1.0) { - makeUpStateDB = log10(levelDB + 2.0) - 1.0 - maxSampleDB; + if (maxSample > thresholdRatio) { + CSAMPLE_GAIN makeUpGainState = pState->previousMakeUpGain; + CSAMPLE_GAIN makeUpTargetRatio = pState->kMakeUpTargetRatio; + CSAMPLE_GAIN makeUp = makeUpTargetRatio / maxSample; + makeUpGainState = kMakeUpAttackCoeff * makeUp + (1 - kMakeUpAttackCoeff) * makeUpGainState; + + // smoothing + if (makeUpGainState * maxSample > makeUpTargetRatio) { + CSAMPLE_GAIN k = (1 - makeUpTargetRatio * makeUpTargetRatio) / + (makeUpGainState * maxSample + 1); + makeUpGainState = (1 - k) / maxSample; } - pState->previousMakeUpGain = makeUpStateDB; - CSAMPLE gain = static_cast(db2ratio(makeUpStateDB)); - SampleUtil::applyGain(pOutput, gain, numSamples); + pState->previousMakeUpGain = makeUpGainState; + SampleUtil::applyGain(pOutput, makeUpGainState, numSamples); } } diff --git a/src/effects/backends/builtin/compressoreffect.h b/src/effects/backends/builtin/compressoreffect.h index 7617ccad5c2..e2cfd463992 100644 --- a/src/effects/backends/builtin/compressoreffect.h +++ b/src/effects/backends/builtin/compressoreffect.h @@ -27,7 +27,10 @@ class CompressorGroupState : public EffectState { double previousAttackCoeff; double previousReleaseParamMs; double previousReleaseCoeff; - double previousMakeUpGain; + double previousThresholdParam; + double previousThresholdParamRatio; + CSAMPLE_GAIN previousMakeUpGain; + CSAMPLE_GAIN kMakeUpTargetRatio; }; class CompressorEffect : public EffectProcessorImpl { From 698201a66f2aae56efb4bb5f4d8c829e95c1d0c7 Mon Sep 17 00:00:00 2001 From: Sergey Date: Mon, 19 Feb 2024 21:10:39 +0100 Subject: [PATCH 30/37] Moving namespace to cpp + add defaut constants --- .../backends/builtin/compressoreffect.cpp | 31 +++++++++++++------ .../backends/builtin/compressoreffect.h | 9 ------ 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/effects/backends/builtin/compressoreffect.cpp b/src/effects/backends/builtin/compressoreffect.cpp index 9cffab119ad..046958c9038 100644 --- a/src/effects/backends/builtin/compressoreffect.cpp +++ b/src/effects/backends/builtin/compressoreffect.cpp @@ -1,5 +1,18 @@ #include "effects/backends/builtin/compressoreffect.h" +namespace { +constexpr CSAMPLE_GAIN kMakeUpAttackCoeff = 0.03f; +constexpr CSAMPLE_GAIN kMakeUpTarget = -3.0f; +constexpr double defaultAttackMs = 10; +constexpr double defaultReleaseMs = 150; +constexpr CSAMPLE_GAIN defaultThresholdDB = -20; + +double calculateBallistics(double paramMs, const mixxx::EngineParameters& engineParameters) { + return exp(-1000.0 / (paramMs * engineParameters.sampleRate())); +} + +} // anonymous namespace + // static QString CompressorEffect::getId() { return "org.mixxx.effects.compressor"; @@ -41,7 +54,7 @@ EffectManifestPointer CompressorEffect::getManifest() { threshold->setValueScaler(EffectManifestParameter::ValueScaler::Linear); threshold->setUnitsHint(EffectManifestParameter::UnitsHint::Decibel); threshold->setNeutralPointOnScale(0); - threshold->setRange(-50, -20, 0); + threshold->setRange(-50, defaultThresholdDB, 0); EffectManifestParameterPointer ratio = pManifest->addParameter(); ratio->setId("ratio"); @@ -79,7 +92,7 @@ EffectManifestPointer CompressorEffect::getManifest() { "compression will set in once the signal exceeds the threshold")); attack->setValueScaler(EffectManifestParameter::ValueScaler::Logarithmic); attack->setUnitsHint(EffectManifestParameter::UnitsHint::Millisecond); - attack->setRange(0, 10, 250); + attack->setRange(0, defaultAttackMs, 250); EffectManifestParameterPointer release = pManifest->addParameter(); release->setId("release"); @@ -93,7 +106,7 @@ EffectManifestPointer CompressorEffect::getManifest() { "may introduce a 'pumping' effect and/or distortion")); release->setValueScaler(EffectManifestParameter::ValueScaler::Integral); release->setUnitsHint(EffectManifestParameter::UnitsHint::Millisecond); - release->setRange(0, 150, 1500); + release->setRange(0, defaultReleaseMs, 1500); EffectManifestParameterPointer gain = pManifest->addParameter(); gain->setId("gain"); @@ -113,13 +126,13 @@ CompressorGroupState::CompressorGroupState( const mixxx::EngineParameters& engineParameters) : EffectState(engineParameters), previousStateDB(0), - previousAttackParamMs(10), - previousAttackCoeff(calculateBallistics(10, engineParameters)), - previousReleaseParamMs(150), - previousReleaseCoeff(calculateBallistics(150, engineParameters)), + previousAttackParamMs(defaultAttackMs), + previousAttackCoeff(calculateBallistics(defaultAttackMs, engineParameters)), + previousReleaseParamMs(defaultReleaseMs), + previousReleaseCoeff(calculateBallistics(defaultReleaseMs, engineParameters)), previousMakeUpGain(1), - previousThresholdParam(-20), - previousThresholdParamRatio(db2ratio(-20.0f * 2)), + previousThresholdParam(defaultThresholdDB), + previousThresholdParamRatio(db2ratio(defaultThresholdDB * 2)), kMakeUpTargetRatio(db2ratio(kMakeUpTarget)) { } diff --git a/src/effects/backends/builtin/compressoreffect.h b/src/effects/backends/builtin/compressoreffect.h index e2cfd463992..69b64952c59 100644 --- a/src/effects/backends/builtin/compressoreffect.h +++ b/src/effects/backends/builtin/compressoreffect.h @@ -8,15 +8,6 @@ #include "util/sample.h" #include "util/types.h" -namespace { -constexpr CSAMPLE_GAIN kMakeUpAttackCoeff = 0.03f; -constexpr CSAMPLE_GAIN kMakeUpTarget = -3.0f; - -double calculateBallistics(double paramMs, const mixxx::EngineParameters& engineParameters) { - return exp(-1000.0 / (paramMs * engineParameters.sampleRate())); -} - -} // anonymous namespace class CompressorGroupState : public EffectState { public: From 2ba06305e4cb7b184cd90e1810847247de2a4825 Mon Sep 17 00:00:00 2001 From: Sergey Date: Mon, 19 Feb 2024 21:21:26 +0100 Subject: [PATCH 31/37] Add line breaks to descriptions --- src/effects/backends/builtin/compressoreffect.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/effects/backends/builtin/compressoreffect.cpp b/src/effects/backends/builtin/compressoreffect.cpp index 046958c9038..6544f398198 100644 --- a/src/effects/backends/builtin/compressoreffect.cpp +++ b/src/effects/backends/builtin/compressoreffect.cpp @@ -62,11 +62,11 @@ EffectManifestPointer CompressorEffect::getManifest() { ratio->setShortName(QObject::tr("Ratio")); ratio->setDescription( QObject::tr("The Ratio knob determines how much the signal is " - "attenuated above the chosen threshold. " + "attenuated above the chosen threshold.\n" "For a ratio of 4:1, one dB remains for every four dB of " - "input signal above the threshold. " + "input signal above the threshold.\n" "At a ratio of 1:1 no compression is happening, as the " - "input is exactly the output")); + "input is exactly the output.")); ratio->setValueScaler(EffectManifestParameter::ValueScaler::Logarithmic); ratio->setUnitsHint(EffectManifestParameter::UnitsHint::Coefficient); ratio->setNeutralPointOnScale(0); @@ -89,7 +89,7 @@ EffectManifestPointer CompressorEffect::getManifest() { attack->setShortName(QObject::tr("Attack")); attack->setDescription(QObject::tr( "The Attack knob sets the time that determines how fast the " - "compression will set in once the signal exceeds the threshold")); + "compression \nwill set in once the signal exceeds the threshold")); attack->setValueScaler(EffectManifestParameter::ValueScaler::Logarithmic); attack->setUnitsHint(EffectManifestParameter::UnitsHint::Millisecond); attack->setRange(0, defaultAttackMs, 250); @@ -100,10 +100,10 @@ EffectManifestPointer CompressorEffect::getManifest() { release->setShortName(QObject::tr("Release")); release->setDescription( QObject::tr("The Release knob sets the time that determines how " - "fast the compressor will recover from the gain " + "fast the compressor will recover from the gain\n" "reduction once the signal falls under the threshold. " - "Depending on the input signal, short release times " - "may introduce a 'pumping' effect and/or distortion")); + "Depending on the input signal, short release times\n" + "may introduce a 'pumping' effect and/or distortion.")); release->setValueScaler(EffectManifestParameter::ValueScaler::Integral); release->setUnitsHint(EffectManifestParameter::UnitsHint::Millisecond); release->setRange(0, defaultReleaseMs, 1500); From 638f1a0a1d170ab4ea1070782d5259bac244da5c Mon Sep 17 00:00:00 2001 From: Sergey Date: Mon, 19 Feb 2024 21:51:42 +0100 Subject: [PATCH 32/37] Change default values --- src/effects/backends/builtin/compressoreffect.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/effects/backends/builtin/compressoreffect.cpp b/src/effects/backends/builtin/compressoreffect.cpp index 6544f398198..3a98c434eea 100644 --- a/src/effects/backends/builtin/compressoreffect.cpp +++ b/src/effects/backends/builtin/compressoreffect.cpp @@ -3,8 +3,8 @@ namespace { constexpr CSAMPLE_GAIN kMakeUpAttackCoeff = 0.03f; constexpr CSAMPLE_GAIN kMakeUpTarget = -3.0f; -constexpr double defaultAttackMs = 10; -constexpr double defaultReleaseMs = 150; +constexpr double defaultAttackMs = 1; +constexpr double defaultReleaseMs = 300; constexpr CSAMPLE_GAIN defaultThresholdDB = -20; double calculateBallistics(double paramMs, const mixxx::EngineParameters& engineParameters) { @@ -70,7 +70,7 @@ EffectManifestPointer CompressorEffect::getManifest() { ratio->setValueScaler(EffectManifestParameter::ValueScaler::Logarithmic); ratio->setUnitsHint(EffectManifestParameter::UnitsHint::Coefficient); ratio->setNeutralPointOnScale(0); - ratio->setRange(1.0, 4.0, 1000); + ratio->setRange(1.0, 6.0, 1000); EffectManifestParameterPointer knee = pManifest->addParameter(); knee->setId("knee"); From 296f7ceb9d9bff5f48975eb36fb06d35aab51d1e Mon Sep 17 00:00:00 2001 From: Sergey Date: Mon, 19 Feb 2024 22:19:20 +0100 Subject: [PATCH 33/37] ratiod2db fix --- src/util/math.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/math.h b/src/util/math.h index 09334c7af7f..0a25dff63cf 100644 --- a/src/util/math.h +++ b/src/util/math.h @@ -74,7 +74,7 @@ roundToFraction(double value, int denominator) { template requires std::is_floating_point_v CMATH_CONSTEXPR T ratio2db(T a) { - return log10(a) * 20; + return static_cast(log10(a) * 20); } template From 82ffc6cc4d8e11675eeb754ef0acf250f6f2b84c Mon Sep 17 00:00:00 2001 From: Sergey Date: Wed, 13 Mar 2024 21:30:27 +0100 Subject: [PATCH 34/37] Fix reorder error --- src/effects/backends/builtin/compressoreffect.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/effects/backends/builtin/compressoreffect.cpp b/src/effects/backends/builtin/compressoreffect.cpp index 3a98c434eea..b95837f3058 100644 --- a/src/effects/backends/builtin/compressoreffect.cpp +++ b/src/effects/backends/builtin/compressoreffect.cpp @@ -130,9 +130,9 @@ CompressorGroupState::CompressorGroupState( previousAttackCoeff(calculateBallistics(defaultAttackMs, engineParameters)), previousReleaseParamMs(defaultReleaseMs), previousReleaseCoeff(calculateBallistics(defaultReleaseMs, engineParameters)), - previousMakeUpGain(1), previousThresholdParam(defaultThresholdDB), previousThresholdParamRatio(db2ratio(defaultThresholdDB * 2)), + previousMakeUpGain(1), kMakeUpTargetRatio(db2ratio(kMakeUpTarget)) { } From a7cbc0801a44c446c206fc34ba6322abf0d75261 Mon Sep 17 00:00:00 2001 From: Sergey Date: Wed, 13 Mar 2024 22:52:06 +0100 Subject: [PATCH 35/37] Fix formatting --- src/effects/backends/builtin/compressoreffect.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/effects/backends/builtin/compressoreffect.h b/src/effects/backends/builtin/compressoreffect.h index 69b64952c59..7904a71b10b 100644 --- a/src/effects/backends/builtin/compressoreffect.h +++ b/src/effects/backends/builtin/compressoreffect.h @@ -8,7 +8,6 @@ #include "util/sample.h" #include "util/types.h" - class CompressorGroupState : public EffectState { public: CompressorGroupState(const mixxx::EngineParameters& engineParameters); From b74c984ff750edd3a1db7427542b077539b066a2 Mon Sep 17 00:00:00 2001 From: Sergey Date: Wed, 27 Mar 2024 21:58:59 +0100 Subject: [PATCH 36/37] Change auto make up algorithm --- .../backends/builtin/compressoreffect.cpp | 40 ++++++------------- .../backends/builtin/compressoreffect.h | 8 ++-- 2 files changed, 17 insertions(+), 31 deletions(-) diff --git a/src/effects/backends/builtin/compressoreffect.cpp b/src/effects/backends/builtin/compressoreffect.cpp index b95837f3058..90613bcfcf7 100644 --- a/src/effects/backends/builtin/compressoreffect.cpp +++ b/src/effects/backends/builtin/compressoreffect.cpp @@ -2,7 +2,6 @@ namespace { constexpr CSAMPLE_GAIN kMakeUpAttackCoeff = 0.03f; -constexpr CSAMPLE_GAIN kMakeUpTarget = -3.0f; constexpr double defaultAttackMs = 1; constexpr double defaultReleaseMs = 300; constexpr CSAMPLE_GAIN defaultThresholdDB = -20; @@ -34,9 +33,10 @@ EffectManifestPointer CompressorEffect::getManifest() { autoMakeUp->setId("automakeup"); autoMakeUp->setName(QObject::tr("Auto Makeup Gain")); autoMakeUp->setShortName(QObject::tr("Makeup")); - autoMakeUp->setDescription( - QObject::tr("The Auto Makeup button enables automatic gain " - "adjustment to almost 0 dBFS volume level")); + autoMakeUp->setDescription(QObject::tr( + "The Auto Makeup button enables automatic gain adjustment to keep " + "the input signal \nand the processed output signal as close as " + "possible in perceived loudness")); autoMakeUp->setValueScaler(EffectManifestParameter::ValueScaler::Toggle); autoMakeUp->setRange(0, 1, 1); autoMakeUp->appendStep(qMakePair( @@ -130,10 +130,7 @@ CompressorGroupState::CompressorGroupState( previousAttackCoeff(calculateBallistics(defaultAttackMs, engineParameters)), previousReleaseParamMs(defaultReleaseMs), previousReleaseCoeff(calculateBallistics(defaultReleaseMs, engineParameters)), - previousThresholdParam(defaultThresholdDB), - previousThresholdParamRatio(db2ratio(defaultThresholdDB * 2)), - previousMakeUpGain(1), - kMakeUpTargetRatio(db2ratio(kMakeUpTarget)) { + previousMakeUpGain(1) { } void CompressorEffect::loadEngineEffectParameters( @@ -164,7 +161,7 @@ void CompressorEffect::processChannel( // Auto make up if (m_pAutoMakeUp->toInt() == static_cast(AutoMakeUp::AutoMakeUpOn)) { - applyAutoMakeUp(pState, pOutput, numSamples); + applyAutoMakeUp(pState, pInput, pOutput, numSamples); } // Output gain @@ -173,29 +170,18 @@ void CompressorEffect::processChannel( } void CompressorEffect::applyAutoMakeUp(CompressorGroupState* pState, + const CSAMPLE* pInput, CSAMPLE* pOutput, const SINT& numSamples) { - double thresholdParam = m_pThreshold->value(); - double thresholdRatio = pState->previousThresholdParamRatio; - if (thresholdParam != pState->previousThresholdParam) { - thresholdRatio = db2ratio(thresholdParam * 2); - pState->previousThresholdParam = thresholdParam; - pState->previousThresholdParamRatio = thresholdRatio; - } - - CSAMPLE maxSample = SampleUtil::maxAbsAmplitude(pOutput, numSamples); - if (maxSample > thresholdRatio) { + CSAMPLE rmsInput = SampleUtil::rms(pInput, numSamples); + if (rmsInput > CSAMPLE_ZERO) { CSAMPLE_GAIN makeUpGainState = pState->previousMakeUpGain; - CSAMPLE_GAIN makeUpTargetRatio = pState->kMakeUpTargetRatio; - CSAMPLE_GAIN makeUp = makeUpTargetRatio / maxSample; - makeUpGainState = kMakeUpAttackCoeff * makeUp + (1 - kMakeUpAttackCoeff) * makeUpGainState; + + CSAMPLE rmsOutput = SampleUtil::rms(pOutput, numSamples); + CSAMPLE_GAIN makeUp = rmsInput / rmsOutput; // smoothing - if (makeUpGainState * maxSample > makeUpTargetRatio) { - CSAMPLE_GAIN k = (1 - makeUpTargetRatio * makeUpTargetRatio) / - (makeUpGainState * maxSample + 1); - makeUpGainState = (1 - k) / maxSample; - } + makeUpGainState = kMakeUpAttackCoeff * makeUp + (1 - kMakeUpAttackCoeff) * makeUpGainState; pState->previousMakeUpGain = makeUpGainState; SampleUtil::applyGain(pOutput, makeUpGainState, numSamples); diff --git a/src/effects/backends/builtin/compressoreffect.h b/src/effects/backends/builtin/compressoreffect.h index 7904a71b10b..5f4efc4a785 100644 --- a/src/effects/backends/builtin/compressoreffect.h +++ b/src/effects/backends/builtin/compressoreffect.h @@ -17,10 +17,7 @@ class CompressorGroupState : public EffectState { double previousAttackCoeff; double previousReleaseParamMs; double previousReleaseCoeff; - double previousThresholdParam; - double previousThresholdParamRatio; CSAMPLE_GAIN previousMakeUpGain; - CSAMPLE_GAIN kMakeUpTargetRatio; }; class CompressorEffect : public EffectProcessorImpl { @@ -66,5 +63,8 @@ class CompressorEffect : public EffectProcessorImpl { const CSAMPLE* pInput, CSAMPLE* pOutput); - void applyAutoMakeUp(CompressorGroupState* pState, CSAMPLE* pOutput, const SINT& numSamples); + void applyAutoMakeUp(CompressorGroupState* pState, + const CSAMPLE* pInput, + CSAMPLE* pOutput, + const SINT& numSamples); }; From 0dafd460380810af103df85aac9dae891b238671 Mon Sep 17 00:00:00 2001 From: Sergey Date: Wed, 27 Mar 2024 22:19:25 +0100 Subject: [PATCH 37/37] Rename output gain to level --- .../backends/builtin/compressoreffect.cpp | 22 +++++++++---------- .../backends/builtin/compressoreffect.h | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/effects/backends/builtin/compressoreffect.cpp b/src/effects/backends/builtin/compressoreffect.cpp index 90613bcfcf7..d5eaaedb9db 100644 --- a/src/effects/backends/builtin/compressoreffect.cpp +++ b/src/effects/backends/builtin/compressoreffect.cpp @@ -108,16 +108,16 @@ EffectManifestPointer CompressorEffect::getManifest() { release->setUnitsHint(EffectManifestParameter::UnitsHint::Millisecond); release->setRange(0, defaultReleaseMs, 1500); - EffectManifestParameterPointer gain = pManifest->addParameter(); - gain->setId("gain"); - gain->setName(QObject::tr("Output gain")); - gain->setShortName(QObject::tr("Gain")); - gain->setDescription( - QObject::tr("The Output gain knob adjusts the level of the output " + EffectManifestParameterPointer level = pManifest->addParameter(); + level->setId("level"); + level->setName(QObject::tr("Level")); + level->setShortName(QObject::tr("Level")); + level->setDescription( + QObject::tr("The Level knob adjusts the level of the output " "signal after the compression was applied")); - gain->setValueScaler(EffectManifestParameter::ValueScaler::Linear); - gain->setUnitsHint(EffectManifestParameter::UnitsHint::Decibel); - gain->setRange(-25, 0, 25); + level->setValueScaler(EffectManifestParameter::ValueScaler::Linear); + level->setUnitsHint(EffectManifestParameter::UnitsHint::Decibel); + level->setRange(-25, 0, 25); return pManifest; } @@ -140,7 +140,7 @@ void CompressorEffect::loadEngineEffectParameters( m_pKnee = parameters.value("knee"); m_pAttack = parameters.value("attack"); m_pRelease = parameters.value("release"); - m_pGain = parameters.value("gain"); + m_pLevel = parameters.value("level"); m_pAutoMakeUp = parameters.value("automakeup"); } @@ -165,7 +165,7 @@ void CompressorEffect::processChannel( } // Output gain - CSAMPLE gain = static_cast(db2ratio(m_pGain->value())); + CSAMPLE gain = static_cast(db2ratio(m_pLevel->value())); SampleUtil::applyGain(pOutput, gain, numSamples); } diff --git a/src/effects/backends/builtin/compressoreffect.h b/src/effects/backends/builtin/compressoreffect.h index 5f4efc4a785..08c681440f8 100644 --- a/src/effects/backends/builtin/compressoreffect.h +++ b/src/effects/backends/builtin/compressoreffect.h @@ -54,7 +54,7 @@ class CompressorEffect : public EffectProcessorImpl { EngineEffectParameterPointer m_pKnee; EngineEffectParameterPointer m_pAttack; EngineEffectParameterPointer m_pRelease; - EngineEffectParameterPointer m_pGain; + EngineEffectParameterPointer m_pLevel; DISALLOW_COPY_AND_ASSIGN(CompressorEffect);