// Assignment 7 drumCircleDSP
public class KickSynC{

    0.0 => float mgain;
    Gain bdmast;
    bdmast.gain(mgain);

    fun void trigger(float volume){
        this.bdmast.gain(volume);
        spork ~ s_do_kick();
    }

    fun void s_do_kick(){

        CurveTable c;
        [0., 310, -.98,  1.0,50,-.6, 11.0, 1.] => c.coefs;

        // frequency curve
        ADSR e => blackhole;
        e.set( 0::ms, 621::ms, 0.0, 135::ms );  //a, d, s, r
        e.keyOn(1);

        // simple adsr
        ADSR volE;
        volE.set( 0::ms, 181::ms, 0.0, 65::ms );  //a, d, s, r
        volE.keyOn();

        // routing.
        c => blackhole;
        SinOsc form => volE => LPF boom => PoleZero dc => bdmast;
        dc.blockZero(0.992);
        70 => boom.freq;

        // set

        now => time start;
        // ready
        while (true)
        {
            c.lookup(1/e.value()) $ int => form.freq;
            boom.Q(1.3);
            41::samp => now;

            // advance time
            if (now > (start + 170::ms)){
                e.keyOff();
                volE.keyOff();
                break;
            }
        }

        1::second => now;
    }

}

KickSynC kick1;

kick1.bdmast => dac;
kick1.trigger(1.3);

1::second => now;

public class KickSynC{

    0.0 => float mgain;
    Gain bdmast;
    bdmast.gain(mgain);

    fun void trigger(float volume){
        this.bdmast.gain(volume);
        spork ~ s_do_kick();
    }

    fun void s_do_kick(){

        CurveTable c;
        [0., 310, -.98,  1.0,50,-.6, 11.0, 1.] => c.coefs;

        // frequency curve
        ADSR e => blackhole;
        e.set( 0::ms, 621::ms, 0.0, 135::ms );  //a, d, s, r
        e.keyOn(1);

        // simple adsr
        ADSR volE;
        volE.set( 0::ms, 181::ms, 0.0, 65::ms );  //a, d, s, r
        volE.keyOn();

        // routing.
        c => blackhole;
        SinOsc form => volE => LPF boom => PoleZero dc => bdmast;
        dc.blockZero(0.992);
        70 => boom.freq;

        // set

        now => time start;
        // ready
        while (true)
        {
            c.lookup(1/e.value()) $ int => form.freq;
            boom.Q(1.3);
            41::samp => now;

            // advance time
            if (now > (start + 170::ms)){
                e.keyOff();
                volE.keyOff();
                break;
            }
        }

        1::second => now;
    }

}

//KickSynC kick1;

//kick1.bdmast => dac;
//kick1.trigger(1.3);

//1::second => now;

Update bassdrum_electronic_deepboom.ck

Update bassdrum_electronic_deepboom.ck


public class WaveformMixerMono{

    SinOsc vsin => Gain final;
    SawOsc vsaw => final;
    TriOsc vtri => final;
    PulseOsc vpls => final;
    Noise vnse => final;

    440 => float frequency;

    fun void pwidth(float pw){
        pw => this.vpls.width;
    }

    fun void freq(float frequency){
        frequency => this.frequency;
        vsin.freq(frequency);
        vsaw.freq(frequency);
        vtri.freq(frequency);
        vpls.freq(frequency);
    }

    fun void mixer(float components[], float mgain){
        mixer(components);
        mgain => this.final.gain;
    }

    fun void mixer2(float continual){

        float mix_comp[];
        if (continual >= 7.9996) [0.0, 0.0, 0.0, 0.0, 1.0] @=> mix_comp;
        else if (continual <= 0.0001) [1.0, 0.0, 0.0, 0.0, 0.0] @=> mix_comp;
        else {
            continual => float j;
            Math.floor(j/2.0) $ int => int k;
            k*2 => int k2;
            ((j - k2) / 2.0) => float n;
            <<< k, n >>>;
            mix_arrays(k, n) @=> mix_comp;
        }
        mixer(mix_comp);
    }

    fun void mixer(float components[]){
        // set defautls, just in case -- make it a SinOsc
        if (!(components.cap() == 5)) {
            [1.0, 0.0, 0.0, 0.0, 0.0] @=> components;
        }

        float summer;
        for(0 => int i; i<components.cap(); i++){
            components[i] +=> summer;
        }

        if (summer <= 0.0) {
            <<< "no sound!" >>>;
            0.0 => this.vsin.gain;
            0.0 => this.vsaw.gain;
            0.0 => this.vtri.gain;
            0.0 => this.vpls.gain;
            0.0 => this.vnse.gain;
        }
        else{
            components[0] / summer => this.vsin.gain;
            components[1] / summer => this.vsaw.gain;
            components[2] / summer => this.vtri.gain;
            components[3] / summer => this.vpls.gain;
            components[4] / summer => this.vnse.gain;
        }
    }

    fun float fixmin(float fin){
        if (fin < 0.0001) return 0.0;
        else return fin;
    }

    fun float[] mix_arrays(int idx, float amount){
        <<< idx, idx+1 >>>;
        [0.0, 0.0, 0.0, 0.0, 0.0] @=> float final_mix[];
        (1-amount) => fixmin => final_mix[idx];
        (amount) => fixmin => final_mix[idx+1];
        return final_mix;
    }

}

// Math.round

WaveformMixerMono bloop;
//bloop.final => dac;

// bloop.final.gain(0.1);
// bloop.mixer([0.0, 0.0, 0.0, 0.0, 1.0]);
// bloop.freq(500.0);

// 2::second => now;
// bloop.mixer([0.0, 0.0, 0.0, 0.0, 1.0], 0.0);
// 0.4::second => now;

// bloop.mixer([0.0, 0.0, 0.0, 0.0, 1.0], 0.2);
// bloop.freq(500.0);

// 2::second => now;

for(0.0 => float i; i<=8.0; 0.01+=> i){
    bloop.mixer2(i);
}

public class WaveformMixerMono{

    SinOsc vsin => Gain final;
    SawOsc vsaw => final;
    TriOsc vtri => final;
    PulseOsc vpls => final;
    Noise vnse => final;

    440 => float frequency;

    fun void pwidth(float pw){
        pw => this.vpls.width;
    }

    fun void freq(float frequency){
        frequency => this.frequency;
        vsin.freq(frequency);
        vsaw.freq(frequency);
        vtri.freq(frequency);
        vpls.freq(frequency);
    }

    fun void mixer(float components[], float mgain){
        mixer(components);
        mgain => this.final.gain;
    }

    fun void mixer2(float continual){
        // continual range is 0.0 to 8.0
        // goes from (sin, saw, tri, pulse to noise)

        float mix_comp[];
        if (continual >= 7.9996) [0.0, 0.0, 0.0, 0.0, 1.0] @=> mix_comp;
        else if (continual <= 0.0001) [1.0, 0.0, 0.0, 0.0, 0.0] @=> mix_comp;
        else {
            continual => float j;
            Math.floor(j/2.0) $ int => int k;
            k*2 => int k2;
            ((j - k2) / 2.0) => float n;
            mix_arrays(k, n) @=> mix_comp;
        }
        mixer(mix_comp);
    }

    fun void mixer(float components[]){
        // set defautls, just in case -- make it a SinOsc
        if (!(components.cap() == 5)) {
            [1.0, 0.0, 0.0, 0.0, 0.0] @=> components;
        }

        float summer;
        for(0 => int i; i<components.cap(); i++){
            components[i] +=> summer;
        }

        if (summer <= 0.0) {
            <<< "no sound!" >>>;
            0.0 => this.vsin.gain;
            0.0 => this.vsaw.gain;
            0.0 => this.vtri.gain;
            0.0 => this.vpls.gain;
            0.0 => this.vnse.gain;
        }
        else{
            components[0] / summer => this.vsin.gain;
            components[1] / summer => this.vsaw.gain;
            components[2] / summer => this.vtri.gain;
            components[3] / summer => this.vpls.gain;
            components[4] / summer => this.vnse.gain;
        }
    }

    fun float fixmin(float fin){
        if (fin < 0.0001) return 0.0;
        else return fin;
    }

    fun float[] mix_arrays(int idx, float amount){
        [0.0, 0.0, 0.0, 0.0, 0.0] @=> float final_mix[];
        (1-amount) => fixmin => final_mix[idx];
        (amount) => fixmin => final_mix[idx+1];
        return final_mix;
    }

}

WaveformMixerMono bloop;
bloop.final => dac;

bloop.final.gain(0.65);
bloop.freq(70.0);

for(0.0 => float i; i<=8.0; 0.01+=> i){
    bloop.mixer2(i);
    25::ms => now;

}

Update WaveformMixerMono.ck

Update WaveformMixerMono.ck


public class WaveformMixerMono{

    SinOsc vsin => Gain final;
    SawOsc vsaw => final;
    TriOsc vtri => final;
    PulseOsc vpls => final;
    Noise vnse => final;

    440 => float frequency;

    fun void freq(float frequency){
        frequency => this.frequency;
        vsin.freq(frequency);
        vsaw.freq(frequency);
        vtri.freq(frequency);
        vpls.freq(frequency);
    }

    fun void mixer(float components[]){
        // set defautls, just in case -- make it a SinOsc
        if (!(components.cap() == 5)) {
            [1.0, 0.0, 0.0, 0.0, 0.0] @=> components;
        }

        float summer;
        for(0 => int i; i<components.cap(); i++){
            components[i] +=> summer;
        }

        if (summer <= 0.0) {
            <<< "no sound!" >>>;
            0.0 => this.vsin.gain;
            0.0 => this.vsaw.gain;
            0.0 => this.vtri.gain;
            0.0 => this.vpls.gain;
            0.0 => this.vnse.gain;
        }
        else{
            components[0] / summer => this.vsin.gain;
            components[1] / summer => this.vsaw.gain;
            components[2] / summer => this.vtri.gain;
            components[3] / summer => this.vpls.gain;
            components[4] / summer => this.vnse.gain;
        }
    }
}

WaveformMixerMono bloop;
bloop.final => dac;
bloop.final.gain(0.4);
bloop.mixer([0.0, 0.0, 1.0, 0.0, 0.0]);
bloop.freq(500.0);

2::second => now;

public class WaveformMixerMono{

/*
def mix_arrays(idx, amount):
    finals = [0.0, 0.0, 0.0, 0.0, 0.0]
    finals[idx] = round((1-amount), 4)
    finals[idx+1] = round((amount), 4)
    print(finals)

jump = 10/5
for i in range(0, 100):
    j = (i/10)
    k = math.floor(j/2)
    k2 = k*2
    n = (j - k2) / 2.0
    mix_arrays(k, n)
*/

    SinOsc vsin => Gain final;
    SawOsc vsaw => final;
    TriOsc vtri => final;
    PulseOsc vpls => final;
    Noise vnse => final;

    440 => float frequency;

    fun void pwidth(float pw){
        pw => this.vpls.width;
    }

    fun void freq(float frequency){
        frequency => this.frequency;
        vsin.freq(frequency);
        vsaw.freq(frequency);
        vtri.freq(frequency);
        vpls.freq(frequency);
    }

    fun void mixer(float components[], float mgain){
        mixer(components);
        mgain => this.final.gain;
    }

    fun void mixer2(float continual){

        float mix_comp[];
        if (continual >= 7.9996) [0.0, 0.0, 0.0, 0.0, 1.0] @=> mix_comp;
        else if (continual <= 0.0001) [1.0, 0.0, 0.0, 0.0, 0.0] @=> mix_comp;
        else {
            continual => float j;
            Math.floor(j/2.0) $ int => int k;
            k*2 => int k2;
            ((j - k2) / 2.0) => float n;
            <<< k, n >>>;
            mix_arrays(k, n) @=> mix_comp;
        }
        mixer(mix_comp);
    }

    fun void mixer(float components[]){
        // set defautls, just in case -- make it a SinOsc
        if (!(components.cap() == 5)) {
            [1.0, 0.0, 0.0, 0.0, 0.0] @=> components;
        }

        float summer;
        for(0 => int i; i<components.cap(); i++){
            components[i] +=> summer;
        }

        if (summer <= 0.0) {
            <<< "no sound!" >>>;
            0.0 => this.vsin.gain;
            0.0 => this.vsaw.gain;
            0.0 => this.vtri.gain;
            0.0 => this.vpls.gain;
            0.0 => this.vnse.gain;
        }
        else{
            components[0] / summer => this.vsin.gain;
            components[1] / summer => this.vsaw.gain;
            components[2] / summer => this.vtri.gain;
            components[3] / summer => this.vpls.gain;
            components[4] / summer => this.vnse.gain;
        }
    }

    fun float fixmin(float fin){
        if (fin < 0.0001) return 0.0;
        else return fin;
    }

    fun float[] mix_arrays(int idx, float amount){
        <<< idx, idx+1 >>>;
        [0.0, 0.0, 0.0, 0.0, 0.0] @=> float final_mix[];
        (1-amount) => fixmin => final_mix[idx];
        (amount) => fixmin => final_mix[idx+1];
        return final_mix;
    }

}

// Math.round

WaveformMixerMono bloop;
//bloop.final => dac;

// bloop.final.gain(0.1);
// bloop.mixer([0.0, 0.0, 0.0, 0.0, 1.0]);
// bloop.freq(500.0);

// 2::second => now;
// bloop.mixer([0.0, 0.0, 0.0, 0.0, 1.0], 0.0);
// 0.4::second => now;

// bloop.mixer([0.0, 0.0, 0.0, 0.0, 1.0], 0.2);
// bloop.freq(500.0);

// 2::second => now;

for(0.0 => float i; i<=8.0; 0.01+=> i){
    bloop.mixer2(i);
}

Update WaveformMixerMono.ck

Update WaveformMixerMono.ck

woah. crazy monophonic synth osc strip.


Gain vibGain => dac;

vibGain.gain(4.0);

[46, 48, 49, 51, 53, 54, 56, 58] @=> int scale[];

repeat(3){
    for(0 => int i; i < scale.cap(); i++)
    {
       <<< i >>>;
       scale[i] => int note;
       spork ~ play_vibra(note);
       .2::second => now;
    }
}

fun void play_vibra(int note){

    ModalBar modalBar => ADSR vibEnv => vibGain;
    320 => modalBar.vibratoFreq;
    6 => modalBar.preset;

                        //int, float (0.0 128.0)
    modalBar.controlChange(2, 123.0);   // - Stick Hardness
    modalBar.controlChange(4, 27.0);    // - Stick Position
    modalBar.controlChange(11, 53.0);  // - Vibrato Gain
    modalBar.controlChange(7, 115.0);   // - Vibrato Frequency
    modalBar.controlChange(1, 0.01);   // - Direct Stick Mix
    modalBar.controlChange(128, 0.2); // - Volume

    vibEnv.set( 42::ms, 371::ms, 0.80, 35::ms );  //a, d, s, r
    vibEnv.keyOn();
    Std.mtof(note)*2 => modalBar.freq;
    1.0 => modalBar.noteOn;
    .75 => modalBar.strike;
    1.4::second => now;

    modalBar =< vibGain;

}

Gain vibGain => dac;

vibGain.gain(4.0);

[46, 48, 49, 51, 53, 54, 56, 58] @=> int scale[];

repeat(3){
    for(0 => int i; i < scale.cap(); i++)
    {
       <<< i >>>;
       scale[i] => int note;
       spork ~ play_vibra(note);
       .2::second => now;
    }
}

fun void play_vibra(int note){

    ModalBar modalBar => ADSR vibEnv => vibGain;
    320 => modalBar.vibratoFreq;
    6 => modalBar.preset;

    // control change takes to parameters,
    // - int, range: depends on parameter
    // - float, range: 0.0...128.0
    modalBar.controlChange(2, 123.0);   // - Stick Hardness
    modalBar.controlChange(4, 27.0);    // - Stick Position
    modalBar.controlChange(11, 53.0);   // - Vibrato Gain
    modalBar.controlChange(7, 115.0);   // - Vibrato Frequency
    modalBar.controlChange(1, 0.01);    // - Direct Stick Mix
    modalBar.controlChange(128, 0.2);   // - Volume

    vibEnv.set( 42::ms, 371::ms, 0.80, 35::ms );  //a, d, s, r
    vibEnv.keyOn();
    Std.mtof(note)*2 => modalBar.freq;
    1.0 => modalBar.noteOn;
    .75 => modalBar.strike;
    1.4::second => now;

    modalBar =< vibGain;

}

Update vibraphoney.ck

Update vibraphoney.ck


// Assignment 7 drumCircleDSP
public class KickSynC{

    0.0 => float mgain;
    Gain bdmast;
    bdmast.gain(mgain);

    fun void trigger(float volume){
        this.bdmast.gain(volume);
        spork ~ s_do_kick();
    }

    fun void s_do_kick(){

        CurveTable c;
        [0., 970, -5.98,  .24, 104,-3.3, 1.8, 41.] => c.coefs;

        // frequency curve
        ADSR e => blackhole;
        e.set( 0::ms, 540::ms, 0.0, 125::ms );  //a, d, s, r
        e.keyOn(1);

        // simple adsr
        ADSR volE;
        volE.set( 0::ms, 281::ms, 0.0, 65::ms );  //a, d, s, r
        volE.keyOn();

        // routing.
        c => blackhole;
        Dyno comp => bdmast;
        comp.compress();
        SinOsc form => volE => LPF boom => PoleZero dc => comp;
        dc.blockZero(0.994);
        132 => boom.freq;

        // set

        now => time start;
        // ready
        while (true)
        {
            c.lookup(1/e.value()) $ int => form.freq;
            boom.Q(.22);
            21::samp => now;

            // advance time
            if (now > (start + 250::ms)){
                e.keyOff();
                volE.keyOff();
                break;
            }
        }

        1::second => now;
    }

}

KickSynC kick1;

kick1.bdmast => dac;
kick1.trigger(4.4);

1::second => now;

Update bassdrum_electronic_deepboom2.ck

Update bassdrum_electronic_deepboom2.ck


class Chord
{
    0=>static int mode;
    0=>int style;
    Chord @ next[];
    int notes[];
    int root;                         //the root key
    int type;                         //major,minor,etc
    float probabilities[][];              //probability for each next state
    Chord @ modulationSequence[][];
    Chord @ modulationChord[];
    int modulationTarget[];
    fun void init(int root, int type, Chord next[], float probabilities[][])
    {
        setRoot(root);
        setType(type);
        setNext(next);
        setProbabilities(probabilities);
        setNotes();
    }
    fun void setRoot(int i)
    {
        i=>root;
    }
    fun void setType(int i)
    {
        i=>type;
    }
    fun void setNext(Chord c[])
    {
        c@=>next;
    }
    fun void setProbabilities(float f[][])
    {
        f@=>probabilities;
    }
    fun Chord getNextChord()
    {
        return getNextChord(mode);
    }
    fun Chord getNextChord(int i)
    {
        Std.rand2f(0, 1)=>float rand;
        0=>float c;
        getProbabilities(i)@=>float p[];
        for (0=>int i; i<p.cap()-1;i++)
        {
            p[i]+=>c;
            if (rand<=c)
                return next[i];
        }
        return next[next.cap()-1];
    }
    fun float[] getProbabilities(int i)
    {
        return probabilities[i];
    }
    fun string toString()
    {
        [["I","i","Idim","Iaug","Isus4","I7"],
         ["bII","bii"],
         ["II","ii"],
         ["bIII","biii"],
         ["III","iii"],
         ["IV","iv"],
         ["bV","bv"],
         ["V","v","Vdim","Vaug","Vsus4","V7"],
         ["bVI","bvi"],
         ["VI","vi","VIdim","VIaug","VIsus4"],
         ["bVII","bvii"],
         ["VII","vii"]]@=>string s[][];
        return s[root][type];
    }
    fun void setNotes()
    {
        if (type==0)
        {
            [root,root+4,root+7]@=>notes;
        }
        if (type==1)
        {
            [root,root+3,root+7]@=>notes;
        }
        if (type==2)
        {
            [root,root+3,root+6]@=>notes;
        }
        if (type==3)
        {
            [root,root+4,root+8]@=>notes;
        }
        if (type==4)
        {
            [root,root+5,root+7]@=>notes;
        }
        if (type==5)
        {
            [root,root+4,root+7,root+10]@=>notes;
        }

    }
    fun int[] getNotesWithin()
    {
        return notes;
    }
    fun void setModulation(Chord modulation[][], int target[], Chord chord[])
    {
        modulation@=>modulationSequence;
        target@=>modulationTarget;
        chord@=>modulationChord;
    }
    fun Chord[][] getModulationSequence()
    {
        return modulationSequence;
    }
    fun int[] getModulationTarget()
    {
        return modulationTarget;
    }
    fun Chord[] getModulationChord()
    {
        return modulationChord;
    }
}

class IntList
{
    0=>int size;
    IntNode @ first;
    IntNode @ last;

    fun void offer(int o)
    {
        IntNode n;
        n.init(o);
        if (size==0)
        {
            n@=>first;
            n@=>last;
        }
        else
        {
            n@=>last.next;
            n@=>last;
        }
        size++;
    }
    fun int poll()
    {
        if (size==0)
            return -1;
        size--;
        first @=> IntNode n;
        n.next @=> first;
        return n.object;
    }
}
class IntNode
{
    int object;
    IntNode @ next;
    fun void init(int o)
    {
        o=>object;
    }
}
class LinkedList                   //great pain to write a linked list in chuck
{
    0=>int size;
    Node @ first;
    Node @ last;

    fun void offer(Object o)
    {
        Node n;
        n.init(o);
        if (size==0)
        {
            n@=>first;
            n@=>last;
        }
        else
        {
            n@=>last.next;
            n@=>last;
        }
        size++;
    }
    fun Object poll()
    {
        if (size==0)
            return null;
        size--;
        first @=> Node n;
        n.next @=> first;
        return n.object;
    }
    fun Object add(Object o[])
    {
        for (0=>int i; i<o.cap(); i++)
        {
            offer(o[i]);
        }
    }
    fun Object getFirst()
    {
        return first.object;
    }
    fun Object getLast()
    {
        return last.object;
    }
}
class Node
{
    Object @ object;
    Node @ next;
    fun void init(Object o)
    {
        o@=>object;
    }
}

//runing code starts here
OscSend send;
"localhost" => string hostname;
6449 => int port;
send.setHost(hostname,port);
Chord current;
Chord I;
Chord I7;
Chord ii;
Chord II;
Chord iii;
Chord III;
Chord IV;
Chord iv;
Chord V;
Chord V7;
Chord vi;
Chord VI;
Chord Isus4;
Chord VIsus4;
I.init(0,0,[I,ii,III,IV,V,vi],[[0.1,0.1,0.1,0.3,0.3,0.1],[0.1,0.1,0.1,0.1,0.1,0.5]]);
I7.init(0,5,[I7],[[1.0],[1.0]]);
ii.init(2,1,[iii,III,V,vi],[[0.2,0.3,0.4,0.1],[0.4,0.3,0.2,0.1]]);
II.init(2,0,[II],[[1.0],[1.0]]);
iii.init(4,1,[V,IV,vi],[[0.4,0.4,0.2],[0.2,0.3,0.5]]);
III.init(4,0,[IV,vi,iv],[[0.5,0.3,0.2],[0.2,0.6,0.2]]);
IV.init(5,0,[I,V,V7,III],[[0.3,0.4,0.2,0.1],[0.2,0.4,0.1,0.3]]);
iv.init(5,1,[VI,V,vi],[[0.3,0.4,0.3],[0.2,0.4,0.4]]);
V.init(7,0,[I,vi,ii,iii,Isus4,V7],[[0.2,0.2,0.1,0.2,0.1,0.2],[0.2,0.1,0.1,0.2,0.2,0.2]]);
V7.init(7,5,[I,vi],[[0.8,0.2],[0.4,0.6]]);
vi.init(9,1,[I,ii,iii,IV,V],[[0.2,0.3,0.1,0.3,0.1],[0.2,0.2,0.2,0.2,0.2]]);
Isus4.init(0,4,[I],[[1.0],[1.0]]);
VIsus4.init(9,4,[vi],[[1.0],[1.0]]);
VI.init(9,0,[VI],[[1.0],[1.0]]);
III.setModulation([[VIsus4]],[-3],[I]);
I.setModulation([[VI],[I7],[VI]],[2,5,7],[I,I,V]);
Rhodey  instruments[4];
IntList beats;
IntList keys;
LinkedList chords;
chords.offer(I);
keys.offer(3);
beats.offer(4);
0=>int rhythmCounter;
fun void generateChords()
{
    chords.getLast() $ Chord @=> Chord lastChord;
    if (lastChord.getModulationSequence()!=null && Math.random2f(0, 1)<0.2)
    {
        lastChord.getModulationSequence()@=>Chord modSqs[][];
        lastChord.getModulationTarget()@=>int modKeys[];
        lastChord.getModulationChord()@=>Chord targetChords[];
        Math.random2f(0,modSqs.cap()) $ int  =>int choice;
        modSqs[choice]@=>Chord modSq[];
        modKeys[choice]=>int keyChange;
        targetChords[choice]@=>Chord targetChord;
        for (0=>int i; i<modSq.cap(); i++)
        {
            chords.offer(modSq[i]);
            keys.offer(keys.last.object);
        }
        chords.offer(targetChord);
        keys.offer((keys.last.object+keyChange+12)%12);
    }
    else
    {
        chords.offer(lastChord.getNextChord(1));
        keys.offer(keys.last.object);
    }
}
fun void generateBeats()
{
    Math.random2f(0,1) => float p;
    if (p<=0.6)
    {
        beats.offer(4);
    }
    else if (p<=0.7)
    {
        beats.offer(3);
        beats.offer(3);
        beats.offer(2);
    }
    else if (p<=0.8)
    {
        beats.offer(3);
        beats.offer(3);
        beats.offer(3);
        beats.offer(3);
    }
    else if (p<=0.9)
    {
        beats.offer(6);
        beats.offer(2);
    }
    else
    {
        beats.offer(3);
        beats.offer(2);
        beats.offer(3);
    }
}

for (0=>int i; i < instruments.cap(); i++)
{
    instruments[i]=>dac;
}

fun void playChord(Chord current, int key, int beat)
{
    if (beats.size==0)
    {
        generateBeats();
    }
    current.root=>int root;
    current.type=>int type;
    send.startMsg("/key/root/type", "i i i");
    key => send.addInt;
    root => send.addInt;
    type => send.addInt;
    current.getNotesWithin()@=>int notes[];
    <<< "Chord Name: ", current.toString() >>>;
    <<< "Sent key: ", key, "root: ", root, ", type: ", type >>>;
    <<< "Beats Played: ", beat>>>;
    for (0=>int j;j<beat;j++)
    {
        0.5::second=>now;
        float dyn;
        if (rhythmCounter == 0)
            0.2=>dyn;
        else if (rhythmCounter == 2)
            0.11=>dyn;
        else
            0.07=>dyn;
        Std.mtof(36+(key+notes[0]%12))=>instruments[0].freq;
        dyn=>instruments[0].noteOn;
        for (1=>int i; i < instruments.cap(); i++)
        {
            Std.mtof(48+(key+notes[i%notes.cap()])%12)=>instruments[i].freq;
            if (j==0)
                dyn=>instruments[i].noteOn;
            else if (Math.random2f(0,1)<0.7)
                dyn=>instruments[i].noteOn;
        }
        <<<"beat: ",  rhythmCounter>>>;
        (rhythmCounter+1)%4=>rhythmCounter;
    }
}
while (true)
{
    if (chords.size<5)
    {
        generateChords();
    }
    if (beats.size<5)
    {
        generateBeats;
    }
    playChord(chords.poll()$Chord, keys.poll(), beats.poll());
}

class Chord
{
    0=>static int mode;
    0=>int style;
    Chord @ next[];
    int notes[];
    int root;                         //the root key
    int type;                         //major,minor,etc
    float probabilities[][];              //probability for each next state
    Chord @ modulationSequence[][];
    Chord @ modulationChord[];
    int modulationTarget[];
    fun void init(int root, int type, Chord next[], float probabilities[][])
    {
        setRoot(root);
        setType(type);
        setNext(next);
        setProbabilities(probabilities);
        setNotes();
    }
    fun void setRoot(int i)
    {
        i=>root;
    }
    fun void setType(int i)
    {
        i=>type;
    }
    fun void setNext(Chord c[])
    {
        c@=>next;
    }
    fun void setProbabilities(float f[][])
    {
        f@=>probabilities;
    }
    fun Chord getNextChord()
    {
        return getNextChord(mode);
    }
    fun Chord getNextChord(int i)
    {
        Std.rand2f(0, 1)=>float rand;
        0=>float c;
        getProbabilities(i)@=>float p[];
        for (0=>int i; i<p.cap()-1;i++)
        {
            p[i]+=>c;
            if (rand<=c)
                return next[i];
        }
        return next[next.cap()-1];
    }
    fun float[] getProbabilities(int i)
    {
        return probabilities[i];
    }
    fun string toString()
    {
        [["I","i","Idim","Iaug","Isus4","I7"],
         ["bII","bii"],
         ["II","ii","IIdim","IIaug","IIsus4","II7","ii7"],
         ["bIII","biii"],
         ["III","iii"],
         ["IV","iv"],
         ["bV","bv","bVdim","bVaug","bVsus4","bV7","bv7"],
         ["V","v","Vdim","Vaug","Vsus4","V7"],
         ["bVI","bvi"],
         ["VI","vi","VIdim","VIaug","VIsus4"],
         ["bVII","bvii"],
         ["VII","vii"]]@=>string s[][];
        return s[root][type];
    }
    fun void setNotes()
    {
        if (type==0)
        {
            [root,root+4,root+7]@=>notes;
        }
        if (type==1)
        {
            [root,root+3,root+7]@=>notes;
        }
        if (type==2)
        {
            [root,root+3,root+6]@=>notes;
        }
        if (type==3)
        {
            [root,root+4,root+8]@=>notes;
        }
        if (type==4)
        {
            [root,root+5,root+7]@=>notes;
        }
        if (type==5)
        {
            [root,root+4,root+7,root+10]@=>notes;
        }
        if (type==6)
        {
            [root,root+3,root+7,root+10]@=>notes;
        }

    }
    fun int[] getNotesWithin()
    {
        return notes;
    }
    fun void setModulation(Chord modulation[][], int target[], Chord chord[])
    {
        modulation@=>modulationSequence;
        target@=>modulationTarget;
        chord@=>modulationChord;
    }
    fun Chord[][] getModulationSequence()
    {
        return modulationSequence;
    }
    fun int[] getModulationTarget()
    {
        return modulationTarget;
    }
    fun Chord[] getModulationChord()
    {
        return modulationChord;
    }
}

class IntList
{
    0=>int size;
    IntNode @ first;
    IntNode @ last;

    fun void offer(int o)
    {
        IntNode n;
        n.init(o);
        if (size==0)
        {
            n@=>first;
            n@=>last;
        }
        else
        {
            n@=>last.next;
            n@=>last;
        }
        size++;
    }
    fun int poll()
    {
        if (size==0)
            return -1;
        size--;
        first @=> IntNode n;
        n.next @=> first;
        return n.object;
    }
}
class IntNode
{
    int object;
    IntNode @ next;
    fun void init(int o)
    {
        o=>object;
    }
}
class LinkedList                   //great pain to write a linked list in chuck
{
    0=>int size;
    Node @ first;
    Node @ last;

    fun void offer(Object o)
    {
        Node n;
        n.init(o);
        if (size==0)
        {
            n@=>first;
            n@=>last;
        }
        else
        {
            n@=>last.next;
            n@=>last;
        }
        size++;
    }
    fun Object poll()
    {
        if (size==0)
            return null;
        size--;
        first @=> Node n;
        n.next @=> first;
        return n.object;
    }
    fun Object add(Object o[])
    {
        for (0=>int i; i<o.cap(); i++)
        {
            offer(o[i]);
        }
    }
    fun Object getFirst()
    {
        return first.object;
    }
    fun Object getLast()
    {
        return last.object;
    }
}
class Node
{
    Object @ object;
    Node @ next;
    fun void init(Object o)
    {
        o@=>object;
    }
}

//runing code starts here
OscSend send;
"localhost" => string hostname;
6449 => int port;
send.setHost(hostname,port);
Chord current;
Chord I;
Chord I7;
Chord ii;
Chord II;
Chord IIdim;
Chord ii7;
Chord iii;
Chord III;
Chord bv7;
Chord IV;
Chord iv;
Chord V;
Chord V7;
Chord vi;
Chord VI;
Chord Isus4;
Chord VIsus4;
I.init(0,0,[I,ii,III,IV,V,vi,ii7],[[0.1,0.1,0.1,0.3,0.2,0.1,0.1],[0.1,0.1,0.1,0.1,0.1,0.4,0.1]]);
I7.init(0,5,[I7],[[1.0],[1.0]]);
ii.init(2,1,[iii,III,V,vi],[[0.2,0.3,0.4,0.1],[0.4,0.3,0.2,0.1]]);
II.init(2,0,[II],[[1.0],[1.0]]);
IIdim.init(2,2,[V],[[1.0],[1.0]]);
ii7.init(2,6,[I,V],[[0.3,0.7],[0.3,0.7]]);
iii.init(4,1,[V,IV,vi],[[0.4,0.4,0.2],[0.2,0.3,0.5]]);
III.init(4,0,[IV,vi,iv],[[0.5,0.3,0.2],[0.2,0.6,0.2]]);
IV.init(5,0,[I,V,V7,III,bv7],[[0.3,0.3,0.2,0.1,0.1],[0.2,0.4,0.1,0.2,0.1]]);
iv.init(5,1,[VI,V,vi],[[0.3,0.4,0.3],[0.2,0.4,0.4]]);
bv7.init(6,6,[V],[[1.0],[1.0]]);
V.init(7,0,[I,vi,ii,iii,Isus4,V7],[[0.2,0.2,0.1,0.2,0.1,0.2],[0.2,0.1,0.1,0.2,0.2,0.2]]);
V7.init(7,5,[I,vi],[[0.8,0.2],[0.4,0.6]]);
vi.init(9,1,[I,ii,iii,IV,V,IIdim],[[0.2,0.2,0.1,0.3,0.1,0.1],[0.2,0.2,0.2,0.2,0.1,0.1]]);
Isus4.init(0,4,[I],[[1.0],[1.0]]);
VIsus4.init(9,4,[vi],[[1.0],[1.0]]);
VI.init(9,0,[VI],[[1.0],[1.0]]);
III.setModulation([[VIsus4]],[-3],[I]);
I.setModulation([[VI],[I7],[VI]],[2,5,7],[I,I,V]);
Rhodey  instruments[4];
IntList beats;
IntList keys;
LinkedList chords;
chords.offer(IV);
keys.offer(3);
beats.offer(4);
0=>int rhythmCounter;
fun void generateChords()
{
    chords.getLast() $ Chord @=> Chord lastChord;
    if (lastChord.getModulationSequence()!=null && Math.random2f(0, 1)<0.2)
    {
        lastChord.getModulationSequence()@=>Chord modSqs[][];
        lastChord.getModulationTarget()@=>int modKeys[];
        lastChord.getModulationChord()@=>Chord targetChords[];
        Math.random2f(0,modSqs.cap()) $ int  =>int choice;
        modSqs[choice]@=>Chord modSq[];
        modKeys[choice]=>int keyChange;
        targetChords[choice]@=>Chord targetChord;
        for (0=>int i; i<modSq.cap(); i++)
        {
            chords.offer(modSq[i]);
            keys.offer(keys.last.object);
        }
        chords.offer(targetChord);
        keys.offer((keys.last.object+keyChange+12)%12);
    }
    else
    {
        chords.offer(lastChord.getNextChord(1));
        keys.offer(keys.last.object);
    }
}
fun void generateBeats()
{
    Math.random2f(0,1) => float p;
    if (p<=0.6)
    {
        beats.offer(4);
    }
    else if (p<=0.7)
    {
        beats.offer(3);
        beats.offer(3);
        beats.offer(2);
    }
    else if (p<=0.8)
    {
        beats.offer(3);
        beats.offer(3);
        beats.offer(3);
        beats.offer(3);
    }
    else if (p<=0.9)
    {
        beats.offer(6);
        beats.offer(2);
    }
    else
    {
        beats.offer(3);
        beats.offer(2);
        beats.offer(3);
    }
}

for (0=>int i; i < instruments.cap(); i++)
{
    instruments[i]=>dac;
}

fun void playChord(Chord current, int key, int beat)
{
    if (beats.size==0)
    {
        generateBeats();
    }
    current.root=>int root;
    current.type=>int type;
    send.startMsg("/key/root/type", "i i i");
    key => send.addInt;
    root => send.addInt;
    type => send.addInt;
    current.getNotesWithin()@=>int notes[];
    <<< "Chord Name: ", current.toString() >>>;
    <<< "Sent key: ", key, "root: ", root, ", type: ", type >>>;
    <<< "Beats Played: ", beat>>>;
    for (0=>int j;j<beat;j++)
    {
        0.5::second=>now;
        float dyn;
        if (rhythmCounter == 0)
            0.2=>dyn;
        else if (rhythmCounter == 2)
            0.11=>dyn;
        else
            0.07=>dyn;
        Std.mtof(36+(key+notes[0]%12))=>instruments[0].freq;
        dyn=>instruments[0].noteOn;
        for (1=>int i; i < instruments.cap(); i++)
        {
            Std.mtof(48+(key+notes[i%notes.cap()])%12)=>instruments[i].freq;
            if (j==0)
                dyn=>instruments[i].noteOn;
            else if (Math.random2f(0,1)<0.7)
                dyn=>instruments[i].noteOn;
        }
        <<<"beat: ",  rhythmCounter>>>;
        (rhythmCounter+1)%4=>rhythmCounter;
    }
}
while (true)
{
    if (chords.size<5)
    {
        generateChords();
    }
    if (beats.size<5)
    {
        generateBeats;
    }
    playChord(chords.poll()$Chord, keys.poll(), beats.poll());
}

Add some chords

Add some chords


"monkey" => string name;
<<< "hello " + name >>>;

fun string greeter( string a )
{
    <<< "Hello " + a >>>;
}

greeter("DevFest") => string greet;

add greeter function

add greeter function


//me.arg(0) => string filename;
//if( filename.length() == 0 ) "foo.wav" => filename;

dac => WvOut2 w => blackhole;
//"data/session" => w.autoPrefix;
"woooot.wav" => w.wavFilename;
1 => w.record;
3::second => now;

// everything in between

0 => w.record;

//me.arg(0) => string filename;
//if( filename.length() == 0 ) "foo.wav" => filename;

dac => Mix2 regulator => WvOut2 w => blackhole;
//"data/session" => w.autoPrefix;

regulator.gain(1.0);
"woooot.wav" => w.wavFilename;
1 => w.record;
3::second => now;

// everything in between gets recorded.

0 => w.record;

Update to_stereo_wav_with_gainParams.ck

Update to_stereo_wav_with_gainParams.ck

added gain possibility.


/* As you can see, this is a very raw Markov chain for chord progressions
 * It would be great if melodies can be generated according to this state machine
 * I use classes only because a ton of "else if" looks really messy, though the object-oriented of this language is really bad
 * The blank funcion is intended for future data receiving
 * It sends basic information of a chord
 * I hope melody can be generated according to the chord
 */

//the very basic chord base
class Chord
{
    0=>int style;
    string name;                      //how you call it
    Chord @ next[];
    int root;                         //the root key
    int type;                         //major,minor,etc
    float probabilities[][];              //probability for each next state
    fun void init(int root, int type, Chord next[], float probabilities[][])
    {
        setRoot(root);
        setType(type);
        setNext(next);
        setProbabilities(probabilities);
    }
    fun void setRoot(int i)
    {
        i=>root;
    }
    fun void setType(int i)
    {
        i=>type;
    }
    fun void setNext(Chord c[])
    {
        c@=>next;
    }
    fun void setProbabilities(float f[][])
    {
        f@=>probabilities;
    }
    fun Chord getNextChord()
    {
        Std.rand2f(0, 1)=>float rand;
        0=>float c;
        getPrabablities()@=>float p[];
        for (0=>int i; i<p.cap();i++)
        {
            p[i]+=>c;
            if (rand<=c)
                return next[i];
        }
        return this;
    }
    fun float[] getPrabablities()
    {
        if (style==0)
            return probabilities[0];
    }
    fun void setStyle(){}           //may be used to change probabilities
}

//runing code starts here
OscSend send;
"localhost" => string hostname;
6449 => int port;
send.setHost(hostname,port);
Chord current;
Chord I;
Chord ii;
Chord iii;
Chord III;
Chord IV;
Chord V;
Chord vi;
I.init(0,0,[I,ii,III,IV,V],[[0.1,0.1,0.1,0.4,0.3]]);
ii.init(2,1,[I,iii,III,V,vi],[[0.1,0.1,0.3,0.4,0.1]]);
iii.init(4,1,[V,IV,vi],[[0.2,0.4,0.4]]);
III.init(4,0,[IV,vi],[[0.4,0.6]]);
IV.init(5,0,[I,V,III],[[0.3,0.6,0.1]]);
V.init(7,0,[I,vi,ii],[[0.6,0.3,0.1]]);
vi.init(9,1,[I,ii,iii,IV,V,vi],[[0.1,0.3,0.1,0.3,0.1,0.1]]);
I @=> current;
while (true)
{
    <<< "Chord Name: ", current.name >>>;
    0=>int key;
    current.root=>int root;
    current.type=>int type;
    key => send.addInt;
    root => send.addInt;
    type => send.addInt;
    <<< "Sent key: ", key, "root: ", root, ", type: ", type >>>;
    current.getNextChord()@=>current;
    6::second=>now;
}

/* As you can see, this is a very raw Markov chain for chord progressions
 * It would be great if melodies can be generated according to this state machine
 * I use classes only because a ton of "else if" looks really messy, though the object-oriented of this language is really bad
 * The blank funcion is intended for future data receiving
 * It sends basic information of a chord
 * I hope melody can be generated according to the chord
 */

//the very basic chord base
class Chord
{
    string name;                      //how you call it
    string nextChord[];               //next states
    int root;                         //the root key
    int type;                         //major,minor,etc
    float probability[];              //probability for each next state
    fun string getNextChordName()     //randomly choose the next chord
    {
        Std.rand2f(0, 1)=>float rand;
        0=>float c;
        for (0=>int i; i<probability.cap();i++)
        {
            probability[i]+=>c;
            if (rand<=c)
                return nextChord[i];
        }
        return this.name;
    }
    fun void setStyle(){}            //may be used to change probabilities
}

class ChordMajor extends Chord
{
    0=>type;
}

class ChordMinor extends Chord
{
    1=>type;
}

class ChordI extends ChordMajor
{
    "I"=>name;
    0=>root;
    ["I", "ii","III","IV","V"]@=>nextChord;
    [0.1,0.1,0.1,0.4,0.3]@=>probability;
}
class Chordii extends ChordMinor
{
    "ii"=>name;
    2=>root;
    ["I","iii","III","V","vi"]@=>nextChord;
    [0.1,0.1,0.3,0.4,0.1]@=>probability;
}
class Chordiii extends ChordMinor
{
    "iii"=>name;
    4=>root;
    ["V","IV","vi"]@=>nextChord;
    [0.2,0.4,0.4]@=>probability;
}
class ChordIII extends ChordMajor
{
    "III"=>name;
    4=>root;
    ["IV","vi"]@=>nextChord;
    [0.4,0.6]@=>probability;
}
class ChordIV extends ChordMajor
{
    "IV"=>name;
    5=>root;
    ["I","V","III"]@=>nextChord;
    [0.3,0.6,0.1]@=>probability;
}
class ChordV extends ChordMajor
{
    "V"=>name;
    7=>root;
    ["I","vi","ii"]@=>nextChord;
    [0.6,0.3,0.1]@=>probability;
}class Chordvi extends ChordMinor
{
    "vi"=>name;
    9=>root;
    ["I","ii","iii","IV","V","vi"]@=>nextChord;
    [0.1,0.3,0.1,0.3,0.1,0.1]@=>probability;
}

//runing code starts here
OscSend send;
"localhost" => string hostname;
6449 => int port;
send.setHost(hostname,port);
Chord current;
ChordI I;
Chordii ii;
Chordiii iii;
ChordIII III;
ChordIV IV;
ChordV V;
Chordvi vi;
fun Chord getChord(string s)
{
    if (s=="I")
        return I;
    if (s=="ii")
        return ii;
    if (s=="iii")
        return iii;
    if (s=="III")
        return III;
    if (s=="IV")
        return IV;
    if (s=="V")
        return V;
    if (s=="vi")
        return vi;
    return null;
}
I @=> current;
while (true)
{
    <<< "Chord Name: ", current.name >>>;
    0=>int key;
    current.root=>int root;
    current.type=>int type;
    key => send.addInt;
    root => send.addInt;
    type => send.addInt;
    <<< "Sent key: ", key, "root: ", root, ", type: ", type >>>;
    getChord(current.getNextChordName())@=>current;
    6::second=>now;
}

Revert "Implementation change"

Revert "Implementation change"

This reverts commit 0933f1697aec78d908f17c10e2acef03b5c3641a.


// Machine.add("utilities.ck");

/*
    definitions

    fun void repr_int_array(int arr[]){}
    fun void repr_string_array(string arr[]){}

    fun int random_from(int arr[]){}
    fun int inArray(int token, int arr[]){}
    fun int indexOfClosest(int ival, int arr[]){}
    fun int to_note(string str){}
    fun int[] join_int_arrays(int arr1[], int arr2[]){}
    fun int[] repeat_int_array(int arr[], int num_times){}
    fun int[] set_from(int arr[]){}
    fun int[] randomArray_from(int arr[], int length){}
    fun int[] range(int start, int end){}
    fun int[] narray(int start, int next, int up_to){}
    fun int[] expand_scale(int scale[], int start_stop[]){
    fun int[][] stepify(string sequence_data[]){}

    fun float average(int arr[]){}

    fun string repr(int arr[]){}
    fun string repr(string arr[]){}
    fun string[] split(string arr, string token){}

    fun SndBuf load_sample(string wavname){}

    https://gist.github.com/anonymous/7206152

*/

fun string[] split_str(string str, string token){

    string collect[0];
    int pos;
    int pos2;
    while( str.find(token) >0){
        str.find(token) => pos2;
        collect << str.substring(pos, pos2);
        str.substring(pos2+1) => str;
    }
    collect << str;
    return collect;
}

fun int random_from(int arr[]){
    return arr[Math.random2(0, arr.cap()-1)];
}

fun int[] join_int_arrays(int arr1[], int arr2[]){
    [arr1, arr2] @=> int arr[][];
    int new_arr[0];
    for(0 => int j; j<arr.cap(); j++){

        for(0 => int i; i<arr[j].cap(); i++){
            new_arr << arr[j][i];
        }
    }
    return new_arr;
}

fun int[] repeat_int_array(int arr[], int num_times){
    int new_arr[0];
    for(0 => int j; j<num_times; j++){
        for(0 => int i; i<arr.cap(); i++){
            new_arr << arr[i];
        }
    }
    return new_arr;
}

fun int[] randomArray_from(int arr[], int length){
    // return new array of capacity length chosing elements from arr
    int generated_arr[0];
    for(0 => int i; i<length; i++){
        generated_arr << random_from(arr); // append element
    }
    return generated_arr;
}

fun int[] range(int start, int end){
    // includes start and end
    int arr[0];
    for(start => int i; i<=end; i++) arr << i;
    return arr;
}

fun int[] narray(int start, int next, int up_to){
    // (start, end..up_to)  (inclusive)
    int arr[0];
    start => int cval;
    next - start => int jump;
    for(cval; cval<=up_to; jump +=> cval){
        arr << cval;
    }
    return arr;  // matey!
}

fun int[] expand_scale(int scale[], int start_stop[]){

    // assumes we start somewhere above 0
    start_stop[0] => int start;
    start_stop[1] => int end;

    int expand_array[0];
    -1 => int last;
    int current;
    for(start => int i; i < end; i++){
        for(0 => int n; n<scale.cap(); n++){
            // avoids doubles, if the incoming scale ends an
            // octave above the first note
            scale[n] + (i*12) => current;
            if (!(current == last)){
                expand_array << current;
                current => last;
            }
        }
    }
    return expand_array;
}

fun string repr(int arr[]){
    /*
    this returns a string representation of an int array,
    useful for debug printing.
    */
    "[" + Std.itoa(arr[0]) => string s;
    for (1 => int i; i < arr.cap(); i++){
        "," + Std.itoa(arr[i]) +=> s;
    }
    return s + "]";
}

fun string repr(string arr[]){

    //this returns a string representation of a string array,
    //useful for debug printing.

    "[" + arr[0] => string s;
    for (1 => int i; i < arr.cap(); i++){
        "," + arr[i] +=> s;
    }
    return s + "]";
}

fun void repr_int_array(int arr[])
{
    arr.cap() => int num_items;
    chout <= "[";
    for(0 => int i; i<num_items; i++){
        if (i>0) chout <= ",";
        chout <= arr[i];
    }
    chout <= "]";
    chout <= IO.newline();
}

fun void repr_string_array(string arr[])
{
    arr.cap() => int num_items;
    chout <= "[";
    for(0 => int i; i<num_items; i++){
        if (i>0) chout <= ",";
        chout <= arr[i];
    }
    chout <= "]";
    chout <= IO.newline();
}

fun int inArray(int token, int arr[]){
    /*
    tests membership of an array
    */
    for(0 => int i; i<arr.cap(); i++){
        if (arr[i]==token) return 1;
    }
    return 0;
}

fun int to_note(string str){
    if (str == "...") return -1;
    if (str == "OFF") return -2;
    if (str == "===") return -3;

    // check if within supported range
    str.substring(2) => Std.atoi => int oct;
    if (oct < 0 || oct > 10) return -4;

    str.substring(0,2) => str;

    [   "C-","C#","D-","D#","E-","F-",
        "F#","G-","G#","A-","A#","B-"
    ] @=> string notes_list[];

    // note must be in this list, else return -5 at the end
    for (0 => int i; i < notes_list.cap(); i++){
        if (str == notes_list[i]){
            return (i + oct * 12);
        }
    }
    return -5;
}

fun int[][] stepify(string sequence_data[]){
    /*
    this function converts a string array to an int array,
    it accepts fuzzy formatting:
    "1..1..1..1.." becomes [1,0,0,1,0,0,1,0,0,1,0,0]
    "1..1.   .1..1.." also becomes [1,0,0,1,0,0,1,0,0,1,0,0]
    */

    sequence_data.cap() => int parts;
    32 => int steps;  // hard code for now
    <<< parts, steps >>>;

    int data_store[parts][steps];
    for(0 => int i; i<sequence_data.cap(); i++){

        sequence_data[i] => string seq_string;
        int part_data[0];
        int trigger;
        //<<< seq_string >>>;
        for(0 => int j; j < seq_string.length(); j++){
            seq_string.substring(j,1) => string token; // crazy

            if (token == " ") continue;
            if (token == ".") 0 => trigger;
            else if (token == "1") 1 => trigger;

            part_data << trigger;
        }
        //<<< repr_int_array(part_data)>>>;
        part_data @=> data_store[i];
    }
    return data_store;
}

fun SndBuf load_sample(string wavname){

    // usage
    // load_sample("kick_02") @=> SndBuf kick => dac;

    // turn incoming wavname into   path/wavename.wav
    // return a reference to a new buffer object.
    SndBuf temp_buff;
    me.dir() + "/audio/" + wavname  + ".wav" => temp_buff.read;

    // set to end, and set gain, then return the object
    temp_buff.samples() => temp_buff.pos;
    0.8 => temp_buff.gain;
    return temp_buff;
}

fun float average(int arr[]){
    int sum;
    arr.cap() => int num_items;
    for(0 => int i; i < num_items; i++){
        arr[i] +=> sum;
    }
    sum $ float => float fsum;
    num_items $ float => float fcap;
    return fsum / fcap;
}

fun int indexOfClosest(int ival, int arr[]){
    // will find the closest value to ival in arr
    // if there are multiple, it will return the first.
    Math.INT_MAX => int min_distance;
    0 => int diff;
    -1 => int idx_tracker;

    for(0 => int i; i<arr.cap(); i++)
    {
        Math.abs(arr[i] - ival) => diff;
        if (diff < min_distance)
        {
            diff => min_distance;
            i => idx_tracker;
        }
    }
    return idx_tracker;

}

fun int[] set_from(int arr[]){
    // no order guaranteed
    // requires  inArray() to be present.
    int new_arr[0];
    new_arr << arr[0];

    for(1 => int i; i<arr.cap(); i++){
        if (inArray(arr[i], new_arr) == 0){
            new_arr << arr[i];
        }
    }
    return new_arr;
}

// Machine.add("utilities.ck");

/*
    definitions

    fun void repr_int_array(int arr[]){}
    fun void repr_string_array(string arr[]){}

    fun int random_from(int arr[]){}
    fun int inArray(int token, int arr[]){}
    fun int indexOfClosest(int ival, int arr[]){}
    fun int to_note(string str){}
    fun int[] transpose(int narray[], int semi_tones){}
    fun int[] join_int_arrays(int arr1[], int arr2[]){}
    fun int[] repeat_int_array(int arr[], int num_times){}
    fun int[] set_from(int arr[]){}
    fun int[] randomArray_from(int arr[], int length){}
    fun int[] range(int start, int end){}
    fun int[] narray(int start, int next, int up_to){}
    fun int[] expand_scale(int scale[], int start_stop[]){
    fun int[][] stepify(string sequence_data[]){}

    fun float average(int arr[]){}

    fun string repr(int arr[]){}
    fun string repr(string arr[]){}
    fun string[] split(string arr, string token){}

    fun SndBuf load_sample(string wavname){}

    https://gist.github.com/anonymous/7206152

*/

fun string[] split_str(string str, string token){

    string collect[0];
    int pos;
    int pos2;
    while( str.find(token) >0){
        str.find(token) => pos2;
        collect << str.substring(pos, pos2);
        str.substring(pos2+1) => str;
    }
    collect << str;
    return collect;
}

fun int random_from(int arr[]){
    return arr[Math.random2(0, arr.cap()-1)];
}

fun int[] transpose(int narray[], int semi_tones){
    int oarray[0];
    for(0 => int i; i<narray.cap(); i++){
        oarray << (narray[i]+semi_tones);
    }
    return oarray;
}

fun int[] join_int_arrays(int arr1[], int arr2[]){
    [arr1, arr2] @=> int arr[][];
    int new_arr[0];
    for(0 => int j; j<arr.cap(); j++){

        for(0 => int i; i<arr[j].cap(); i++){
            new_arr << arr[j][i];
        }
    }
    return new_arr;
}

fun int[] repeat_int_array(int arr[], int num_times){
    int new_arr[0];
    for(0 => int j; j<num_times; j++){
        for(0 => int i; i<arr.cap(); i++){
            new_arr << arr[i];
        }
    }
    return new_arr;
}

fun int[] randomArray_from(int arr[], int length){
    // return new array of capacity length chosing elements from arr
    int generated_arr[0];
    for(0 => int i; i<length; i++){
        generated_arr << random_from(arr); // append element
    }
    return generated_arr;
}

fun int[] range(int start, int end){
    // includes start and end
    int arr[0];
    for(start => int i; i<=end; i++) arr << i;
    return arr;
}

fun int[] narray(int start, int next, int up_to){
    // (start, end..up_to)  (inclusive)
    int arr[0];
    start => int cval;
    next - start => int jump;
    for(cval; cval<=up_to; jump +=> cval){
        arr << cval;
    }
    return arr;  // matey!
}

fun int[] expand_scale(int scale[], int start_stop[]){

    // assumes we start somewhere above 0
    start_stop[0] => int start;
    start_stop[1] => int end;

    int expand_array[0];
    -1 => int last;
    int current;
    for(start => int i; i < end; i++){
        for(0 => int n; n<scale.cap(); n++){
            // avoids doubles, if the incoming scale ends an
            // octave above the first note
            scale[n] + (i*12) => current;
            if (!(current == last)){
                expand_array << current;
                current => last;
            }
        }
    }
    return expand_array;
}

fun string repr(int arr[]){
    /*
    this returns a string representation of an int array,
    useful for debug printing.
    */
    "[" + Std.itoa(arr[0]) => string s;
    for (1 => int i; i < arr.cap(); i++){
        "," + Std.itoa(arr[i]) +=> s;
    }
    return s + "]";
}

fun string repr(string arr[]){

    //this returns a string representation of a string array,
    //useful for debug printing.

    "[" + arr[0] => string s;
    for (1 => int i; i < arr.cap(); i++){
        "," + arr[i] +=> s;
    }
    return s + "]";
}

fun void repr_int_array(int arr[])
{
    arr.cap() => int num_items;
    chout <= "[";
    for(0 => int i; i<num_items; i++){
        if (i>0) chout <= ",";
        chout <= arr[i];
    }
    chout <= "]";
    chout <= IO.newline();
}

fun void repr_string_array(string arr[])
{
    arr.cap() => int num_items;
    chout <= "[";
    for(0 => int i; i<num_items; i++){
        if (i>0) chout <= ",";
        chout <= arr[i];
    }
    chout <= "]";
    chout <= IO.newline();
}

fun int inArray(int token, int arr[]){
    /*
    tests membership of an array
    */
    for(0 => int i; i<arr.cap(); i++){
        if (arr[i]==token) return 1;
    }
    return 0;
}

fun int to_note(string str){
    if (str == "...") return -1;
    if (str == "OFF") return -2;
    if (str == "===") return -3;

    // check if within supported range
    str.substring(2) => Std.atoi => int oct;
    if (oct < 0 || oct > 10) return -4;

    str.substring(0,2) => str;

    [   "C-","C#","D-","D#","E-","F-",
        "F#","G-","G#","A-","A#","B-"
    ] @=> string notes_list[];

    // note must be in this list, else return -5 at the end
    for (0 => int i; i < notes_list.cap(); i++){
        if (str == notes_list[i]){
            return (i + oct * 12);
        }
    }
    return -5;
}

fun int[][] stepify(string sequence_data[]){
    /*
    this function converts a string array to an int array,
    it accepts fuzzy formatting:
    "1..1..1..1.." becomes [1,0,0,1,0,0,1,0,0,1,0,0]
    "1..1.   .1..1.." also becomes [1,0,0,1,0,0,1,0,0,1,0,0]
    */

    sequence_data.cap() => int parts;
    32 => int steps;  // hard code for now
    <<< parts, steps >>>;

    int data_store[parts][steps];
    for(0 => int i; i<sequence_data.cap(); i++){

        sequence_data[i] => string seq_string;
        int part_data[0];
        int trigger;
        //<<< seq_string >>>;
        for(0 => int j; j < seq_string.length(); j++){
            seq_string.substring(j,1) => string token; // crazy

            if (token == " ") continue;
            if (token == ".") 0 => trigger;
            else if (token == "1") 1 => trigger;

            part_data << trigger;
        }
        //<<< repr_int_array(part_data)>>>;
        part_data @=> data_store[i];
    }
    return data_store;
}

fun SndBuf load_sample(string wavname){

    // usage
    // load_sample("kick_02") @=> SndBuf kick => dac;

    // turn incoming wavname into   path/wavename.wav
    // return a reference to a new buffer object.
    SndBuf temp_buff;
    me.dir() + "/audio/" + wavname  + ".wav" => temp_buff.read;

    // set to end, and set gain, then return the object
    temp_buff.samples() => temp_buff.pos;
    0.8 => temp_buff.gain;
    return temp_buff;
}

fun float average(int arr[]){
    int sum;
    arr.cap() => int num_items;
    for(0 => int i; i < num_items; i++){
        arr[i] +=> sum;
    }
    sum $ float => float fsum;
    num_items $ float => float fcap;
    return fsum / fcap;
}

fun int indexOfClosest(int ival, int arr[]){
    // will find the closest value to ival in arr
    // if there are multiple, it will return the first.
    Math.INT_MAX => int min_distance;
    0 => int diff;
    -1 => int idx_tracker;

    for(0 => int i; i<arr.cap(); i++)
    {
        Math.abs(arr[i] - ival) => diff;
        if (diff < min_distance)
        {
            diff => min_distance;
            i => idx_tracker;
        }
    }
    return idx_tracker;

}

fun int[] set_from(int arr[]){
    // no order guaranteed
    // requires  inArray() to be present.
    int new_arr[0];
    new_arr << arr[0];

    for(1 => int i; i<arr.cap(); i++){
        if (inArray(arr[i], new_arr) == 0){
            new_arr << arr[i];
        }
    }
    return new_arr;
}

Update common_functions.ck

Update common_functions.ck


class Chord
{
    0=>int style;
    Chord @ next[];
    int root;                         //the root key
    int type;                         //major,minor,etc
    float probabilities[][];              //probability for each next state
    fun void init(int root, int type, Chord next[], float probabilities[][])
    {
        setRoot(root);
        setType(type);
        setNext(next);
        setProbabilities(probabilities);
    }
    fun void setRoot(int i)
    {
        i=>root;
    }
    fun void setType(int i)
    {
        i=>type;
    }
    fun void setNext(Chord c[])
    {
        c@=>next;
    }
    fun void setProbabilities(float f[][])
    {
        f@=>probabilities;
    }
    fun Chord getNextChord()
    {
        return getNextChord(0);
    }
    fun Chord getNextChord(int i)
    {
        Std.rand2f(0, 1)=>float rand;
        0=>float c;
        getProbabilities(i)@=>float p[];
        for (0=>int i; i<p.cap();i++)
        {
            p[i]+=>c;
            if (rand<=c)
                return next[i];
        }
        return this;
    }
    fun float[] getProbabilities(int i)
    {
        return probabilities[i];
    }
    fun string toString()
    {
        [["I","i"],
         ["bII","bii"],
         ["II","ii"],
         ["bIII","biii"],
         ["III","iii"],
         ["IV","vi"],
         ["bV","bv"],
         ["V","v"],
         ["bVI","bvi"],
         ["VI","vi"],
         ["bVII","bvii"],
         ["VII","vii"]]@=>string s[][];
        return s[root][type];
    }
    fun int[] getNotesWithin()
    {
        if (type==0)
        {
            return [root,root+4,root+7];
        }
        if (type==1)
        {
            return [root,root+3,root+7];
        }
        if (type==2)
        {
            return [root,root+3,root+6];
        }
        return null;
    }
}

//runing code starts here
OscSend send;
"localhost" => string hostname;
6449 => int port;
send.setHost(hostname,port);
Chord previous;
Chord current;
Chord I;
Chord ii;
Chord iii;
Chord III;
Chord IV;
Chord V;
Chord V7;
Chord vi;
I.init(0,0,[I,ii,III,IV,V,vi],[[0.1,0.1,0.1,0.3,0.3,0.1],[0.1,0.1,0.1,0.1,0.1,0.5]]);
ii.init(2,1,[I,iii,III,V,vi],[[0.1,0.1,0.3,0.4,0.1],[0.1,0.4,0.3,0.1,0.1]]);
iii.init(4,1,[V,IV,vi],[[0.4,0.4,0.2],[0.2,0.3,0.5]]);
III.init(4,0,[IV,vi],[[0.6,0.4],[0.3,0.7]]);
IV.init(5,0,[I,V,III],[[0.3,0.6,0.1],[0.2,0.5,0.3]]);
V.init(7,0,[I,vi,ii,iii],[[0.5,0.2,0.1,0.2],[0.3,0.4,0.1,0.2]]);
vi.init(9,1,[I,ii,iii,IV,V,vi],[[0.1,0.3,0.1,0.3,0.1,0.1],[0.1,0.2,0.2,0.2,0.2,0.1]]);
I @=> current;
Rhodey  instruments[4];
for (0=>int i; i < instruments.cap(); i++)
{
    instruments[i]=>dac;
}
while (true)
{
    <<< "Chord Name: ", current.toString() >>>;
    0=>int key;
    current.root=>int root;
    current.type=>int type;
    key => send.addInt;
    root => send.addInt;
    type => send.addInt;
    <<< "Sent key: ", key, "root: ", root, ", type: ", type >>>;
    current.getNotesWithin()@=>int notes[];
    for (0=>int j;j<4;j++)
    {
        0.7::second=>now;
        for (0=>int i; i < instruments.cap(); i++)
        {
            Std.mtof(48+key+(notes[i%notes.cap()])%12)=>instruments[i].freq;
            if (j==0)
                0.2=>instruments[i].noteOn;
            else if (Math.random2f(0,1)<0.7)
                0.1=>instruments[i].noteOn;
        }
    }
    current.getNextChord(1)@=>Chord temp;
    while (temp==previous)
    {
        current.getNextChord(1)@=>temp;
    }
    current @=> previous;
    temp @=> current;
}

class Chord
{
    0=>static int mode;
    0=>int style;
    Chord @ next[];
    int notes[];
    int root;                         //the root key
    int type;                         //major,minor,etc
    float probabilities[][];              //probability for each next state
    Chord @ modulationSequence[][];
    Chord @ modulationChord[];
    int modulationTarget[];
    fun void init(int root, int type, Chord next[], float probabilities[][])
    {
        setRoot(root);
        setType(type);
        setNext(next);
        setProbabilities(probabilities);
        setNotes();
    }
    fun void setRoot(int i)
    {
        i=>root;
    }
    fun void setType(int i)
    {
        i=>type;
    }
    fun void setNext(Chord c[])
    {
        c@=>next;
    }
    fun void setProbabilities(float f[][])
    {
        f@=>probabilities;
    }
    fun Chord getNextChord()
    {
        return getNextChord(mode);
    }
    fun Chord getNextChord(int i)
    {
        Std.rand2f(0, 1)=>float rand;
        0=>float c;
        getProbabilities(i)@=>float p[];
        for (0=>int i; i<p.cap()-1;i++)
        {
            p[i]+=>c;
            if (rand<=c)
                return next[i];
        }
        return next[next.cap()-1];
    }
    fun float[] getProbabilities(int i)
    {
        return probabilities[i];
    }
    fun string toString()
    {
        [["I","i","Idim","Iaug","Isus4","I7"],
         ["bII","bii"],
         ["II","ii"],
         ["bIII","biii"],
         ["III","iii"],
         ["IV","vi"],
         ["bV","bv"],
         ["V","v","Vdim","Vaug","Vsus4","V7"],
         ["bVI","bvi"],
         ["VI","vi","VIdim","VIaug","VIsus4"],
         ["bVII","bvii"],
         ["VII","vii"]]@=>string s[][];
        return s[root][type];
    }
    fun void setNotes()
    {
        if (type==0)
        {
            [root,root+4,root+7]@=>notes;
        }
        if (type==1)
        {
            [root,root+3,root+7]@=>notes;
        }
        if (type==2)
        {
            [root,root+3,root+6]@=>notes;
        }
        if (type==3)
        {
            [root,root+4,root+8]@=>notes;
        }
        if (type==4)
        {
            [root,root+5,root+7]@=>notes;
        }
        if (type==5)
        {
            [root,root+4,root+7,root+10]@=>notes;
        }

    }
    fun int[] getNotesWithin()
    {
        return notes;
    }
    fun void setModulation(Chord modulation[][], int target[], Chord chord[])
    {
        modulation@=>modulationSequence;
        target@=>modulationTarget;
        chord@=>modulationChord;
    }
    fun Chord[][] getModulationSequence()
    {
        return modulationSequence;
    }
    fun int[] getModulationTarget()
    {
        return modulationTarget;
    }
    fun Chord[] getModulationChord()
    {
        return modulationChord;
    }
}

//runing code starts here
OscSend send;
"localhost" => string hostname;
6449 => int port;
send.setHost(hostname,port);
Chord current;
Chord I;
Chord I7;
Chord ii;
Chord II;
Chord iii;
Chord III;
Chord IV;
Chord V;
Chord V7;
Chord vi;
Chord VI;
Chord Isus4;
Chord VIsus4;
I.init(0,0,[I,ii,III,IV,V,vi],[[0.1,0.1,0.1,0.3,0.3,0.1],[0.1,0.1,0.1,0.1,0.1,0.5]]);
I7.init(0,5,[I7],[[1.0],[1.0]]);
ii.init(2,1,[I,iii,III,V,vi],[[0.1,0.1,0.3,0.4,0.1],[0.1,0.4,0.3,0.1,0.1]]);
II.init(2,0,[II],[[1.0],[1.0]]);
iii.init(4,1,[V,IV,vi],[[0.4,0.4,0.2],[0.2,0.3,0.5]]);
III.init(4,0,[IV,vi],[[0.6,0.4],[0.3,0.7]]);
IV.init(5,0,[I,V,III],[[0.3,0.6,0.1],[0.2,0.5,0.3]]);
V.init(7,0,[I,vi,ii,iii,Isus4,V7],[[0.2,0.2,0.1,0.2,0.1,0.2],[0.2,0.1,0.1,0.2,0.2,0.2]]);
V7.init(7,5,[I,vi],[[0.8,0.2],[0.4,0.6]]);
vi.init(9,1,[I,ii,iii,IV,V,vi],[[0.1,0.3,0.1,0.3,0.1,0.1],[0.1,0.2,0.2,0.2,0.2,0.1]]);
Isus4.init(0,4,[I],[[1.0],[1.0]]);
VIsus4.init(9,4,[vi],[[1.0],[1.0]]);
VI.init(9,0,[VI],[[1.0],[1.0]]);
III.setModulation([[VIsus4,VI]],[-3],[I]);
I.setModulation([[VI,II],[I7,IV]],[2,5],[I,I]);
I @=> current;
Rhodey  instruments[4];
for (0=>int i; i < instruments.cap(); i++)
{
    instruments[i]=>dac;
}
0=>int key;
while (true)
{
    <<< "Chord Name: ", current.toString() >>>;
    current.root=>int root;
    current.type=>int type;
    key => send.addInt;
    root => send.addInt;
    type => send.addInt;
    <<< "Sent key: ", key, "root: ", root, ", type: ", type >>>;
    current.getNotesWithin()@=>int notes[];
    for (0=>int j;j<4;j++)
    {
        0.5::second=>now;
        for (0=>int i; i < instruments.cap(); i++)
        {
            Std.mtof(48+(key+notes[i%notes.cap()])%12)=>instruments[i].freq;
            if (j==0)
                0.2=>instruments[i].noteOn;
            else if (Math.random2f(0,1)<0.7)
                0.1=>instruments[i].noteOn;
        }
    }
    if (current.getModulationTarget()!=null&&Math.random2f(0,1)<0.9)
    {

        current.getModulationSequence()@=>Chord sq[][];
        current.getModulationTarget()@=>int keys[];
        current.getModulationChord()@=>Chord chords[];
        Math.random2f(0,sq.cap())  $ int  =>int choice;
        sq[choice]@=>Chord chordSq[];
        keys[choice]=>int keyChange;
        chords[choice]@=>Chord modChord;
        for (0=>int i; i <chordSq.cap();i++)
        {
            chordSq[i]@=>current;
                <<< "Chord Name: ", current.toString() >>>;
            current.root=>int root;
            current.type=>int type;
            key => send.addInt;
            root => send.addInt;
            type => send.addInt;
            <<< "Sent key: ", key, "root: ", root, ", type: ", type >>>;
            current.getNotesWithin()@=>int notes[];
            for (0=>int j;j<4;j++)
            {
                0.5::second=>now;
                for (0=>int i; i < instruments.cap(); i++)
                {
                    Std.mtof(48+(key+notes[i%notes.cap()])%12)=>instruments[i].freq;
                    if (j==0)
                        0.2=>instruments[i].noteOn;
                    else if (Math.random2f(0,1)<0.7)
                        0.1=>instruments[i].noteOn;
                }
            }
        }
        modChord.getNextChord()@=>current;
        (key+keyChange+12)%12=>key;
    }
    else
    {
        current.getNextChord()@=>current;
    }
}

Update chordProgression

Update chordProgression

modulation added
\>chuck chordProgression
1. send chords out (key/root/type)
2. play chords in Rhodey


// Machine.add("utilities.ck");

/*
    definitions

    fun void repr_int_array(int arr[]){}
    fun void repr_string_array(string arr[]){}

    fun int random_from(int arr[]){}
    fun int inArray(int token, int arr[]){}
    fun int indexOfClosest(int ival, int arr[]){}
    fun int to_note(string str){}
    fun int[] join_int_arrays(int arr1[], int arr2[]){}
    fun int[] set_from(int arr[]){}
    fun int[] randomArray_from(int arr[], int length){}
    fun int[] range(int start, int end){}
    fun int[] narray(int start, int next, int up_to){}
    fun int[] expand_scale(int scale[], int start_stop[]){
    fun int[][] stepify(string sequence_data[]){}

    fun float average(int arr[]){}

    fun string repr(int arr[]){}
    fun string repr(string arr[]){}
    fun string[] split(string arr, string token){}

    fun SndBuf load_sample(string wavname){}

    https://gist.github.com/anonymous/7206152

*/

fun string[] split_str(string str, string token){

    string collect[0];
    int pos;
    int pos2;
    while( str.find(token) >0){
        str.find(token) => pos2;
        collect << str.substring(pos, pos2);
        str.substring(pos2+1) => str;
    }
    collect << str;
    return collect;
}

fun int random_from(int arr[]){
    return arr[Math.random2(0, arr.cap()-1)];
}

fun int[] join_int_arrays(int arr1[], int arr2[]){
    for(0 => int i; i<arr2.cap(); i++){
        arr1 << arr2[i];
    }
    return arr1;
}

fun int[] randomArray_from(int arr[], int length){
    // return new array of capacity length chosing elements from arr
    int generated_arr[0];
    for(0 => int i; i<length; i++){
        generated_arr << random_from(arr); // append element
    }
    return generated_arr;
}

fun int[] range(int start, int end){
    // includes start and end
    int arr[0];
    for(start => int i; i<=end; i++) arr << i;
    return arr;
}

fun int[] narray(int start, int next, int up_to){
    // (start, end..up_to)  (inclusive)
    int arr[0];
    start => int cval;
    next - start => int jump;
    for(cval; cval<=up_to; jump +=> cval){
        arr << cval;
    }
    return arr;  // matey!
}

fun int[] expand_scale(int scale[], int start_stop[]){

    // assumes we start somewhere above 0
    start_stop[0] => int start;
    start_stop[1] => int end;

    int expand_array[0];
    -1 => int last;
    int current;
    for(start => int i; i < end; i++){
        for(0 => int n; n<scale.cap(); n++){
            // avoids doubles, if the incoming scale ends an
            // octave above the first note
            scale[n] + (i*12) => current;
            if (!(current == last)){
                expand_array << current;
                current => last;
            }
        }
    }
    return expand_array;
}

fun string repr(int arr[]){
    /*
    this returns a string representation of an int array,
    useful for debug printing.
    */
    "[" + Std.itoa(arr[0]) => string s;
    for (1 => int i; i < arr.cap(); i++){
        "," + Std.itoa(arr[i]) +=> s;
    }
    return s + "]";
}

fun string repr(string arr[]){

    //this returns a string representation of a string array,
    //useful for debug printing.

    "[" + arr[0] => string s;
    for (1 => int i; i < arr.cap(); i++){
        "," + arr[i] +=> s;
    }
    return s + "]";
}

fun void repr_int_array(int arr[])
{
    arr.cap() => int num_items;
    chout <= "[";
    for(0 => int i; i<num_items; i++){
        if (i>0) chout <= ",";
        chout <= arr[i];
    }
    chout <= "]";
    chout <= IO.newline();
}

fun void repr_string_array(string arr[])
{
    arr.cap() => int num_items;
    chout <= "[";
    for(0 => int i; i<num_items; i++){
        if (i>0) chout <= ",";
        chout <= arr[i];
    }
    chout <= "]";
    chout <= IO.newline();
}

fun int inArray(int token, int arr[]){
    /*
    tests membership of an array
    */
    for(0 => int i; i<arr.cap(); i++){
        if (arr[i]==token) return 1;
    }
    return 0;
}

fun int to_note(string str){
    if (str == "...") return -1;
    if (str == "OFF") return -2;
    if (str == "===") return -3;

    // check if within supported range
    str.substring(2) => Std.atoi => int oct;
    if (oct < 0 || oct > 10) return -4;

    str.substring(0,2) => str;

    [   "C-","C#","D-","D#","E-","F-",
        "F#","G-","G#","A-","A#","B-"
    ] @=> string notes_list[];

    // note must be in this list, else return -3 at the end
    for (0 => int i; i < notes_list.cap(); i++){
        if (str == notes_list[i]){
            return (i + oct * 12);
        }
    }
    return -5;
}

fun int[][] stepify(string sequence_data[]){
    /*
    this function converts a string array to an int array,
    it accepts fuzzy formatting:
    "1..1..1..1.." becomes [1,0,0,1,0,0,1,0,0,1,0,0]
    "1..1.   .1..1.." also becomes [1,0,0,1,0,0,1,0,0,1,0,0]
    */

    sequence_data.cap() => int parts;
    32 => int steps;  // hard code for now
    <<< parts, steps >>>;

    int data_store[parts][steps];
    for(0 => int i; i<sequence_data.cap(); i++){

        sequence_data[i] => string seq_string;
        int part_data[0];
        int trigger;
        //<<< seq_string >>>;
        for(0 => int j; j < seq_string.length(); j++){
            seq_string.substring(j,1) => string token; // crazy

            if (token == " ") continue;
            if (token == ".") 0 => trigger;
            else if (token == "1") 1 => trigger;

            part_data << trigger;
        }
        //<<< repr_int_array(part_data)>>>;
        part_data @=> data_store[i];
    }
    return data_store;
}

fun SndBuf load_sample(string wavname){

    // usage
    // load_sample("kick_02") @=> SndBuf kick => dac;

    // turn incoming wavname into   path/wavename.wav
    // return a reference to a new buffer object.
    SndBuf temp_buff;
    me.dir() + "/audio/" + wavname  + ".wav" => temp_buff.read;

    // set to end, and set gain, then return the object
    temp_buff.samples() => temp_buff.pos;
    0.8 => temp_buff.gain;
    return temp_buff;
}

fun float average(int arr[]){
    int sum;
    arr.cap() => int num_items;
    for(0 => int i; i < num_items; i++){
        arr[i] +=> sum;
    }
    sum $ float => float fsum;
    num_items $ float => float fcap;
    return fsum / fcap;
}

fun int indexOfClosest(int ival, int arr[]){
    // will find the closest value to ival in arr
    // if there are multiple, it will return the first.
    Math.INT_MAX => int min_distance;
    0 => int diff;
    -1 => int idx_tracker;

    for(0 => int i; i<arr.cap(); i++)
    {
        Math.abs(arr[i] - ival) => diff;
        if (diff < min_distance)
        {
            diff => min_distance;
            i => idx_tracker;
        }
    }
    return idx_tracker;

}

fun int[] set_from(int arr[]){
    // no order guaranteed
    // requires  inArray() to be present.
    int new_arr[0];
    new_arr << arr[0];

    for(1 => int i; i<arr.cap(); i++){
        if (inArray(arr[i], new_arr) == 0){
            new_arr << arr[i];
        }
    }
    return new_arr;
}

// Machine.add("utilities.ck");

/*
    definitions

    fun void repr_int_array(int arr[]){}
    fun void repr_string_array(string arr[]){}

    fun int random_from(int arr[]){}
    fun int inArray(int token, int arr[]){}
    fun int indexOfClosest(int ival, int arr[]){}
    fun int to_note(string str){}
    fun int[] join_int_arrays(int arr1[], int arr2[]){}
    fun int[] set_from(int arr[]){}
    fun int[] randomArray_from(int arr[], int length){}
    fun int[] range(int start, int end){}
    fun int[] narray(int start, int next, int up_to){}
    fun int[] expand_scale(int scale[], int start_stop[]){
    fun int[][] stepify(string sequence_data[]){}

    fun float average(int arr[]){}

    fun string repr(int arr[]){}
    fun string repr(string arr[]){}
    fun string[] split(string arr, string token){}

    fun SndBuf load_sample(string wavname){}

    https://gist.github.com/anonymous/7206152

*/

fun string[] split_str(string str, string token){

    string collect[0];
    int pos;
    int pos2;
    while( str.find(token) >0){
        str.find(token) => pos2;
        collect << str.substring(pos, pos2);
        str.substring(pos2+1) => str;
    }
    collect << str;
    return collect;
}

fun int random_from(int arr[]){
    return arr[Math.random2(0, arr.cap()-1)];
}

fun int[] join_int_arrays(int arr1[], int arr2[]){
    [arr1, arr2] @=> int arr[][];
    int new_arr[0];
    for(0 => int j; j<arr.cap(); j++){

        for(0 => int i; i<arr[j].cap(); i++){
            new_arr << arr[j][i];
        }
    }
    return new_arr;
}

fun int[] randomArray_from(int arr[], int length){
    // return new array of capacity length chosing elements from arr
    int generated_arr[0];
    for(0 => int i; i<length; i++){
        generated_arr << random_from(arr); // append element
    }
    return generated_arr;
}

fun int[] range(int start, int end){
    // includes start and end
    int arr[0];
    for(start => int i; i<=end; i++) arr << i;
    return arr;
}

fun int[] narray(int start, int next, int up_to){
    // (start, end..up_to)  (inclusive)
    int arr[0];
    start => int cval;
    next - start => int jump;
    for(cval; cval<=up_to; jump +=> cval){
        arr << cval;
    }
    return arr;  // matey!
}

fun int[] expand_scale(int scale[], int start_stop[]){

    // assumes we start somewhere above 0
    start_stop[0] => int start;
    start_stop[1] => int end;

    int expand_array[0];
    -1 => int last;
    int current;
    for(start => int i; i < end; i++){
        for(0 => int n; n<scale.cap(); n++){
            // avoids doubles, if the incoming scale ends an
            // octave above the first note
            scale[n] + (i*12) => current;
            if (!(current == last)){
                expand_array << current;
                current => last;
            }
        }
    }
    return expand_array;
}

fun string repr(int arr[]){
    /*
    this returns a string representation of an int array,
    useful for debug printing.
    */
    "[" + Std.itoa(arr[0]) => string s;
    for (1 => int i; i < arr.cap(); i++){
        "," + Std.itoa(arr[i]) +=> s;
    }
    return s + "]";
}

fun string repr(string arr[]){

    //this returns a string representation of a string array,
    //useful for debug printing.

    "[" + arr[0] => string s;
    for (1 => int i; i < arr.cap(); i++){
        "," + arr[i] +=> s;
    }
    return s + "]";
}

fun void repr_int_array(int arr[])
{
    arr.cap() => int num_items;
    chout <= "[";
    for(0 => int i; i<num_items; i++){
        if (i>0) chout <= ",";
        chout <= arr[i];
    }
    chout <= "]";
    chout <= IO.newline();
}

fun void repr_string_array(string arr[])
{
    arr.cap() => int num_items;
    chout <= "[";
    for(0 => int i; i<num_items; i++){
        if (i>0) chout <= ",";
        chout <= arr[i];
    }
    chout <= "]";
    chout <= IO.newline();
}

fun int inArray(int token, int arr[]){
    /*
    tests membership of an array
    */
    for(0 => int i; i<arr.cap(); i++){
        if (arr[i]==token) return 1;
    }
    return 0;
}

fun int to_note(string str){
    if (str == "...") return -1;
    if (str == "OFF") return -2;
    if (str == "===") return -3;

    // check if within supported range
    str.substring(2) => Std.atoi => int oct;
    if (oct < 0 || oct > 10) return -4;

    str.substring(0,2) => str;

    [   "C-","C#","D-","D#","E-","F-",
        "F#","G-","G#","A-","A#","B-"
    ] @=> string notes_list[];

    // note must be in this list, else return -3 at the end
    for (0 => int i; i < notes_list.cap(); i++){
        if (str == notes_list[i]){
            return (i + oct * 12);
        }
    }
    return -5;
}

fun int[][] stepify(string sequence_data[]){
    /*
    this function converts a string array to an int array,
    it accepts fuzzy formatting:
    "1..1..1..1.." becomes [1,0,0,1,0,0,1,0,0,1,0,0]
    "1..1.   .1..1.." also becomes [1,0,0,1,0,0,1,0,0,1,0,0]
    */

    sequence_data.cap() => int parts;
    32 => int steps;  // hard code for now
    <<< parts, steps >>>;

    int data_store[parts][steps];
    for(0 => int i; i<sequence_data.cap(); i++){

        sequence_data[i] => string seq_string;
        int part_data[0];
        int trigger;
        //<<< seq_string >>>;
        for(0 => int j; j < seq_string.length(); j++){
            seq_string.substring(j,1) => string token; // crazy

            if (token == " ") continue;
            if (token == ".") 0 => trigger;
            else if (token == "1") 1 => trigger;

            part_data << trigger;
        }
        //<<< repr_int_array(part_data)>>>;
        part_data @=> data_store[i];
    }
    return data_store;
}

fun SndBuf load_sample(string wavname){

    // usage
    // load_sample("kick_02") @=> SndBuf kick => dac;

    // turn incoming wavname into   path/wavename.wav
    // return a reference to a new buffer object.
    SndBuf temp_buff;
    me.dir() + "/audio/" + wavname  + ".wav" => temp_buff.read;

    // set to end, and set gain, then return the object
    temp_buff.samples() => temp_buff.pos;
    0.8 => temp_buff.gain;
    return temp_buff;
}

fun float average(int arr[]){
    int sum;
    arr.cap() => int num_items;
    for(0 => int i; i < num_items; i++){
        arr[i] +=> sum;
    }
    sum $ float => float fsum;
    num_items $ float => float fcap;
    return fsum / fcap;
}

fun int indexOfClosest(int ival, int arr[]){
    // will find the closest value to ival in arr
    // if there are multiple, it will return the first.
    Math.INT_MAX => int min_distance;
    0 => int diff;
    -1 => int idx_tracker;

    for(0 => int i; i<arr.cap(); i++)
    {
        Math.abs(arr[i] - ival) => diff;
        if (diff < min_distance)
        {
            diff => min_distance;
            i => idx_tracker;
        }
    }
    return idx_tracker;

}

fun int[] set_from(int arr[]){
    // no order guaranteed
    // requires  inArray() to be present.
    int new_arr[0];
    new_arr << arr[0];

    for(1 => int i; i<arr.cap(); i++){
        if (inArray(arr[i], new_arr) == 0){
            new_arr << arr[i];
        }
    }
    return new_arr;
}

Update common_functions.ck

Update common_functions.ck

haha, changing array references tripped me up.


// Machine.add("utilities.ck");

/*
    definitions

    fun void repr_int_array(int arr[]){}
    fun void repr_int_array(string arr[]){}

    fun int random_from(int arr[]){}
    fun int inArray(int token, int arr[]){}
    fun int indexOfClosest(int ival, int arr[]){}
    fun int to_note(string str){}
    fun int[] randomArray_from(int arr[], int length){}
    fun int[] range(int start, int end){}
    fun int[] narray(int start, int next, int up_to){}
    fun int[][] stepify(string sequence_data[]){}

    fun float average(int arr[]){}

    fun string repr(int arr[]){}
    fun string repr(string arr[]){}
    fun string[] split(string arr, string token){}

    fun SndBuf load_sample(string wavname){}

    https://gist.github.com/anonymous/7206152

*/

fun string[] split_str(string str, string token){

    string collect[0];
    int pos;
    int pos2;
    while( str.find(token) >0){
        str.find(token) => pos2;
        collect << str.substring(pos, pos2);
        str.substring(pos2+1) => str;
    }
    collect << str;
    return collect;
}

fun int random_from(int arr[]){
    return arr[Math.random2(0, arr.cap()-1)];
}

fun int[] randomArray_from(int arr[], int length){
    // return new array of capacity length chosing elements from arr
    int generated_arr[0];
    for(0 => int i; i<length; i++){
        generated_arr << random_from(arr); // append element
    }
    return generated_arr;
}

fun int[] range(int start, int end){
    // includes start and end
    int arr[0];
    for(start => int i; i<=end; i++) arr << i;
    return arr;
}

fun int[] narray(int start, int next, int up_to){
    // (start, end..up_to)  (inclusive)
    int arr[0];
    start => int cval;
    next - start => int jump;
    for(cval; cval<=up_to; jump +=> cval){
        arr << cval;
    }
    return arr;  // matey!
}

fun string repr(int arr[]){
    /*
    this returns a string representation of an int array,
    useful for debug printing.
    */
    "[" + Std.itoa(arr[0]) => string s;
    for (1 => int i; i < arr.cap(); i++){
        "," + Std.itoa(arr[i]) +=> s;
    }
    return s + "]";
}

fun string repr(string arr[]){

    //this returns a string representation of a string array,
    //useful for debug printing.

    "[" + arr[0] => string s;
    for (1 => int i; i < arr.cap(); i++){
        "," + arr[i] +=> s;
    }
    return s + "]";
}

fun void repr_int_array(int arr[])
{
    arr.cap() => int num_items;
    chout <= "[";
    for(0 => int i; i<num_items; i++){
        if (i>0) chout <= ",";
        chout <= arr[i];
    }
    chout <= "]";
    chout <= IO.newline();
}

fun void repr_int_array(string arr[])
{
    arr.cap() => int num_items;
    chout <= "[";
    for(0 => int i; i<num_items; i++){
        if (i>0) chout <= ",";
        chout <= arr[i];
    }
    chout <= "]";
    chout <= IO.newline();
}

fun int inArray(int token, int arr[]){
    /*
    tests membership of an array
    */
    for(0 => int i; i<arr.cap(); i++){
        if (arr[i]==token) return 1;
    }
    return 0;
}

fun int to_note(string str){
    if (str == "...") return -1;
    if (str == "OFF") return -2;
    if (str == "===") return -3;

    // check if within supported range
    str.substring(2) => Std.atoi => int oct;
    if (oct < 0 || oct > 10) return -4;

    str.substring(0,2) => str;

    [   "C-","C#","D-","D#","E-","F-",
        "F#","G-","G#","A-","A#","B-"
    ] @=> string notes_list[];

    // note must be in this list, else return -3 at the end
    for (0 => int i; i < notes_list.cap(); i++){
        if (str == notes_list[i]){
            return (i + oct * 12);
        }
    }
    return -5;
}

fun int[][] stepify(string sequence_data[]){
    /*
    this function converts a string array to an int array,
    it accepts fuzzy formatting:
    "1..1..1..1.." becomes [1,0,0,1,0,0,1,0,0,1,0,0]
    "1..1.   .1..1.." also becomes [1,0,0,1,0,0,1,0,0,1,0,0]
    */

    sequence_data.cap() => int parts;
    32 => int steps;  // hard code for now
    <<< parts, steps >>>;

    int data_store[parts][steps];
    for(0 => int i; i<sequence_data.cap(); i++){

        sequence_data[i] => string seq_string;
        int part_data[0];
        int trigger;
        //<<< seq_string >>>;
        for(0 => int j; j < seq_string.length(); j++){
            seq_string.substring(j,1) => string token; // crazy

            if (token == " ") continue;
            if (token == ".") 0 => trigger;
            else if (token == "1") 1 => trigger;

            part_data << trigger;
        }
        //<<< repr_int_array(part_data)>>>;
        part_data @=> data_store[i];
    }
    return data_store;
}

fun SndBuf load_sample(string wavname){

    // usage
    // load_sample("kick_02") @=> SndBuf kick => dac;

    // turn incoming wavname into   path/wavename.wav
    // return a reference to a new buffer object.
    SndBuf temp_buff;
    me.dir() + "/audio/" + wavname  + ".wav" => temp_buff.read;

    // set to end, and set gain, then return the object
    temp_buff.samples() => temp_buff.pos;
    0.8 => temp_buff.gain;
    return temp_buff;
}

fun float average(int arr[]){
    int sum;
    arr.cap() => int num_items;
    for(0 => int i; i < num_items; i++){
        arr[i] +=> sum;
    }
    sum $ float => float fsum;
    num_items $ float => float fcap;
    return fsum / fcap;
}

fun int indexOfClosest(int ival, int arr[]){
    // will find the closest value to ival in arr
    // if there are multiple, it will return the first.
    Math.INT_MAX => int min_distance;
    0 => int diff;
    -1 => int idx_tracker;

    for(0 => int i; i<arr.cap(); i++)
    {
        Math.abs(arr[i] - ival) => diff;
        if (diff < min_distance)
        {
            diff => min_distance;
            i => idx_tracker;
        }
    }
    return idx_tracker;

}

// Machine.add("utilities.ck");

/*
    definitions

    fun void repr_int_array(int arr[]){}
    fun void repr_int_array(string arr[]){}

    fun int random_from(int arr[]){}
    fun int inArray(int token, int arr[]){}
    fun int indexOfClosest(int ival, int arr[]){}
    fun int to_note(string str){}
    fun int[] randomArray_from(int arr[], int length){}
    fun int[] range(int start, int end){}
    fun int[] narray(int start, int next, int up_to){}
    fun int[] expand_scale(int scale[], int start_stop[]){
    fun int[][] stepify(string sequence_data[]){}

    fun float average(int arr[]){}

    fun string repr(int arr[]){}
    fun string repr(string arr[]){}
    fun string[] split(string arr, string token){}

    fun SndBuf load_sample(string wavname){}

    https://gist.github.com/anonymous/7206152

*/

fun string[] split_str(string str, string token){

    string collect[0];
    int pos;
    int pos2;
    while( str.find(token) >0){
        str.find(token) => pos2;
        collect << str.substring(pos, pos2);
        str.substring(pos2+1) => str;
    }
    collect << str;
    return collect;
}

fun int random_from(int arr[]){
    return arr[Math.random2(0, arr.cap()-1)];
}

fun int[] randomArray_from(int arr[], int length){
    // return new array of capacity length chosing elements from arr
    int generated_arr[0];
    for(0 => int i; i<length; i++){
        generated_arr << random_from(arr); // append element
    }
    return generated_arr;
}

fun int[] range(int start, int end){
    // includes start and end
    int arr[0];
    for(start => int i; i<=end; i++) arr << i;
    return arr;
}

fun int[] narray(int start, int next, int up_to){
    // (start, end..up_to)  (inclusive)
    int arr[0];
    start => int cval;
    next - start => int jump;
    for(cval; cval<=up_to; jump +=> cval){
        arr << cval;
    }
    return arr;  // matey!
}

fun int[] expand_scale(int scale[], int start_stop[]){

    // assumes we start somewhere above 0
    start_stop[0] => int start;
    start_stop[1] => int end;

    int expand_array[0];
    -1 => int last;
    int current;
    for(start => int i; i < end; i++){
        for(0 => int n; n<scale.cap(); n++){
            // avoids doubles, if the incoming scale ends an
            // octave above the first note
            scale[n] + (i*12) => current;
            if (!(current == last)){
                expand_array << current;
                current => last;
            }
        }
    }
    return expand_array;
}

fun string repr(int arr[]){
    /*
    this returns a string representation of an int array,
    useful for debug printing.
    */
    "[" + Std.itoa(arr[0]) => string s;
    for (1 => int i; i < arr.cap(); i++){
        "," + Std.itoa(arr[i]) +=> s;
    }
    return s + "]";
}

fun string repr(string arr[]){

    //this returns a string representation of a string array,
    //useful for debug printing.

    "[" + arr[0] => string s;
    for (1 => int i; i < arr.cap(); i++){
        "," + arr[i] +=> s;
    }
    return s + "]";
}

fun void repr_int_array(int arr[])
{
    arr.cap() => int num_items;
    chout <= "[";
    for(0 => int i; i<num_items; i++){
        if (i>0) chout <= ",";
        chout <= arr[i];
    }
    chout <= "]";
    chout <= IO.newline();
}

fun void repr_int_array(string arr[])
{
    arr.cap() => int num_items;
    chout <= "[";
    for(0 => int i; i<num_items; i++){
        if (i>0) chout <= ",";
        chout <= arr[i];
    }
    chout <= "]";
    chout <= IO.newline();
}

fun int inArray(int token, int arr[]){
    /*
    tests membership of an array
    */
    for(0 => int i; i<arr.cap(); i++){
        if (arr[i]==token) return 1;
    }
    return 0;
}

fun int to_note(string str){
    if (str == "...") return -1;
    if (str == "OFF") return -2;
    if (str == "===") return -3;

    // check if within supported range
    str.substring(2) => Std.atoi => int oct;
    if (oct < 0 || oct > 10) return -4;

    str.substring(0,2) => str;

    [   "C-","C#","D-","D#","E-","F-",
        "F#","G-","G#","A-","A#","B-"
    ] @=> string notes_list[];

    // note must be in this list, else return -3 at the end
    for (0 => int i; i < notes_list.cap(); i++){
        if (str == notes_list[i]){
            return (i + oct * 12);
        }
    }
    return -5;
}

fun int[][] stepify(string sequence_data[]){
    /*
    this function converts a string array to an int array,
    it accepts fuzzy formatting:
    "1..1..1..1.." becomes [1,0,0,1,0,0,1,0,0,1,0,0]
    "1..1.   .1..1.." also becomes [1,0,0,1,0,0,1,0,0,1,0,0]
    */

    sequence_data.cap() => int parts;
    32 => int steps;  // hard code for now
    <<< parts, steps >>>;

    int data_store[parts][steps];
    for(0 => int i; i<sequence_data.cap(); i++){

        sequence_data[i] => string seq_string;
        int part_data[0];
        int trigger;
        //<<< seq_string >>>;
        for(0 => int j; j < seq_string.length(); j++){
            seq_string.substring(j,1) => string token; // crazy

            if (token == " ") continue;
            if (token == ".") 0 => trigger;
            else if (token == "1") 1 => trigger;

            part_data << trigger;
        }
        //<<< repr_int_array(part_data)>>>;
        part_data @=> data_store[i];
    }
    return data_store;
}

fun SndBuf load_sample(string wavname){

    // usage
    // load_sample("kick_02") @=> SndBuf kick => dac;

    // turn incoming wavname into   path/wavename.wav
    // return a reference to a new buffer object.
    SndBuf temp_buff;
    me.dir() + "/audio/" + wavname  + ".wav" => temp_buff.read;

    // set to end, and set gain, then return the object
    temp_buff.samples() => temp_buff.pos;
    0.8 => temp_buff.gain;
    return temp_buff;
}

fun float average(int arr[]){
    int sum;
    arr.cap() => int num_items;
    for(0 => int i; i < num_items; i++){
        arr[i] +=> sum;
    }
    sum $ float => float fsum;
    num_items $ float => float fcap;
    return fsum / fcap;
}

fun int indexOfClosest(int ival, int arr[]){
    // will find the closest value to ival in arr
    // if there are multiple, it will return the first.
    Math.INT_MAX => int min_distance;
    0 => int diff;
    -1 => int idx_tracker;

    for(0 => int i; i<arr.cap(); i++)
    {
        Math.abs(arr[i] - ival) => diff;
        if (diff < min_distance)
        {
            diff => min_distance;
            i => idx_tracker;
        }
    }
    return idx_tracker;

}

Update common_functions.ck

Update common_functions.ck


// Assignment 7 drumCircleDSP

public class KickSynC{

    Gain bdmaster2 => dac;
    bdmaster2.gain(0.02);

    fun void trigger(float volume){
        /* this makes it possible to trigger
        the bassdrum in a new thread */
        spork ~ s_do_kick(volume);
    }

    fun void s_do_kick(float volume){

        3850 => float frequency;

        SinOsc bd_osc =>
        Gain preAmp => HPF bf => ADSR volEnv =>
        PoleZero dc => LPF highs => bdmaster2;

        dc.blockZero(0.99);
        bf.freq(50);
        bf.Q(4.1);
        highs.freq(332);

        volEnv.set( 1::ms, 181::ms, 0.3, 35::ms );
        bdmaster2.gain(volume);

        1 => int fa;
        44 => int fd;
        50 => int fs;
        120 => int fr;

        44100/frequency => float grain;

        Step s5 => ADSR pitchEnv => blackhole;
        pitchEnv.set(fa::ms, (fd/1.2)::ms, fs/100, fr::ms);
        pitchEnv.keyOn(1);
        volEnv.keyOn(1);
        (140)::ms + now => time later;
        while(now < later)
        {
            850 => int min_freq;
            51 => int bass_freq;
            ((pitchEnv.last()*220) + min_freq) $ int => int pitch_curve;
            Math.max(pitch_curve, bass_freq) - 800.0 => float debug_freq => bd_osc.freq;

            grain::samp => now;

            if( now > later){
                (120)::ms => now;
                volEnv.keyOff(1);
                pitchEnv.keyOff(1);
            }
        }

        1.5::second => now;
        bd_osc =< preAmp;

    }

}

KickSynC kick1;

kick1.trigger(0.5);

1::second => now;

// Assignment 7 drumCircleDSP
public class KickSynC{

    0.0 => float mgain;
    Gain bdmast;
    bdmast.gain(mgain);

    fun void trigger(float volume){
        this.bdmast.gain(volume);
        spork ~ s_do_kick();
    }

    fun void s_do_kick(){

        CurveTable c;
        [0., 310, -.98,  1.0,50,-.6, 11.0, 1.] => c.coefs;

        // frequency curve
        ADSR e => blackhole;
        e.set( 0::ms, 621::ms, 0.0, 135::ms );  //a, d, s, r
        e.keyOn(1);

        // simple adsr
        ADSR volE;
        volE.set( 0::ms, 181::ms, 0.0, 65::ms );  //a, d, s, r
        volE.keyOn();

        // routing.
        c => blackhole;
        SinOsc form => volE => LPF boom => PoleZero dc => bdmast;
        dc.blockZero(0.992);
        70 => boom.freq;

        // set

        now => time start;
        // ready
        while (true)
        {
            c.lookup(1/e.value()) $ int => form.freq;
            boom.Q(1.3);
            41::samp => now;

            // advance time
            if (now > (start + 170::ms)){
                e.keyOff();
                volE.keyOff();
                break;
            }
        }

        1::second => now;
    }

}

KickSynC kick1;

kick1.bdmast => dac;
kick1.trigger(1.3);

1::second => now;

Update bassdrum_electronic_deepboom.ck

Update bassdrum_electronic_deepboom.ck