Connections Not Allowed

stringtapper's icon

Another post about self modulating FM prompted me to try making the same patch in Gen and I noticed (and have noticed with other patches) that some connections will not work when you're trying to feed signals back into themselves. For this patch the only way I figured out how to make the connection was to place a [history] operator and introduce a single sample delay.

So my question is what is the theoretical reason that connections like this can't happen, and is there any other way to achieve this kind of self-modulating feedback without introducing any delay?

Thanks,

Max Patch
Copy patch and select New From Clipboard in Max.

Dave

Floating Point's icon

I haven't looked at your patch, but it shouldn't matter as the answer would be the same anyway, and that is if you think about it you would otherwise be creating an infinite loop, where the process the result feeds back into just keeps recalculating for that one sample frame. So the history object creates an automatic end condition, sort of like a for loop with only 1 iteration (for (i=0, i
But maybe that will change soon, as apparently the c74 people are working on for loops in gen~. So you _could_ have crazy recursive structures in gen that occur within one sample frame, but in order to hear them, you'd still have to have an end condition, otherwise the sample frame would never be output. It's a limitation of discrete sampling in digital audio, as distinct from the continuous world of analogue audio.

Graham Wakefield's icon

Exactly -- it's not logically possible to have a delay-less feedback loop in discrete time-based systems. The patcher environment tries its best to prevent any such case happening, as it would behave unexpectedly. A [history] or [delay] object is necessary for feedback in this way. Gen~ at least lets you get to that theoretical limit of 1 sample feedback, which wasn't possible before :-)

1 sample is pretty short :-)

In some limited cases, it is possible to avoid the feedback loop altogether by using an analytical mathematical model of the resultant ideal system, based on the math of infinite series for example. Unfortunately, not only does this require good old algebra on paper, it does not present solutions for general cases, nor in most for most of the situations that we typically find 'interesting'... Alternatively, some infinite systems can be approximated using finite systems. For example, careful design of a FIR filter can approximate the sound of certain IIR filters, without needing the feedback loop. However, they can be expensive and very difficult to design. I may be wrong, but I suspect that such an approximation of feedback FM would miss all the interestingness of it.

@Terry: for loops were introduced in 6.0.7, and should be getting more expressive in future updates. We're also looking into supporting recursion.

stringtapper's icon

Got it, thanks guys. So basically it would be like looking into the future to be able to have something like that work without any delay I guess.

stringtapper's icon

Ok that was a bit of theory before. Here's where this kind of thing has actually affected something I'm working on.

In the [gen~] patcher below I have coded three scattering junctions to be used as nodes within a 2d (and eventually 3d) mesh. The nodes on the left are encapsulated versions of the nodes on the right. As you can see the sub-patcher nodes don't allow certain connection that the un-encapsulated nodes do.

The whole point of wanting to encapsulate the nodes is to make the patch less messy and more readable. The current workaround is to either code the scattering junctions in Codebox or copy the visual code of a scattering junction and paste it into a Codebox. This is less than ideal for me because I'm trying to make the Gen patching environment resemble standard block diagrams of the processes as part of project to create a system that can teach the user about the processes as they put them to use.

So it seems like the [gen~] patcher can't "see" what's inside of its sub-patchers to allow feedback connections? Is this something that could be logged as a feature request or something that is an inherent limitation?

Thanks,

Max Patch
Copy patch and select New From Clipboard in Max.

Dave

Graham Wakefield's icon

Yes, currently feedback patching is not supported when it goes though a sub-gen. This is partly due to how sub-gens are parsed separately and combined, which involves some degree of caching to speed it up. Basically the way to think of it is that the parser cannot look inside the sub-gens to see what they contain.

Your example will work fine if the last history nodes are lifted out of the sub-gen.

We've been working on speeding up the parsing & compiling in the last few months, and if this makes a big difference, then maybe we can relax the limitation of caching sub-gens which would allow for feedback tracing though sub-gens; we'll see how it goes.