ChucK a Day => Scott Hewitt
For one month I will strive to update this page with a ChucK program.

You can find out more about Chuck at http://chuck.cs.princeton.edu/.

More about me at www.scotthewitt.co.uk and about my PhD.

Send comments to @scotthewitt.

More about ChucK Instrument Processing (CIP) here.

Day 1

The first ChucK file done, this is mainly a learning exercise for myself as though I have played with Chuck in the past I want to really learn its insides.

As always an immediately unintended outcome is that I ended up writing a php syntax highlight for Chuck which I will use on this page.

/*Number 1
Chuck a day 2009
by Scott Hewitt
www.ablelemon.co.uk/chuckaday */

//Build DSP
SinOsc s => dac;

440 => s.freq;

//Declare
int i;

//Loop
while (i < 50)
{
    //Random frequency
    Std.rand2f(200, 500) => s.freq;
    //Random duration to pass
    Std.rand2f(10, 500)*1::ms => now;
    //Increment Loop
    i++;
}

ChucK file 1.ck


Day 2

Playing with spork-ing today, most challenging issue was getting the main shred to run until all the sporked shreds had finished. int f does this by keeping count of how many shreds are active and keeping time going while f > 0.

If you remove the // on the print lines <<< you can see f's value change over time.

//Number 2
//Chuck a day 2009
//by Scott Hewitt
//www.ablelemon.co.uk/chuckaday

//Declare
int k;
//int used to track if shreds are running
int f;

//main function
fun void valueshift() 
{
    //Build DSP
    SinOsc s => dac;
    //declare freq
    440 => s.freq;
    int i;
    
    f++;
    //<<< f >>>;
    while (i < 50)
    {
        //Random frequency
        Std.rand2f(200, 1000) => s.freq;
        //Random duration to pass
        Std.rand2f(10, 500)*1::ms => now;
        //Increment Loop
        i++;
    }
    f--;
    //<<< f >>>;
}

//sporks shreds off
while (k < 6)
{
    spork~ valueshift();
    2000::ms => now;
    k++;
}

//loop time until all shreds are dead
while (f > 0 )
{
    500::ms => now;
    //<<< "waiting on" >>>;
    //<<< f >>>;
}

ChucK file 2.ck


Day 3

Playing with if statements today and the idea of separating the sonic generation and the score.

The sonic material is contained within the function build() while the score is the the list of function calls separated by lengths of time.

Could not find away to manipulate dsp control parameters outside of there if statements so will revisit that.

//Number 3
//Chuck a day 2009
//by Scott Hewitt
//www.ablelemon.co.uk/chuckaday

//function holds 'instrument'
function void build(int d, dur e){
    0 => int b;
    0 => int a;
while (b < d){
    Std.rand2(1,4) => a;
    <<< a >>>;
    if (a == 1)
    {
        SinOsc s => dac;
        0.3 => s.gain;
        Std.rand2f(440, 800) => s.freq;
    }else{
     TriOsc f => dac;
     0.3 => f.gain;
     Std.rand2f(440, 800) => f.freq;        
    }
    b++;
    e => now;
}
}

//a score?
build(2, 100::ms);
2000::ms => now;
build(2, 400::ms);
4000::ms => now;
build(2, 10::ms);
1000::ms => now;
build(2, 999::ms);
1000::ms => now;

ChucK file 3.ck


Day 4

Experimenting with events mainly today to control the structure of the piece. Also used Envelope and Pan2 within the code.

The event communication seams a great way to communicate between the parent and children shreds and I imagine waiting for something to happen rather than querying to see if it has is more efficient coding.

//Number 4
//Chuck a day 2009
//by Scott Hewitt
//www.ablelemon.co.uk/chuckaday

//Events for note on/off
Event e; Event f; Event g; Event h;

//int represents how many voices are sounding
0 => int stop;
//signals score progression
Event i;

//synth function int set frequency, responds to event
function void synthee (Event event, int xx){
    SawOsc s => Envelope env => Pan2 p => dac;
    0.3 => s.gain;
    100::ms => env.duration;
    xx => s.freq;
    <<< xx >>>;
    while (true){
     event => now;
        0.8 => env.target;
        Std.rand2f(-1.0, 1.0) => p.pan;
        1 => env.keyOn;
        stop++;
        <<< stop >>>;
        event => now;
        0 => env.target;
        1 => env.keyOff;
        stop--;
    }
}

//signal events
function void control () {
    while (true){
    if (maybe){
        g.signal();
        Std.rand2f(100, 800) * 1::ms => now;
    }
    if (maybe){
        h.signal();
        Std.rand2f(100, 800) * 1::ms => now;
    }
    if (maybe){
        e.signal();
        Std.rand2f(100, 800) * 1::ms => now;
}
if (maybe){
    f.signal();
    Std.rand2f(100, 800) * 1::ms => now;
}
}
1::ms => now;
}

//counts 20 seconds and then moves on score
function void timer ()
{
 20::second => now;
 i.signal();
}

//create multiple voices using sporking
spork ~ synthee(e, 500);
spork ~ synthee(f, 800);
spork ~ synthee(g, 1000);
spork ~ synthee(h, 600);

//Score ??
//counts 20 seconds
spork ~ timer();

//changes synthee values
spork ~ control();

//awaits signal to start end
i => now;
<<< "to end" >>> ;

//waits for all notes to be off and ends
while (stop != 0){
1::ms => now;
}
//allows final envelope to end
101::ms => now;

ChucK file 4.ck


Day 5

Experimenting with a high pass filter and then setting the values by using global variables acorss the parent / child relationship.

I can see this dynamic parameter change being useful in FM synthesis and for other stuff.

If your running this code please send me comments or follow me on twitter @scotthewitt.

//Number 5
//Chuck a day 2009
//by Scott Hewitt
//www.ablelemon.co.uk/chuckaday

//dsp chain
SinOsc n => HPF biq => dac;

//randoms and then sweeps freq value
function void freqsweep ()
{
    while (true){
        0 => int dd;
        Std.rand2f(0, 1) => biq.freq;
        while (dd < 10 )
        {
            1000::ms => now;
            biq.freq() - 0.1 => biq.freq;
            dd++;
        }
         Std.rand2f(10, 100) * 1::ms => now;
    }
}

//randoms and then sweeps q value
function void qsweep ()
{
    while (true){
         0 => int cc;
         Std.rand2f(0, 1) + 0.1 => biq.Q;
         while (cc < 10 )
         {
             1000::ms => now;
             biq.Q() - 0.01 => biq.Q;
             cc++;
         }
         Std.rand2f(10, 100) * 1::ms => now;         
     }
 }

//changes frequency and sweeps
spork ~ freqsweep();
//changes q and sweeps
spork ~ qsweep();

//run for 60 seconds
60::second => now;

ChucK file 5.ck


Day 6

Looking at using some of the built in instrument synthesis and arrays within this code.

Also used the Echo Ugen to fill out the sitar sound.

Used the zero values in the arrays to introduce shape to the lines, as they cause a break to occur, though had to add additional if statements looking for them, otherwise they just cause errors.

Any ideas for day 7? @scotthewitt

//Number 6
//Chuck a day 2009
//by Scott Hewitt
//www.ablelemon.co.uk/chuckaday

//Today we play with arrays
[440,400,300,0,600,590,550,520,420] @=> int tune[];
[200,220,210,180,300,240,0,310,200] @=> int tuneb[];
[210,350,400,260,200,320,310] @=> int tunec[];

Event enew;
Event eenew;
Event eeenew;

//DSP (maybe there is a better way of dong this)
Sitar sit => Echo e => dac;
Sitar sitb => Echo ee => dac;
Sitar sitc => Echo eee => dac;

1000::ms => e.max => ee.max => eee.max;
0.1 => e.mix => ee.mix => eee.mix;

//play array
function void mel (){
for (0 => int i; i < tune.cap(); i++){
    if(tune[i] != 0){
        tune[i] => sit.freq;
        Std.rand2f(0, 1) => sit.pluck;
        0.9 => sit.noteOn;
        200::ms => now;
        0.0 => sit.noteOff;
        200::ms => now;
        enew.signal();
        }else{
            400::ms => now;
        }
    }
}

function void accop () {
for (0 => int i; i < tuneb.cap(); i++){
    if(tuneb[i] != 0){
        tuneb[i] => sitb.freq;
        Std.rand2f(0, 1) => sitb.pluck;
        0.9 => sitb.noteOn;
        200::ms => now;
        0.0 => sitb.noteOff;
        200::ms => now;
        eenew.signal();
        }else{
            400::ms => now;
        }
    }
}

function void melb (){
    int kk;
for (0 => int i; i < tunec.cap(); i++){
    Std.rand2(1, (tunec.cap() -1)) => kk;
    if(tune[kk] != 0){
        tunec[kk] => sitc.freq;
        Std.rand2f(0, 1) => sitc.pluck;
        0.9 => sitc.noteOn;
        200::ms => now;
        0.0 => sitc.noteOff;
        200::ms => now;
        eeenew.signal();
        }else{
            400::ms => now;
        }
    }
}

//create echo values
function void echoer (){
    while (true){
         enew => now;
         Std.rand2(100, 900) * 1::ms => e.delay;
     } 
}

function void echoerb (){
    while (true){
         eenew => now;
         Std.rand2(100, 1000) * 1::ms => ee.delay;
     }
}
 
 function void echoerc (){
     while (true){
         eeenew => now;
         Std.rand2(100, 700) * 1::ms => eee.delay;
     }
}

//spork shreds
spork~ echoer();
spork~ echoerb();
spork~ echoerc();
spork~ mel();
spork~ melb();
spork~ accop(); 

//keep parent alive so children complete
4::second => now;  

ChucK file 6.ck


Day 7

This ChucK program is a multi delay effect so it requires audio input.

Has more complicated Ugen network with some Ugens feeding back into each other.

I am finding that 'spork~ing' things is the easiest way to modulate multiple parameters.

As always and ideas are welcome @scotthewitt.

//Number 7
//Chuck a day 2009
//by Scott Hewitt
//www.ablelemon.co.uk/chuckaday

//DSP
adc => Delay del => dac;
del => Delay delb => dac;
delb => del;

//Control
Envelope env => blackhole;
Envelope envb => blackhole;
SinOsc s => blackhole;

//Preset values
1000 => s.freq;
0.5 => delb.gain;
5000::ms => del.max;
1000::ms => del.delay;
5000::ms => delb.max;
1000::ms => delb.delay;

//amplitude modulation 
function void feedbackamp (){
    while (true){
        s.last() => delb.gain;
        //<<< s.last() >>>;
        <<< delb.gain() >>>;
        21::ms => now;
    }
}

//change delay value delb
function void delaa (){
    while (true){
        env.value() * 1::ms => delb.delay;
        100::ms => now;
    }   
}

//change delay value del
function void delbb (){
    while (true){
        envb.value() * 0.7::ms => del.delay;
        100::ms => now;
    }   
}

//envelope control
function void envbcontrol() {
    while (true){
         Std.rand2(10, 4500) => envb.value; 
         Std.rand2(10, 4500) => envb.target;
         Std.rand2(10, 4500) => envb.time;
         envb.keyOn;   
         envb.time() * 1::ms => now;  
    }
}

spork ~ feedbackamp();
spork ~ delaa();
spork ~ delbb();
spork ~ envbcontrol();

//main loop
while (true) {
 1000::ms => now;
 Std.rand2(10, 1500) => env.value; 
 Std.rand2(10, 1500) => env.target;
 Std.rand2(10, 4500) => env.time;
 
 env.keyOn;
 env.time() * 1::ms => now;
}

ChucK file 7.ck


Day 8

Kassen suggested that I try to make some sort of melody maker that did not heavily rely on randomness and without a preset scale.

This code sort of does it. Pitches are created based on random choice between movments allowed. The available movments are hardcoded as a percentage of the length of score.

Sort of works - one thing I am sure of is that ChucK seames to handle this kind of thing quite well.

As always any comments to @scotthewitt.

//Number 8
//Chuck a day 2009
//by Scott Hewitt
//www.ablelemon.co.uk/chuckaday

int scorelength;
Std.rand2(10, 30) => scorelength;
int score[scorelength];
float beat[scorelength];
int ups;
int downs;
int change;
int extra;
int doublebar;
float f;

scorelength / 4 $ int => doublebar;

//layout picths steps
<<< "scorelength", scorelength >>>;
scorelength * 0.4 => f;
f $ int => ups;
<<< "ups", ups >>>;
scorelength * 0.4 => f;
f $ int => downs;
<<< "downs", downs >>>;
scorelength * 0.2 => f;
f $ int => change;
<<< "change", change >>>;

scorelength - ups - downs - change => extra;
change + extra => change;

<<< "change + extra", change >>>;

int i;
int control;
0 => int shift;

//functions handle pitch steps
function void upper(int move){
    score[i-1] + move + shift => score[i];
    ups--;
}

function void downer(int move){
    score[i-1] - move + shift => score[i];
    downs--;
}

function void changer(int move){
    score[i-1] + move + shift => score[i];
    change--;
}

//tempo score
function void rythmscore(){
    <<< "rythm" >>>;
    int kk;
    for (1 => int ii; ii < scorelength; ii++)
    {
        1 => beat[ii];
        kk++;
        if (kk == 3){
            if (maybe){
                0.7 => beat[ii];
            }   else 1.3 => beat[ii];
        }
        if (kk > doublebar){
            0 => kk;
            if (maybe){
                2.54 => beat[ii];
            }   else 4.56 => beat[ii]; 
    }   
}
}

//creates score using pitch step values
function void makescore() {
    <<< "score" >>>;
    1 => score[0];
    for (1 => i; i < scorelength; i++)
    {
        if (score[i-1] == 7)
        {
            8 => shift;
           // 4 => beat[i-1];
            //1 => beat[i];
        }
        if (shift == 8){
            if (score[i-1] == 11){
                0 => shift;
              //  4 => beat[i-1];
               // 1 => beat[i];                
            }   
        }       
        0 => control;
        <<< "shift", shift >>>;
        if (ups > 0)
        {
            control + 1 => control;
        }
        if (downs > 0)
        {
            control + 2 => control;
        }
        if (change > 0){
            control + 4 => control;
        }
        <<< "control" , control >>>;
        if (control == 0){
            Std.rand2(0,2) => int choice;
            <<< "choice", choice >>>;
            if (choice == 0){
                upper(4);
            }
            if (choice == 1){
                downer(4);
            }
            if (choice == 2){
                changer(-8);
            }                        
        }
        if (control == 1){
            upper(2);
        }
        if (control == 2){
            downer(2);
        }
        if (control == 3){
            if (maybe){
                upper(3);
            }else downer(3);
        }
        if (control == 4){
            changer(5);
        }
        if (control == 5){
            if (maybe){
                upper(5);
            }else changer(6);
        }
        if (control == 6){
            if (maybe){
                downer(3);
            }else changer(3);
        }
        if (control == 7){
            Std.rand2(0,2) => int choice;
            <<< "choice", choice >>>;
            if (choice == 0){
                upper(4);
            }
            if (choice == 1){
                downer(2);
            }
            if (choice == 2){
                changer(5);
            }                        
        }
    }
}

//creats pitch score
makescore();
rythmscore();

SinOsc s => Envelope env => dac;
1 => env.value;
0.1 => s.gain;

//plays score
while (true){
    
int j;
for (1 => j; j < scorelength; j++)
{
   <<< "score: ", score[j] >>>;
   if (Std.mtof(score[j] + 69.0) > 100){
       if (Std.mtof(score[j] + 69.0) < 2000){
        Std.mtof(score[j] + 69.0) => s.freq;
    }
}
   <<< "freq: ",s.freq() >>>;
   130::ms => env.duration;
   1.0 => env.target;
   1 => env.keyOn;
   100::ms => now;
   beat[j] * 500::ms => now;
   130::ms => env.duration;
   0.0 => env.target;
   1 => env.keyOn;
   400::ms => now;
   <<< "beat: ", beat[j] >>>;
}
makescore();
rythmscore();
<<< "next score" >>>;
150::ms => env.duration;
0.0 => env.target;
1 => env.keyOn;
1000::ms => now;
0 => env.keyOff;
1 => env.value;
}

ChucK file 8.ck


Day 9

One line ChucK 80 characters max like these.

As always any comments to @scotthewitt.

//Number 9
//Chuck a day 2009
//by Scott Hewitt
//www.ablelemon.co.uk/chuckaday

Impulse x => Pan2 b => dac;while(10::ms=>now) x.next(0.9/(Std.randf()))=>b.pan;

ChucK file 9.ck


Day 10

Looking at FM synthesis by hand here. With multiple operators modulating parameters.

Killing the sporks off by using a global int as the control for the while loops works well.

As always any comments to @scotthewitt.

//Number 10
//Chuck a day 2009
//by Scott Hewitt
//www.ablelemon.co.uk/chuckaday

SinOsc s => dac;
SinOsc d => blackhole;
SinOsc f => blackhole;
TriOsc tri => blackhole;

1000 => f.freq;
90 => tri.freq;

200 => d.freq;

11 => float m;
400 => float depth;
8.01 => float ma;
10.01 => float deptha;

1 => int mbcontrol;
1 => int scontrol;

function void modderb (){
    while(mbcontrol){
        ma + (deptha * f.last()) => d.freq;
        //<<< s.freq() >>>;
        1::samp => now;
    }
}

function void modder (){
    while(true){
        m + (depth * d.last()) => s.freq;
        //<<< s.freq() >>>;
        1::samp => now;
    }
}

function void sweep () {
    while (scontrol){
        depth + (tri.last() * 3.0) => depth;
        //<<< tri.last() >>>;
    1::samp => now;
}
}

3000::ms => dur dd;

spork ~ modder();
dd => now;

spork ~ modderb();
dd => now;

spork ~ sweep();
dd => now;
//end sporks
0 => mbcontrol;
dd => now;
//end sporks
0 => scontrol;
dd => now;

ChucK file 10.ck


Day 11

Playing with the synthesized shakers within ChucK today.

Would be cool to make some some of drum machine using ChucK, however tomorrow I think I might do some poly rhythms.

As always any comments to @scotthewitt.

//Number 11
//Chuck a day 2009
//by Scott Hewitt
//www.ablelemon.co.uk/chuckaday

//main called function
function void drum (dur beat, int max, float dec){
    Shakers s => dac;
    Std.rand2(0, 128) => s.objects;
    dec => s.decay;
    <<< s.objects() >>>;
for (0 => int i; i < max; i++){
    1 => s.noteOn;
    beat => now;
    0 => s.noteOff;
    <<< me.id() >>>;
}     
}

0.5 => float decc;

500::ms => dur gap;
5 => int hits;
spork ~ drum(gap, hits, decc);
gap * hits => now;

400::ms => gap;
5 => hits;
spork ~ drum(gap, hits, decc);
spork ~ drum(500::ms, 24, decc);
gap * hits => now;

300::ms => gap;
5 => hits;
spork ~ drum(gap, hits, decc);
gap * hits => now;

200::ms => gap;
10 => hits;
spork ~ drum(gap, hits, decc);
gap * hits => now;

100::ms => gap;
10 => hits;
spork ~ drum(gap, hits, decc);

1000::ms => now;
0.6 => decc;
 
1764::ms => gap;
10 => hits;
spork ~ drum(gap, hits, decc);
spork ~ drum(0.5 * gap, hits, decc);
spork ~ drum(0.7 * gap, hits, 0.4);

500::ms => gap;
10 => hits;
spork ~ drum(gap, hits, decc);
gap * hits => now;

0.7 => decc;

400::ms => gap;
spork ~ drum(gap, hits, decc);
gap * hits => now;

300::ms => gap;
spork ~ drum(gap, hits, decc);
gap * hits => now;

0.8 => decc;

200::ms => gap;
spork ~ drum(gap, hits, decc);
gap * hits => now;

5000::ms => now;

ChucK file 11.ck


Day 12

This some of rhythmic play it to easy to do in ChucK not to do it.

Will revisit this as a more extended work.

As always any comments to @scotthewitt.

//Number 12
//Chuck a day 2009
//by Scott Hewitt
//www.ablelemon.co.uk/chuckaday

//main called function
function void drum (dur beat, int max, float dec){
    Shakers s => dac;
    11 => s.objects;
    dec => s.decay;
    <<< s.objects() >>>;
    for (0 => int i; i < max; i++){
        1 => s.noteOn;
        beat => now;
        0 => s.noteOff;
        <<< now, me.id() >>>;
    }     
}

0.5 => float decc;

1100::ms => dur gap;
11 => int hits;
spork ~ drum(gap, hits, decc);
1000::ms => gap;
12 => hits;
spork ~ drum(gap, hits, decc);

gap * hits => now;

ChucK file 12.ck


Day 13

Out of phase sine waves arranged into a small composition.

As always any comments to @scotthewitt.

//Number 13
//Chuck a day 2009
//by Scott Hewitt
//www.ablelemon.co.uk/chuckaday

0 => int control;

function void audio (int hz, dur length, dur hold, dur rel){
    control++;
    <<< control >>>;
    SinOsc s => Envelope e => dac;
    0.0 => e.value;
    hz => s.freq;
    length => e.duration;
    1 => e.target;
    1 => e.keyOn;
    length => now;
    hold => now;
    length => e.duration;
    0 => e.keyOff;
    0 => e.target;
    rel => now;
    control--;
}   

spork ~ audio(440, 2500::ms, 2500::ms, 2500::ms);
2500::ms => now;
spork ~ audio(441, 2500::ms, 2500::ms, 2500::ms);
2500::ms => now;
spork ~ audio(442, 2500::ms, 2500::ms, 2500::ms);
2500::ms => now;
spork ~ audio(443, 2500::ms, 2500::ms, 2500::ms);

2500::ms => now;

3000::ms => now;
spork ~ audio(442, 500::ms, 500::ms, 500::ms);
spork ~ audio(441, 500::ms, 500::ms, 500::ms);
spork ~ audio(440, 500::ms, 500::ms, 500::ms);

//2000::ms => now;
spork ~ audio(440, 500::ms, 500::ms, 500::ms);
10::ms => now;
spork ~ audio(440, 500::ms, 500::ms, 500::ms);
10::ms => now;
spork ~ audio(440, 500::ms, 500::ms, 500::ms);

//part b
spork ~ audio(440, 2500::ms, 2800::ms, 4000::ms);
2000::ms => now;
spork ~ audio(441, 2100::ms, 2600::ms, 2500::ms);
2900::ms => now;
spork ~ audio(442, 2000::ms, 2500::ms, 2200::ms);
2200::ms => now;
spork ~ audio(443, 2300::ms, 2900::ms, 2800::ms);

spork ~ audio(443, 500::ms, 100::ms, 500::ms);
10::ms => now;
spork ~ audio(444, 500::ms, 100::ms, 500::ms);
10::ms => now;
spork ~ audio(445, 500::ms, 100::ms, 500::ms);

do{
1::second => now;
<<< control >>>;
} while (control > 0);

ChucK file 13.ck


Day 14

Using the mouse button here to control the number of drums sounding.

mouse.ck in the examples was invaluable here to handle the mouse interaction

As always any comments to @scotthewitt. #hackpact

//Number 14
//Chuck a day 2009
//by Scott Hewitt
//www.ablelemon.co.uk/chuckaday

//Human you => you.clickmouse()

// make HidIn and HidMsg
Hid hi;
HidMsg msg;

// which mouse
0 => int device;
// get from command line
if( me.args() ) me.arg(0) => Std.atoi => device;

// open mouse 0, exit on fail
if( !hi.openMouse( device ) ) me.exit();
<<< "mouse '" + hi.name() + "' ready", "" >>>;

function void buttonstate (){
// infinite event loop
while( true )
{
    // wait on HidIn as event
    hi => now;
    
    // messages received
    while( hi.recv( msg ) )
    {         
        if( msg.isButtonDown() )
        {
            <<< "mouse button", msg.which, "down" >>>;  
            //spork new shred
            spork ~ sound();
        }
    }
}
}

//generate audio
function void sound (){
      Shakers s => dac;
      Std.rand2(0, 128) => s.objects;
      Std.rand2(1000, 3000) * 1::ms => dur gap;
      <<< "shaker object:", s.objects(), "gap:", gap >>>;
      while (true){
      1 => s.noteOn;
      100::ms => now;
      0 => s.noteOff;
      gap => now;
  }
}

//look for mouse button down
spork ~ buttonstate();

1::minute => now;   

ChucK file 14.ck


Day 15

Looking at dynamically changing the dsp in ChucK this is going to be an ongoing investigation for a few days.

As always and ideas are welcome @scotthewitt. #hackpact

//Number 15
//Chuck a day 2009
//by Scott Hewitt
//www.ablelemon.co.uk/chuckaday

float sinlast;
float sinfre;
440 => sinfre;

//create dsp
function void sour (UGen u){
 SinOsc s => u;
 if (u == dac){
     <<< "ok" >>>;
     while (true){
         sinfre => s.freq;
         100::ms => now;   
     }
 }
 if (u == blackhole){
     <<< "blackhole" >>>;
     while (true){
         44 => s.freq;
         s.last() => sinlast;
         100::ms => now;   
     }
 } 
}

//modulate
function void mod(){
    while (true){
    (sinlast * 20) + sinfre => sinfre;
    100::ms => now;
}
}

//spork shreds
spork ~ sour(dac);
spork ~ sour(blackhole);
spork ~ mod();

1000::ms => now;

ChucK file 15.ck


Day 16

Think this approach will form a major part of the my yet to be announced, or made CIP software.

Buses idea from here.

As always and ideas are welcome @scotthewitt. #hackpact

//Number 16
//Chuck a day 2009
//by Scott Hewitt
//www.ablelemon.co.uk/chuckaday

//increase the size of the array to get more channels
public class bus
{
    static Gain @ chan[8];
}
new Gain[8] @=> bus.chan;


function void test(UGen u){
    SinOsc s => u;
    440 => s.freq;
    1000::ms => now;
}

spork ~ test(bus.chan[1]);

bus.chan[1] => dac;
2000::ms => now;

ChucK file 16.ck


Day 17

This is the sketch layout of the CIP program I am planning on developing for the next couple of weeks.

The modular design should allow me to post parts as I build them.

As always and ideas are welcome @scotthewitt. #hackpact

//Number 17
//Chuck a day 2009
//by Scott Hewitt
//www.ablelemon.co.uk/chuckaday

//This does nothing its the first plan for CIP

public class bus
{
    static Gain @ chan[8];
}
new Gain[8] @=> bus.chan;

adc => bus.chan[1];

bus.chan[1] => processing => bus.chan[2];

bus.chan[2] => processing => bus.chan[3];

bus.chan[4] => processing => bus.chan[8];

bus.chan[1] => processing => bus.chan[5];

bus.chan[5] => processing => bus.chan[8];

bus.chan[8] => dac;

ChucK file 17.ck


Day 18

This evening I performed at an Inclusive Improv improv session so here are three of the chuck things I built for the evening.

They are included as one file though they should be broken into three sections. They work best when used multiple times concurrently with altered values.

As always and ideas are welcome @scotthewitt. #hackpact

//Number 18
//Chuck a day 2009
//by Scott Hewitt
//www.ablelemon.co.uk/chuckaday

//Number 1
adc => Delay a => dac;

Delay b => dac;

a => b;

1::minute => a.max => b.max;

10::second => a.delay;

function void sweep(){
    SinOsc s => blackhole;
    100 => s.freq;
    while(true){
        s.last() => a.gain;
        1::ms => now;
    }
}


spork ~ sweep();

while(true){
    1000::ms => now;
}

//Number 2

function void noiser(){
    Noise nn => dac;
    while(true){
        0.1 ==> nn.gain;
        Std.rand2(1,50) * 1::ms => now;
        0.0 => nn.gain;
        Std.rand2(100,8000) * 1::ms => now;   
    }    
}

spork ~ noiser();

while(true){
    3000::ms => now;
}

//Number 3

function void siner(int a, int b){
    SinOsc s => Envelope e => dac;
    b => s.freq;
    a * 1::ms => dur b;
    0.5 => e.target;
    b => e.duration;
    1 => e.keyOn;
    b => now;
    0.0 => e.target;
    b => e.duration;
    1 => e.keyOn;
    b => now;
}

function void other(){
    while(true){
        spork ~ siner(Std.rand2(100,400),Std.rand2(400, 800)); 
        6000::ms => now;
    }  
}

spork ~ other();

while(true){
    spork ~ siner(Std.rand2(10,100),Std.rand2(200,400));
    
    4000::ms => now;
}

ChucK file 18.ck


Day 19

Thanks to Kassen on this thread.

This is a continuation of my investigations into dynamically altering the dsp processing.

As always and ideas are welcome @scotthewitt. #hackpact

//Number 19
//Chuck a day 2009
//by Scott Hewitt
//www.ablelemon.co.uk/chuckaday

//thanks to Kassen for help with this

fun void setFreq(UGen u) 
{ 
    Std.rand2f(200,600) => float freq;
    //Cast resolves issues issue of no .freq in UGen
    freq => (u $ SinOsc).freq; 
}

TriOsc s => dac;
SinOsc k => dac;
SawOsc f => dac;

setFreq(s);
setFreq(k);
setFreq(f);

1000::ms => now;

ChucK file 19.ck


Day 20

Playing with impulse here and also some dsp routing as well.

This feels much more like compositional approach rather and gives an interesting idea of a score.

As always and ideas are welcome @scotthewitt. #hackpact

//Number 20
//Chuck a day 2009
//by Scott Hewitt
//www.ablelemon.co.uk/chuckaday

Impulse imp => Delay dela => dac;
imp => Delay delb => dac;
imp => Delay delc => dac;

3000::ms => dela.max => delb.max => delc.max;

function void fire(dur a){
    while(true){
        1.0 => imp.next;
        a => now;
    }
}

spork ~ fire(1000::ms);
3000::ms => now;

500::ms => dela.delay;
700::ms => delb.delay;

3000::ms => now;

spork ~ fire(900::ms);
900::ms => delc.delay;
9000::ms => now;

delb => Gain g => delc;
<<<"stage">>>;
0.5 => g.gain;

9000::ms => now;

dela =< dac;
dela => delb;
spork ~ fire(770::ms);
9000::ms => now;

spork ~ fire(200::ms);
9000::ms => now;
spork ~ fire(100::ms);
2000::ms => now;

ChucK file 20.ck


Day 21

First experiments with midi in ChucK going to look at poly-phonic methods soon.

As always and ideas are welcome @scotthewitt. #hackpact

//Number 21
//Chuck a day 2009
//by Scott Hewitt
//www.ablelemon.co.uk/chuckaday

SinOsc s => dac;

//create midi object
MidiIn min;
MidiMsg msg;

//check if midi present
if( !min.open(0) ) { me.exit(); }

<<< "midi connected" >>>;

function void midiinput(){
    while(true){
        min => now;
        while( min.recv(msg) ){
            <<< msg.data2 >>>; 
            Std.mtof(msg.data2) => s.freq;
        }
    }
}

spork ~ midiinput();

while (true){
    5000::ms => now;
}

ChucK file 21.ck


Day 22

Add multi voice polyphony by sporking shreds for each pitch being played and then using an extend Event (ZeroEvent) to stop them when required.

Happy to see how doable this is and think the event signaling is something to be used more often.

As always and ideas are welcome @scotthewitt. #hackpact

//Number 22
//Chuck a day 2009
//by Scott Hewitt
//www.ablelemon.co.uk/chuckaday

//extend event for noteoffs
class Zeroevent extends Event{
    int pitch;
}

Zeroevent noteoff;

//create midi object
MidiIn min;
MidiMsg msg;

//check if midi present
if( !min.open(0) ) { me.exit(); }
<<< "midi connected" >>>;

//handle midi input
function void midiinput(){
    while(true){
        min => now;
        while( min.recv(msg) ){
            if(msg.data3 == 0){
                //send pitch noteoff to child shreds
                msg.data2 => noteoff.pitch;
                noteoff.broadcast();  
            }else{
                //new picth spork shred (voice)
                spork ~ synth(msg.data2, msg.data3);
        }
        }
    }
}

//synth
function void synth(int a, int b){
    //synth dsp
    SinOsc s => Envelope env => dac;
    50::ms => env.duration;
    1 => env.keyOn;
    Std.mtof(a) => s.freq;
    while(true){
            //await noteoff event
            noteoff => now;
            //match noteoff
            if(noteoff.pitch == a){
                1 => env.keyOff;
                51::ms => now;
                me.exit();
            }
        }
}
    

spork ~ midiinput();

while (true){
    5000::ms => now;
}

ChucK file 22.ck


Day 23

Bit of a non event this code just added a filter and a modulator for its values, sonically ineffective but the code works.

As always and ideas are welcome @scotthewitt. #hackpact

//Number 23
//Chuck a day 2009
//by Scott Hewitt
//www.ablelemon.co.uk/chuckaday

//extend event for noteoffs
class Zeroevent extends Event{
    int pitch;
}

Zeroevent noteoff;

//create midi object
MidiIn min;
MidiMsg msg;

//check if midi present
if( !min.open(0) ) { me.exit(); }
<<< "midi connected" >>>;

//handle midi input
function void midiinput(){
    while(true){
        min => now;
        while( min.recv(msg) ){
            if(msg.data3 == 0){
                //send pitch noteoff to child shreds
                msg.data2 => noteoff.pitch;
                noteoff.broadcast();  
            }else{
                //new picth spork shred (voice)
                spork ~ synth(msg.data2, msg.data3);
        }
        }
    }
}

//synth
function void synth(int a, int b){
    float kxf;
    //synth dsp
    TriOsc s => ResonZ rz => Envelope env => dac;
    SinOsc sx => blackhole;
    10 => sx.freq;
    (Std.mtof(a) * 2)=> kxf;    
    //play
    50::ms => env.duration;
    1 => env.keyOn;
    Std.mtof(a) => s.freq;
    while(noteoff.pitch != a){
        sx.last() * 80 + kxf => rz.freq;
        1::ms => now;
        <<< rz.freq() >>>;
        }
                1 => env.keyOff;
                51::ms => now;
                me.exit();
}
    

spork ~ midiinput();

while (true){
    5000::ms => now;
}

ChucK file 23.ck


Day 24

Starting to develop the CIP application, here is the main GUI being laid out. This is my first use of the MAUI elements which look to be easy to exploit.

As always and ideas are welcome @scotthewitt. #hackpact

//Number 24
//Chuck a day 2009
//by Scott Hewitt
//www.ablelemon.co.uk/chuckaday

public class bus
{
    static Gain @ chan[8];
}
new Gain[8] @=> bus.chan;

//labels for sliders
["0","1","2","3","4","5","6","7"] @=> string label[];

MAUI_View bus_view;
bus_view.size( 250, 500 );
    
MAUI_Gauge gauge[8];
MAUI_Slider slider[8];
    
//setup gauge
function void lev_mon (int a){
    while (true){
        bus.chan[a].last() * 100.0 => gauge[a].value;
        20::ms => now;
    }
}
    
    //await slider movment
function void slid_event (int b){
    while (true){
        slider[b] => now;
        slider[b].value() => bus.chan[b].gain;
    }
}
    
    //setup interface for each bus
for(0 => int i; i < 8; i++ ){
    bus_view.addElement (gauge[i]);
    gauge[i].position(0,(i * 60));
    bus_view.addElement (slider[i]);
    label[i] => slider[i].name;
    slider[i].position(0,(i * 60));
    spork ~ lev_mon(i);
    spork ~ slid_event(i);
    0 => bus.chan[i].gain;
}

//draw display    
bus_view.display();

//demo connects
adc => bus.chan[0];
adc => bus.chan[4];

bus.chan[0] => dac;
bus.chan[4] => dac;

while(true) {
    5::second => now;
}

ChucK file 24.ck


Day 25

This is designed to become part of my CIP application but for now it is a multi tap delay line with feedback and features a complete user front end.

I have developed it on OSX so there maybe some graphic issues on other platforms also you need the miniAudicle for this one.

As always and ideas are welcome @scotthewitt. #hackpact

//Number 25
//Chuck a day 2009
//by Scott Hewitt
//www.ablelemon.co.uk/chuckaday


//DSP
DelayL del[3];
Gain feedback[3];
adc => Gain gmm => Gain gm => del[0] => dac;
gm => del[1] => dac;
gm => del[2] => dac;

del[0] => feedback[0] => gm;
del[1] => feedback[1] => gm;
del[2] => feedback[2] => gm;

20::second => del[0].max => del[1].max => del[2].max;
0.0 => gmm.gain;
1.0 => gm.gain;
0.0 => feedback[0].gain => feedback[1].gain => feedback[2].gain;
0.0 => del[0].gain => del[1].gain => del[2].gain;

Event exitevent;

//GUI elements and layout
MAUI_View del_view;
del_view.size( 800, 250 );

MAUI_Slider slidermaster;
MAUI_Gauge gaugemaster;
MAUI_Button exitbutton;
exitbutton.pushType();
exitbutton.name("Exit");

del_view.addElement (slidermaster);
"Input Volume" => slidermaster.name;
slidermaster.position(0,0);
del_view.addElement (gaugemaster);
gaugemaster.position(250,0);
del_view.addElement (exitbutton);
exitbutton.position(500,0);


MAUI_Slider slider[9];

for(0 => int i; i < 3; i++){
    del_view.addElement (slider[i]);
    "Tap "+ Std.itoa(i) + " Gain" => slider[i].name;
    slider[i].position(0,((i * 60) + 55));
}

for(3 => int i; i < 6; i++){
    del_view.addElement (slider[i]);
    slider[i].precision(8);
    slider[i].range(0, 20000);
    "Tap "+ Std.itoa((i - 3)) + " Delay" => slider[i].name;
    slider[i].position(250,(((i - 3) * 60) + 55));
}

for(6 => int i; i < 9; i++){
    del_view.addElement (slider[i]);
    "Tap "+ Std.itoa((i - 6)) + " Feedback" => slider[i].name;
    slider[i].position(500,(((i - 6) * 60)+ 55));
}

MAUI_Gauge gauge[3];

for(0 => int i; i < 3; i++){
    del_view.addElement (gauge[i]);
    gauge[i].size(100.0, 50.0);
    gauge[i].position(710,((i * 60)+ 65));
}

del_view.display();

//GUI functions

//a much better way to do the monitor outputs
function void lev_mon (){
    while (true){
        del[0].last() * 100.0 => gauge[0].value;
        del[1].last() * 100.0 => gauge[1].value;
        del[2].last() * 100.0 => gauge[2].value;
        gmm.last() * 100.0 => gaugemaster.value;
        20::ms => now;
    }
}

//exit button event
function void exitbutton_event (){
    while (true){
        exitbutton => now;
        exitevent.broadcast();
    }
}

//input slider
function void slidinput_event (){
    while (true){
        slidermaster => now;
        slidermaster.value() => gmm.gain;
    }
}

//gain slider
function void slid_event (int b){
    while (true){
        slider[b] => now;
        slider[b].value() => del[b].gain;
    }
}

//delay slider
function void sliddel_event (int b){
    while (true){
        slider[b] => now;
        slider[b].value()  * 1::ms => del[(b - 3)].delay;
    }
}

//feedback slider
function void slidfb_event (int b){
    while (true){
        slider[b] => now;
        slider[b].value() => feedback[(b - 6)].gain;
    }
}


//Program
//level monitor
spork ~ lev_mon();

spork ~ slidinput_event();

spork ~ exitbutton_event();

//gain slider
spork ~ slid_event(0);
spork ~ slid_event(1);
spork ~ slid_event(2);

//del slider
spork ~ sliddel_event(3);
spork ~ sliddel_event(4);
spork ~ sliddel_event(5);

//fb slider
spork ~ slidfb_event(6);
spork ~ slidfb_event(7);
spork ~ slidfb_event(8);

500::ms => now;

exitevent => now;
<<<"test">>>;

me.exit();

//this does not seam to work
del_view.destroy();

ChucK file 25.ck


Day 26

A Chorus application to be integrated into my CIP code.

As always and ideas are welcome @scotthewitt. #hackpact

//Number 26
//Chuck a day 2009
//by Scott Hewitt
//www.ablelemon.co.uk/chuckaday

//DSP
adc => Gain ginput => Chorus c => dac;
0.0 => ginput.gain;
0.0 => c.modFreq;
0.0 => c.modDepth;

Event exitevent;

//GUI elements and layout
MAUI_View cho_view;
cho_view.size( 500, 220 );

MAUI_Slider slidermaster;
MAUI_Slider slidermix;
MAUI_Slider slidermodf;
MAUI_Slider slidermodd;
MAUI_Gauge gaugemaster;
MAUI_Button exitbutton;
exitbutton.pushType();
exitbutton.name("Exit");

cho_view.addElement (slidermaster);
"Input Volume" => slidermaster.name;
slidermaster.position(0,0);

cho_view.addElement (slidermodf);
"Modulation Freq" => slidermodf.name;
slidermodf.precision(3);
slidermodf.range(0., 10.0);
slidermodf.position(0, 60);

cho_view.addElement (slidermodd);
"Modulation Depth" => slidermodd.name;
slidermodd.precision(3);
slidermodd.range(0., 5.0);
slidermodd.position(250, 60);

cho_view.addElement (slidermix);
"Wet/Dry" => slidermix.name;
slidermix.position(0, 120);

cho_view.addElement (gaugemaster);
gaugemaster.position(250,10);

cho_view.addElement (exitbutton);
exitbutton.position(250, 120);

cho_view.display();

//GUI functions

//level monitor
function void lev_mon(){
    while (true){
        ginput.last() * 100.0 => gaugemaster.value;
        20::ms => now;
    }
}

//exit button event
function void exitbutton_event (){
    while (true){
        exitbutton => now;
        exitevent.broadcast();
    }
}

//input slider
function void slidinput_event (){
    while (true){
        slidermaster => now;
        slidermaster.value() => ginput.gain;
    }
}

//wet dry slider
function void slidwetdry_event (){
    while (true){
        slidermix => now;
        slidermix.value() => c.mix;
    }
}

//mod depth slider
function void slidmoddepth_event (){
    while (true){
        slidermodd => now;
        slidermodd.value() => c.modDepth;
    }
}

//mod freq slider
function void slidmodfreq_event (){
    while (true){
        slidermodf => now;
        slidermodf.value() => c.modFreq;
    }
}

//spork all functions
spork ~ lev_mon();
spork ~ exitbutton_event();
spork ~ slidinput_event();
spork ~ slidwetdry_event();
spork ~ slidmoddepth_event();
spork ~ slidmodfreq_event();

exitevent => now;
<<<"Chorus Exit">>>;

me.exit();

//this does not seam to work
cho_view.destroy();

ChucK file 26.ck


Day 27

A Pitch Shift application to be integrated into my CIP code.

As always and ideas are welcome @scotthewitt. #hackpact

//Number 27
//Chuck a day 2009
//by Scott Hewitt
//www.ablelemon.co.uk/chuckaday

//DSP
adc => Gain ginput => PitShift ps => dac;

Event exitevent;

//GUI
MAUI_View pitgui;

MAUI_Slider pitshift;
MAUI_Slider pitmix;
MAUI_Button exitbutton;
MAUI_Gauge gaugemaster;


pitgui.addElement (gaugemaster);
gaugemaster.position(250,10);

pitshift.position(0,0);
pitmix.position(0,60);
exitbutton.position(300,60);
exitbutton.pushType();
exitbutton.name("Exit");

pitshift.name("Pitch Shift");
pitshift.range(0.5, 1.5);

pitmix.name("Pitch Mix");

pitgui.addElement(exitbutton);
pitgui.addElement(pitshift);
pitgui.addElement(pitmix);

pitgui.size(500, 200);

pitgui.display();

//exit button event
function void exitbutton_event (){
    while (true){
        exitbutton => now;
        exitevent.broadcast();
    }
}

function void shift_event(){
    while (true){
        pitshift => now;
        pitshift.value() => ps.shift;
    }
}

function void mix_event(){
    while (true)
    {
        pitmix => now;
        pitmix.value() => ps.mix;
    }
}

function void lev_mon(){
    while (true){
        ginput.last() * 100.0 => gaugemaster.value;
        20::ms => now;
    }
}

//sporks
spork ~ lev_mon();   
spork ~ exitbutton_event();   
spork ~ shift_event();
spork ~ mix_event();

exitevent => now;
<<<"Pitch Shift Exit">>>;

me.exit();

ChucK file 27.ck


Day 28

Sound file playback today and what could easily be expanded into a fully fledge drum machine.

You can choose the example sound files included with ChucK. Not sure if I like having standalone buttons or a more polished interface.

As always and ideas are welcome @scotthewitt. #hackpact

//Number 28
//Chuck a day 2009
//by Scott Hewitt
//www.ablelemon.co.uk/chuckaday

//base tempo
500::ms => dur basetempo;

//Sound file player
function void player(string file, dur tempo){
    SndBuf sf => dac;
    file => sf.read;
    while(true){
        0 => sf.pos;
        1 => sf.rate;
        tempo => now;
    }
} 

//file player gui and playback logic
function void fileplay(string file, float subdivision, string name){
    MAUI_Button button;
    button.toggleType();
    button.name( name );
    button.display();
    basetempo * subdivision => dur elementtempo;
    while(true)
    {
        button => now;
        //this is the key line @=> Shred offspring
        spork ~ player(file, elementtempo) @=> Shred offspring;
        button => now;
        //exit shred identified
        offspring.exit();
    }
}

//spork kit parts
spork ~ fileplay("chuckaday/hihat.wav", 4, "hihat");
spork ~ fileplay("chuckaday/snare-chili.wav", 3, "snare");

while (true){
1::minute => now;
}

ChucK file 28.ck


Day 29

Looking at FFT anyalsis today this is kind of fun.

Changin the fftsize is alot of fun as well.

As always and ideas are welcome @scotthewitt. #hackpact

//Number 29
//Chuck a day 2009
//by Scott Hewitt
//www.ablelemon.co.uk/chuckaday

adc => JCRev jrev => FFT fft =>blackhole;
TriOsc t => JCRev jrevA => FFT ffta => blackhole;

IFFT ifft => dac;

400 => t.freq;
1024 => fft.size => ffta.size => int fftsize;

fftsize / 4 => int frame;

complex store[fftsize];
complex storeA[fftsize];
complex storeC[fftsize];

while(true){
    fft.upchuck();
    fft.spectrum(store);
    ffta.upchuck();
    ffta.spectrum(storeA);
    for(int i; i < fftsize / 2 ; i++){
        store[i] * storeA[i] => storeC[i];
    }
    //<<< store[2], storeA[2], storeC[2] >>>;
    ifft.transform(storeC);
    ifft.upchuck();
    frame::samp => now;
}

ChucK file 29.ck


Day 30

This is my first Chuck Instrument Processing (CIP) example patch. To use this you need to first of add the other files which are part of CIP.

You can download it here.

As always and ideas are welcome @scotthewitt. #hackpact

function void pitchshift(){
CIPps ps;

ps.inouta(0,1);
ps.go();
}

function void delayeffect(){
CIPdel pdel;
pdel.inouta(1,2);
pdel.go();
}

function void chory(){
CIPch pch;
pch.inouta(2,3);
pch.go();
}

spork ~ pitchshift();
spork ~ delayeffect();
spork ~ chory();

while (true){ 1::minute => now;} 

ChucK file 30.ck


Day 31

Today I have converted my fft chuck into a class for use with CIP.

As always and ideas are welcome @scotthewitt. #hackpact

This is the end of my Chuck A Day, 31 days done, lots of Chuck learnt, CIP project will be ongoing here.

Thanks for everyones help.

Scott

public class XSynth
{

UGen in;
UGen out;

int inputbusnum;
int outputbusnum;

function void inouta(int xx, int zz){
    bus.chan[xx] => in;
    xx => inputbusnum;
    out => bus.chan[zz];
    zz => outputbusnum;
}

//GUI elements and layout
MAUI_View xsynth_view;
xsynth_view.name( "xsynth" );
xsynth_view.size( 800, 250 );

//cip interface stuff
MAUI_Slider slidermaster;
MAUI_Gauge gaugemaster;
MAUI_Button exitbutton;
exitbutton.pushType();
exitbutton.name("Exit");

xsynth_view.addElement (slidermaster);
"Input Volume" => slidermaster.name;
slidermaster.position(0,0);
xsynth_view.addElement (gaugemaster);
gaugemaster.position(250,0);
xsynth_view.addElement (exitbutton);
exitbutton.position(500,0);

//app interface stuff
MAUI_Slider fftsizeslider;
"FFT size" => fftsizeslider.name;
fftsizeslider.precision(8);
fftsizeslider.range(4, 1024);
xsynth_view.addElement (fftsizeslider);
fftsizeslider.position(0,100);

xsynth_view.display();

//DSP
in => Gain gm => FFT fft =>blackhole;
TriOsc t => JCRev jrevA => FFT ffta => blackhole;

IFFT ifft => out;

int fftsize;

//exit button
Event exitevent;

400 => t.freq;
80 => fft.size => ffta.size => fftsize;


fftsize / 4 => int frame;


//exit button event
function void exitbutton_event (){
    while (true){
        exitbutton => now;
        exitevent.broadcast();
    }
}

function void slidinput_event (){
    while (true){
        slidermaster => now;
        slidermaster.value() => gm.gain;
    }
}

function void fftsizeslider_event (){
    while (true){
        fftsizeslider => now;
        fftsizeslider.value() $ int => fftsize => fft.size => ffta.size;
    }
}

function void lev_mon(){
    while (true){
        gm.last() * 100 => gaugemaster.value;
        20::ms => now;
    }
}

function void mainfft (){
    while(true){
        complex store[fftsize];
        complex storeA[fftsize];
        complex storeC[fftsize];
        fft.upchuck();
        fft.spectrum(store);
        ffta.upchuck();
        ffta.spectrum(storeA);
        for(int i; i < fftsize / 2 ; i++){
            store[i] * storeA[i] => storeC[i];
        }
        //<<< store[2], storeA[2], storeC[2] >>>;
        ifft.transform(storeC);
        ifft.upchuck();
        frame::samp => now;
    }
}

function void viewtitle(){
    xsynth_view.name( "bus.chan["+Std.itoa(inputbusnum)+"] => XSynth => bus.chan[" + Std.itoa(outputbusnum) +"]" );
}

function void go(){
viewtitle();
spork ~ lev_mon();
spork ~ slidinput_event();
spork ~ exitbutton_event();
spork ~ mainfft();
spork ~ fftsizeslider_event();


exitevent => now;
xsynth_view.name("dead");
<<<"test">>>;

me.exit();

//this does not seam to work
xsynth_view.destroy();
}
}

ChucK file 31.ck


Day 32

An extra ChucK a Day Code which demos one way of making system wide events.

Plan to use this sort of code on Friday at the Leeds Sound and Music Expo.

As always and ideas are welcome @scotthewitt. #hackpact

//Number 32
//Chuck a day 2009
//by Scott Hewitt
//www.ablelemon.co.uk/chuckaday

//Each section should be added to the ChucK VM in turn

//Section 1
//Extend Event Class
public class E extends Event{
    int value;
}

//Section 2
//Create VM wide extended event
public class F{
    static E @ value;
}
new E @=> F.value;

//Section 3
//Send extended events with ints
function void s (){
    while (true){
        Std.rand2(100,300) => F.value.value;
        F.value.broadcast();
        500::ms => now;
        <<<"sent">>>;
    }
}

//spork ~ r();
spork ~ s();

while (true){
    1::day => now;
}

//Section 4
//print recieved event int values
while (true){
    F.value => now;
    <<>>;
    <<<"got">>>;
}

ChucK file 32.ck