I am trying to write a SynthDef that can write to multiple buffers, depending on the numChannels argument. I wanted it to be more flexible regarding the number of channels used. I wanted it to behave similarly with one channel as with several, provided I allocate a bunch of buffers in order. It works fine without the “.do”-loop but gives me this cryptic error-message: “ERROR: Non Boolean in test.” when I try to evaluate this snippet.
Is this not allowed or is there a way to do this and make it work?
SynthDef(\bufWrite, {
var numChannels = \numChannels.kr(1);
var in = In.ar(\in.kr(0), numChannels);
in.do({|channel, i|
BufWr.ar(
channel,
\buf.kr(0) + i,
Phasor.ar(
1,
BufRateScale.kr(\buf.kr + i) * \rate.kr(1),
0,
BufFrames.kr(\buf.kr + i)
)
);
});
}).add;
An honest question is what part of my question is common? I did not know the \numChannels was a reserved symbol until you told me. What do you suppose I search for?
It can’t be a SynthDef argument because a SynthDef’s structure must be 100% predetermined. The server has no power to change the structure. If you try to change your synth from 2 to 3 channels, it means creating more UGens = different structure = not supported within one SynthDef.
This should definitely be mentioned in the SynthDef help file. Probably in the tutorial series too.
For your case, I think it would be best to have one SynthDef for one channel, another for two channels etc. These can be mass-produced in a loop:
(1..10).do { |numCh|
SynthDef(("bufWrite" ++ numCh).asSymbol, {
var in = In.ar(\in.kr(1), numCh);
...
}).add;
};
Thanks for the explanation, what you wrote was identical to the SynthDef Issues-paragraph in the documentation FAQ. I was convinced that I had done something similar befor, but that was static. Perhaps it could be solved by using SynthDef.wrap?
SynthDef.wrap would be a less convenient way to write the same design as my suggestion.
It doesn’t sidestep the fixed-structure requirement, because there is no way anywhere in SC to sidestep that at the level of SynthDef. It would be possible to write a class for a higher level object that constructs a SynthDef on demand with the right number of channels (could be a big job to handle general cases!), but the SynthDef itself must be a fixed structure.