Conditional muting of synths

Say I have a few synths which output to a bus. Before I route it to the main output, I want to pass that bus through another synth that also reads a phasor, and if that phasor’s value crosses a certain threshold (in this case 1) I want to mute those synths, otherwise pass them straight to the output. Is there a way to achieve this seemingly simple task?

As a side question, is there a good reason why SuperCollider doesn’t have conditional and/or ordering UGens? Max/MSP for example has the useful <~, >~ and =~ which test two signals for ordering and equality, and they don’t seem too hard to implement on the SC server. Also objects like selector~ (output one of many inputs) and gate~ (output to one of many outputs) make a lot of sense for controlling the routing of signals in real time, especially within a single SynthDef.

Perhaps take a look at Select as an option

{Select.ar( K2A.ar(MouseX.kr(0, 2) > 1), [SinOsc.ar(440, 0, 0.5), PinkNoise.ar(0.5)])}.play

Equality on the Server is strange … But greater than and less than can work as a gate:

{SinOsc.ar(440, 0, 0.5) * (MouseX.kr(0, 2) > 1)}.play

wrapping that in a lag can smooth it out

{SinOsc.ar(440, 0, 0.5) * Lag.kr((MouseX.kr(0, 2) > 1))}.play

Josh beat me to the answer. Select is definitely the way to go here:

This example does what you ask for:

(
SynthDef(\synthy, {
  Out.ar(\bus.kr(0), SinOsc.ar(\freq.kr(440) * -3.dbamp));
}).add;
)
(
SynthDef(\gate, {
  var in = In.ar(\bus.kr(0));
  var phas = LFSaw.kr(4);
  var out = in * Select.kr(phas < 0.5, [0, 1]);
  Out.ar(0, out);
}).add
)  

x = Synth(\gate, [\bus, 4])
y = Synth(\synthy, [\bus, 4])

Equality is tricky, mainly because it’s quite rare in practice (all signals are a floating point). If you can come up of an example of why you’d want it we may be able to help you.

Output to multiple outputs is trivial in SuperCollider. For example:

// make a mono signal stereo
{var sig = SinOsc.ar(440); Out.ar(0, [sig, sig];}.play;

// which can also be written:
{var sig = SinOsc.ar(440); Out.ar(0, sig!2);}.play;

Or you could send to specific buses:

{
  var sig1 = SinOsc.ar(440);
  var sig2 = SinOsc.ar(445);
  Out.ar(0, [sig1, sig2, sig1, sig2]); // send sig1 to bus 0 and 2, send sig2 to bus 1 and 3;
}.play

All of these examples are for buses. Obviously if all your routing occurs within a synthdef, then you can assign an output as a variable and use it in as many places as you like.

Thank you both, I don’t know how I missed Select! I remember, during my first days learning about SuperCollider, reading about conditionals on the server not being what you’d expect and it sort of scared me away from using them, but it turns out they’re fine as long as your logic can be implemented with the 1s and 0s that the comparisons produce (and mine definitely can).

Thanks again, I learned something today!

1 Like

I think

  • > in scsynth works in the same way of >~ in Max.
  • < in scsynth works in the same way of <~ in Max.

Try the followings:

{ Select.ar(SinOsc.ar(1) > SinOsc.ar(2), [SinOsc.ar, WhiteNoise.ar(0.1)]) }.play
 // > is the same as >~ in Max.



{ ((SinOsc.ar(1) > SinOsc.ar(2) )).poll * WhiteNoise.ar(0.1) }.play
// > is the same as >~ in Max.
{[SinOsc.ar(1), SinOsc.ar(2), SinOsc.ar(1) > SinOsc.ar(2)]}.plot(2)

{ ((SinOsc.ar(1) < SinOsc.ar(2) )).poll * WhiteNoise.ar(0.1) }.play
// > is the same as <~ in Max.

{ (SinOsc.ar(1) < 0).poll * WhiteNoise.ar(0.1) }.play
// > is the same as <~ in Max.

{ ((SinOsc.kr(1) > SinOsc.kr(2)) * (SinOsc.kr(1) < SinOsc.kr(2))) * WhiteNoise.ar }.play
// > is the same as >~ in Max.
// < is the same as <~ in Max.

{ ((SinOsc.kr(1) >= SinOsc.kr(2)) * (SinOsc.kr(1) <= SinOsc.kr(2))) * WhiteNoise.ar }.play
// the result of >= is the same as the result of > 
// it returns 0. 
(0 >= 0) && (0 <= 0)
// the same logic in sclang returns true.
// it returns 0. 

{ Select.ar(SinOsc.ar(1) == SinOsc.ar(2), [SinOsc.ar, WhiteNoise.ar]) }.play
// == is not supported. error

{ Select.ar(SinOsc.ar(1) != SinOsc.ar(2), [SinOsc.ar, WhiteNoise.ar]) }.play
// != is not supported. error

Am I correct?

~ in Max works correctly!
The phase of SinOsc.ar in SC and the phase of cycle~ in Max is different. I removed the related section.