I have a Synthesizer with more than one oscillator, the tail-off when a key is released produce clicks, following is the renderNextBlock function
void renderNextBlock(juce::AudioSampleBuffer& outputBuffer, int startSample, int numSamples) override
{
if (noteOnFlag)
{
int initialStartSample = startSample;
int initialNumSamples = numSamples;
float initialTailOff = tailOff;
// After Key Off
if (tailOff > 0.0) // [7]
{
for (auto oscillatorIndex = 0; oscillatorIndex < oscillators.size(); ++oscillatorIndex)
{
initialStartSample = startSample;
initialNumSamples = numSamples;
initialTailOff = tailOff;
while (--initialNumSamples >= 0)
{
auto levelSample = oscillators.getUnchecked(oscillatorIndex)->getNextSample() * level * tailOff;
for (auto i = outputBuffer.getNumChannels(); --i >= 0;)
outputBuffer.addSample(i, initialStartSample, levelSample);
tailOff -= 0.001;
if (tailOff <= 0.0)
{
noteOnFlag = false;
break;
}
++initialStartSample;
}
}
if (tailOff <= 0)
{
clearCurrentNote();
resetIndex();
}
}
// After Key On
else
{
for (auto oscillatorIndex = 0; oscillatorIndex < oscillators.size(); ++oscillatorIndex)
{
initialStartSample = startSample;
initialNumSamples = numSamples;
while (--initialNumSamples >= 0)
{
auto levelSample = oscillators.getUnchecked(oscillatorIndex)->getNextSample() * level;
for (auto i = outputBuffer.getNumChannels(); --i >= 0;)
outputBuffer.addSample(i, initialStartSample, levelSample);
++initialStartSample;
}
}
}
}
}
private:
int counter = 0;
const unsigned int tableSize = 1 << 7;
float level = 0.0f, tailOff = 0.0f;
bool killQuick = false;
bool noteOnFlag = false;
juce::AudioSampleBuffer sineTable;
juce::OwnedArray<WavetableOscillator> oscillators;
};
An image of the tail off

