Segmentation fault with the compressor function

i getting some issues while trying to implement the compressor in my juce app, it always give me the segmentation fault when i try to check if it is not null and process it, here is the following parts of the processor

MainComponent.h

private:
// Limiter por canal
    std::vector<std::unique_ptr<juce::dsp::Compressor<float>>> compressors;

    // Estado do compressor por canal (ativo ou inativo)
    std::vector<bool> compressorActivated;

    // Modo Automatico por canal
    std::vector<bool> compressorAutomaticMode;

    // Parametros do compressor
    struct CompressorParameters
    {
        float threshold = 0.0f; // Default threshold in dB
        float ratio = 1.0f;
        float attack = 10.0f;    // Default attack time in ms
        float release = 160.0f; // Default release time in ms
    };
    std::vector<CompressorParameters> compressorParams;
MainComponent::MainComponent(){
      //...other declarations like sliders and gains
        
// Inicializa compressor por canal
    compressors.resize(numChannels);
    compressorActivated.resize(numChannels, false);      
    compressorAutomaticMode.resize(numChannels, true);   
    compressorParams.resize(numChannels);
    
    for (int channel = 0; channel < numChannels; ++channel)
    {
        compressors[channel] = std::make_unique<juce::dsp::Compressor<float>>();
        // Defina os parâmetros padrão
        compressors[channel]->setThreshold(compressorParams[channel].threshold);
        compressors[channel]->setRatio(compressorParams[channel].ratio);
        compressors[channel]->setAttack(compressorParams[channel].attack);
        compressors[channel]->setRelease(compressorParams[channel].release);
        compressors[channel]->prepare(spec);
    }
}
void MainComponent::audioDeviceAboutToStart(juce::AudioIODevice* device)
{
    currentSampleRate = device->getCurrentSampleRate();

    // Prepare os crossovers com a nova taxa de amostragem
    juce::dsp::ProcessSpec spec;
    spec.sampleRate = currentSampleRate;
    spec.maximumBlockSize = 512;
    spec.numChannels = 1;

    for (int channel = 0; channel < numChannels; ++channel)
    {
        if (crossovers[channel] != nullptr)
        {
            crossovers[channel]->prepare(spec);
        }
        if (compressors[channel] != nullptr)
        {
            compressors[channel]->prepare(spec);
        }
    }
}
void MainComponent::processOutputBuffer(juce::AudioBuffer<float>& outputBuffer)
{
    int numOutputChannels = outputBuffer.getNumChannels();
    int numSamples = outputBuffer.getNumSamples();

    juce::dsp::AudioBlock<float> audioBlock(outputBuffer);

    for (int channel = 0; channel < numOutputChannels; ++channel)
    {
//Aplica Compressor
        if (compressorActivated[channel] && compressors[channel] != nullptr)
        {
            // If automatic mode is on, update threshold based on some logic
            if (compressorAutomaticMode[channel])
            {
                float   autoAttack = 10;
                float   autoRelease = 160;
                        
                if(crossovers[channel] != nullptr){
                    autoAttack = (crossovers[channel]->getHpfGain())/500;
                    autoRelease = autoAttack*16;
                }
                compressors[channel]->setThreshold(compressorParams[channel].threshold);
                compressors[channel]->setRatio(compressorParams[channel].ratio);
                compressors[channel]->setAttack(autoAttack);
                compressors[channel]->setRelease(autoRelease);
            }
            else
            {
                // Use manual parameters
                compressors[channel]->setThreshold(compressorParams[channel].threshold);
                compressors[channel]->setRatio(compressorParams[channel].ratio);
                compressors[channel]->setAttack(compressorParams[channel].attack);
                compressors[channel]->setRelease(compressorParams[channel].release);
            }

            compressors[channel]->process(context);
        }
    }

    // Aplica o ganho master
    outputBuffer.applyGain(static_cast<float>(masterGainSlider.getValue()));
}

and if i remove it from the output buffer the app work normally

The code you posted is missing too many details, it’s pretty difficult to say why the crash might be happening. Is it possible for you to post the full project on Github or somewhere so it can be built and tested?

Roughly:

  • Run the code inside the debugger (essential for getting it fixed easily)
  • Find the line of code which gives you the segmentation fault
  • Check to see if the pointer which is wrong (can be a reference but usually a pointer!) is null or not
  • If it’s null figure out why
  • It’s it’s not null then it’s either not been initialised properly or it’s been deleted after it was created.
    Again, figure out why.

Various causes of pointers being wrong:

  • Silly mistakes (#1 cause)
  • Failing to understand construction/destruction order
  • Passing a pointer into a function before it’s initialised (very common)
  • Harder: overwriting your pointer with garbage because of another mistake

There’s plenty more, but those are the common ones that sprang to mind :slight_smile:

1 Like

Obviously for greater longer term benefits, the original poster should learn debugging techniques. :slight_smile:

Took me ages to get good at it. Like at least a year and a half of staring at impossible errors wondering why it was so hard.

Internalising this helped a bunch with some of the harder ones: What is the order in which the destructors and the constructors are called in C++ - Stack Overflow

i checked here with debug messages and found the problem, i needed declare it in audio device about to start, after i did this it worked, i often forget to use the debug functions to check if everything is alright

edit:

to be honest the compressor is not working yet but now i think i can just keep checking to see why it is not working

1 Like

During development always run in the debugger unless there’s a good reason not to. Programming will be far less annoying - use a DAW for testing that boots quickly - REAPER is great during development :slight_smile:

i usually cant use the debugger, im working with a embedded and when i compile in debug it always make the processor heat up to much (it is strange to be honest) then usually i make it as release, but for the tests i will use more the debugger

i mean to see if it is working before i put in the embedded

1 Like

Oh fair enough. Embedded can be hard work :slight_smile: