Phase started behaving strange negative numbers

Hi I’m calculating my phase like this:

  void renderNextBlock (AudioBuffer <float> &outputBuffer, int startSample, int numSamples) override
    {
      if(tune < 0){increment = (frequency / tune_holder) * wt_size / samplerate;}
      else{        increment = (frequency * tune_holder) * wt_size / samplerate;}

      //float outSample = 0.0f;
      //std::cout << wavetable[id][20];
      adsr.setParameters(adsr_parameters);
        for (int sample = 0; sample < numSamples; ++sample)
        {
            for (int channel = 0; channel < outputBuffer.getNumChannels(); ++channel)
            {
              //outputBuffer.addSample(channel, startSample, outSample * level * adsr.getNextSample() * gain );
              //outputBuffer.addSample(channel, startSample, wavetable[id][first_sample + (int) phase_0] * level * adsr.getNextSample() * gain );
              phase_0 = fmod(phase_0 + increment,wt_size);
              std::cout << phase_0 << std::endl;
            }
            ++startSample;
        }
    }

It was working correctly before, then I started to call it from different processors and now it outputs some garbage and then 000 after that it stays at -848. I have no clue why it stopped working all of a sudden.

Full SynthVoice:

/*
  ==============================================================================

    SynthVoice.h
    Created: 6 Jul 2020 6:33:34pm
    Author:  eye

  ==============================================================================
*/

#pragma once

#include <JuceHeader.h>
#include "SynthSound.h"

class SynthVoice : public SynthesiserVoice
{
public:
    bool canPlaySound (SynthesiserSound* sound) override
    {
        return dynamic_cast <SynthSound*>(sound) != nullptr;
    }

    void setPitchBend(int pitchWheelPos)
    {
        if (pitchWheelPos > 8192)
        {
            // shifting up
            pitchBend = float(pitchWheelPos - 8192) / (16383 - 8192);
        }
        else
        {
            // shifting down
            pitchBend = float(8192 - pitchWheelPos) / -8192;    // negative number
        }
    }

    float pitchBendCents()
    {
        if (pitchBend >= 0.0f)
        {
            // shifting up
            return pitchBend * pitchBendUpSemitones * 100;
        }
        else
        {
            // shifting down
            return pitchBend * pitchBendDownSemitones * 100;
        }
    }

    static double noteHz(int midiNoteNumber, double centsOffset)
    {
        double hertz = MidiMessage::getMidiNoteInHertz(midiNoteNumber);
        hertz *= std::pow(2.0, centsOffset / 1200);
        return hertz;
    }

    //=======================================================

    void startNote (int midiNoteNumber, float velocity, SynthesiserSound* sound, int currentPitchWheelPosition) override
    {
        adsr.noteOn();
        noteNumber = midiNoteNumber;
        setPitchBend(currentPitchWheelPosition);
        frequency = noteHz(noteNumber, pitchBendCents());
        level = velocity;
        phase_0 = 0.0f;
    }

    //=======================================================

    void stopNote (float velocity, bool allowTailOff) override
    {
      adsr.noteOff();
        if (velocity == 0)
            clearCurrentNote();

    }

    //=======================================================

    void pitchWheelMoved (int newPitchWheelValue) override
    {
        setPitchBend(newPitchWheelValue);
        frequency = noteHz(noteNumber, pitchBendCents());
    }

    //=======================================================

    void controllerMoved (int controllerNumber, int newControllerValue) override
    {

    }

    void setSampleRate(double lastSampleRate)
    {
      samplerate = lastSampleRate;
      adsr.setSampleRate(samplerate);
    }

    void setWavetable(const std::array<std::array<float, 1081>, 2>& wavetable_h, int id_h)
    {
      wavetable = wavetable_h;
      id = id_h;
    }

    void setADSRParameters (std::atomic<float>* attack, std::atomic<float>* decay, std::atomic<float>* sustain, std::atomic<float>* release)
    {
      adsr_parameters.attack = *attack;
      adsr_parameters.decay = *decay;
      adsr_parameters.sustain = *sustain;
      adsr_parameters.release = *release;
    }

    void setGain(std::atomic<float>* gain_value)
    {
      gain = *gain_value;
    }

    void setTableRange(std::atomic<float>* start_sample ,std::atomic<float>* stop_sample)
    {
        first_sample = static_cast<int> (*start_sample);
        wt_size = static_cast<int> (*stop_sample - *start_sample);
    }

    void setTuning(std::atomic<float>* tuning)
    {
        tune = *tuning;
        if (tune > -1 && tune < 1 )
        {
          tune_holder = fabs(tune)+ 1;
        } else
        {
          tune_holder = fabs(tune) * 2;
        }
    }
    void renderNextBlock (AudioBuffer <float> &outputBuffer, int startSample, int numSamples) override
    {
      if(tune < 0){increment = (frequency / tune_holder) * wt_size / samplerate;}
      else{        increment = (frequency * tune_holder) * wt_size / samplerate;}

      //float outSample = 0.0f;
      //std::cout << wavetable[id][20];
      adsr.setParameters(adsr_parameters);
        for (int sample = 0; sample < numSamples; ++sample)
        {
            for (int channel = 0; channel < outputBuffer.getNumChannels(); ++channel)
            {
              //outputBuffer.addSample(channel, startSample, outSample * level * adsr.getNextSample() * gain );
              //outputBuffer.addSample(channel, startSample, wavetable[id][first_sample + (int) phase_0] * level * adsr.getNextSample() * gain );
              phase_0 = fmod(phase_0 + increment,wt_size);
              std::cout << phase_0 << std::endl;
            }
            ++startSample;
        }
    }

private:
  double level;
  double frequency;
  int noteNumber;

  float pitchBend = 0.0f;
  float pitchBendUpSemitones = 2.0f;
  float pitchBendDownSemitones = 2.0f;
  float gain;

  int wt_size;
  int first_sample;

  int phase_0;
  float increment;
  double samplerate;
  std::array<std::array<float, 1081>, 2> wavetable;
  int id;

  ADSR adsr;
  ADSR::Parameters adsr_parameters;

  float tune, tune_holder;
};

Full source :

Why is phase_0 an integer? Seems like you’d want to use a double precision float.

Or, better yet, use the handy JUCE Phase struct:

https://docs.juce.com/master/structdsp_1_1Phase.html

Matt