wax icon indicating copy to clipboard operation
wax copied to clipboard

How to express circular connections

Open jussi-kalliokoski opened this issue 7 years ago • 3 comments

The most common scenario for this is a delay with feedback, often with gain and/or a filter applied before feeding back to the input of the delay, but there are more complex setups too.

Ideally, the solution is not named inputs and outputs, e.g. <Delay name=”d”/><Gain output=”d”/>, at least I personally consider string references a design failure in pretty much every scenario due to creating a non-(trivially-)verifiable namespace and an easy error surface, e.g. see ref in React.

jussi-kalliokoski avatar Oct 15 '18 08:10 jussi-kalliokoski

Hey @jussi-kalliokoski,

Thanks for reaching out! I think this is a general limitation of expressing a multidirectional graph model using a tree, but I have a couple of ideas to mitigate this. I'll address this properly over the next few days and share my thoughts with you.

I agree with your points on refs. I thought of implementing the function-based version (i.e. ref={audioNode => {...}}) but decided against it for similar reasons.

jamesseanwright avatar Oct 16 '18 19:10 jamesseanwright

ref={audioNode => {...}} but decided against it for similar reasons.

Yeah, good call, people are already struggling with understanding how function refs work in React when it's just assigning them to class properties, I can just imagine the mess people would get themselves into if they should do connection logic in the ref callbacks.

I'll address this properly over the next few days and share my thoughts with you.

Sounds cool, looking forward to it!

jussi-kalliokoski avatar Oct 18 '18 05:10 jussi-kalliokoski

One idea I have that should work with the existing version of Wax is:

const gain = <Gain gain={0.4} />;

return (
    <AudioGraph>
        <Aggregation>
            {gain}
            <StereoPanner pan={0.2} />
            {gain}
        </Aggregation>
    {gain}
    </AudioGraph>
);

This will render a single GainNode, connect it to a StereoPannerNode, connect said StereoPannerNode back into the GainNodes input, and then connect the GainNode to the destination node.

Perhaps for readability, I would consider introducing a Circular component:

<Circular>
    {gain}
    <StereoPanner />
</Circular>

This would be analogous to the above example using the Aggregation component. What do you think?

jamesseanwright avatar Oct 24 '18 08:10 jamesseanwright