• jon@schemawound.com

Supercollider Tweets: Background / Tips

Updated 11/20/2012: Added 7 new tips courtesy of Nathaniel Virgo

I have previously made two blog posts showing some of my Supercollider tweets (Part 1 and Part 2). I posted these up without any real explanation and I wanted to spend a little time talking about why and how I have been creating these.

My main interest has been in the extreme limitation of trying to fit interesting code into 140 characters. Limitations often push you into artistic directions you might have never explored otherwise, this has been the main reason behind my interest in contributing to themed compilations such as SIGNALVOID and those put out by Waxen Wings.

Another benefit is the 140 character limitation forces you to explore areas of Supercollider you may have never explored otherwise. When each character matters you sometimes have to dig through the help files to find an alternate way of accomplishing your goals.

Supercollider is an ideal language for the task, it is full of syntactic sugar allowing you to express the same concept many different way. I have found a number of different useful tricks to use when trying to shorten code to fit within a tweet.


Receiver Notation vs. Functional Notation

In Supercollider you have a choice between two different style of sending messages to objects. You can sometimes save several characters by switching from one form to another.

These two statements are equivalent:

100.rand
rand(100)

So are these:

{SinOsc.ar(440)}.play
play{SinOsc.ar(440)}

Stereo Trick
!2 can be used as a simple trick to make a mono signal into stereo

These two statements are equivalent:

play{SinOsc.ar([440,440])}
play{SinOsc.ar(440)!2}

Assigning Ugens to Variables
If you are using the same Ugen several times you may be able to save space by assigning it to a variable and calling your .ar and .kr methods on the variable

These two statements are equivalent:

play{;DFM1.ar(FreeVerb.ar(FreeVerb.ar(GVerb.ar(Dust.ar(9),10,3,0.5),1,1)*SinOsc.ar(60),1,1)*SinOsc.ar(150),SinOsc.kr([0.1,0.17]).range(900,9999))}
play{x=FreeVerb;y=SinOsc;DFM1.ar(x.ar(x.ar(GVerb.ar(Dust.ar(9),10,3,0.5),1,1)*y.ar(60),1,1)*y.ar(150),y.kr([0.1,0.17]).range(900,9999))}

Changing Values
Sometimes you can save a character by changing a value to take up one less character

These two statements are not equivalent but are close enough for most purposes:

play{SinOsc.ar(1000)}
play{SinOsc.ar(999)}

Shortcut Method / Classes
You can often find a shortcut method of class that will allow you to accomplish your goals using much less code.

These two statements are equivalent:

Routine{"x".postln;1.wait;"y".postln}.play
fork{"x".postln;1.wait;"y".postln}

Array Shortcuts
You can save quite a lot of space by creating arrays in the following way

These two statements are equivalent:

[1,2,3,4,5,6,7,8,9,10]
(1..10)

So are these:

[3,6,9,12,15,18,21,24,27,30]
(1..10)*3

Method Chaining
Look for opportunities to chain methods

These two statements are equivalent:

play{x=SinOsc.ar(100);x.clip2(0.5)}
play{SinOsc.ar(100).clip2(0.5)}

Shortcut Syntax for Functions
The shortcut syntax for functions can save quite a lot of space when used properly.

These two statements are equivalent:

{|x|x.isPrime}!10
_.isPrime!10

So are these:

play{Mix(SinOsc.ar((0..100)))}
play{Mix(SinOsc.ar(_)!100)}

Take Advantage Of The Lack Of Operator Precedence (Submitted by Nathaniel Virgo)
Supercollider reads all math equations from left to right instead of following operator precedence, this can allow you to avoid adding parenthesis in many places.

These two statements are equivalent:

a*(b+c)
b+c*a

Use Exponentiation Instead Of .exprange (Submitted by Nathaniel Virgo)
Supercollider reads all math equations from left to right instead of following operator precedence, this can allow you to avoid adding parenthesis in many places.

These two statements are equivalent:

SinOsc.kr(1).exprange(10,40)
2**SinOsc.kr(1)*20

it can be fiddly to work out the parameters, but you can evaluate the following 2 statements to get the min and max values:

2**-1*20
2**1*20

Use CuspN.ar Or CuspL.ar Instead Of WhiteNoise.ar (Submitted by Nathaniel Virgo)
It doesn’t sound quite the same but it has a much shorter name.


Use Scientific Notation (Submitted by Nathaniel Virgo)
These two statements are equivalent:

2000
2e3

And these:

0.001
1e-3

Use Division (Submitted by Nathaniel Virgo)
These two statements are equivalent:

x*0.1
x/10

And this might be close enough:

x/9

Assign Variables Inside Statements (Submitted by Nathaniel Virgo)
These two statements are equivalent:

play{x=Saw.ar;RLPF.ar(x)+x}
play{RLPF.ar(x=Saw.ar)+x}

Use Weird Syntax For Methods (Submitted by Nathaniel Virgo)
This one is only useful occasionally, because it only works if the method has exactly one argument, but these are equivalent:

play{SinOsc.ar(440)}
play{SinOsc ar:440}

Conclusion
While many of these tips are useful for shortening code to fit within a tweet they can also make your code much more difficult to read. I would recommend you take care if you choose to implement these techniques in your regular Supercollider code. Please feel free to share any other tips you have in the comments.