I’ve been trying to figure out how the Oversampling
class works and have run into a few hiccups, especially regarding what to do with the sample rate and block size of oversampled processors.
The oversampling demos I saw in the JUCE codebase only use the WaveShaper
class, which doesn’t seem to care about the sample rate at all (I assume they’re just a static waveshaper/lookup).
In my particular case, I’m trying to use other waveshaping/wavefolding techniques that use the sample rate as a parameter of the algorithm.
The question is, how should I prepare my processor for this kind of use? What should the ProcessSpec
look like?
I tried prepping it like this in my plugin’s prepareToPlay
:
void PluginProcessor::prepareToPlay(double sampleRate, int samplesPerBlock)
{
lastSampleRate = sampleRate;
dsp::ProcessSpec spec;
spec.sampleRate = lastSampleRate;
spec.maximumBlockSize = (unsigned int) samplesPerBlock;
spec.numChannels = (unsigned int) getMainBusNumOutputChannels();
oversampler.reset();
oversampler.initProcessing (spec.maximumBlockSize);
// Processors that run before oversampling
gain.reset();
gain.prepare(spec);
// Oversampled processors
auto oversamplingTimes = static_cast<uint32>(std::pow(2, oversampler.factorOversampling));
// NOTICE scaled sample rate AND max block size
saturator.prepare(
{ spec.sampleRate * oversamplingTimes, (uint32) spec.maximumBlockSize * oversamplingTimes, (uint32) spec.numChannels });
// Processors that run after oversampling
mixer.reset();
mixer.prepare(spec);
}
The saturator
processor has other things inside it (like a HP filter) and when that process is ran it fails assertions about hitting NaN samples. This leads me to think I’m not setting the block size correctly. Does the block size change when oversampling? I think I saw a larger block size in the debugger so I assumed it was multiplied by the same factor as the sample rate, but now I’m not sure at all.
I’ve also read in some posts that the block size can change block by block if my DAW decides to, which adds extra confusion. Wouldn’t that cause NaN samples passing through my processors also? Do I have to broadcast the block size to my processors on each processBlock
call?