I’m having issues after upgrading JUCE from5.4.2 to 5.4.5. Specifically here is what is happening:
We use an AudioProcessorGraph with Nodes, as described in this tutorial: https://docs.juce.com/master/tutorial_audio_processor_graph.html
We have some unit tests, that expect to read the audio and midi coming out of the plugin, the most basic of which is something like this:
TEST_F(APlugin, ProducesAudioWhenAudioIsInput)
{
int num_frames = (mPlugin->calcLatencySamples() / mPlugin->getBlockSize()) + 1; // Enough frames to get over latency hump
for (int frame = 0; frame < num_frames; ++frame)
{
FillWithRandom(mBuffer);
mPlugin->processBlock(mBuffer, mMidiBuffer);
}
// Now assert that data is coming out by taking the max of samples
float maxSample = mBuffer.getMagnitude(0, mBuffer.getNumSamples());
ASSERT_GT(maxSample, 0.001f); < — FAILS, maxSample is always 0
}
Basically, just fill a buffer with data, and expect the data comes out. Simple right?
In 5.4.2 this works as intended, both audio and midi sent into the plugin, come out of the plugin unchanged as we expect in this case.
However, in 5.4.4 and 5.4.5 we no longer have this occurring. At some point, after our nodes are done processing this buffer is cleared. Specifically in this line in juce_AudioProcessorGraph.cpp:
{
const Context context { renderingBuffer.getArrayOfWritePointers(), midiBuffers.begin(), audioPlayHead, numSamples };
for (auto* op : renderOps)
op->perform (context);
}
for (int i = 0; i < buffer.getNumChannels(); ++i)
buffer.copyFrom (i, 0, currentAudioOutputBuffer, i, 0, numSamples); <— HERE!!!
In inspecting this further, in 5.4.2 the currentAudioOutputBuffer was filled at some point, in 5.4.5 it is not. The filling happens after our nodes are done, in the audioOutputNode, but in 5.4.5 we never get there.
It appears as if our connections being set up correctly, and all error codes are being checked along the way, the only difference is changing to unique pointers when the input/output nodes are initialized, due to the SDK change:
mAudioInputNode = this->addNode(
std::make_unique<AudioProcessorGraph::AudioGraphIOProcessor>(AudioProcessorGraph::AudioGraphIOProcessor::audioInputNode),
AudioProcessorGraph::NodeID((uint32_t) - 1));
mAudioOutputNode = this->addNode(
std::make_unique<AudioProcessorGraph::AudioGraphIOProcessor>(AudioProcessorGraph::AudioGraphIOProcessor::audioOutputNode),
AudioProcessorGraph::NodeID((uint32_t) - 2));
mMidiInputNode = this->addNode(
std::make_unique<AudioProcessorGraph::AudioGraphIOProcessor>(AudioProcessorGraph::AudioGraphIOProcessor::midiInputNode),
AudioProcessorGraph::NodeID((uint32_t) - 3));
mMidiOutputNode = this->addNode(
std::make_unique<AudioProcessorGraph::AudioGraphIOProcessor>(AudioProcessorGraph::AudioGraphIOProcessor::midiOutputNode),
AudioProcessorGraph::NodeID((uint32_t) - 4));
Any ideas on what could have changed that we are missing?