New way to do tail offs if anyone is interested

struct Onepole {
    double g;
    double s;
    double sr;
    void init() {
        s = 0;
        setParams(480, 44100.0);
    }
    void setParams(double cutoff, double sampleRate) {
        g = tan(M_PI*(cutoff/sampleRate));
    }
    
    double process(double in) {
        double out = ( g *  (in) + s ) / (  g + 1 );
        s = 2 * out - s;
        return out;
    }
};
void startNote (int midiNoteNumber, float velocity,
                    juce::SynthesiserSound* /*sound*/,
                    int /*currentPitchWheelPosition*/) override
    {

        gate = 1.0;
        //tailOff = 0.0;

        
    }
void stopNote (float /*velocity*/, bool allowTailOff) override
    {
        
        gate = 0;
        
        //clearCurrentNote();

    }
while (--numSamples >= 0)
            {
                auto s = //sampledata
                auto g = gateLP.process(gate);
                for (auto i = outputBuffer.getNumChannels(); --i >= 0;)
                    outputBuffer.addSample (i, startSample, s*g);
                startSample++;
                
                if(juce::approximatelyEqual(0.0, g)){
                    clearCurrentNote();
                }
                
            }

if you are trying to avoid clicks you have to create two mini voices for each parent voice

like so
env = 0 on start note
envInc is set to 1/32.0 samples or so to fade in

this way you dont have to write your own midi handlers

while (--numSamples >= 0)
            {
                
                double s = 0;
                if(env < 1.0){
                    s = env*mini[swap].process() + (1-env)*mini[!swap].process();
                    env += envInc;
                }else{
                    s = mini[swap].process();
                    
                }
                auto g = gateLP.process(gate);
                for (auto i = outputBuffer.getNumChannels(); --i >= 0;)
                    outputBuffer.addSample (i, startSample, s*g);
                startSample++;
                
                if(juce::approximatelyEqual(0.0, g)){
                    clearCurrentNote();
                }
                
            }