By looking quickly into your code, I guess the issue is the fact that you are not using properly your lookup table buffer. You are using the AudioBuffer::applyRamp function from an index of the buffer to another one without caring about the fact that other one is sometimes higher than the size of the buffer, and that the ramp must restart then from the index 0 to the remaining samples. So you get a click (and a bad memory access !)
Moreover, I don’t really get why your LFO buffer has a size of sampleRate. Even if the circular buffer thing was implemented correctly, every time you are at the end of the LFO table, the next sample is going to be one without any continuous transition ! The last phase value might be say pi/3.5, and the one for the next sample is going to be 0.
So, I guess that you should try another approach first before trying to do the lookup table thing, like using the new dsp::Oscillator class to get a sine output easily without storing the result. Anyway it’s not a good approach imho to have to refill a long buffer every time you change the LFO speed. Ideally, you should store a lookup table for a sinus of a given size with exactly one period of that since inside, and then you read the content of the table at different speeds depending on the speed parameter. This way, the transition between the end of the table and the beginning is right.
Other remarks :
- you don’t need to create a fSampleRate variable since the sample rate of the process is registered automatically thanks to the prepareToPlay function, and available with the function getSampleRate()
- the use of M_PI should be avoided in every JUCE project code, since it’s not compatible with Windows, and because JUCE provides float_Pi or double_Pi as a replacement
- I tend also to avoid the use of sinf and cosf for a few reasons we talked a few days earlier on the JUCE forums, I use now std::cos and std::sin instead