Noise gate gain reduction

Hi everyone,

I thought getting gain reduction values here would simply be subtracting the output from the input but for some reasons on the console I only get 0 dB even if there is gain reduction from the noise gate. What am I missing?
Here is the code

template <typename ProcessContext>    void process (const ProcessContext& context) noexcept    {            const auto& inputBlock = context.getInputBlock();            auto& outputBlock      = context.getOutputBlock();            const auto numChannels = outputBlock.getNumChannels();            const auto numSamples  = outputBlock.getNumSamples();            jassert (inputBlock.getNumChannels() == numChannels);            jassert (inputBlock.getNumSamples() == numSamples);            if (context.isBypassed)            {                outputBlock.copyFrom (inputBlock);                return;            }            for (size_t channel = 0; channel < numChannels; ++channel)            {                auto* inputSamples  = inputBlock .getChannelPointer (channel);                auto* outputSamples = outputBlock.getChannelPointer (channel);                for (size_t i = 0; i < numSamples; ++i)                {                    float gainReduction = 0.0;                    outputSamples[i] = processSample ((int) channel, inputSamples[i]);                    float inputLevelDb = Decibels::gainToDecibels(std::abs(inputSamples[i]));                    float outputLevelDb = Decibels::gainToDecibels(std::abs(outputSamples[i]));                    gainReduction = inputLevelDb - outputLevelDb;                }                DBG("Channel " << channel << " gain reduction : " << gainReduction << "db");            }    }

Thanks everyone

The AudioBlock class is a lightweight wrapper view into the AudioBuffer. The input block and output block are likely pointing to the same data.

@Fandusss Thank you for your response, this make sense. I will verify this by printing both input and output to the console see if i get same values. How can I calculate the gain reduction then if that’s the case?

I’m thinking in order to resolve this, I need to make sure I calculate the gain reduction based on the original input signal, not the modified output signal. I think I can achieve this by copying the input samples to a temporary buffer before processing.

Ok i tried different solutions for this but it still doesnt work. Can anyone please help me with this.

Can you format the code so it’s not all on one line?

Some notes:

Decibels::gainToDecibels(inputSamples[i]); is fine, no need to abs() the input to this function.

If using a ContextReplacing type, the input and output data will be the same data, so you will need to shift around the order:

float inputLevelDb = Decibels::gainToDecibels(inputSamples[i]);                    
outputSamples[i] = processSample ((int) channel, inputSamples[i]);                    
float outputLevelDb = Decibels::gainToDecibels(outputSamples[i]);                    
gainReduction = inputLevelDb - outputLevelDb;   

The gainReduction variable is updating every sample, unconditionally. This means your value will be the last sample of the last channel. You should have some check in here so you are storing the minimum value (eg the most gain reduction). Up to you if you want it per channel or not.

You are also declaring the gainReduction variable inside the sample loop, so the scope ends after each loop, and then when you use it in the DBG statement, it’s out of scope entirely.

@Fandusss sorry for that, when I pasted the code it wasn’t on the same line I’m not sure what happened. Let me try post it again

void process(const ProcessContext& context) noexcept
{
const auto& inputBlock = context.getInputBlock();
auto& outputBlock = context.getOutputBlock();
const auto numChannels = outputBlock.getNumChannels();
const auto numSamples = outputBlock.getNumSamples();

jassert(inputBlock.getNumChannels() == numChannels);
jassert(inputBlock.getNumSamples() == numSamples);

if (context.isBypassed)
{
    outputBlock.copyFrom(inputBlock);
    return;
}

for (size_t channel = 0; channel < numChannels; ++channel)
{
    auto* inputSamples = inputBlock.getChannelPointer(channel);
    auto* outputSamples = outputBlock.getChannelPointer(channel);

    // Initialize gain reduction value
    float gainReduction = 0.0f;

    for (size_t i = 0; i < numSamples; ++i)
    {
        outputSamples[i] = processSample((int)channel, inputSamples[i]);

        // Calculate gain reduction by comparing input and output levels
        if (outputSamples[i] != 0.0f)
        {
            gainReduction = jmax(gainReduction, 20.0f * std::log10(std::abs(inputSamples[i] / outputSamples[i])));
        }
    }

    // Store gain reduction value for each channel (you can use it for your gain reduction meter)
    // Here, you can store the gain reduction value in an array or any suitable data structure
    // For simplicity, let's print it for now
    DBG("Channel " << channel << " Gain Reduction: " << gainReduction);
}

}

Thank you for your assistance

I found a way to make this work.