LinearSmoothedValue doesn't update

Hi,

I was trying to do some meters and to do them smoothed Id like to use LinearSmoothedValue instead only just float, when I used float values all worked but with LinearSmoothedValue values are ever 0.0…

I cannot understand why…

Here my code:

    const int METER_SAMPES_BUFFER = 4096; //TODO: far in modo che il meter bufferizzi bene quindi che faccia l'update dei valori solo ogni 4096 samples

    template <typename Type>
    class MeterVisualizer
    {
    public:
        MeterVisualizer() {}
        ~MeterVisualizer() {}
        
        //==============================================================================

        void initializeMeterLevels(const int numChannels, const double sampleRate, const int samplesPerBlock)
        {
            lastBufferFill = 0;
            buffer.clear();
            
            int realBufferNumsSamples = (samplesPerBlock % METER_SAMPES_BUFFER == 0 ? METER_SAMPES_BUFFER : samplesPerBlock * (METER_SAMPES_BUFFER/samplesPerBlock));
            
            buffer.setSize(numChannels, realBufferNumsSamples);
            
            rmsLevels = Array<LinearSmoothedValue<float>>{};
            magnitudeLevels = Array<LinearSmoothedValue<float>>{};
            
            for (int i = 0; i < numChannels; i++)
            {
                rmsLevels.add(LinearSmoothedValue<float>{});
                rmsLevels[i].reset(sampleRate, 1.0);
                rmsLevels[i].setCurrentAndTargetValue(0.0);
                
                magnitudeLevels.add(LinearSmoothedValue<float>{});
                magnitudeLevels[i].reset(sampleRate, 1.0);
                magnitudeLevels[i].setCurrentAndTargetValue(0.0);
            }
        }

        void updateVisualizer(const AudioBuffer<Type>& bufferSource)
        {
            const int bufferSourceNumSamples = bufferSource.getNumSamples();
            const int bufferNumSamples = buffer.getNumSamples();
            
            const int bufferSourceNumChannels = bufferSource.getNumChannels();
            const int bufferNumChannels = buffer.getNumChannels();
            
            jassert(bufferNumChannels <= bufferSourceNumChannels);
            
            for (int chan = 0; chan < bufferNumChannels; ++chan)
            {
                auto* dest = buffer.getWritePointer(chan);
                auto* src = bufferSource.getReadPointer(chan);
 
                int tempLastBufferFill = lastBufferFill;
                
                for (int i = 0; i < bufferSourceNumSamples; ++i)
                {
                    dest[tempLastBufferFill + i] = src[i];
                    tempLastBufferFill++;
                }
                
                if (chan == bufferNumChannels - 1)
                    lastBufferFill = tempLastBufferFill;
            }

            
            if (lastBufferFill == bufferNumSamples)
            {
                for (int chan = 0; chan < bufferNumChannels; ++chan)
                {
                    rmsLevels[chan].skip(bufferNumSamples);
                    
                    {
                        const float rmsValue = buffer.getRMSLevel(chan, 0, bufferNumSamples);
                        
                        if (rmsValue < rmsLevels[chan].getCurrentValue())
                            rmsLevels[chan].setTargetValue(rmsValue);
                        else
                            rmsLevels[chan].setCurrentAndTargetValue(rmsValue);
                    }
                    
                    magnitudeLevels[chan].skip(bufferNumSamples);
                    
                    {
                        const float magnitudeValue = buffer.getMagnitude(chan, 0, bufferNumSamples);
                        
                        if (magnitudeValue < magnitudeLevels[chan].getCurrentValue())
                            magnitudeLevels[chan].setTargetValue(magnitudeValue);
                        else
                            magnitudeLevels[chan].setCurrentAndTargetValue(magnitudeValue);
                    }
                }
                
                lastBufferFill = 0;
            }
        }
        
        //==============================================================================

        float getRMSLevel(const int channel) const
        {
            return rmsLevels[channel].getCurrentValue() < 0 ? 0 : rmsLevels[channel].getCurrentValue();
        }
        
        float getMagnitudeLevel(const int channel) const
        {
            return magnitudeLevels[channel].getCurrentValue() < 0 ? 0 : magnitudeLevels[channel].getCurrentValue();
        }
        
        float getRMSLevelDecibles(const int channel) const
        {
            return Decibels::gainToDecibels(getRMSLevel(channel));
        }
        
        float getMagnitudeLevelDecibles(const int channel) const
        {
            return Decibels::gainToDecibels(getMagnitudeLevel(channel));
        }
        
        //==============================================================================
        
        float getPanLevel(const int leftCh, const int rightCh) const
        {
            float leftMagnitude = getMagnitudeLevel(leftCh);
            float rightMagnitude = getMagnitudeLevel(rightCh);
            
            if (leftMagnitude > 1) { leftMagnitude = 1; }
            if (rightMagnitude > 1) { rightMagnitude = 1; }
            
            const float difference = rightMagnitude - leftMagnitude;
            
            if (difference == 0.0f) { return 0.0f; }
            
            const float maxMagnitude = jmax(rightMagnitude, leftMagnitude);
            
            const float panLevel = jmap(abs(difference), 0.0f, maxMagnitude, 0.0f, 1.0f);
            
            return (difference < 0) ? -panLevel : panLevel;
        }
        
        //==============================================================================
         
    private:
    
        AudioBuffer<Type> buffer;
        
        int lastBufferFill = 0;
        
        Array<LinearSmoothedValue<float>> rmsLevels;
        Array<LinearSmoothedValue<float>> magnitudeLevels;
        
        JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MeterVisualizer)
    };

I think you want to call getNextValue() instead of getCurrentValue().

But I am not sure if that is the right class for the job.
Maybe have a look at BallisticsFilter

1 Like

ok that you, I’ll take a look but I suppose that even call set currentValue it cannot be ever 0.0f…