Switchable dsp::Oversampling Factor

Hi, I am trying to make my plugin always run at 176.4k or 192k sample rate, regardless of the actual sample rate of the source audio. I figured something like this would work:

// In Prepare to Play
if (sampleRate <= 44100.0 || sampleRate == 48000.0) {
    oversampler.factorOversampling = 2;
} else if (sampleRate == (44100.0 * 2.0) || sampleRate == (48000.0 * 2.0)) {
    oversampler.factorOversampling = 1;
} else if (sampleRate == (44100.0 * 4.0) || sampleRate >= (48000.0 * 4.0)){
    oversampler.factorOversampling = 0;
} else {
    oversampler.factorOversampling = 0;
}

This seems to change the value of oversampler.getOversamplingFactor(), but not of the actual number of samples generated in oversampler.processSamplesUp(). Changing the initialization in

oversampler(2 /* channels */, 1 /* factor oversampling */, juce::dsp::Oversampling<float>::FilterType::filterHalfBandPolyphaseIIR, true, false)

does not change the number of samples created in oversampler.processSamplesUp() either.

Do you all have some suggestions of what I could change to make this idea work?

Thank you!

(Removed)

Your branches assume only multiples of 44.1khz, what about 48khz?

Can you post the code you are using to process samples up?

Sure thing!

// In PluginProcessor.h
juce::dsp::Oversampling<float> oversampler;

// In Initalizer List
oversampler(2, 2, juce::dsp::Oversampling<float>::FilterType::filterHalfBandPolyphaseIIR, true, false)

// In Prepare to Play
oversampler.setUsingIntegerLatency(false);
oversampler.clearOversamplingStages();
oversampler.numChannels = getTotalNumInputChannels();
 
if (sampleRate <= 44100.0 || sampleRate == 48000.0) {
    oversampler.factorOversampling = 2;
} else if (sampleRate == (44100.0 * 2.0) || sampleRate == (48000.0 * 2.0)) {
    oversampler.factorOversampling = 1;
} else if (sampleRate == (44100.0 * 4.0) || sampleRate >= (48000.0 * 4.0)){
    oversampler.factorOversampling = 0;
} else {
    oversampler.factorOversampling = 0;
}
 
oversampler.addOversamplingStage(juce::dsp::Oversampling<float>::FilterType::filterHalfBandPolyphaseIIR, 0.05f, -90.0f, 0.05f, -90.0f);
 
oversampler.reset();
oversampler.initProcessing(samplesPerBlock);

// In Process Block
juce::dsp::AudioBlock<float> block (buffer);
auto returnBlock = oversampler.processSamplesUp(block);
/* use returnBlock in processing */
oversampler.processSamplesDown(block);

Regardless of what I put for oversampling factor anywhere in the chain (initializer or prepareToPlay), it always comes back x2 oversampled at the returnBlock.

I think that’s because in prepare to play you are clearing all the stages then adding a single stage back, which means it oversamples once no matter what. The way this class works is in stages of 2x. For 4x oversampling you need 2 stages, etc.

A solution could be to make the instance a unique ptr, then call reset on it in prepare to play and construct a new instance with the right arguments.

Or add stages in a for loop, eg for i < numStages

1 Like

Great! Thank you!

1 Like