Multichannel control bus and .asMap

If I have a lot of parameters in a SynthDefs that I’d like to control via asMap arguments in the Synths, is there a way to do that with multichannel control busses or do I need to make an individual control bus for each parameter?

This doesn’t work but it’s what I’m imagining:

~tmp = Bus.control(s, 2);
~tmp.setn([500, 0.2]); //freq, vol
x = {arg freq=440, vol=0.1; SinOsc.ar(freq,0,vol)}.play;
x.set(\freq, ~tmp.asMap.at(0), \vol, ~tmp.asMap.at(1))

I see that subBus works how I’m thinking

~tmpf = ~tmp.subBus(0,1);
~tmpv = ~tmp.subBus(1,1);
x.set(\freq, ~tmpf.asMap, \vol, ~tmpv.asMap);
~tmp.setn([1000, 0.03]); //freq, vol

but I don’t understand how/if that’s easier/better than just doing two separate Buses in the first place

In the case you present above, I believe it is better to use individual busses. The multichannel busses simply allocate consecutive indices for single busses.

" Note that using the Bus class to allocate a multichannel bus does not ‘create’ a multichannel bus, but rather simply reserves a series of adjacent bus indices with the bus’ Server object’s bus allocators. abus.index simply returns the first of those indices."

A use case for a multichannel bus is setting something in a Synth that takes an array, but that wouldn’t use .asMap. The code for .asMap looks like this:

asMap {
	^mapSymbol ?? {
		if(index.isNil) { MethodError("bus not allocated.", this).throw };
		mapSymbol = if(rate == \control) { "c" } { "a" };
		mapSymbol = (mapSymbol ++ index).asSymbol;
	}
}

Where we see that the message passed to the server uses a single index, which would be the first of the indices allocated by the multichannel bus.

thank you! I skipped right past that in the Bus help file. I think what my brain wants is an array of busses then

~tmp = [Bus.control(s), Bus.control(s)];
~tmp.at(0).set(500); ~tmp.at(1).set(0.2);
x = {arg freq=440, vol=0.1; SinOsc.ar(freq,0,vol)}.play;
x.set(\freq, ~tmp.at(0).asMap, \vol, ~tmp.at(1).asMap)

~tmp.at(0).set(700);
~tmp.at(1).set(0.15);
1 Like

Yes, that makes sense

Sometimes, I use a Dictionary of Busses when it is easier to keep track of things by name.

a = Dictionary.new;
a.put(\ampBus, Bus.control(s, 1));
a put(\freqBus, Bus control(s, 1));
a.at(\ampBus).asMap;
a.at(\freqBus).asMap;

1 Like