SuperCollider Cookbook

From CCRMA Wiki
Jump to: navigation, search

SuperCollider Cookbook / Quick Reference

This page collects short and simple code examples of useful stuff. These are just quick "reminders" of how to do common things.

Play a sound file, vary speed, reverse

create a buffer

~pizza = Buffer.read(s, "path/to/sound/file.wav");

simple play

{PlayBuf.ar(1, ~pizza)}.play; // number of channels and buffer

get sound file info

[~pizza.bufnum, ~pizza.numChannels, ~pizza.path, ~pizza.numFrames];

varying speed

{PlayBuf.ar(1, ~pizza, 2, loop: 1)}.play; // play 2x faster

{PlayBuf.ar(1, ~pizza, 0.5, loop: 1)}.play; // play at half the speed

{PlayBuf.ar(1, ~pizza, Line.kr(0.5, 2, 10), loop: 1)}.play; // playback speed goes from 0.5 to 2 in 10 seconds

changing direction (reverse)

{PlayBuf.ar(1, ~pizza, -1, loop: 1)}.play; // reverse sound

{PlayBuf.ar(1, ~pizza, -0.5, loop: 1)}.play; // play at half the speed AND reversed

Play a MIDI file

Do this and that.

Random numbers

rrand

rrand(0, 5)   // generates a random number between 0 and 5 (inclusive)

rand

rand(10)  // generates a random integer number between 0 and 10 (10 not included)

rand(10.0) // generates a random decimal number between 0.0 and 10.0 (10.0 not included)

10.0.rand  // same as above

10.0.rand.round(0.01) // same as above with rounding

exprand(1, 10.0)  // generates a random decimal number between 0.0 and 10.0, mostly lower values

Note the difference between these two:

dup(rand(100), 5)   // picks a number, duplicates it

dup({rand(100)}, 5) // duplicates the function of picking a number

LFNoise0, LFNoise1, LFNoise2

Random values between -1 and +1 generated at a specified rate. Compare the three:

{LFNoise0.ar(5000)}.plot
{LFNoise1.ar(5000)}.plot
{LFNoise2.ar(5000)}.plot

// freq - approximate rate at which to generate random values.
// LFNoise0.ar(freq, mul, add)
// LFNoise0.kr(freq, mul, add)

// One way of hearing the difference - try replacing LFNoise0 by LFNoise1 and LFNoise2:

{SinOsc.ar(800, mul: LFNoise0.kr(7))}.scope

Dust

Generates random impulses from 0 to +1.

{Dust.ar(5000)}.plot;

// Dust.ar(density, mul, add)
// density: average number of impulses per second

TRand

Generates a random float value in uniform distribution from lo to hi each time the trig signal changes from nonpositive to positive values:

(
 {var trig = Dust.kr(10);
  SinOsc.ar(TRand.kr(300, 3000, trig)) * 0.1
 }.play;
)

Mouse input

MouseX, MouseY

(
 {
  var freq = MouseX.kr(220, 440), amp = MouseY.kr(0, 0.3);
  SinOsc.ar(freq, mul: amp)
 }.play
)

Scale and Offset (mul, add)

SinOsc.kr.signalRange  // is the UGen bipolar (outputs between -1 and +1) or unipolar (outputs between 0 and +1)?

{SinOsc.kr(1, mul: 200, add: 1000).poll(label: "output")}.play // outputs numbers between 800-1200

{SinOsc.kr(1).range(800, 1200).poll(label: "output")}.play     // same result as above

LFPulse.kr.signalRange  // this one is unipolar

{LFPulse.kr(1, mul: 400, add: 800).poll(label: "output")}.play  // outputs 800-1200

{LFPulse.kr(1).range(800, 1200).poll(label: "output")}.play     // same result as above

Looping

While

(
i = 0;
while ( { i < 5 }, { i = i + 1; "boing".postln });
)

For

for (3, 7, { arg i; i.postln }); // prints values 3 through 7

ForBy

forBy (0, 8, 2, { arg i; i.postln }); // prints values 0 through 8 by 2's

Do

do(9, {"Wow".postln}); // print "Wow" nine times

9.do({"Wow".postln}); // same as above

5.do({ arg item; item.postln }); // iterates from zero to four

do(5, {arg item; item.postln}); // same as above

Compare the output of these:

do(9, {arg whatevername; whatevername.postln}); // give whatever name you want to the arg of 'do'

do([9, 8, 3, 5], {arg whatevername; whatevername.postln}); // elements from collection (not a counter)

do([9, 8, 3, 5], {arg whatevs1, whatevs2; [whatevs2, whatevs1].postln}); // second argument works as a counter

More examples:

["zero", "first", "second", "third", 500].do({ arg item, i; [i, item].postln; });

do(["zero", "first", "second", "third", 500], {arg item, i; [i, item].postln});

"you".do({ arg item; item.postln }); // a String is a collection of characters

'they'.do({ arg item; item.postln }); // a Symbol is a singular item

(8..20).do({ arg item; item.postln }); // iterates from eight to twenty 

(8,10..20).do({ arg item; item.postln }); // iterates from eight to twenty, with stepsize two

If...Else

Syntax is if(condition, {true action}, {false action}). Examples:

if(10 == 10, {"10 is indeed equal to 10"}, {"false"})

if(condition, {true action}, {false action});

if(10 == 10, {"10 is indeed equal to 10"}, {"false"})

if((1 < 20).and(1.8.isInteger), {"very true"}, {"hmmm..."})

10.do({arg count; [count, if(count.odd, {"odd"}, {"even"})].postln})

(
84.do({arg count; if([0, 4, 7].includes(count%12), 
	{count.post; " is part of a C triad.".postln}, 
	{count.post; " is not part of a C triad".postln})})
)

50.do({if(1.0.rand.round(0.01).post > 0.5,  {" > 0.5".postln}, {" < 0.5".postln})})

50.do({if(1.0.rand > 0.5,  {"play a note".postln}, {"rest".postln})})

50.do({if(0.5.coin, {"play a note".postln}, {"rest".postln})}) // same as above

if((10.odd).or(10 < 20), {"true".postln}, {"false".postln})

Arrays

Various array operations:

a = [10, 11, 12, 13, 14, 15, 16, 17]

a.reverse  // reverse

a.scramble // scramble

a.choose  // picks one element at random

a.size	  // returns size of array

a.at(0)   // retrieves item at specified position

a[0]	  // same as above

a.wrapAt(9) // retrives item at specified position, wrapping around if > a.size

a ++ 999  // ++ (concatenate) adds something to the end of the array

a ++ \hi  // a Symbol is a single character

a ++ 'hi' // same as above

a ++ "hi" // a String is a collection of characters

a.insert(5, "wow") // inserts "wow" at position 5, pushes other items forward

a // evaluate this and see that none of the above operations actually changed the original array

a.put(2, "oops") // put "oops" at index 2 (destructive; evaluate line above again to check)

a.add(44)    // adds new element at the end of the array (permanently) 

a.do({arg whatever, blech; [blech, whatever].postln}) 	// how to "do" an array

b = Array.series(5, 1); // create an array with 5 sequential numbers, starting at 1)

b.mirror  // makes it a palindrome

b.permute(3) // permute: item in position 3 goes to position 0, and vice-versa 

b.powerset // returns all possible combinations of the array's elements

Array.fill(10, "same"); // Another way of building an array

Array.fill(10, {arg counter; (counter + 1)*440}); 

More info: http://sc3howto.blogspot.com/2010/05/arrays.html

poll and scope

Check what's going on with your UGens:

{SinOsc.kr(1/2).round(0.01).poll(label: "watchThis")}.scope

Amplitude Modulation

Frequency Modulation

Additive Synthesis

Subtractive Synthesis