The ChucK Tutorial

version: 1.2.x.x (dracula)

Hello ChucK:

This tutorial was written for the command line version of ChucK (currently the most stable and widely supported). Other methods of running ChucK includes the miniAudicle (now on all major platforms) and the Audicle (in pre-pre-alpha). The code is the same, but the way to run them differs, depending the ChucK system.

The first thing we are going to do is do generate a sine wave and send to the speaker so we can hear it. We can do this easily ChucK by connecting audio processing modules (unit generators) and having them work together to compute the sound.

We start with a blank ChucK program, and add the following line of code: (by default, a ChucK program starts executing from the first instruction in the top-level (global) scope).

      SinOsc s => dac;

The above does several things. (1) it creates a new unit generator of type 'SinOsc' (sine oscillator), and store its reference in variable 's'. (2) 'dac' (D/A convertor) is a special unit generator (created by the system) which is our abstraction for the underlying audio interface. (3) we are using the ChucK operator (=>) to ChucK 's' to 'dac'. In ChucK, when one unit generator is ChucKed to another, we connect them. We can think of this line as setting up a data flow from 's', a signal generator, to 'dac', the sound card/speaker. Collectively, we will call this a 'patch'.


      SinOsc s => dac;

      // allow 2 seconds to pass
      2::second => now;
Let's now run this (assuming you saved the file as 'foo.ck'):
      %> chuck foo.ck

This would cause the sound to play for 2 seconds, during which time audio data is processed (and heard), afterwhich the program exits (since it has reached the end). For now, we can just take the second line of code to mean "let time pass for 2 seconds (and let audio compute during that time)". If you want to play it indefinitely, we could write a loop:

      SinOsc s => dac;

      // loop in time
      while( true ) {
          2::second => now;

In ChucK, this is called a 'time-loop' (in fact this is an 'infinite time loop'). This program executes (and generate/process audio) indefinitely. Try runnig this program.


So far, since all we are doing is advancing time, it doesn't really matter (for now) what value we advance time by - (we used 2::second here, but we could have used any number of 'ms', 'second', 'minute', 'hour', 'day', and even 'week'), and the result would be the same. It is good to keep in mind from this example that almost everything in ChucK happens naturally from the timing.

Now, let's try changing the frequency randomly every 100ms:

      // make our patch
      SinOsc s => dac;

      // time-loop, in which the osc's frequency is changed every 100 ms
      while( true ) {
          100::ms => now;
          Std.rand2f(30.0, 1000.0) => s.freq;


Go ahead and run this (again replace foo.ck with your filename):

      %> chuck foo.ck
Play with the parameters in the program. change 100::ms to something else (like 50::ms or 500::ms, or 1::ms or perhaps 1::samp(every sample)), or change 1000.0 to 5000.0...

Run and listen:
      %> chuck foo.ck


Concurrency in ChucK:

Now let's write another (slightly longer) program: (these files can be found in the examples/ directory, so you don't have to type them in)
      // impulse to filter to dac
      Impulse i => BiQuad f => dac;
      // set the filter's pole radius
      .99 => f.prad;
      // set equal gain zero's
      1 => f.eqzs;
      // initialize float variable
      0.0 => float v;

      // infinite time-loop
      while( true )
          // set the current sample/impulse
          1.0 => i.next;
          // sweep the filter resonant frequency
          // increment v
          v + .1 => v;
          // advance time
          100::ms => now;
Name this moe.ck, and run it:
      %> chuck moe.ck

Now, make two copies of moe.ck - larry.ck and curly.ck. Make the following modifications. 1) change larry.ck to advance time by 99::ms (instead of 100::ms). 2) change curly.ck to advance time by 101::ms (instead of 100::ms). 3) optionally, change the 4000.0 to something else (like 400.0 for curly).

Run all three in parallel:

      %> chuck moe.ck larry.ck curly.ck




Moving forward:

For more detail on each particular aspect of the ChucK language and virtual machine environment, please see the language specification

A large collection of pre-made examples have been arranged and provided with this distribution in the /doc/examples directory, and are mirrored here

chuck | soundlab | cs | music | ccrma