Functions with several statements


#1

Hi there

I’m new to SuperCollider, so any advice is much appreciated. My question is: is it true that any message sent to a function with several statements is executed on the last statement only? Thanks!

(
x = {
SinOsc.ar(200, 0, [0.5, 0.5]);
SinOsc.ar(400, 0, [0.5, 0.5]);
}.play;
) //plays only the 400Hz tone, and…

(
x = {
SinOsc.ar(400, 0, [0.5, 0.5]);
SinOsc.ar(200, 0, [0.5, 0.5]);
}.play;
) //plays only the 200Hz tone. Why is that exactly?


#2

If you define a function, the last line determines what is returned from the function. In your case you call “play” on the return value of a function that returns a single SinOsc.
If you wanted to hear both simultaneously, you could add them up:

(
x = { (SinOsc.ar(200) + SinOsc.ar(400))*0.5 ! 2 }.play;
)


#3

Hi!

Function.play is a convenience method that

a) turns your function into a SynthDef,

b) sends it to the server, and then

c) creates a Synth from / of it.

Part of a) is to assume the last statement in your function is producing the signal that is to be output, and create a corresponding Out.ar for you.

See e.g. http://doc.sccode.org/Classes/Function.html

(Audio section)

I messed around with SC a very great deal before I really understood this, so your question is absolutely justified

Btw, you can have both of your sines by enclosing them in brackets and separating with a comma instead of semicolon. Then they are interpreted as the two halves of a single, 2-channel signal. Also have a look at Mix and Splay to combine several signals into one.

fork{loop{h=[5,7,8].choose*(2**(2 .. 8).choose);play{Splay.ar({SinOsc.ar(exprand(h,h+(h/64)),0,0.1)}!64)*LFGauss.ar(9,1/4,0,0,2)};2.wait}};

Have fun! It’s a great time to be alive

eddi


#4

Thanks both for your helpful responses, that’s much appreciated!