Synthesiser Block-Rendering problems

I’ve been pulling my hair out trying to fix this glitch since last night and I just can’t seem to figure out what I’m doing wrong.

My SynthesiserVoice contains this renderNextBlock() method:

void renderNextBlock (AudioSampleBuffer& outputBuffer, int startSample, int numSamples) { float incr = freq*length/sr; for(int j=0; j < numSamples; j++) { for (int i = outputBuffer.getNumChannels(); --i >= 0;) { *outputBuffer.getSampleData(i, startSample) += (float) amp*table[(int)(*index)]; } *index += incr; while(*index >= length) *index -= length; while(*index < 0) *index += length; ++startSample; } } /* freq = frequency length = wavetable length sr = sampling rate numSamples is being used as the vector size for the oscillator */

The above code is of a basic truncating wavetable-lookup oscillator. I’m trying to have it produce a vector of samples = numSamples in size and it’s working in so far as the wavetable lookup, amplitude and pitch are concerned, but the output is ‘blipping/clicking’ at a rate that seems to vary with the number of samples being rendered.
At 960 samples it fits about 9 oscillations of the waveform between each blip and about 10 oscillations at 1024 samples, whereas at 3072 samples it sounds almost as it should, but with minor clicks in the output at a specific interval.
In the attached image you can see the output produced at 960 samples, with the glitches marked with red spots.

The fact that there appears to be a correlation between the number of samples per rendered block and the time between the glitches suggests that it’s something really simple that I’ve missed but it’s driving me crazy!

I’ve used these oscillator algorithms plenty of times before with other APIs (such as PortAudio) and not had any trouble, so I’m either missing something basic in the JUCE API or making some other silly programming mistake here to cause these glitches.

Any help whatsoever would be very welcome!

Can’t see anything in that code but it’s certainly going to be one of those obvious bloopers that’s obvious once you spot it. What you’ve got there is terribly inefficient - maybe try optimising it properly and you might spot the problem while you’re rewriting it.