Array of Buses in Patterns

I have two SynthDefs which communicate by way of an audio bus. I´d like to be able to call this pair of Synths as often as I like, but I would like to use a different bus each time I call it, to avoid feedback or interaction within the busses. I have already created an Array of busses successfully. The next step: Is there a way for SC to know which bus I used in the last instance? Something like

fork {
Synth(\synthName, [\bus, ~bus[nextInArray]; //with wrapping capabilities…
rand(1.5, 0.5).wait;
}

  1. Is there a way to do this within a PBind?

Pbind(\instrument, \test,
\freq, Prand([1, 1.2, 2, 2.5, 3, 4], inf),
\bus, ~bus[nextInArray, inf).play;

One way:

\busnum, Pseq((0…~bus.size),inf),
\bus, Pfunc({|event| ~bus[event.busnum].play}

If I understand correctly, I need both of these lines in order for this to work?
The first one sort of creates a variable out of \busnum?

Thanks for the answer!

Yep you need both lines. Pbind generates a stream of Events - each Event has one key for each of the keys in the Pbind. When you call .play on the Pbind , .asStream is called on each value, and then at each iteration the resulting EventStreamPlayer calls .next on each of those Streams to get the value for the keys for the resulting Events.(phew!) Pfunc can access those keys by passing the event in as an argument to the ‘next’ function (see the Pfunc help).

Make sure to enclose your code in backticks so that it’s formatted correctly: ```<code>```

I sometimes use a “factory Pbind” design pattern to accomplish this. It’s not the only way to do this, and not necesarily the simplest, but it’s re-usable and ensures the buses are cleaned up when your pattern is done.

You can use Pproto to allocate resources, with one or more “getter” functions that I can refer to in whichever pattern I end up using it.

Here’s my factory:

(

Pdef(\busPool, Pproto(
    {
        var index = -1; // Gotcha: The proto event is copied, 
                        // so you can't track the index INSIDE your event with e.g. ~index.
        
         ~buses = 20.collect {
            (type: \audioBus, channels: 2).yield.postln
        };
        
        ~nextBus = {
            ~buses[index = index + 1];
        }
    },
    Pbind() // We don't need any additional keys beyond the above, so this can be empty.
));

)

Then I can <> compose my factory with another Pbind, and call my getter functions to fetch values. Playing a Pbind with it’s own bus pool looks like:

(

Pdef(\test, 
	Pdef(\busPool) 
	<> Pbind(
		\instrument, \test,
		\out, { ~nextBus.value }  // {} functions as Event values don't get called until the last minute
                                  // when the finalized Event is being played.
	) 
).play;

)

Each time you compose the factory with a Pbind, that Pbind has it’s OWN pool of buses, so you don’t have to worry about conflicts over resources.

One subtle gotcha: Pdef(\busPool) has to be composed AFTER your Pbind, e.g. to the left - if it’s to the right, then the “setup” events from Pproto get passed through your Pbind and end up being processed as notes.

1 Like