[chuck-users] Getting Started with ChucK

Michael Heuer heuermh at gmail.com
Tue Jul 21 14:53:21 EDT 2009


Hans Aberg wrote:

> This is an independent issue. Chuck needs some components so that the
> creation of basic units becomes simpler.
>
> This might be tied to a multiple timing model. The per-sample timing is only
> needed when creating a single sound generator, corresponding to a string or
> pipe in a music instrument. When coordinating those into music instrument, a
> timing of about 10 millisecond might suffice. A group of music instruments
> might do with somewhat less. - Just an input.

This higher-level timing composition was my goal in the functor
objects and Loops construct in LiCK:

http://github.com/heuermh/lick/blob/b30c8ab28abe6e1580e43819fe586af247cfd298/Loops.ck

Here's a stupid example:

96 => int bpm;

0::ms => dur none;
240000::ms / (1 * bpm) => dur w;
240000::ms / (2 * bpm) => dur h;
240000::ms / (4 * bpm) => dur q;
240000::ms / (8 * bpm) => dur e;
240000::ms / (16 * bpm) => dur s;

class Sample extends Procedure
{
    SndBuf buf => dac;
    {
        0.0 => buf.gain;
    }

    fun void run()
    {
        0 => buf.pos;
        1.0 => buf.gain;
        1.0 => buf.rate;
    }
}

class Kick extends Sample
{
    {
        "samples/kick_opn_50.wav" => buf.read;
    }
}

class Snare extends Sample
{
    {
        "samples/snr_ord_r42.wav" => buf.read;
    }
}

class Bass extends FloatProcedure
{
    Wurley wurley => dac;
    float minFreq;
    float maxFreq;
    Interpolation interpolate;

    fun void run(float arg)
    {
        minFreq + (interpolate.evaluate(arg) * (maxFreq - minFreq)) =>
wurley.freq;
        wurley.noteOn(0.4);
    }
}

Kick kick;
Snare snare;

Loops.loop(kick, q, w) @=> Procedure kick0;
Loops.loop(kick, e, h) @=> Procedure kick1;
Loops.loop(kick, s, h) @=> Procedure kick2;
Loops.append(kick0, Loops.append(kick1, kick2)) @=> Procedure kickVerse;
Loops.loop(kickVerse, 4) @=> Procedure kickSong;

Loops.loop(snare, q, w) @=> Procedure snare0;
Loops.loop(snare0, 2) @=> Procedure snareVerse;
Loops.loop(snareVerse, e, none, 4) @=> Procedure snareSong;

Bass bass;
43.65 => bass.minFreq;
65.41 => bass.maxFreq;
CircularOut circularOut;
circularOut @=> bass.interpolate;

Bass bassEnd;
43.65 => bassEnd.minFreq;
87.31 => bassEnd.maxFreq;
QuadraticIn quadIn;
quadIn @=> bassEnd.interpolate;

Loops.loop(bass, e, 3 * q) @=> Procedure bassVerse;
Loops.append(Loops.loop(bassVerse, w, none, 9), Loops.loop(bassEnd, s,
3 * q)) @=> Procedure bassSong;

spork ~ kickSong.run();
spork ~ snareSong.run();
spork ~ bassSong.run();

18 * w => now;


>> I'd like to see a example of what you or Tom (or anyone else for that
>> matter) would imagine a Lambda operator would look like in ChucK or what it
>> would solve.
>
> One can write very expressive and compact code. There is a good chance it
> will help in music, as music often have structures that should be repeated
> with some variations.

Heh, as you may have noticed, the above is not very expressive or
compact.  Anonymous functions or closures or lambda functions or
whatever you want to call them would help in that matter.

   michael


More information about the chuck-users mailing list