changed midi ccs to osc.

changed midi ccs to osc.

OscRecv           wm;
Launchpad         lp;
OscBank oscBank;

false    =>   int prompt;
50::samp =>   dur gainResolution;
0.0016   => float releaseDecay;
0.00001   => float sustainDecay;
0.00001   => float sostenutoDecay;
0.01     => float pressAttack;
0.80     => float maxNoteGain;
0.0      =>   float rawGain;
0        =>   int currentTone;
false    =>   int sustain;
              int sustainStatus[8][8];
false    =>   int sostenuto;
              int sostenutoStatus[8][8];
0        =>   int lpChannel;

LaunchpadColor.red => int keyOnColor;
LaunchpadColor.lightRed => int keySustainColor;
LaunchpadColor.lightRed => int keySostenutoColor;
LaunchpadColor.red => int toneChoiceColor;
// ToneCalc.grid(8, 8, 1, 5,  82.4068867, 12.0) @=> float toneMap[][];
ToneCalc.grid(8, 8, 1, 5, 55.0, 12.0) @=> float toneMap[][];

fun void setup()
{
    OscBank.OscBank(8, 8, 1, 5, 55.0, 12.0) @=> oscBank;

    if(prompt)
    {
        intPrompt("Enter Midi Channel for Launchpad input: ") => lpChannel;

        Launchpad.Launchpad(lpChannel) @=> lp;
    }
    else
    {
        Launchpad.Launchpad(0) @=> lp;
    }

    me.yield();
    lp.clear();
    lp.setGridLight(8, currentTone, toneChoiceColor);

    spork ~ launchpadListener();
    spork ~ wiiListener();
    spork ~ updateGains();
}

fun void setTone(int toneChoice)
{
    if(toneChoice == currentTone)
    {
        return;
    }

    if(toneChoice == 0)
    {
        oscBank.setPatch("SinOsc");
    }
    else if(toneChoice == 1)
    {
        oscBank.setPatch("SqrOsc");
    }
    else if(toneChoice == 2)
    {
        oscBank.setPatch("SawOsc");
    }
    else if(toneChoice == 3)
    {
        oscBank.setPatch("TriOsc");
    }
    else
    {
        return;
    }

    lp.setGridLight(8, currentTone, 0);
    lp.setGridLight(8, toneChoice, toneChoiceColor);
    toneChoice => currentTone;
}

fun void sostenutoOn()
{
    true => sostenuto;
    for(0 => int i; i < 8; i++)
    {
        for(0 => int j; j < 8; j++)
        {
            if(lp.keyDown[i][j])
            {
                true => sostenutoStatus[i][j];
            }
        }
    }
}

fun void sostenutoOff()
{
    false => sostenuto;
    for(0 => int i; i < 8; i++)
    {
        for(0 => int j; j < 8; j++)
        {
            false => sostenutoStatus[i][j];
            if(!lp.keyDown[i][j])
            {
                lp.setGridLight(i, j, 0);
            }
        }
    }
}

fun void sustainOn()
{
    true => sustain;
    for(0 => int i; i < 8; i++)
    {
        for(0 => int j; j < 8; j++)
        {
            if(lp.keyDown[i][j])
            {
                true => sustainStatus[i][j];
            }
        }
    }
}

fun void sustainOff()
{
    false => sustain;
    for(0 => int i; i < 8; i++)
    {
        for(0 => int j; j < 8; j++)
        {
            false => sustainStatus[i][j];
            if(!lp.keyDown[i][j])
            {
                lp.setGridLight(i, j, 0);
            }
        }
    }
}

fun void release(int column, int row)
{
    Math.max(oscBank.gains[column][row].gain() - releaseDecay, 0.00)
        => oscBank.gains[column][row].gain;
}

fun void updateSustain(int column, int row, float targetGain)
{
    if(sustain && sustainStatus[column][row])
    {
        Math.max(oscBank.gains[column][row].gain() - sustainDecay, 0.00)
            => oscBank.gains[column][row].gain;
    }
    else
    {
        release(column, row);
    }
}

fun void updateSostenuto(int column, int row, float targetGain)
{
    if(sostenuto && sostenutoStatus[column][row])
    {
        Math.max(oscBank.gains[column][row].gain() - sostenutoDecay, 0.00)
            => oscBank.gains[column][row].gain;
    }
    else
    {
        updateSustain(column, row, targetGain);
    }
}

fun void update(int column, int row, float targetGain)
{
    if(lp.keyDown[column][row] && targetGain > oscBank.gains[column][row].gain())
    {
        Math.min(oscBank.gains[column][row].gain() + pressAttack, maxNoteGain)
            => oscBank.gains[column][row].gain;
    }
    else
    {
        updateSostenuto(column, row, targetGain);
    }
}

fun void updateGains()
{
    float targetGain;
    while(true) {
        // Math.max(0.0, (rawGain - 32) / 95.0) => targetGain;
        rawGain => targetGain;

        for(0 => int i; i < 8; i++)
        {
            for(0 => int j; j < 8; j++)
            {
                update(i, j, targetGain);
            }
        }

        gainResolution => now;
    }
}

fun int intPrompt(string msg)
{
    int in;
    ConsoleInput cin;
    StringTokenizer tok;
    cin.prompt(msg) => now;
    while(cin.more())
    {
        tok.set(cin.getLine());
        while(tok.more())
        {
            Std.atoi(tok.next()) => in;
        }
    }
    return in;
}

fun void launchpadListener()
{
    while(true)
    {
        lp.e => now;

        // ignore button presses that are not on the grid
        if(lp.e.column < 0 || lp.e.column > 8) continue;
        if(lp.e.row < 0 || lp.e.row > 7) continue;

        if(lp.e.column == 8)
        {
            if(lp.e.velocity == 127)
            {
                setTone(lp.e.row);
            }
        }
        else if(lp.e.velocity == 127)
        {
            if(sustain)
            {
                true => sustainStatus[lp.e.column][lp.e.row];
            }
            lp.setGridLight(lp.e.column, lp.e.row, keyOnColor);
            1 => oscBank.bank[lp.e.column][lp.e.row].op;
        }
        else if(sostenuto && sostenutoStatus[lp.e.column][lp.e.row])
        {
            lp.setGridLight(lp.e.column, lp.e.row, keySostenutoColor);
        }
        else if(sustain && sustainStatus[lp.e.column][lp.e.row])
        {
            lp.setGridLight(lp.e.column, lp.e.row, keySustainColor);
        }
        else
        {
            lp.setGridLight(lp.e.column, lp.e.row, 0);
        }
    }
}

// fun void wiiParser(MidiMsg msg)
// {
//     if(msg.data1 == 176) // midi CC
//     {
//         if(msg.data2 == 64)
//         { // wiimote acceleration
//             msg.data3 => rawGain;
//         }
//         else if (msg.data2 == 65)
//         {   // wiimote button b
//             if(msg.data3 == 127)
//             {
//                 sustainOn();
//             }
//             else
//             {
//                 sustainOff();
//             }
//         }
//         else if (msg.data2 == 66)
//         {   // wiimote button a
//             if(msg.data3 == 127)
//             {
//                 sostenutoOn();
//             }
//             else
//             {
//                 sostenutoOff();
//             }
//         }
//     }
// }

fun void sustainListener()
{
    wm.event("/wii/1/button/B,i") @=> OscEvent e;
    while(true)
    {
        e => now;
        while(e.nextMsg() != 0)
        {
            if(e.getInt() == 0)
            {
                sustainOff();
            }
            else
            {
                sustainOn();
            }
        }
    }
}

fun void sostenutoListener()
{
    wm.event("/wii/1/button/A,i") @=> OscEvent e;
    while(true)
    {
        e => now;
        while(e.nextMsg() != 0)
        {
            if(e.getInt() == 0)
            {
                sostenutoOff();
            }
            else
            {
                sostenutoOn();
            }
        }
    }
}

fun void accelListener()
{
    wm.event("/wii/1/accel/pry/3,f") @=> OscEvent e;
    while(true)
    {
        e => now;
        while(e.nextMsg() != 0)
        {
            e.getFloat() => rawGain;
        }
    }
}

fun void wiiListener()
{
    6449 => wm.port;
    wm.listen();
    spork ~ sustainListener();
    spork ~ sostenutoListener();
    spork ~ accelListener();
    while(true)
    {
        1::second => now;
    }
}

setup();

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

MidiIn            wm;
Launchpad         lp;
OscBank oscBank;

false    =>   int prompt;
50::samp =>   dur gainResolution;
0.0016   => float releaseDecay;
0.00001   => float sustainDecay;
0.00001   => float sostenutoDecay;
0.01     => float pressAttack;
0.80     => float maxNoteGain;
0        =>   int rawGain;
0        =>   int currentTone;
false    =>   int sustain;
              int sustainStatus[8][8];
false    =>   int sostenuto;
              int sostenutoStatus[8][8];
0        =>   int lpChannel;
1        =>   int wiimoteChannel;

LaunchpadColor.red => int keyOnColor;
LaunchpadColor.lightRed => int keySustainColor;
LaunchpadColor.lightRed => int keySostenutoColor;
LaunchpadColor.red => int toneChoiceColor;
// ToneCalc.grid(8, 8, 1, 5,  82.4068867, 12.0) @=> float toneMap[][];
ToneCalc.grid(8, 8, 1, 5, 55.0, 12.0) @=> float toneMap[][];

fun void setup()
{
    OscBank.OscBank(8, 8, 1, 5, 55.0, 12.0) @=> oscBank;

    if(prompt)
    {
        intPrompt("Enter Midi Channel for Launchpad input: ") => lpChannel;
        intPrompt("Enter Midi Channel for Wiimote input: ") => wiimoteChannel;

        Launchpad.Launchpad(lpChannel) @=> lp;
        connectWiimote(wiimoteChannel);
    }
    else
    {
        Launchpad.Launchpad(0) @=> lp;
        connectWiimote(1);
    }

    me.yield();
    lp.clear();
    lp.setGridLight(8, currentTone, toneChoiceColor);

    spork ~ launchpadListener();
    spork ~ wiiListener();
    spork ~ updateGains();
}

fun void setTone(int toneChoice)
{
    if(toneChoice == currentTone)
    {
        return;
    }

    if(toneChoice == 0)
    {
        oscBank.setPatch("SinOsc");
    }
    else if(toneChoice == 1)
    {
        oscBank.setPatch("SqrOsc");
    }
    else if(toneChoice == 2)
    {
        oscBank.setPatch("SawOsc");
    }
    else if(toneChoice == 3)
    {
        oscBank.setPatch("TriOsc");
    }
    else
    {
        return;
    }

    lp.setGridLight(8, currentTone, 0);
    lp.setGridLight(8, toneChoice, toneChoiceColor);
    toneChoice => currentTone;
}

fun void sostenutoOn()
{
    true => sostenuto;
    for(0 => int i; i < 8; i++)
    {
        for(0 => int j; j < 8; j++)
        {
            if(lp.keyDown[i][j])
            {
                true => sostenutoStatus[i][j];
            }
        }
    }
}

fun void sostenutoOff()
{
    false => sostenuto;
    for(0 => int i; i < 8; i++)
    {
        for(0 => int j; j < 8; j++)
        {
            false => sostenutoStatus[i][j];
            if(!lp.keyDown[i][j])
            {
                lp.setGridLight(i, j, 0);
            }
        }
    }
}

fun void sustainOn()
{
    true => sustain;
    for(0 => int i; i < 8; i++)
    {
        for(0 => int j; j < 8; j++)
        {
            if(lp.keyDown[i][j])
            {
                true => sustainStatus[i][j];
            }
        }
    }
}

fun void sustainOff()
{
    false => sustain;
    for(0 => int i; i < 8; i++)
    {
        for(0 => int j; j < 8; j++)
        {
            false => sustainStatus[i][j];
            if(!lp.keyDown[i][j])
            {
                lp.setGridLight(i, j, 0);
            }
        }
    }
}

fun void release(int column, int row)
{
    Math.max(oscBank.gains[column][row].gain() - releaseDecay, 0.00)
        => oscBank.gains[column][row].gain;
}

fun void updateSustain(int column, int row, float targetGain)
{
    if(sustain && sustainStatus[column][row])
    {
        Math.max(oscBank.gains[column][row].gain() - sustainDecay, 0.00)
            => oscBank.gains[column][row].gain;
    }
    else
    {
        release(column, row);
    }
}

fun void updateSostenuto(int column, int row, float targetGain)
{
    if(sostenuto && sostenutoStatus[column][row])
    {
        Math.max(oscBank.gains[column][row].gain() - sostenutoDecay, 0.00)
            => oscBank.gains[column][row].gain;
    }
    else
    {
        updateSustain(column, row, targetGain);
    }
}

fun void update(int column, int row, float targetGain)
{
    if(lp.keyDown[column][row] && targetGain > oscBank.gains[column][row].gain())
    {
        Math.min(oscBank.gains[column][row].gain() + pressAttack, maxNoteGain)
            => oscBank.gains[column][row].gain;
    }
    else
    {
        updateSostenuto(column, row, targetGain);
    }
}

fun void updateGains()
{
    float targetGain;
    while(true) {
        Math.max(0.0, (rawGain - 32) / 95.0) => targetGain;

        for(0 => int i; i < 8; i++)
        {
            for(0 => int j; j < 8; j++)
            {
                update(i, j, targetGain);
            }
        }

        gainResolution => now;
    }
}

fun int intPrompt(string msg)
{
    int in;
    ConsoleInput cin;
    StringTokenizer tok;
    cin.prompt(msg) => now;
    while(cin.more())
    {
        tok.set(cin.getLine());
        while(tok.more())
        {
            Std.atoi(tok.next()) => in;
        }
    }
    return in;
}

fun void launchpadListener()
{
    while(true)
    {
        lp.e => now;

        // ignore button presses that are not on the grid
        if(lp.e.column < 0 || lp.e.column > 8) continue;
        if(lp.e.row < 0 || lp.e.row > 7) continue;

        if(lp.e.column == 8)
        {
            if(lp.e.velocity == 127)
            {
                setTone(lp.e.row);
            }
        }
        else if(lp.e.velocity == 127)
        {
            if(sustain)
            {
                true => sustainStatus[lp.e.column][lp.e.row];
            }
            lp.setGridLight(lp.e.column, lp.e.row, keyOnColor);
            1 => oscBank.bank[lp.e.column][lp.e.row].op;
        }
        else if(sostenuto && sostenutoStatus[lp.e.column][lp.e.row])
        {
            lp.setGridLight(lp.e.column, lp.e.row, keySostenutoColor);
        }
        else if(sustain && sustainStatus[lp.e.column][lp.e.row])
        {
            lp.setGridLight(lp.e.column, lp.e.row, keySustainColor);
        }
        else
        {
            lp.setGridLight(lp.e.column, lp.e.row, 0);
        }
    }
}

fun void wiiParser(MidiMsg msg)
{
    if(msg.data1 == 176) // midi CC
    {
        if(msg.data2 == 64)
        { // wiimote acceleration
            msg.data3 => rawGain;
        }
        else if (msg.data2 == 65)
        {   // wiimote button b
            if(msg.data3 == 127)
            {
                sustainOn();
            }
            else
            {
                sustainOff();
            }
        }
        else if (msg.data2 == 66)
        {   // wiimote button a
            if(msg.data3 == 127)
            {
                sostenutoOn();
            }
            else
            {
                sostenutoOff();
            }
        }
    }
}

fun void connectWiimote(int midiChannel)
{
    if(!wm.open(midiChannel)) me.exit();

    chout <= "Midi device: " <= midiChannel <= " -> " <= wm.name()
        <= IO.newline();
}

fun void wiiListener()
{
    MidiMsg msg;
    while(true)
    {
        wm => now;
        while(wm.recv(msg))
        {
            wiiParser(msg);
        }
    }
}

setup();

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


Update bassdrum_electronic_deepboom.ck

Update bassdrum_electronic_deepboom.ck

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;

// 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;


starting to phatten out

starting to phatten out

lead synth just found cheesecake.


more complicated test case for if

more complicated test case for if


recording put into the file

recording put into the file

/*
Data on Acid hack

Iain Emsley

SSI hack March 2015

*/

//SawOsc s => dac;
Flute flute => PoleZero f => JCRev r => dac;
.95 => r.gain;
.05 => r.mix;
.99 => f.blockZero;

.2 => float timeSt;
//recording
dac => Gain g => WvOut w => blackhole;

// print out all arguments
me.arg(0) => string inname;
me.arg(1) => string outname;

int drama[5000];
//create the array and push into a variable
readInts(inname) @=> drama;

outname => w.wavFilename;

// any gain you want for the output
.5 => g.gain;

//start recording
1 => w.record;

for (0 => int i; i<drama.cap();i++) {
      play(flute,drama[i],.5);
}

//stop recording
0 => w.record;

// temporary workaround to automatically close file on remove-shred
null @=> w;

// play the note
fun void play(Flute flute, int note, float velocity) {
    // start the note
    Std.mtof( note ) => flute.freq;
    velocity => flute.noteOn;
    .6      => flute.gain;
    100::ms => now;
    velocity => flute.noteOff;
    //10::ms => now;
}

// read the ints into an array
// http://wiki.cs.princeton.edu/index.php/ChucK/Dev/IO/FileIO
fun int[] readInts(string path) {

    // open the file
    FileIO file;
    if (!file.open(path, FileIO.READ)) {
        <<< "file read failed" >>>;
        <<< path >>>;
        int ret[0]; // error opening the specified file
        return ret;
    }

    // read the size of the array
    //4096 => int size;
    file => int size;
    // now read in the contents
    int ret[size];
    for (0 => int i; i < size; i++)
        file => ret[i];

    file.close();
    return ret;
}

/*
Data on Acid hack

Iain Emsley

SSI hack March 2015

*/

//SawOsc s => dac;
Flute flute => PoleZero f => JCRev r => dac;
.95 => r.gain;
.05 => r.mix;
.99 => f.blockZero;

.2 => float timeSt;
// print out all arguments

// print out all arguments
me.arg(0) => string fname;

int drama[5000];
readInts(fname) @=> drama;

for (0 => int i; i<drama.cap();i++) {
      play(flute,drama[i],.5);
}

// play the note
fun void play(Flute flute, int note, float velocity) {
    // start the note
    Std.mtof( note ) => flute.freq;
    velocity => flute.noteOn;
    .6      => flute.gain;
    100::ms => now;
    velocity => flute.noteOff;
    //10::ms => now;
}

// read the ints into an array
// http://wiki.cs.princeton.edu/index.php/ChucK/Dev/IO/FileIO
fun int[] readInts(string path) {

    // open the file
    FileIO file;
    if (!file.open(path, FileIO.READ)) {
        <<< "file read failed" >>>;
        <<< path >>>;
        int ret[0]; // error opening the specified file
        return ret;
    }

    // read the size of the array
    //4096 => int size;
    file => int size;
    // now read in the contents
    int ret[size];
    for (0 => int i; i < size; i++)
        file => ret[i];

    file.close();
    return ret;
}


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 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;

}

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);
}


Update WaveformMixerMono.ck

Update WaveformMixerMono.ck

woah. crazy monophonic synth osc strip.

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);
}

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;


colors are a bit more obvious now

colors are a bit more obvious now

OscRecv           wm;
Launchpad         lp;
OscBank oscBank;

false    =>   int prompt;
50::samp =>   dur gainResolution;
0.0016   => float releaseDecay;
0.00001  => float sustainDecay;
0.00001  => float sostenutoDecay;
0.01     => float pressAttack;
0.80     => float maxNoteGain;
0.0      => float wiiAccel;
0        =>   int currentTone;
false    =>   int sustain;
              int sustainStatus[8][8];
false    =>   int sostenuto;
              int sostenutoStatus[8][8];
0        =>   int lpChannel;

LaunchpadColor.green => int keyOnColor;
LaunchpadColor.red => int keySustainColor;
LaunchpadColor.orange => int keySostenutoColor;
LaunchpadColor.red => int toneChoiceColor;

fun void setup()
{
    OscBank.OscBank(8, 8, 1, 5, 82.4068867, 12.0) @=> oscBank;

    if(prompt) {
        intPrompt("Enter Midi Channel for Launchpad input: ") => lpChannel;
        Launchpad.Launchpad(lpChannel) @=> lp;
    } else {
        Launchpad.Launchpad(0) @=> lp;
    }

    me.yield();
    lp.clear();
    lp.setGridLight(8, currentTone, toneChoiceColor);

    spork ~ launchpadListener();
    spork ~ wiiListener();
    spork ~ updateGains();
}

fun void setTone(int toneChoice)
{
    if(toneChoice == currentTone) { return; }
    else if(toneChoice == 0)      { oscBank.setPatch("SinOsc"); }
    else if(toneChoice == 1)      { oscBank.setPatch("SqrOsc"); }
    else if(toneChoice == 2)      { oscBank.setPatch("SawOsc"); }
    else if(toneChoice == 3)      { oscBank.setPatch("TriOsc"); }
    else                          { return; }

    lp.setGridLight(8, currentTone, 0);
    lp.setGridLight(8, toneChoice, toneChoiceColor);
    toneChoice => currentTone;
}

fun void setSostenuto(int enabled) {
    enabled => sostenuto;
    for(0 => int x; x < 8; x++) {
        for(0 => int y; y < 8; y++) {
            lp.keyDown[x][y] && enabled => sostenutoStatus[x][y];
            if(!enabled && !lp.keyDown[x][y] && !sustainStatus[x][y]) {
                lp.setGridLight(x, y, 0);
            }
        }
    }
}

fun void setSustain(int enabled) {
    enabled => sustain;
    for(0 => int x; x < 8; x++) {
        for(0 => int y; y < 8; y++) {
            lp.keyDown[x][y] => int down;
            down && enabled => sustainStatus[x][y];
            if(!down && !sostenutoStatus[x][y]) {
                lp.setGridLight(x, y, 0);
            }
        }
    }
}

fun void release(int column, int row)
{
    Math.max(oscBank.gains[column][row].gain() - releaseDecay, 0.00)
        => oscBank.gains[column][row].gain;
}

fun void updateSustain(int column, int row, float targetGain)
{
    if(sustain && sustainStatus[column][row])
    {
        Math.max(oscBank.gains[column][row].gain() - sustainDecay, 0.00)
            => oscBank.gains[column][row].gain;
    }
    else
    {
        release(column, row);
    }
}

fun void updateSostenuto(int column, int row, float targetGain)
{
    if(sostenuto && sostenutoStatus[column][row])
    {
        Math.max(oscBank.gains[column][row].gain() - sostenutoDecay, 0.00)
            => oscBank.gains[column][row].gain;
    }
    else
    {
        updateSustain(column, row, targetGain);
    }
}

fun void update(int column, int row, float targetGain)
{
    if(lp.keyDown[column][row] && targetGain > oscBank.gains[column][row].gain())
    {
        Math.min(oscBank.gains[column][row].gain() + pressAttack, maxNoteGain)
            => oscBank.gains[column][row].gain;
    }
    else
    {
        updateSostenuto(column, row, targetGain);
    }
}

fun void updateGains()
{
    float targetGain;
    while(true) {
        // Math.max(0.0, (wiiAccel - 32) / 95.0) => targetGain;
        wiiAccel => targetGain;

        for(0 => int i; i < 8; i++) {
            for(0 => int j; j < 8; j++) {
                update(i, j, targetGain);
            }
        }

        gainResolution => now;
    }
}

fun int intPrompt(string msg)
{
    int in;
    ConsoleInput cin;
    StringTokenizer tok;
    cin.prompt(msg) => now;
    while(cin.more())
    {
        tok.set(cin.getLine());
        while(tok.more())
        {
            Std.atoi(tok.next()) => in;
        }
    }
    return in;
}

fun void launchpadListener()
{
    while(true)
    {
        lp.e => now;

        // ignore button presses that are not on the grid
        if(lp.e.column < 0 || lp.e.column > 8) continue;
        if(lp.e.row < 0 || lp.e.row > 7) continue;

        if(lp.e.column == 8)
        {
            if(lp.e.velocity == 127)
            {
                setTone(lp.e.row);
            }
        }
        else if(lp.e.velocity == 127)
        {
            if(sustain)
            {
                true => sustainStatus[lp.e.column][lp.e.row];
            }
            lp.setGridLight(lp.e.column, lp.e.row, keyOnColor);
            1 => oscBank.bank[lp.e.column][lp.e.row].op;
        }
        else if(sostenuto && sostenutoStatus[lp.e.column][lp.e.row])
        {
            lp.setGridLight(lp.e.column, lp.e.row, keySostenutoColor);
        }
        else if(sustain && sustainStatus[lp.e.column][lp.e.row])
        {
            lp.setGridLight(lp.e.column, lp.e.row, keySustainColor);
        }
        else
        {
            lp.setGridLight(lp.e.column, lp.e.row, 0);
        }
    }
}

fun void sustainListener() {
    wm.event("/wii/1/button/B,i") @=> OscEvent e;
    while(true) {
        e => now;
        while(e.nextMsg() != 0) {
            setSustain(e.getInt() != 0);
        }
    }
}

fun void sostenutoListener()
{
    wm.event("/wii/1/button/A,i") @=> OscEvent e;
    while(true) {
        e => now;
        while(e.nextMsg() != 0) {
            setSostenuto(e.getInt() != 0);
        }
    }
}

fun void accelListener()
{
    wm.event("/wii/1/accel/pry/3,f") @=> OscEvent e;
    while(true) {
        e => now;
        while(e.nextMsg() != 0) {
            Math.max(0.0, e.getFloat() - 0.22) => wiiAccel;
            chout <= wiiAccel <= IO.newline();
        }
    }
}

fun void wiiListener()
{
    6449 => wm.port;
    // 8000 => wm.port;
    wm.listen();
    spork ~ sustainListener();
    spork ~ sostenutoListener();
    spork ~ accelListener();
    while(true) { 1::second => now; }
}

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

OscRecv           wm;
Launchpad         lp;
OscBank oscBank;

false    =>   int prompt;
50::samp =>   dur gainResolution;
0.0016   => float releaseDecay;
0.00001  => float sustainDecay;
0.00001  => float sostenutoDecay;
0.01     => float pressAttack;
0.80     => float maxNoteGain;
0.0      => float rawGain;
0        =>   int currentTone;
false    =>   int sustain;
              int sustainStatus[8][8];
false    =>   int sostenuto;
              int sostenutoStatus[8][8];
0        =>   int lpChannel;

LaunchpadColor.red => int keyOnColor;
LaunchpadColor.lightRed => int keySustainColor;
LaunchpadColor.lightRed => int keySostenutoColor;
LaunchpadColor.red => int toneChoiceColor;

fun void setup()
{
    OscBank.OscBank(8, 8, 1, 5, 82.4068867, 12.0) @=> oscBank;

    if(prompt) {
        intPrompt("Enter Midi Channel for Launchpad input: ") => lpChannel;
        Launchpad.Launchpad(lpChannel) @=> lp;
    } else {
        Launchpad.Launchpad(0) @=> lp;
    }

    me.yield();
    lp.clear();
    lp.setGridLight(8, currentTone, toneChoiceColor);

    spork ~ launchpadListener();
    spork ~ wiiListener();
    spork ~ updateGains();
}

fun void setTone(int toneChoice)
{
    if(toneChoice == currentTone) { return; }
    else if(toneChoice == 0)      { oscBank.setPatch("SinOsc"); }
    else if(toneChoice == 1)      { oscBank.setPatch("SqrOsc"); }
    else if(toneChoice == 2)      { oscBank.setPatch("SawOsc"); }
    else if(toneChoice == 3)      { oscBank.setPatch("TriOsc"); }
    else                          { return; }

    lp.setGridLight(8, currentTone, 0);
    lp.setGridLight(8, toneChoice, toneChoiceColor);
    toneChoice => currentTone;
}

fun void setSostenuto(int enabled) {
    enabled => sostenuto;
    for(0 => int x; x < 8; x++) {
        for(0 => int y; y < 8; y++) {
            lp.keyDown[x][y] && enabled => sostenutoStatus[x][y];
            if(!enabled && !lp.keyDown[x][y] && !sustainStatus[x][y]) {
                lp.setGridLight(x, y, 0);
            }
        }
    }
}

fun void setSustain(int enabled) {
    enabled => sustain;
    for(0 => int x; x < 8; x++) {
        for(0 => int y; y < 8; y++) {
            lp.keyDown[x][y] => int down;
            down && enabled => sustainStatus[x][y];
            if(!down && !sostenutoStatus[x][y]) {
                lp.setGridLight(x, y, 0);
            }
        }
    }
}

fun void release(int column, int row)
{
    Math.max(oscBank.gains[column][row].gain() - releaseDecay, 0.00)
        => oscBank.gains[column][row].gain;
}

fun void updateSustain(int column, int row, float targetGain)
{
    if(sustain && sustainStatus[column][row])
    {
        Math.max(oscBank.gains[column][row].gain() - sustainDecay, 0.00)
            => oscBank.gains[column][row].gain;
    }
    else
    {
        release(column, row);
    }
}

fun void updateSostenuto(int column, int row, float targetGain)
{
    if(sostenuto && sostenutoStatus[column][row])
    {
        Math.max(oscBank.gains[column][row].gain() - sostenutoDecay, 0.00)
            => oscBank.gains[column][row].gain;
    }
    else
    {
        updateSustain(column, row, targetGain);
    }
}

fun void update(int column, int row, float targetGain)
{
    if(lp.keyDown[column][row] && targetGain > oscBank.gains[column][row].gain())
    {
        Math.min(oscBank.gains[column][row].gain() + pressAttack, maxNoteGain)
            => oscBank.gains[column][row].gain;
    }
    else
    {
        updateSostenuto(column, row, targetGain);
    }
}

fun void updateGains()
{
    float targetGain;
    while(true) {
        // Math.max(0.0, (rawGain - 32) / 95.0) => targetGain;
        rawGain => targetGain;

        for(0 => int i; i < 8; i++)
        {
            for(0 => int j; j < 8; j++)
            {
                update(i, j, targetGain);
            }
        }

        gainResolution => now;
    }
}

fun int intPrompt(string msg)
{
    int in;
    ConsoleInput cin;
    StringTokenizer tok;
    cin.prompt(msg) => now;
    while(cin.more())
    {
        tok.set(cin.getLine());
        while(tok.more())
        {
            Std.atoi(tok.next()) => in;
        }
    }
    return in;
}

fun void launchpadListener()
{
    while(true)
    {
        lp.e => now;

        // ignore button presses that are not on the grid
        if(lp.e.column < 0 || lp.e.column > 8) continue;
        if(lp.e.row < 0 || lp.e.row > 7) continue;

        if(lp.e.column == 8)
        {
            if(lp.e.velocity == 127)
            {
                setTone(lp.e.row);
            }
        }
        else if(lp.e.velocity == 127)
        {
            if(sustain)
            {
                true => sustainStatus[lp.e.column][lp.e.row];
            }
            lp.setGridLight(lp.e.column, lp.e.row, keyOnColor);
            1 => oscBank.bank[lp.e.column][lp.e.row].op;
        }
        else if(sostenuto && sostenutoStatus[lp.e.column][lp.e.row])
        {
            lp.setGridLight(lp.e.column, lp.e.row, keySostenutoColor);
        }
        else if(sustain && sustainStatus[lp.e.column][lp.e.row])
        {
            lp.setGridLight(lp.e.column, lp.e.row, keySustainColor);
        }
        else
        {
            lp.setGridLight(lp.e.column, lp.e.row, 0);
        }
    }
}

fun void sustainListener() {
    wm.event("/wii/1/button/B,i") @=> OscEvent e;
    while(true) {
        e => now;
        while(e.nextMsg() != 0) {
            setSustain(e.getInt() != 0);
        }
    }
}

fun void sostenutoListener()
{
    wm.event("/wii/1/button/A,i") @=> OscEvent e;
    while(true) {
        e => now;
        while(e.nextMsg() != 0) {
            setSostenuto(e.getInt() != 0);
        }
    }
}

fun void accelListener()
{
    wm.event("/wii/1/accel/pry/3,f") @=> OscEvent e;
    while(true)
    {
        e => now;
        while(e.nextMsg() != 0)
        {
            Math.max(0.0, e.getFloat() - 0.22) => rawGain;
            chout <= rawGain <= IO.newline();
        }
    }
}

fun void wiiListener()
{
    6449 => wm.port;
    // 8000 => wm.port;
    wm.listen();
    spork ~ sustainListener();
    spork ~ sostenutoListener();
    spork ~ accelListener();
    while(true)
    {
        1::second => now;
    }
}

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


130902.0


removed evil brackets

removed evil brackets

MidiIn            wm;
Launchpad         lp;

false    =>   int prompt;
50::samp =>   dur gainResolution;
0.0016   => float releaseDecay;
0.00001   => float sustainDecay;
0.00001   => float sostenutoDecay;
0.01     => float pressAttack;
0.80     => float maxNoteGain;
0        =>   int rawGain;
             UGen @ oscBank[8][8];
             Gain @ patchBank[8][8];
0        =>   int currentTone;
false    =>   int sustain;
              int sustainStatus[8][8];
false    =>   int sostenuto;
              int sostenutoStatus[8][8];
0        =>   int lpChannel;
1        =>   int wiimoteChannel;

LaunchpadColor.red => int keyOnColor;
LaunchpadColor.lightRed => int keySustainColor;
LaunchpadColor.lightRed => int keySostenutoColor;
LaunchpadColor.red => int toneChoiceColor;
ToneCalc.grid(8, 8, 1, 5,  82.4068867, 12.0) @=> float toneMap[][];

fun void setup()
{

    if(prompt)
    {
        intPrompt("Enter Midi Channel for Launchpad input: ") => lpChannel;
        intPrompt("Enter Midi Channel for Wiimote input: ") => wiimoteChannel;

        Launchpad.Launchpad(lpChannel) @=> lp;
        connectWiimote(wiimoteChannel);
    }
    else
    {
        Launchpad.Launchpad(0) @=> lp;
        connectWiimote(1);
    }

    lp.clear();
    lp.setGridLight(8, currentTone, toneChoiceColor);

    chout <= "Create oscillators" <= IO.newline();
    for(0 => int i; i < 8; i++)
    {
        for(0 => int j; j < 8; j++)
        {
            SinOsc s;
            toneMap[i][j] => s.freq;
            0.0 => s.gain;
            chout <= ".";

            Gain g;
            1.0 => g.gain;

            s @=> oscBank[i][j] => g @=> patchBank[i][j] => dac;
        }
    }
    chout <= "done." <= IO.newline();

    spork ~ launchpadListener();
    spork ~ wiiListener();
    spork ~ updateGains();
}

fun UGen toneChoiceFactory(int toneChoice, UGen @ sourceUGen, float freq)
{
    if(toneChoice == 0)
    {
        SinOsc s;
        freq => s.freq;
        sourceUGen.op() => s.op;
        sourceUGen.gain() => s.gain;
        return s;
    }
    else if(toneChoice == 1)
    {
        TriOsc s;
        freq => s.freq;
        sourceUGen.op() => s.op;
        sourceUGen.gain() => s.gain;
        return s;
    }
    else if(toneChoice == 2)
    {
        SqrOsc s;
        freq => s.freq;
        sourceUGen.op() => s.op;
        sourceUGen.gain() => s.gain;
        return s;
    }
    else if(toneChoice == 3)
    {
        SawOsc s;
        freq => s.freq;
        sourceUGen.op() => s.op;
        sourceUGen.gain() => s.gain;
        return s;
    }
    else
    {
        cherr <= "Unrecognized input fed to toneChoiceFactory: " <= toneChoice
            <= IO.newline();
        SinOsc s;
        freq => s.freq;
        sourceUGen.op() => s.op;
        sourceUGen.gain() => s.gain;
        return s;
    }
}

fun void setTone(int toneChoice)
{

    if(toneChoice == currentTone)
    {
        return;
    }

    for(0 => int i; i < 8; i++)
    {
        for(0 => int j; j < 8; j++)
        {
            UGen u;
            toneChoiceFactory(toneChoice, oscBank[i][j], toneMap[i][j]) @=> u;
            0 => oscBank[i][j].op;
            oscBank[i][j] =< patchBank[i][j];
            u @=> oscBank[i][j] => patchBank[i][j];
        }
    }

    lp.setGridLight(8, currentTone, 0);
    lp.setGridLight(8, toneChoice, toneChoiceColor);
    toneChoice => currentTone;
}

fun void sostenutoOn()
{
    true => sostenuto;
    for(0 => int i; i < 8; i++)
    {
        for(0 => int j; j < 8; j++)
        {
            if(lp.keyDown[i][j])
            {
                true => sostenutoStatus[i][j];
            }
        }
    }
}

fun void sostenutoOff()
{
    false => sostenuto;
    for(0 => int i; i < 8; i++)
    {
        for(0 => int j; j < 8; j++)
        {
            false => sostenutoStatus[i][j];
            if(!lp.keyDown[i][j])
            {
                lp.setGridLight(i, j, 0);
            }
        }
    }
}

fun void sustainOn()
{
    true => sustain;
    for(0 => int i; i < 8; i++)
    {
        for(0 => int j; j < 8; j++)
        {
            if(lp.keyDown[i][j])
            {
                true => sustainStatus[i][j];
            }
        }
    }
}

fun void sustainOff()
{
    false => sustain;
    for(0 => int i; i < 8; i++)
    {
        for(0 => int j; j < 8; j++)
        {
            false => sustainStatus[i][j];
            if(!lp.keyDown[i][j])
            {
                lp.setGridLight(i, j, 0);
            }
        }
    }
}

fun void release(int column, int row)
{
    Math.max(oscBank[column][row].gain() - releaseDecay, 0.00)
        => oscBank[column][row].gain;
}

fun void updateSustain(int column, int row, float targetGain)
{
    if(sustain && sustainStatus[column][row])
    {
        Math.max(oscBank[column][row].gain() - sustainDecay, 0.00)
            => oscBank[column][row].gain;
    }
    else
    {
        release(column, row);
    }
}

fun void updateSostenuto(int column, int row, float targetGain)
{
    if(sostenuto && sostenutoStatus[column][row])
    {
        Math.max(oscBank[column][row].gain() - sostenutoDecay, 0.00)
            => oscBank[column][row].gain;
    }
    else
    {
        updateSustain(column, row, targetGain);
    }
}

fun void update(int column, int row, float targetGain)
{
    if(lp.keyDown[column][row] && targetGain > oscBank[column][row].gain())
    {
        Math.min(oscBank[column][row].gain() + pressAttack, maxNoteGain)
            => oscBank[column][row].gain;
    }
    else
    {
        updateSostenuto(column, row, targetGain);
    }
}

fun void updateGains()
{
    float targetGain;
    while(true) {
        Math.max(0.0, (rawGain - 32) / 95.0) => targetGain;

        for(0 => int i; i < 8; i++)
        {
            for(0 => int j; j < 8; j++)
            {
                update(i, j, targetGain);
            }
        }

        gainResolution => now;
    }
}

fun int intPrompt(string msg)
{
    int in;
    ConsoleInput cin;
    StringTokenizer tok;
    cin.prompt(msg) => now;
    while(cin.more())
    {
        tok.set(cin.getLine());
        while(tok.more())
        {
            Std.atoi(tok.next()) => in;
        }
    }
    return in;
}

fun void launchpadListener()
{
    while(true)
    {
        lp.e => now;

        // ignore button presses that are not on the grid
        if(lp.e.column < 0 || lp.e.column > 8) continue;
        if(lp.e.row < 0 || lp.e.row > 8) continue;

        if(lp.e.column == 8)
        {
            if(lp.e.velocity == 127)
            {
                setTone(lp.e.row);
            }
        }
        else if(lp.e.velocity == 127)
        {
            if(sustain)
            {
                true => sustainStatus[lp.e.column][lp.e.row];
            }
            lp.setGridLight(lp.e.column, lp.e.row, keyOnColor);
            1 => oscBank[lp.e.column][lp.e.row].op;
        }
        else if(sostenuto && sostenutoStatus[lp.e.column][lp.e.row])
        {
            lp.setGridLight(lp.e.column, lp.e.row, keySostenutoColor);
        }
        else if(sustain && sustainStatus[lp.e.column][lp.e.row])
        {
            lp.setGridLight(lp.e.column, lp.e.row, keySustainColor);
        }
        else
        {
            lp.setGridLight(lp.e.column, lp.e.row, 0);
        }
    }
}

fun void wiiParser(MidiMsg msg)
{
    if(msg.data1 == 176) // midi CC
    {
        if(msg.data2 == 64)
        { // wiimote acceleration
            msg.data3 => rawGain;
        }
        else if (msg.data2 == 65)
        {   // wiimote button b
            if(msg.data3 == 127)
            {
                sustainOn();
            }
            else
            {
                sustainOff();
            }
        }
        else if (msg.data2 == 66)
        {   // wiimote button a
            if(msg.data3 == 127)
            {
                sostenutoOn();
            }
            else
            {
                sostenutoOff();
            }
        }
    }
}

fun void connectWiimote(int midiChannel)
{
    if(!wm.open(midiChannel)) me.exit();

    chout <= "Midi device: " <= midiChannel <= " -> " <= wm.name()
        <= IO.newline();
}

fun void wiiListener()
{
    MidiMsg msg;
    while(true)
    {
        wm => now;
        while(wm.recv(msg))
        {
            wiiParser(msg);
        }
    }
}

setup();

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

MidiIn            wm;
Launchpad         lp;

false    =>   int prompt;
50::samp =>   dur gainResolution;
0.0016   => float releaseDecay;
0.0001   => float sustainDecay;
0.0001   => float sostenutoDecay;
0.01     => float pressAttack;
0.80     => float maxNoteGain;
0        =>   int rawGain;
             UGen @ oscBank[8][8];
             Gain @ patchBank[8][8];
0        =>   int currentTone;
false    =>   int sustain;
              int sustainStatus[8][8];
false    =>   int sostenuto;
              int sostenutoStatus[8][8];
0        =>   int lpChannel;
1        =>   int wiimoteChannel;

LaunchpadColor.red => int keyOnColor;
LaunchpadColor.lightRed => int keySustainColor;
LaunchpadColor.lightRed => int keySostenutoColor;
LaunchpadColor.red => int toneChoiceColor;
ToneCalc.grid(8, 8, 1, 5,  82.4068867, 12.0) @=> float toneMap[][];

fun void setup() {

    if(prompt) {
        intPrompt("Enter Midi Channel for Launchpad input: ") => lpChannel;
        intPrompt("Enter Midi Channel for Wiimote input: ") => wiimoteChannel;

        Launchpad.Launchpad(lpChannel) @=> lp;
        connectWiimote(wiimoteChannel);
    } else {
        Launchpad.Launchpad(0) @=> lp;
        connectWiimote(1);
    }

    lp.clear();
    lp.setGridLight(8, currentTone, toneChoiceColor);

    chout <= "Create oscillators" <= IO.newline();
    for(0 => int i; i < 8; i++) {
        for(0 => int j; j < 8; j++) {
            SinOsc s;
            toneMap[i][j] => s.freq;
            0.0 => s.gain;
            chout <= ".";

            Gain g;
            1.0 => g.gain;

            s @=> oscBank[i][j] => g @=> patchBank[i][j] => dac;
        }
    }
    chout <= "done." <= IO.newline();

    spork ~ launchpadListener();
    spork ~ wiiListener();
    spork ~ updateGains();
}

fun UGen toneChoiceFactory(int toneChoice, UGen @ sourceUGen, float freq) {
    if(toneChoice == 0) {
        SinOsc s;
        freq => s.freq;
        sourceUGen.op() => s.op;
        sourceUGen.gain() => s.gain;
        return s;
    } else if(toneChoice == 1) {
        TriOsc s;
        freq => s.freq;
        sourceUGen.op() => s.op;
        sourceUGen.gain() => s.gain;
        return s;
    } else if(toneChoice == 2) {
        SqrOsc s;
        freq => s.freq;
        sourceUGen.op() => s.op;
        sourceUGen.gain() => s.gain;
        return s;
    } else if(toneChoice == 3) {
        SawOsc s;
        freq => s.freq;
        sourceUGen.op() => s.op;
        sourceUGen.gain() => s.gain;
        return s;
    } else {
        cherr <= "Unrecognized input fed to toneChoiceFactory: " <= toneChoice
            <= IO.newline();
        SinOsc s;
        freq => s.freq;
        sourceUGen.op() => s.op;
        sourceUGen.gain() => s.gain;
        return s;
    }
}

fun void setTone(int toneChoice) {

    if(toneChoice == currentTone) {
        return;
    }

    for(0 => int i; i < 8; i++) {
        for(0 => int j; j < 8; j++) {
            UGen u;
            toneChoiceFactory(toneChoice, oscBank[i][j], toneMap[i][j]) @=> u;
            0 => oscBank[i][j].op;
            oscBank[i][j] =< patchBank[i][j];
            u @=> oscBank[i][j] => patchBank[i][j];
        }
    }

    lp.setGridLight(8, currentTone, 0);
    lp.setGridLight(8, toneChoice, toneChoiceColor);
    toneChoice => currentTone;
}

fun void sostenutoOn() {
    true => sostenuto;
    for(0 => int i; i < 8; i++) {
        for(0 => int j; j < 8; j++) {
            if(lp.keyDown[i][j]) {
                true => sostenutoStatus[i][j];
            }
        }
    }
}

fun void sostenutoOff() {
    false => sostenuto;
    for(0 => int i; i < 8; i++) {
        for(0 => int j; j < 8; j++) {
            false => sostenutoStatus[i][j];
            if(!lp.keyDown[i][j]) {
                lp.setGridLight(i, j, 0);
            }
        }
    }
}

fun void sustainOn() {
    true => sustain;
    for(0 => int i; i < 8; i++) {
        for(0 => int j; j < 8; j++) {
            if(lp.keyDown[i][j]) {
                true => sustainStatus[i][j];
            }
        }
    }
}

fun void sustainOff() {
    false => sustain;
    for(0 => int i; i < 8; i++) {
        for(0 => int j; j < 8; j++) {
            false => sustainStatus[i][j];
            if(!lp.keyDown[i][j]) {
                lp.setGridLight(i, j, 0);
            }
        }
    }
}

fun void release(int column, int row) {
    Math.max(oscBank[column][row].gain() - releaseDecay, 0.00)
        => oscBank[column][row].gain;
}

fun void updateSustain(int column, int row, float targetGain) {
    if(sustain && sustainStatus[column][row]) {
        Math.max(oscBank[column][row].gain() - sustainDecay, 0.00)
            => oscBank[column][row].gain;
    } else {
        release(column, row);
    }
}

fun void updateSostenuto(int column, int row, float targetGain) {
    if(sostenuto && sostenutoStatus[column][row]) {
        Math.max(oscBank[column][row].gain() - sostenutoDecay, 0.00)
            => oscBank[column][row].gain;
    } else {
        updateSustain(column, row, targetGain);
    }
}

fun void update(int column, int row, float targetGain) {
    if(lp.keyDown[column][row] && targetGain > oscBank[column][row].gain()) {
        Math.min(oscBank[column][row].gain() + pressAttack, maxNoteGain)
            => oscBank[column][row].gain;
    } else {
        updateSostenuto(column, row, targetGain);
    }
}

fun void updateGains() {
    float targetGain;
    while(true) {
        Math.max(0.0, (rawGain - 32) / 95.0) => targetGain;

        for(0 => int i; i < 8; i++) {
            for(0 => int j; j < 8; j++) {
                update(i, j, targetGain);
            }
        }

        gainResolution => now;
    }
}

fun int intPrompt(string msg) {
    int in;
    ConsoleInput cin;
    StringTokenizer tok;
    cin.prompt(msg) => now;
    while(cin.more()) {
        tok.set(cin.getLine());
        while(tok.more()) {
            Std.atoi(tok.next()) => in;
        }
    }
    return in;
}

fun void launchpadListener() {
    while(true) {
        lp.e => now;

        // ignore button presses that are not on the grid
        if(lp.e.column < 0 || lp.e.column > 8) continue;
        if(lp.e.row < 0 || lp.e.row > 8) continue;

        if(lp.e.column == 8) {
            if(lp.e.velocity == 127) {
                setTone(lp.e.row);
            }
        } else if(lp.e.velocity == 127) {
            if(sustain) {
                true => sustainStatus[lp.e.column][lp.e.row];
            }
            lp.setGridLight(lp.e.column, lp.e.row, keyOnColor);
            1 => oscBank[lp.e.column][lp.e.row].op;
        } else if(sostenuto && sostenutoStatus[lp.e.column][lp.e.row]) {
            lp.setGridLight(lp.e.column, lp.e.row, keySostenutoColor);
        } else if(sustain && sustainStatus[lp.e.column][lp.e.row]) {
            lp.setGridLight(lp.e.column, lp.e.row, keySustainColor);
        } else {
            lp.setGridLight(lp.e.column, lp.e.row, 0);
        }
    }
}

fun void wiiParser(MidiMsg msg) {
    if(msg.data1 == 176) {              // midi CC
        if(msg.data2 == 64) { // wiimote acceleration
            msg.data3 => rawGain;
        } else if (msg.data2 == 65) {   // wiimote button b
            if(msg.data3 == 127) {
                sustainOn();
            } else {
                sustainOff();
            }
        } else if (msg.data2 == 66) {   // wiimote button a
            if(msg.data3 == 127) {
                sostenutoOn();
            } else {
                sostenutoOff();
            }
        }
    }
}

fun void connectWiimote(int midiChannel)
{
    if(!wm.open(midiChannel)) me.exit();

    chout <= "Midi device: " <= midiChannel <= " -> " <= wm.name()
        <= IO.newline();
}

fun void wiiListener() {
    MidiMsg msg;
    while(true) {
        wm => now;
        while(wm.recv(msg)) {
            wiiParser(msg);
        }
    }
}

setup();

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


Update vibraphoney.ck

Update vibraphoney.ck

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;

}

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;

}


louisiana: more padding on ck script

louisiana: more padding on ck script

0 => int padding_start;
12000 => int padding_end;
2 => int instrument_buffers;
0 => int start;
me.sourceDir() => string base_dir;

// normalize base directory
if (base_dir.charAt(base_dir.length()-1) != '/')
{
    "/" +=> base_dir;
}

// instrument object
class Instrument {
    string filename;
    SndBuf buf[8];
    int plays;
}

// data files
base_dir + "data/ck_instruments.csv" => string instruments_file;
base_dir + "data/ck_sequence.csv" => string sequence_file;

// read data files
FileIO instruments_fio;
FileIO sequence_fio;
instruments_fio.open( instruments_file, FileIO.READ );
sequence_fio.open( sequence_file, FileIO.READ );

// check if files are valid
if( !instruments_fio.good() || !sequence_fio.good() )
{
    cherr <= "can't open instrument and/or sequence files for reading..."
          <= IO.newline();
    me.exit();
}

// create instruments array
Instrument instruments[256];

// read instruments file
while( instruments_fio.more() )
{
    // read instrument index and filename
    Std.atoi(instruments_fio.readLine()) => int instrument_index;
    instruments_fio.readLine() => string filename;
    filename.find("\r") => int return_match;
    if (return_match >= 0)
    {
        filename.erase(return_match, 1);
    }
    base_dir + filename => instruments[instrument_index].filename;
    0 => instruments[instrument_index].plays;
    // create buffers from filename
    for( 0 => int i; i < instrument_buffers; i++ )
    {
        instruments[instrument_index].filename => instruments[instrument_index].buf[i].read;
        // set position to end, so it won't play immediately upon open
        instruments[instrument_index].buf[i].samples() => instruments[instrument_index].buf[i].pos;
        instruments[instrument_index].buf[i] => dac;
    }

}

// Add padding
padding_start::ms => now;
padding_start => int elapsed_ms;

// read sequence from file
while( sequence_fio.more() ) {
    Std.atoi(sequence_fio.readLine()) => int instrument_index;
    Std.atoi(sequence_fio.readLine()) => int position;
    Std.atof(sequence_fio.readLine()) => float gain;
    Std.atof(sequence_fio.readLine()) => float rate;
    Std.atoi(sequence_fio.readLine()) => int milliseconds;

    elapsed_ms + milliseconds => elapsed_ms;
    if (start > elapsed_ms)
    {
        continue;
    }

    // wait duration
	if (milliseconds > 0)
    {
        milliseconds::ms => now;
    }

    // choose buffer index
    instruments[instrument_index].plays % instrument_buffers => int buffer_index;
    instruments[instrument_index].plays++;

    // play the instrument
    position => instruments[instrument_index].buf[buffer_index].pos;
    gain => instruments[instrument_index].buf[buffer_index].gain;
    rate => instruments[instrument_index].buf[buffer_index].rate;
}

// Add padding
padding_end::ms => now;

<<< "Done." >>>;

0 => int padding_start;
4000 => int padding_end;
2 => int instrument_buffers;
0 => int start;
me.sourceDir() => string base_dir;

// normalize base directory
if (base_dir.charAt(base_dir.length()-1) != '/')
{
    "/" +=> base_dir;
}

// instrument object
class Instrument {
    string filename;
    SndBuf buf[8];
    int plays;
}

// data files
base_dir + "data/ck_instruments.csv" => string instruments_file;
base_dir + "data/ck_sequence.csv" => string sequence_file;

// read data files
FileIO instruments_fio;
FileIO sequence_fio;
instruments_fio.open( instruments_file, FileIO.READ );
sequence_fio.open( sequence_file, FileIO.READ );

// check if files are valid
if( !instruments_fio.good() || !sequence_fio.good() )
{
    cherr <= "can't open instrument and/or sequence files for reading..."
          <= IO.newline();
    me.exit();
}

// create instruments array
Instrument instruments[256];

// read instruments file
while( instruments_fio.more() )
{
    // read instrument index and filename
    Std.atoi(instruments_fio.readLine()) => int instrument_index;
    instruments_fio.readLine() => string filename;
    filename.find("\r") => int return_match;
    if (return_match >= 0)
    {
        filename.erase(return_match, 1);
    }
    base_dir + filename => instruments[instrument_index].filename;
    0 => instruments[instrument_index].plays;
    // create buffers from filename
    for( 0 => int i; i < instrument_buffers; i++ )
    {
        instruments[instrument_index].filename => instruments[instrument_index].buf[i].read;
        // set position to end, so it won't play immediately upon open
        instruments[instrument_index].buf[i].samples() => instruments[instrument_index].buf[i].pos;
        instruments[instrument_index].buf[i] => dac;
    }

}

// Add padding
padding_start::ms => now;
padding_start => int elapsed_ms;

// read sequence from file
while( sequence_fio.more() ) {
    Std.atoi(sequence_fio.readLine()) => int instrument_index;
    Std.atoi(sequence_fio.readLine()) => int position;
    Std.atof(sequence_fio.readLine()) => float gain;
    Std.atof(sequence_fio.readLine()) => float rate;
    Std.atoi(sequence_fio.readLine()) => int milliseconds;

    elapsed_ms + milliseconds => elapsed_ms;
    if (start > elapsed_ms)
    {
        continue;
    }

    // wait duration
	if (milliseconds > 0)
    {
        milliseconds::ms => now;
    }

    // choose buffer index
    instruments[instrument_index].plays % instrument_buffers => int buffer_index;
    instruments[instrument_index].plays++;

    // play the instrument
    position => instruments[instrument_index].buf[buffer_index].pos;
    gain => instruments[instrument_index].buf[buffer_index].gain;
    rate => instruments[instrument_index].buf[buffer_index].rate;
}

// Add padding
padding_end::ms => now;

<<< "Done." >>>;


Perlin noise working smoothly and gentlygit status

/*
*  One dimensional Perlin Noise implementation based on:
*  http://freespace.virgin.net/hugo.elias/models/m_perlin.htm
*
*  Usage:
*    next()      --> get next perlin noise values
*
*  Getters and setters and provided for:
*    seed        --> where to start from
*    delta       --> how far the next value lies
*    octaves     --> how many noise functions to be used
*    persistence --> harshness of the amp/freq computation
*/

public class Ken
{
    int _octaves;
    float _persistence;
    float _seed;
    float _delta;

    // constructor
    {
        5    => _octaves;
        0.25 => _persistence;

        ( 0.0, 200.0 ) => Std.rand2f => seed;
        0.01 => delta;
    }

    //  resturns next perlin noise value
    fun float next()
    {
        float result;

        _perlin_noise( seed ) => result;
        seed + delta => seed;

        return result;
    }

    //
    //  setters and getters section

    // delta setter
    fun float delta( float new_delta )
    {
        new_delta => _delta;

        return _delta;
    }

    // delta getter
    fun float delta()
    {
        return _delta;
    }

    // seed setter
    fun float seed( float new_seed )
    {
        new_seed => _seed;

        return _seed;
    }

    // seed getter
    fun float seed()
    {
        return _seed;
    }

    // octaves setter
    fun float octaves( float new_octaves )
    {
        new_octaves => _octaves;

        return _octaves;
    }

    // octaves getter
    fun float octaves()
    {
        return _octaves;
    }

    // persistence setter
    fun float persistence( float new_persistence )
    {
        new_persistence => _persistence;

        return _persistence;
    }

    // persostence getter
    fun float persistence()
    {
        return _persistence;
    }

    //
    // perlin noise implementation
    // this should be a private section

    // pseudo random number generator
    fun float _simple_noise( int x )
    {
        (( x << 13 ) ^ x ) => x;
        return ( 1.0 - ( (x * (x * x * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0);
    }

    // cosine interpolation
    fun float _cos_interpolation( float a, float b, float x )
    {
        float ft;
        float f;

        x * pi => ft;
        ( 1 - Math.cos( ft )) * 0.5 => f;

        return a * (1-f) + b * f;
    }

    // smooting the psude random noise
    fun float _smooth_noise( int x )
    {
        float result;

        _simple_noise( x ) / 2.0 => result;
        _simple_noise( x-1 ) / 4.0 +=> result;
        _simple_noise( x+1 ) / 4.0 +=> result;

        return result;
    }

    // noise cosine interpolation
    fun float _interpolated_noise( float x )
    {
        int integer;
        float fractorial;
        float v1, v2;

        x $ int => integer;
        x - integer => fractorial;

        _smooth_noise( integer ) => v1;
        _smooth_noise( integer+1 ) => v2;

        return _cos_interpolation( v1, v2, fractorial );
    }

    // actual perlin noise algorithm
    fun float _perlin_noise( float x )
    {
        float total;
        float persistence;
        float amp, freq;
        int octaves;

        0.0  => total;
        0.25 => persistence;
        5    => octaves;

        for( 0 => int i; i < octaves-1; i++ )
        {
            Math.pow( 2, i ) => freq;
            Math.pow( persistence, i ) => amp;

            _interpolated_noise( x * freq ) * amp +=> total;
        }

        return total;
    }
}

/*
*  --------------> WARNING <--------------
*  This is a sketch for the class implementing
*  one dimentional perlin noise
*  it's a code taken from Processing source repo
*  and re-written to ChucK. Unfortunatelly
*  it doesn't work well, so needs some testing
*/

public class Ken
{

    4 => int PERLIN_YWRAPB;
    ( 1 << PERLIN_YWRAPB ) => int PERLIN_YWRAP;
    8 => int PERLIN_ZWRAPB;
    ( 1 << PERLIN_ZWRAPB ) => int PERLIN_ZWRAP;
    4095 => int PERLIN_SIZE;

    4 => int perlin_octaves; // default to medium smooth
    0.5 => float perlin_amp_falloff; // 50% reduction/octave

    0.5 => float SINCOS_PRECISION;
    ( 360 / SINCOS_PRECISION ) $ int => int SINCOS_LENGTH;

    SINCOS_LENGTH => int perlin_TWOPI => int perlin_PI;
    ( perlin_PI >> 1 ) => perlin_PI;
    float perlin_cosTable[ SINCOS_LENGTH ];
    float perlin[ PERLIN_SIZE + 1 ];

    { // CONSTRUCTOR
        for( 0 => int i; i < SINCOS_LENGTH; i++ )
        {
            Math.cos( i * ( Math.PI / 180.0 ) * SINCOS_PRECISION ) => perlin_cosTable[ i ];
        }
    }

    fun float noise( float x )
    {
        return noise( x, 0.0, 0.0 );
    }

    fun float noise( float x, float y )
    {
        return noise( x, y, 0.0 );
    }

    fun float noise( float x, float y, float z )
    {
        if( perlin == NULL )
        {
            for( 0 => int i; i < PERLIN_SIZE + 1; i++)
            {
                Std.randf() => perlin[ i ];
            }
        }

        if( x < 0 )
        -x => x;
        if( y < 0 )
        -y => y;
        if( z < 0 )
        -z => z;

        x $ int => int xi;
        y $ int => int yi;
        z $ int => int zi;

        ( x - xi ) $ float => float xf;
        ( y - yi ) $ float => float yf;
        ( z - zi ) $ float => float zf;

        float rxf, ryf;

        0.0 => float r;
        0.5 => float ampl;

        float n1, n2, n3;

        for( 0 => int i; i < perlin_octaves; i++ )
        {
            xi + ( yi << PERLIN_YWRAPB ) + ( zi << PERLIN_ZWRAPB ) => int of;

            noise_fsc( xf ) => rxf;
            noise_fsc( yf ) => ryf;

            perlin[ of & PERLIN_SIZE ] => n1;
            rxf * ( perlin[ ( of + 1 ) & PERLIN_SIZE ] - n1 ) +=> n1;
            perlin[ ( of + PERLIN_YWRAP ) & PERLIN_SIZE ] => n2;
            rxf * ( perlin[ ( of + PERLIN_YWRAP + 1 ) & PERLIN_SIZE ] - n2) +=> n2;
            ryf*(n2-n1) +=> n1;

            PERLIN_ZWRAP +=> of;
            perlin[ of & PERLIN_SIZE ] => n2;
            rxf * ( perlin[ ( of + 1 ) & PERLIN_SIZE ] - n2 ) +=> n2;
            perlin[ ( of + PERLIN_YWRAP ) & PERLIN_SIZE ] => n3;
            rxf * ( perlin[ ( of + PERLIN_YWRAP + 1 ) & PERLIN_SIZE ] - n3 ) +=> n3;
            ryf * ( n3 - n2 ) +=> n2;

            noise_fsc( zf ) * ( n2 - n1 ) +=> n1;

            n1 * ampl +=> r;
            perlin_amp_falloff *=> ampl;
            xi << 1 => xi;
            2 *=> xf;
            yi << 1 => yi;
            2 *=> yf;
            zi << 1 => zi;
            2 *=> zf;

            if( xf >= 1.0 )
            {
                xi++;
                1.0 -=> xf;
            }
            if( yf >= 1.0 )
            {
                yi++;
                1.0 -=> yf;
            }
            if( zf >= 1.0 )
            {
                zi++;
                1.0 -=> zf;
            }
        }
        return r;
    }

    fun float noise_fsc(float i)
    {
        // using bagel's cosine table instead
        return 0.5 * ( 1.0 - perlin_cosTable[ ( ( i * perlin_PI ) % perlin_TWOPI ) $ int ] );
    }

}


Update bassdrum_electronic_deepboom2.ck

Update bassdrum_electronic_deepboom2.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;


took out gravity hum.

took out gravity hum.

OscRecv           wm;
Launchpad         lp;
OscBank oscBank;

false    =>   int prompt;
50::samp =>   dur gainResolution;
0.0016   => float releaseDecay;
0.00001   => float sustainDecay;
0.00001   => float sostenutoDecay;
0.01     => float pressAttack;
0.80     => float maxNoteGain;
0.0      =>   float rawGain;
0        =>   int currentTone;
false    =>   int sustain;
              int sustainStatus[8][8];
false    =>   int sostenuto;
              int sostenutoStatus[8][8];
0        =>   int lpChannel;

LaunchpadColor.red => int keyOnColor;
LaunchpadColor.lightRed => int keySustainColor;
LaunchpadColor.lightRed => int keySostenutoColor;
LaunchpadColor.red => int toneChoiceColor;
// ToneCalc.grid(8, 8, 1, 5,  82.4068867, 12.0) @=> float toneMap[][];
ToneCalc.grid(8, 8, 1, 5, 55.0, 12.0) @=> float toneMap[][];

fun void setup()
{
    OscBank.OscBank(8, 8, 1, 5, 55.0, 12.0) @=> oscBank;

    if(prompt)
    {
        intPrompt("Enter Midi Channel for Launchpad input: ") => lpChannel;

        Launchpad.Launchpad(lpChannel) @=> lp;
    }
    else
    {
        Launchpad.Launchpad(0) @=> lp;
    }

    me.yield();
    lp.clear();
    lp.setGridLight(8, currentTone, toneChoiceColor);

    spork ~ launchpadListener();
    spork ~ wiiListener();
    spork ~ updateGains();
}

fun void setTone(int toneChoice)
{
    if(toneChoice == currentTone)
    {
        return;
    }

    if(toneChoice == 0)
    {
        oscBank.setPatch("SinOsc");
    }
    else if(toneChoice == 1)
    {
        oscBank.setPatch("SqrOsc");
    }
    else if(toneChoice == 2)
    {
        oscBank.setPatch("SawOsc");
    }
    else if(toneChoice == 3)
    {
        oscBank.setPatch("TriOsc");
    }
    else
    {
        return;
    }

    lp.setGridLight(8, currentTone, 0);
    lp.setGridLight(8, toneChoice, toneChoiceColor);
    toneChoice => currentTone;
}

fun void sostenutoOn()
{
    true => sostenuto;
    for(0 => int i; i < 8; i++)
    {
        for(0 => int j; j < 8; j++)
        {
            if(lp.keyDown[i][j])
            {
                true => sostenutoStatus[i][j];
            }
        }
    }
}

fun void sostenutoOff()
{
    false => sostenuto;
    for(0 => int i; i < 8; i++)
    {
        for(0 => int j; j < 8; j++)
        {
            false => sostenutoStatus[i][j];
            if(!lp.keyDown[i][j])
            {
                lp.setGridLight(i, j, 0);
            }
        }
    }
}

fun void sustainOn()
{
    true => sustain;
    for(0 => int i; i < 8; i++)
    {
        for(0 => int j; j < 8; j++)
        {
            if(lp.keyDown[i][j])
            {
                true => sustainStatus[i][j];
            }
        }
    }
}

fun void sustainOff()
{
    false => sustain;
    for(0 => int i; i < 8; i++)
    {
        for(0 => int j; j < 8; j++)
        {
            false => sustainStatus[i][j];
            if(!lp.keyDown[i][j])
            {
                lp.setGridLight(i, j, 0);
            }
        }
    }
}

fun void release(int column, int row)
{
    Math.max(oscBank.gains[column][row].gain() - releaseDecay, 0.00)
        => oscBank.gains[column][row].gain;
}

fun void updateSustain(int column, int row, float targetGain)
{
    if(sustain && sustainStatus[column][row])
    {
        Math.max(oscBank.gains[column][row].gain() - sustainDecay, 0.00)
            => oscBank.gains[column][row].gain;
    }
    else
    {
        release(column, row);
    }
}

fun void updateSostenuto(int column, int row, float targetGain)
{
    if(sostenuto && sostenutoStatus[column][row])
    {
        Math.max(oscBank.gains[column][row].gain() - sostenutoDecay, 0.00)
            => oscBank.gains[column][row].gain;
    }
    else
    {
        updateSustain(column, row, targetGain);
    }
}

fun void update(int column, int row, float targetGain)
{
    if(lp.keyDown[column][row] && targetGain > oscBank.gains[column][row].gain())
    {
        Math.min(oscBank.gains[column][row].gain() + pressAttack, maxNoteGain)
            => oscBank.gains[column][row].gain;
    }
    else
    {
        updateSostenuto(column, row, targetGain);
    }
}

fun void updateGains()
{
    float targetGain;
    while(true) {
        // Math.max(0.0, (rawGain - 32) / 95.0) => targetGain;
        rawGain => targetGain;

        for(0 => int i; i < 8; i++)
        {
            for(0 => int j; j < 8; j++)
            {
                update(i, j, targetGain);
            }
        }

        gainResolution => now;
    }
}

fun int intPrompt(string msg)
{
    int in;
    ConsoleInput cin;
    StringTokenizer tok;
    cin.prompt(msg) => now;
    while(cin.more())
    {
        tok.set(cin.getLine());
        while(tok.more())
        {
            Std.atoi(tok.next()) => in;
        }
    }
    return in;
}

fun void launchpadListener()
{
    while(true)
    {
        lp.e => now;

        // ignore button presses that are not on the grid
        if(lp.e.column < 0 || lp.e.column > 8) continue;
        if(lp.e.row < 0 || lp.e.row > 7) continue;

        if(lp.e.column == 8)
        {
            if(lp.e.velocity == 127)
            {
                setTone(lp.e.row);
            }
        }
        else if(lp.e.velocity == 127)
        {
            if(sustain)
            {
                true => sustainStatus[lp.e.column][lp.e.row];
            }
            lp.setGridLight(lp.e.column, lp.e.row, keyOnColor);
            1 => oscBank.bank[lp.e.column][lp.e.row].op;
        }
        else if(sostenuto && sostenutoStatus[lp.e.column][lp.e.row])
        {
            lp.setGridLight(lp.e.column, lp.e.row, keySostenutoColor);
        }
        else if(sustain && sustainStatus[lp.e.column][lp.e.row])
        {
            lp.setGridLight(lp.e.column, lp.e.row, keySustainColor);
        }
        else
        {
            lp.setGridLight(lp.e.column, lp.e.row, 0);
        }
    }
}

fun void sustainListener()
{
    wm.event("/wii/1/button/B,i") @=> OscEvent e;
    while(true)
    {
        e => now;
        while(e.nextMsg() != 0)
        {
            if(e.getInt() == 0)
            {
                sustainOff();
            }
            else
            {
                sustainOn();
            }
        }
    }
}

fun void sostenutoListener()
{
    wm.event("/wii/1/button/A,i") @=> OscEvent e;
    while(true)
    {
        e => now;
        while(e.nextMsg() != 0)
        {
            if(e.getInt() == 0)
            {
                sostenutoOff();
            }
            else
            {
                sostenutoOn();
            }
        }
    }
}

fun void accelListener()
{
    wm.event("/wii/1/accel/pry/3,f") @=> OscEvent e;
    while(true)
    {
        e => now;
        while(e.nextMsg() != 0)
        {
            Math.max(0.0, e.getFloat() - 0.22) => rawGain;
            // chout <= rawGain <= IO.newline();
        }
    }
}

fun void wiiListener()
{
    6449 => wm.port;
    wm.listen();
    spork ~ sustainListener();
    spork ~ sostenutoListener();
    spork ~ accelListener();
    while(true)
    {
        1::second => now;
    }
}

setup();

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

OscRecv           wm;
Launchpad         lp;
OscBank oscBank;

false    =>   int prompt;
50::samp =>   dur gainResolution;
0.0016   => float releaseDecay;
0.00001   => float sustainDecay;
0.00001   => float sostenutoDecay;
0.01     => float pressAttack;
0.80     => float maxNoteGain;
0.0      =>   float rawGain;
0        =>   int currentTone;
false    =>   int sustain;
              int sustainStatus[8][8];
false    =>   int sostenuto;
              int sostenutoStatus[8][8];
0        =>   int lpChannel;

LaunchpadColor.red => int keyOnColor;
LaunchpadColor.lightRed => int keySustainColor;
LaunchpadColor.lightRed => int keySostenutoColor;
LaunchpadColor.red => int toneChoiceColor;
// ToneCalc.grid(8, 8, 1, 5,  82.4068867, 12.0) @=> float toneMap[][];
ToneCalc.grid(8, 8, 1, 5, 55.0, 12.0) @=> float toneMap[][];

fun void setup()
{
    OscBank.OscBank(8, 8, 1, 5, 55.0, 12.0) @=> oscBank;

    if(prompt)
    {
        intPrompt("Enter Midi Channel for Launchpad input: ") => lpChannel;

        Launchpad.Launchpad(lpChannel) @=> lp;
    }
    else
    {
        Launchpad.Launchpad(0) @=> lp;
    }

    me.yield();
    lp.clear();
    lp.setGridLight(8, currentTone, toneChoiceColor);

    spork ~ launchpadListener();
    spork ~ wiiListener();
    spork ~ updateGains();
}

fun void setTone(int toneChoice)
{
    if(toneChoice == currentTone)
    {
        return;
    }

    if(toneChoice == 0)
    {
        oscBank.setPatch("SinOsc");
    }
    else if(toneChoice == 1)
    {
        oscBank.setPatch("SqrOsc");
    }
    else if(toneChoice == 2)
    {
        oscBank.setPatch("SawOsc");
    }
    else if(toneChoice == 3)
    {
        oscBank.setPatch("TriOsc");
    }
    else
    {
        return;
    }

    lp.setGridLight(8, currentTone, 0);
    lp.setGridLight(8, toneChoice, toneChoiceColor);
    toneChoice => currentTone;
}

fun void sostenutoOn()
{
    true => sostenuto;
    for(0 => int i; i < 8; i++)
    {
        for(0 => int j; j < 8; j++)
        {
            if(lp.keyDown[i][j])
            {
                true => sostenutoStatus[i][j];
            }
        }
    }
}

fun void sostenutoOff()
{
    false => sostenuto;
    for(0 => int i; i < 8; i++)
    {
        for(0 => int j; j < 8; j++)
        {
            false => sostenutoStatus[i][j];
            if(!lp.keyDown[i][j])
            {
                lp.setGridLight(i, j, 0);
            }
        }
    }
}

fun void sustainOn()
{
    true => sustain;
    for(0 => int i; i < 8; i++)
    {
        for(0 => int j; j < 8; j++)
        {
            if(lp.keyDown[i][j])
            {
                true => sustainStatus[i][j];
            }
        }
    }
}

fun void sustainOff()
{
    false => sustain;
    for(0 => int i; i < 8; i++)
    {
        for(0 => int j; j < 8; j++)
        {
            false => sustainStatus[i][j];
            if(!lp.keyDown[i][j])
            {
                lp.setGridLight(i, j, 0);
            }
        }
    }
}

fun void release(int column, int row)
{
    Math.max(oscBank.gains[column][row].gain() - releaseDecay, 0.00)
        => oscBank.gains[column][row].gain;
}

fun void updateSustain(int column, int row, float targetGain)
{
    if(sustain && sustainStatus[column][row])
    {
        Math.max(oscBank.gains[column][row].gain() - sustainDecay, 0.00)
            => oscBank.gains[column][row].gain;
    }
    else
    {
        release(column, row);
    }
}

fun void updateSostenuto(int column, int row, float targetGain)
{
    if(sostenuto && sostenutoStatus[column][row])
    {
        Math.max(oscBank.gains[column][row].gain() - sostenutoDecay, 0.00)
            => oscBank.gains[column][row].gain;
    }
    else
    {
        updateSustain(column, row, targetGain);
    }
}

fun void update(int column, int row, float targetGain)
{
    if(lp.keyDown[column][row] && targetGain > oscBank.gains[column][row].gain())
    {
        Math.min(oscBank.gains[column][row].gain() + pressAttack, maxNoteGain)
            => oscBank.gains[column][row].gain;
    }
    else
    {
        updateSostenuto(column, row, targetGain);
    }
}

fun void updateGains()
{
    float targetGain;
    while(true) {
        // Math.max(0.0, (rawGain - 32) / 95.0) => targetGain;
        rawGain => targetGain;

        for(0 => int i; i < 8; i++)
        {
            for(0 => int j; j < 8; j++)
            {
                update(i, j, targetGain);
            }
        }

        gainResolution => now;
    }
}

fun int intPrompt(string msg)
{
    int in;
    ConsoleInput cin;
    StringTokenizer tok;
    cin.prompt(msg) => now;
    while(cin.more())
    {
        tok.set(cin.getLine());
        while(tok.more())
        {
            Std.atoi(tok.next()) => in;
        }
    }
    return in;
}

fun void launchpadListener()
{
    while(true)
    {
        lp.e => now;

        // ignore button presses that are not on the grid
        if(lp.e.column < 0 || lp.e.column > 8) continue;
        if(lp.e.row < 0 || lp.e.row > 7) continue;

        if(lp.e.column == 8)
        {
            if(lp.e.velocity == 127)
            {
                setTone(lp.e.row);
            }
        }
        else if(lp.e.velocity == 127)
        {
            if(sustain)
            {
                true => sustainStatus[lp.e.column][lp.e.row];
            }
            lp.setGridLight(lp.e.column, lp.e.row, keyOnColor);
            1 => oscBank.bank[lp.e.column][lp.e.row].op;
        }
        else if(sostenuto && sostenutoStatus[lp.e.column][lp.e.row])
        {
            lp.setGridLight(lp.e.column, lp.e.row, keySostenutoColor);
        }
        else if(sustain && sustainStatus[lp.e.column][lp.e.row])
        {
            lp.setGridLight(lp.e.column, lp.e.row, keySustainColor);
        }
        else
        {
            lp.setGridLight(lp.e.column, lp.e.row, 0);
        }
    }
}

// fun void wiiParser(MidiMsg msg)
// {
//     if(msg.data1 == 176) // midi CC
//     {
//         if(msg.data2 == 64)
//         { // wiimote acceleration
//             msg.data3 => rawGain;
//         }
//         else if (msg.data2 == 65)
//         {   // wiimote button b
//             if(msg.data3 == 127)
//             {
//                 sustainOn();
//             }
//             else
//             {
//                 sustainOff();
//             }
//         }
//         else if (msg.data2 == 66)
//         {   // wiimote button a
//             if(msg.data3 == 127)
//             {
//                 sostenutoOn();
//             }
//             else
//             {
//                 sostenutoOff();
//             }
//         }
//     }
// }

fun void sustainListener()
{
    wm.event("/wii/1/button/B,i") @=> OscEvent e;
    while(true)
    {
        e => now;
        while(e.nextMsg() != 0)
        {
            if(e.getInt() == 0)
            {
                sustainOff();
            }
            else
            {
                sustainOn();
            }
        }
    }
}

fun void sostenutoListener()
{
    wm.event("/wii/1/button/A,i") @=> OscEvent e;
    while(true)
    {
        e => now;
        while(e.nextMsg() != 0)
        {
            if(e.getInt() == 0)
            {
                sostenutoOff();
            }
            else
            {
                sostenutoOn();
            }
        }
    }
}

fun void accelListener()
{
    wm.event("/wii/1/accel/pry/3,f") @=> OscEvent e;
    while(true)
    {
        e => now;
        while(e.nextMsg() != 0)
        {
            e.getFloat() => rawGain;
        }
    }
}

fun void wiiListener()
{
    6449 => wm.port;
    wm.listen();
    spork ~ sustainListener();
    spork ~ sostenutoListener();
    spork ~ accelListener();
    while(true)
    {
        1::second => now;
    }
}

setup();

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