So I’m trying to build my mixer graph… and everything’s working fine except I’d like my Aux Tracks to also have sends… so I can send the return of my Aux Track 1 into my Aux Track 2 for instance… but the AudioProcessorGraph stops rendering (the bus connections) if you have any feedback loops. Most DAWs allow you to have sends on Aux Tracks even allowing the user to create feedback loops (send back to the Aux Track input for things like ping-pong delays for instance)
(See: http://www.juce.com/forum/topic/audioprocessorgraph-dead-nodes and
I’d really like to fix this… so my questions are:
Why are feedback loops not allowed ?
Has anyone modified the JUCE code to allow it?
Here’s a simple block diagram showing the graph connections which are causing the loop and the rendering to stop on the sends:
I’ll try and make time to create a test app to demonstrate the issue if required.
a feedback loop would always introduce a delay, which is as long as the block size which is used.
Even if you proceed with only one sample block size (which will introduce massive cpu overhead), it will still have 1 sample delay
(Think of a plugin, and connect the output with the input, and you realize why real feedback isn't easy, as long you didn't implement a statistical approximation algorithm, like in zero-delay filters (theres as thread in the kvraudio forum, about this topic), but in a plugin-context this would be even more complicated. An another approach would be to heavily oversample the audio-signal and than use sample by sample processing.)
Yeah, I’ll wait to hear back from Jules… meanwhile, I did check 3 JUCE based commercial products… and none of them (obviously) allow feedback loops… each handles the scenario differently (from not allowing Aux tracks to be bussed to other Aux tracks… to throwing up warning messages when a feedback loop would occur)… unless Jules has a solution I’m thinking I’ll probably just enable and disable sends dynamically if they would create a feedback loop.
TBH I can't remember how the graph works in detail, but it's pretty complicated in there..
Yes it is… I spent some time looking into it today… As discussed in the previous thread… if there’s a feedback loop… the input is set to zero
I don’t even think it would be easy to add a method like: willConnectionCauseFeedbackLoop()… so I’m working on handling the dynamic enabling & disabling of sends externally (to the AudioProcessorGraph).
I guess this’ll go on the wish list pile.
Well, I don't think there's any reason for it to avoid feedback loops.. Obviously there'll be a delay introduced if you add a loop, but it should still be able to play them.
We'll be doing some hard thinking about this for tracktion this year, so there could be some spin-offs from that work that end up improving these classes.
Anyone have any ideas on how to speed this up if there are no connections between the nodes….?
/** Returns true if there is any connection between any of the channels of
two specified nodes.
bool AudioProcessorGraph::isConnectedIndirectly (const uint32 possibleSourceNodeId,
const uint32 possibleDestNodeId) const
for (int i = connections.size(); --i >= 0;)
const Connection* const c = connections.getUnchecked(i);
if (c->sourceNodeId == possibleSourceNodeId)
if (c->destNodeId == possibleDestNodeId)
if (isConnectedIndirectly (c->destNodeId, possibleDestNodeId))
In Release it’s not too bad, but in Debug it’s pretty slow…