you should call the function once per audio frame instead of calling it for the whole block, e.g.:
void render(BelaContext *context, void *userData)
{
for(unsigned int n = 0; n < context->audioFrames; ++n){
// Render audio frames
float res;
osc.process(1, &res);
audioWrite(context, n, 0, arr[n]);
audioWrite(context, n, 1, arr[n]);
}
}
If you are changing the frequency once per frame, it looks like the class implementation could be improved by storing the inverse of the sampling rate instead of the sampling rate, so that
void setFrequency(int n, float frequency){
// For efficiency, frequency is internally stored in change in wavetable position per sample, not Hz or radians
frequencies[n] = frequency * (float)wavetableLength / sampleRate;
}
turns into the more efficient
void setFrequency(int n, float frequency){
// For efficiency, frequency is internally stored in change in wavetable position per sample, not Hz or radians
frequencies[n] = frequency * (float)wavetableLength * invSampleRate;
}