Jump to content

SuperCollider Cookbook: Difference between revisions

From CCRMA Wiki
Ruviaro (talk | contribs)
Ruviaro (talk | contribs)
 
(55 intermediate revisions by the same user not shown)
Line 1: Line 1:
'''SuperCollider Cookbook by Bruno'''
'''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==
==Play a sound file, vary speed, reverse==
'''create a buffer'''
'''create a buffer'''
<pre>
<pre>
~mysound = Buffer.read(s, "path/to/sound/file.wav");
~pizza = Buffer.read(s, "path/to/sound/file.wav");
</pre>
</pre>
'''simple play'''
'''simple play'''
<pre>{PlayBuf.ar(1, ~mysound)}.play; // number of channels and buffer</pre>
<pre>
{PlayBuf.ar(1, ~pizza)}.play; // number of channels and buffer</pre>
'''get sound file info'''
'''get sound file info'''
<pre>[~mysound.bufnum, ~mysound.numChannels, ~mysound.path, ~mysound.numFrames];</pre>
<pre>[~pizza.bufnum, ~pizza.numChannels, ~pizza.path, ~pizza.numFrames];</pre>
'''varying speed'''
'''varying speed'''
<pre>{PlayBuf.ar(1, ~mysound, 2, loop: 1)}.play; // play 2x faster
<pre>
{PlayBuf.ar(1, ~mysound, 0.5, loop: 1)}.play; // play at half the speed
{PlayBuf.ar(1, ~pizza, 2, loop: 1)}.play; // play 2x faster
{PlayBuf.ar(1, ~mysound, Line.kr(0.5, 2, 10), loop: 1)}.play; // playback speed goes from 0.5 to 2 in 10 seconds</pre>
 
'''changing direction'''
{PlayBuf.ar(1, ~pizza, 0.5, loop: 1)}.play; // play at half the speed
<pre>{PlayBuf.ar(1, ~mysound, -1, loop: 1)}.play; // reverse sound
 
{PlayBuf.ar(1, ~mysound, -0.5, loop: 1)}.play; // play at half the speed AND reversed</pre>
{PlayBuf.ar(1, ~pizza, Line.kr(0.5, 2, 10), loop: 1)}.play; // playback speed goes from 0.5 to 2 in 10 seconds</pre>
'''changing direction (reverse)'''
<pre>
{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</pre>


==Play a MIDI file==
==Play a MIDI file==
Line 22: Line 30:
Do this and that.
Do this and that.


==List Operations==
==Random numbers==
'''scramble'''
'''rrand'''
'''reverse'''
<pre>
'''find nth'''
rrand(0, 5)  // generates a random number between 0 and 5 (inclusive)
</pre>
 
'''rand'''
<pre>
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
</pre>
Note the difference between these two:
<pre>
dup(rand(100), 5)  // picks a number, duplicates it
 
dup({rand(100)}, 5) // duplicates the function of picking a number
</pre>
'''LFNoise0, LFNoise1, LFNoise2'''
 
Random values between -1 and +1 generated at a specified rate. Compare the three:
 
<pre>
{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
</pre>
 
'''Dust'''


Generates random impulses from 0 to +1.
<pre>
{Dust.ar(5000)}.plot;
// Dust.ar(density, mul, add)
// density: average number of impulses per second
</pre>
'''TRand'''
Generates a random float value in uniform distribution from lo to hi each time the trig signal changes from nonpositive to positive values:
<pre>
(
{var trig = Dust.kr(10);
  SinOsc.ar(TRand.kr(300, 3000, trig)) * 0.1
}.play;
)
</pre>
==Mouse input==
'''MouseX, MouseY'''
<pre>
(
{
  var freq = MouseX.kr(220, 440), amp = MouseY.kr(0, 0.3);
  SinOsc.ar(freq, mul: amp)
}.play
)
</pre>
==Scale and Offset (mul, add)==
<pre>
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
</pre>


==Looping==
==Looping==


'''While'''
'''While'''
<pre>(
<pre>(
i = 0;
i = 0;
Line 38: Line 129:


'''For'''
'''For'''
<pre>for (3, 7, { arg i; i.postln }); // prints values 3 through 7</pre>
<pre>for (3, 7, { arg i; i.postln }); // prints values 3 through 7</pre>


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


'''Do'''
'''Do'''
<pre>
do(9, {"Wow".postln}); // print "Wow" nine times
9.do({"Wow".postln}); // same as above


<pre>
5.do({ arg item; item.postln }); // iterates from zero to four
5.do({ arg item; item.postln }); // iterates from zero to four
do(5, {arg item; item.postln}); // same as above
do(5, {arg item; item.postln}); // same as above
</pre>
</pre>
Now compare these:
Compare the output of these:
<pre>
<pre>
do(9, {arg whatevername; whatevername.postln});
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});
 
do([9, 8, 3, 5], {arg whatevs1, whatevs2; [whatevs2, whatevs1].postln});
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
</pre>
</pre>
 
More examples:
<pre>
["zero", "first", "second", "third", 500].do({ arg item, i; [i, item].postln; });
["zero", "first", "second", "third", 500].do({ arg item, i; [i, item].postln; });


Line 69: Line 165:


(8,10..20).do({ arg item; item.postln }); // iterates from eight to twenty, with stepsize two
(8,10..20).do({ arg item; item.postln }); // iterates from eight to twenty, with stepsize two
</pre>
==If...Else==
Syntax is ''if(condition, {true action}, {false action})''. Examples:
<pre>
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})
</pre>
==Arrays==
Various array operations:
<pre>
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});
</pre>
More info: http://sc3howto.blogspot.com/2010/05/arrays.html
==poll and scope==
Check what's going on with your UGens:
<pre>
{SinOsc.kr(1/2).round(0.01).poll(label: "watchThis")}.scope
</pre>
</pre>



Latest revision as of 06:32, 11 June 2011

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