SuperCollider Cookbook: Difference between revisions
(55 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
'''SuperCollider Cookbook | '''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> | ||
~ | ~pizza = Buffer.read(s, "path/to/sound/file.wav"); | ||
</pre> | </pre> | ||
'''simple play''' | '''simple play''' | ||
<pre>{PlayBuf.ar(1, ~ | <pre> | ||
{PlayBuf.ar(1, ~pizza)}.play; // number of channels and buffer</pre> | |||
'''get sound file info''' | '''get sound file info''' | ||
<pre>[~ | <pre>[~pizza.bufnum, ~pizza.numChannels, ~pizza.path, ~pizza.numFrames];</pre> | ||
'''varying speed''' | '''varying speed''' | ||
<pre>{PlayBuf.ar(1, ~ | <pre> | ||
{PlayBuf.ar(1, ~ | {PlayBuf.ar(1, ~pizza, 2, loop: 1)}.play; // play 2x faster | ||
{PlayBuf.ar(1, ~ | |||
'''changing direction''' | {PlayBuf.ar(1, ~pizza, 0.5, loop: 1)}.play; // play at half the speed | ||
<pre>{PlayBuf.ar(1, ~ | |||
{PlayBuf.ar(1, ~ | {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. | ||
== | ==Random numbers== | ||
''' | '''rrand''' | ||
''' | <pre> | ||
''' | 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 | |||
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> | ||
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