It looks like your Oversampling instance is only being prepared to work with a single channel (the first constructor argument). If your plugin accepts multiple channels, you must initialise the Oversampling instance with the same number of channels.
There are a few other issues in the snippet you posted that might prevent the Oversampling class from working as expected: Normally, initProcessing would be called from prepareToPlay. Calling it in each block may cause issues. Also, calling addOversamplingStage inside processBlock will add a new stage on each audio callback, which is unlikely to be what you want. Finally, you need to call oversampler.processSamplesDown (outputBlock) after doing your processing on the returnBlock in order to return the block to the host’s sampling rate.
Thank you for your help! I switched the channel number to 2 from 1 and Logic still gives errors on those channel-based jassert lines. Is there something else I am missing?
It sounds like the audio buffer being passed into processSamplesUp still has more channels than the oversampler is expecting. When you hit the assertion in processSamplesUp, you should be able to see the number of channels in the inputBlock in your debugger. (You could also add a DBG (inputBlock.getNumChannels()) statement to print the number of channels in the block).
If your plugin only supports certain channel counts, you should override isBusesLayoutSupported in your AudioProcessor to prevent the plugin from being instantiated with an unsupported channel layout.
I’ve configured isBussesLayoutSupported to only support stereo processing, and have configured my oversampler in PluginProcessor.h to look like this. The jasserts still come up. The channels of the inputBlock and the buffer read 2 and 2. Is there something I am missing?
When you hit the first assertion, try checking all of the values involved to work out why the assertion is firing. Then, you should be able to look up the call stack to find out where the incorrect value is coming from.
Are you sure that you’re initialising the oversampler correctly? If the input block definitely has only two channels, you should check ParentType::buffer.getNumChannels() to make sure that the oversampler is prepared to process that many channels.
Thank you for your help. How do I check the ParentType::buffer.getNumChannels()? I have done oversampler.numChannels and compared it to buffer.getNumChannels() and the two match in my cout statement. Even when I set the oversampler to 0 channels, I still get the flag in Logic that
You can either look at the number of channels in the buffer member using a debugger, or you could add a line like this to the oversampler implementation:
Might I ask you where you initialize your oversampler? Because it does not have a default constructor and so you should initialize it in the initializer list of your PluginProcessor constructor.
I think the problem is that the number of channels in the oversampling stage’s buffer is only set during initProcessing. Moving the call to initProcessing after the call to addOversamplingStage should resolve the issue.
I am now having an issue with processSamplesDown() where line 202 in juce_Oversampling.cpp throws the following error, even thought outputBlock.getNumSamples() * ParentType::factor == 4096 and ParentType::buffer.getNumSamples() == 32768. Is the second number higher than I should be expecting for a buffer? Thank you!
I can’t reproduce this problem, so I’m not sure exactly what’s going on. It’s easier for other people to help if you provide a small program which exhibits the problem.
I don’t think that assertion would fire if the left-hand of the <= is really smaller than the right-hand side. I’d recommend adding some logging to make absolutely sure of the values involved in the assertion. If you put the logging directly before the assertion, then at the point that you hit the assertion, you’ll be able to see the values involved in the console window.
It looks a bit suspicious that you’re writing to the factorOversampling data member. Modifying this member directly may break the invariants of the Oversampling instance. I’d recommend removing all writes to factorOversampling and checking whether that resolves your problem.
Here’s how I am calling the two functions now. I am not getting any logical errors in Logic, but I am not seeing the effects of the oversampling filter in DDMF’s PluginDoctor.
auto returnBlock = oversampler.processSamplesUp(buffer);
juce::AudioBuffer<float> buffer2;
returnBlock.copyTo(buffer2);
//Processing using buffer2
juce::dsp::AudioBlock<float> outputBlock;
outputBlock.copyFrom(buffer2);
oversampler.processSamplesDown(outputBlock);
for (auto i = totalNumInputChannels; i < totalNumOutputChannels; ++i)
buffer.clear (i, 0, buffer.getNumSamples());
outputBlock.copyTo(buffer);
So first of all, why are u calling always audioblock.copyTo(audioBuffer) ?
After the upsampling process you can use directly the returnBlock. That audioblock already contains a reference to the upsampled buffer! Moreover, you can get the audiosamples directly by calling returnBlock.getChannelPointer(channel)[numSample].
I think that creating a new buffer and calling copyTo function, could allocate new memory in the buffer2 (but I am not sure if this happens, I’ve never used copyTo() ) . And allocating new memory on the audio thread is always a not-safe operation
What you could do is simply
dsp::AudioBlock<float> inputBlock (buffer);
auto returnBlock = oversampler.processSamplesUp(inputBlock);
// Processing using returnBlock
oversampler.processSamplesDown(inputBlock);
// Continue processing using inputBlock
Hey! Thank you for your help! I got it to work! I didn’t realize you could use getChannelPointer() in an audio block like getWritePointer() in a buffer. That solved all my problems!