Notes Hang At Full Volume After Several Minutes In Logic Pro

I’m playing notes via a synth similar to the one the keyboard uses. What I’m experiencing is that the code works fine in a native mac app, the problem only occurs inside logic pro. Essentially, after playing some notes, it’ll be silent for several minutes. Out of nowhere, it will suddenly blast me with full-volume, full-velocity notes. I’m not sure how the buffer is picking them up though. Like I said, this only happens when I launch the app in logic pro, not when I launch a native apple application. Here’s what my synth instrument looks like.

struct SineWaveVoice   : public juce::SynthesiserVoice
{
    SineWaveVoice() {}
    bool canPlaySound (juce::SynthesiserSound* sound) override
    {
        return dynamic_cast<SineWaveSound*> (sound) != nullptr;
    }

    void startNote (int midiNoteNumber, float velocity,
                    juce::SynthesiserSound*, int /*currentPitchWheelPosition*/) override
    {
        currentAngle = 0.0;
        storedVelocity = velocity * 0.15;
        level = 0.01;
        tailOff = tailOffDefault;
        tailIn = 0.01;
        
        auto cyclesPerSecond = juce::MidiMessage::getMidiNoteInHertz (midiNoteNumber);
        auto cyclesPerSample = cyclesPerSecond / getSampleRate();

        angleDelta = cyclesPerSample * 2.0 * juce::MathConstants<double>::pi;
    }

    void stopNote (float /*velocity*/, bool allowTailOff) override
    {
        if (tailOff <= 0.0){
            tailOff = 0;
        }
    }

    void pitchWheelMoved (int) override      {}
    void controllerMoved (int, int) override {}

    void renderNextBlock (juce::AudioSampleBuffer& outputBuffer, int startSample, int numSamples) override
    {
        if (angleDelta != 0.0)
        {
            
            if (tailOff > 0.0) // [7]
            {
                while (--numSamples >= 0)
                {
                    auto currentSample = (float) (std::sin (currentAngle) * level * tailOff);

                    for (auto i = outputBuffer.getNumChannels(); --i >= 0;)
                        outputBuffer.addSample (i, startSample, currentSample);

                    currentAngle += angleDelta;
                    ++startSample;

                    if(tailIn < storedVelocity){
                        tailIn *= tailInRatio;
                        level *= levelInRatio;
                    } else {
                        tailOff *= tailOffRatio; // [8]
                        
                        level *=(tailOffRatio - 0.0002);

                        if (tailOff <= 0.001)
                        {
                            clearCurrentNote(); // [9]

                            angleDelta = 0.0;
                            break;
                        }
                    }
                }
            } else {
                clearCurrentNote(); // [9]

                angleDelta = 0.0;
            }
        } else {
            clearCurrentNote();
        }
    }
    double tailOffRatio = 0.99992, tailInRatio=1.08, levelInRatio = 1.08;
private:
    double currentAngle = 0.0, angleDelta = 0.0, level = 0.0, tailOff = 0.0, tailOffDefault = 1, tailInDefault = 1, tailIn = 0, storedVelocity = 0;
};

A quick note here:
Sometimes I notice that when I’m debugging, breaking pointing and stepping through the app seems to fix it. Maybe an issue with processing?