I’ve declared the synthesis buffer in the class scope, and I’m assuming newBlocksize is meant to be samplesPerBlock. It still has a clicking noise at the end of MIDI notes, but now I’ve noticed that it’s only some notes. For example, a C clicks, while a D# does not. My current code is below.
void prepareToPlay(double sampleRate, int samplesPerBlock, int outputChannels)
{
synthesisBuffer.setSize(1, samplesPerBlock, true, true, true);
juce::dsp::ProcessSpec spec;
spec.maximumBlockSize = samplesPerBlock;
spec.sampleRate = sampleRate;
spec.numChannels = outputChannels;
sinOsc.prepare(spec);
triangleOsc.prepare(spec);
sawOsc.prepare(spec);
squareOsc.prepare(spec);
gain.prepare(spec);
adsr.setSampleRate(sampleRate);
}
void renderNextBlock(AudioBuffer<float>& outputBuffer, int startSample, int numSamples)
{
dsp::AudioBlock<float> audioBlock{ synthesisBuffer };
if (waveType == sine)
sinOsc.process(juce::dsp::ProcessContextReplacing<float>(audioBlock));
else if (waveType == triangle)
triangleOsc.process(juce::dsp::ProcessContextReplacing<float>(audioBlock));
else if (waveType == saw)
sawOsc.process(juce::dsp::ProcessContextReplacing<float>(audioBlock));
else if (waveType == square)
squareOsc.process(juce::dsp::ProcessContextReplacing<float>(audioBlock));
gain.process(juce::dsp::ProcessContextReplacing<float>(audioBlock));
adsr.applyEnvelopeToBuffer(synthesisBuffer, startSample, numSamples);
for (int chan = 0; chan < outputBuffer.getNumChannels(); ++chan)
outputBuffer.addFrom(chan, startSample, synthesisBuffer, 0, startSample, numSamples, 1.0f);
}