Update common_functions.ck

Update common_functions.ck

// 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[] 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 -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;
}


Support backspace in readline implementation


chordProgression change

chordProgression change

Now use queue to store chords.
/> chuck chordProgression to run

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"],
         ["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;
    }
}


Debug strings added

Debug strings added

<<< "Testing Stammer class" >>>;

<<< "Loading class" >>>;
Stammer stm => dac;
2.0 => stm.set_freq;
spork ~ stm.local_loop();

<<< "Loading audio files" >>>;
SndBuf buf_1;
SndBuf buf_2;
me.dir() + "/../sounds/test_sound_01.wav" => buf_1.read;
me.dir() + "/../sounds/test_sound_02.wav" => buf_2.read;

<<< "Running test" >>>;
buf_2 => stm;
10::second => now;

buf_2 =< stm;
buf_1 => stm;
10::second => now;

buf_2 => stm;
10::second => now;

Stammer stm => dac;
2.0 => stm.set_freq;
spork ~ stm.local_loop();

SndBuf buf_1;
SndBuf buf_2;
me.dir() + "/../sounds/test_sound_01.wav" => buf_1.read;
me.dir() + "/../sounds/test_sound_02.wav" => buf_2.read;

buf_2 => stm;
10::second => now;

buf_2 =< stm;
buf_1 => stm;
10::second => now;

buf_2 => stm;
10::second => now;


add chuck

add chuck

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

error: pathspec 'chuck/hello.ck' did not match any file(s) known to git


Create picking_oscillators.ck

Create picking_oscillators.ck

"sqr" => string voiceType;

Osc voiceOsc[1];

if (voiceType == "saw") {new SawOsc @=> voiceOsc[0];}
else if (voiceType == "sin") {new SinOsc @=> voiceOsc[0];}
else if (voiceType == "sqr") {new SqrOsc @=> voiceOsc[0];}

voiceOsc[0].gain(0.5);
voiceOsc[0] => dac;

2::second => now;

error: pathspec 'demo_files/picking_oscillators.ck' did not match any file(s) known to git


added BKickONE class

added BKickONE class

this might be a convenient way to write a percussion synth class,
convenience methods for patch setting and saving.

public class BKickONE {

    Mix2 mout;
    dur a, d, s, r;
    float slevel;
    float vol;

    float fg, fph, ffr;
    float sg, sph, sfr;

    fun void adssr(dur a, dur d, dur s, dur r, float slevel){
        a => this.a;
        d => this.d;
        s => this.s;
        r => this.r;
        slevel => this.slevel;
    }

    fun void set_values_direct(float values[]){
        values[0] => this.fg;
        values[1] => this.fph;
        values[2] => this.ffr;
        values[3] => this.sg;
        values[4] => this.sph;
        values[5] => this.sfr;
    }

    fun void patch(int n){
        if (n==1) set_values_direct([222.0, -pi, 1.27, -3.1, -pi/2, .01]);
    }

    fun void trigger(float vol){
        vol => this.vol;
        mout.gain(vol);
        spork ~ do_kick();
    }

    fun void do_kick(){

        // carrier
        SinOsc s;
        s.gain(vol);
        s => ADSR vEnv => mout;

        // modulator
        SawOsc sawForm => s;
        s.phase(0);
        s.sync(2);
        sawForm.gain(fg);
        sawForm.phase(fph);
        sawForm.freq(ffr);

        // modulate the modulator
        SinOsc sShape => sawForm;
        sawForm.sync(2);
        sShape.gain(sg);
        sShape.phase(sph);
        sShape.freq(sfr);

        // pass time
        vEnv.set(a, d, slevel, r);
        vEnv.keyOn();
        (this.a + this.d + this.s) => now;

        vEnv.keyOff();
        this.r => now;

    }

    // set defaults
    adssr(2::ms, 171::ms, 0::ms, 35::ms, 0.20);
    patch(1);

}

BKickONE kick;
kick.mout => dac;
kick.trigger(.9);

2::second => now;

// edit -w

error: pathspec 'patches/percussion/BKickONE.ck' did not match any file(s) known to git


Create bassdrum_electric_thud.ck

Create bassdrum_electric_thud.ck

// bassdrum synthesis
// Dealga McArdle, Nov 2013
SawOsc spitch => SinOsc bd_osc =>
Gain preAmp => ADSR bdADSR => Gain master => dac;

1.2 => master.gain;
20 => bd_osc.freq;
162.02 => spitch.gain;
2 => bd_osc.sync;
.7 => preAmp.gain;

fun void BD1_ON(float pgain){
    bdADSR.set( 2::ms, 181::ms, 0.0, 35::ms );
    pgain => preAmp.gain;
    -1.0 => spitch.phase;
    .5 => spitch.sfreq;
    bdADSR.keyOn();
}

BD1_ON(.7);
0.75::second => now;

error: pathspec 'patches/percussion/bassdrum_electric_thud.ck' did not match any file(s) known to git


Create common_functions.ck

Create common_functions.ck

i've used these a lot already.

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

}

error: pathspec 'utility_functions/common_functions.ck' did not match any file(s) known to git


Create MidiIn2Notes.ck

Create MidiIn2Notes.ck

MidiIn min;
MidiMsg msg;

// open midi receiver, exit on fail
if ( !min.open(0) ) me.exit();

int notes[0];
int ncount;
while( true )
{
    min => now;
    while( min.recv( msg ) )
    {
        msg.data1 => int mode;
        //<<< mode >>>;
        msg.data2 => int note;
        msg.data3 => int volume;

        if (mode == 144) {
             chout <= note;
             chout <= ", ";
        }
    }

    chout <= IO.newline();
    int a[0] @=> notes;
}

error: pathspec 'utility_functions/MidiIn2Notes.ck' did not match any file(s) known to git


renamed the to mouse

renamed the to mouse

// control LFO's (no sound)
SinOsc a => blackhole;
SinOsc b => blackhole;

// frequencies
1.1 => a.freq;
1.13 => b.freq;

// FM synthesis
SinOsc c => SinOsc d => dac;
2 => d.sync;

// time loop
while( true )
{
    // send data to graphics
    VR.setFloat( "color-x", (a.last()+1)/2*620 );
    VR.setFloat( "color-y", (b.last()+1)/2*620 );

    // get values from graphics
    VR.getFloat( "mouse-x" ) => d.freq;
    d.freq() * 2 => c.freq;
    VR.getFloat( "mouse-y" ) => c.gain;

    // when there is a new graphics draw
    VR.displaySync() => now;
}

error: pathspec 'example/ck/mouse.ck' did not match any file(s) known to git


Initial record to file

Initial record to file

// chuck this with other shreds to record to file
// example> chuck foo.ck bar.ck rec (see also rec2.ck)

// arguments: rec:<filename>

// get name
me.arg(0) => string filename;
if( filename.length() == 0 ) "audio.mp3" => filename;

// pull samples from the dac
dac => Gain g => WvOut w => blackhole;
// this is the output file name
filename => w.wavFilename;
<<<"writing to file:", "'" + w.filename() + "'">>>;
// any gain you want for the output
.5 => g.gain;

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

// infinite time loop...
// ctrl-c will stop it, or modify to desired duration
while( true ) 1::second => now;

error: pathspec 'rec.ck' did not match any file(s) known to git


adding first turenas example

adding first turenas example

// keyboard
Hid kb;
// hid message
HidMsg msg;

// open
if( !kb.openKeyboard(0) ) me.exit();
<<< "KB open:", kb.name() >>>;
spork ~ kbf();

// patch
SndBuf L => dac.left;
SndBuf R => dac.right;

// envelope followers
L => OnePole envL => blackhole; L => envL; 3 => envL.op;
R => OnePole envR => blackhole; R => envR; 3 => envR.op;
.9995 => envL.pole => envR.pole;

// load
me.dir() + "../audio/turenas-L.aiff" => L.read;
me.dir() + "../audio/turenas-R.aiff" => R.read;
L.samples() => L.pos;
R.samples() => R.pos;
0 => L.gain => R.gain;

-100 => float FRONT;
FRONT * .5 => float FRONT_FENCE;
100 => float BACK;
BACK * .5 => float BACK_FENCE;

// entities
VREntity es[0];
vec3 v;
polar p;
complex c;
fun void makeOne()
{
    // make a some points
    VR.makeEntity("one"+es.size(),"mesh") @=> VREntity mesh;
    // make
    mesh.eval( "vertex -1 -1 0" );
    //mesh.eval( "color 1 1 1" );
    mesh.eval( "normal 0 0 1" );
    mesh.eval( "vertex 1 -1 0" );
    //mesh.eval( "color 1 1 1" );
    mesh.eval( "normal 0 0 1" );
    mesh.eval( "vertex -1 1 0" );
    //mesh.eval( "color 1 1 1" );
    mesh.eval( "normal 0 0 1" );
    mesh.eval( "vertex 1 1 0" );
    //mesh.eval( "color 1 1 1" );
    mesh.eval( "normal 0 0 1" );
    // draw as triangle
    mesh.eval( "draw trianglestrip" );
    // add to world
    VR.root().addChild( mesh );
    // loc
    Math.random2f(5,100) => p.mag;
    Math.random2f(-pi,pi) => p.phase;
    p$complex => c;
    c.re => mesh.loc.x;
    c.im => mesh.loc.z;
    Math.random2f(FRONT,FRONT_FENCE) => mesh.loc.y;

    Math.random2f(.1,1) => mesh.rgba.r;
    Math.random2f(.1,1) => mesh.rgba.g;
    Math.random2f(.1,1) => mesh.rgba.b;
    Math.random2f(0,0) => mesh.rgba.a;
    Math.random2f(0,360) => mesh.ori.y;

    // add
    es << mesh;
}

VREntity @ es2[0];
float es2t[0];

fun void makeTwo()
{
    // make a some points
    VR.makeEntity("two"+es.size(),"flare") @=> VREntity f;
    // set the texture
    f.setString( "texture", "texture:flare-1");
    // loc
    Math.random2f(5,100) => p.mag;
    Math.random2f(-pi,pi) => p.phase;
    p$complex => c;
    c.re => f.loc.x;
    c.im => f.loc.y;
    f.sca.setAll(10);
    Math.random2f(FRONT,FRONT_FENCE) => f.loc.z;

    Math.random2f(1,1) => f.rgba.r;
    Math.random2f(1,1) => f.rgba.g;
    Math.random2f(1,1) => f.rgba.b;
    Math.random2f(0,0) => f.rgba.a;

    // add
    es2 << f;
    es2t << Math.random2f(0,2*pi);

    // add to world
    VR.root().addChild( f );
}

VREntity @ es3[0];
float es3t[0];

-500 => float FRONT3;
FRONT3 * .5 => float FRONT_FENCE3;
300 => float BACK3;
BACK3 * .5 => float BACK_FENCE3;

fun void makeThree( float inner, float outer, float whereY, float varyY )
{
    // make a some points
    VR.makeEntity("three"+es.size(),"mesh") @=> VREntity f;
    // set the texture
    f.setString( "texture", "texture:flare-1");

    f.eval( "draw points" );
    repeat(4000)
    {
        // loc
        Math.random2f(inner,outer) => p.mag;
        Math.random2f(-pi,pi) => p.phase;
        p$complex => c;
        c.re => v.x;
        Math.random2f(-1,1) => v.y;
        c.im => v.z;
        f.eval( "vertex", v );
    }

    0 => f.loc.x;
    0 => f.loc.z;
    Math.random2f(whereY,whereY*varyY) => f.loc.y;

    Math.random2f(1,1) => f.rgba.r;
    Math.random2f(1,1) => f.rgba.g;
    Math.random2f(1,1) => f.rgba.b;
    Math.random2f(0,0) => f.rgba.a;

    // add
    es3 << f;
    es3t << .0000002 / Math.pow((inner+outer)/6.0/outer,10);
    // <<< "spin:", es3t[es3t.size()-1] >>>;

    // add to world
    VR.root().addChild( f );
}

//repeat(4)
//    for(int i; i < 10; i++ )
//        makeThree( 2*(20+i*15), 4*(20+i*15+5), FRONT3*3, .6 );

//repeat(4)
//    for(int i; i < 10; i++ )
//        makeThree( 2*(20+i*15), 4*(20+i*15+5), FRONT3*6, .6 );

//repeat(4)
//    for(int i; i < 10; i++ )
//        makeThree( 2*(20+i*15), 4*(20+i*15+5), FRONT3*12, .6 );

// disable lights
VR.allLightsOn();

// bang detector
fun void bangDetect()
{
    while( true )
    {
        if( envL.last() > 0.0001 )
        {
            <<< "BANG!!", now/second >>>;
            100::ms => now;
        }
        10::ms => now;
    }
}

// detector
// spork ~ bangDetect();
VREntity @ e;

// loop
while( true )
{
    for( int i; i < es.size(); i++ )
    {
        es[i] @=> e;
        if( e.loc.y <= FRONT_FENCE )
            1-Math.fabs((e.loc.y-FRONT_FENCE)/(FRONT-FRONT_FENCE)) => e.rgba.a;
        else if( e.loc.y >= BACK_FENCE )
            1-Math.fabs((e.loc.y-BACK_FENCE)/(BACK-BACK_FENCE)) => e.rgba.a;
        else
            1 => e.rgba.a;

        if( e.rgba.a < 0 ) 0 => e.rgba.a;
        else if( e.rgba.a > 1 ) 1 => e.rgba.a;

        5 +=> e.ori.y;
        .5 +=> e.loc.y;
        if( e.loc.y > BACK ) FRONT => e.loc.y;
    }

    for( int i; i < es2.size(); i++ )
    {
        es2[i] @=> e;
        if( e.loc.z <= FRONT_FENCE )
            1-Math.fabs((e.loc.z-FRONT_FENCE)/(FRONT-FRONT_FENCE)) => e.rgba.a;
        else if( e.loc.z >= BACK_FENCE )
            1-Math.fabs((e.loc.z-BACK_FENCE)/(BACK-BACK_FENCE)) => e.rgba.a;
        else
            1 => e.rgba.a;

        if( e.rgba.a < 0 ) 0 => e.rgba.a;
        else if( e.rgba.a > 1 ) 1 => e.rgba.a;

        Math.pow(envL.last(),1)*100 *=> e.rgba.a;

        5 * (1 + .2*Math.sin(es2t[i])) => e.sca.setAll; .1 +=> es2t[i];
        .2 +=> e.loc.z;
        if( e.loc.z > BACK ) FRONT => e.loc.z;
    }

    for( int i; i < es3.size(); i++ )
    {
        es3[i] @=> e;
        if( e.loc.y <= FRONT_FENCE3 )
            1-Math.fabs((e.loc.y-FRONT_FENCE3)/(FRONT3-FRONT_FENCE3)) => e.rgba.a;
        else if( e.loc.y >= BACK_FENCE3 )
            1-Math.fabs((e.loc.y-BACK_FENCE3)/(BACK3-BACK_FENCE3)) => e.rgba.a;
        else
            1 => e.rgba.a;

        if( e.rgba.a < 0 ) 0 => e.rgba.a;
        else if( e.rgba.a > 1 ) 1 => e.rgba.a;

        es3t[i] +=> e.ori.y;
        .5 +=> e.loc.y;
        if( e.loc.y > BACK3 ) FRONT3 => e.loc.y;
    }

    // VR.root().rgba.setAll(Math.pow(envL.last(),.75)*500);

    // synch with display
    VR.displaySync() => now;
}

fun void kbf()
{
    while( true )
    {
        // wait
        kb => now;
        // wait
        while( kb.recv(msg) )
        {
            if( !msg.isButtonDown() )
                continue;

            if( msg.ascii == 48 ) // 1
            {
                0 => L.pos => R.pos;
                1 => L.gain => R.gain;
            }
            // <<< "kb:", msg.ascii >>>;
            if( msg.ascii == 49 ) // 1
            {
                repeat(10) makeOne();
            }
            else if( msg.ascii == 50 ) // 2
            {
                repeat(10) makeTwo();
            }
            else if( msg.ascii == 51 ) // 3
            {
                for(int i; i < 10; i++ )
                    makeThree( 2*(20+i*15), 4*(20+i*15+5), FRONT3*2.5, .75 );
            }
        }
    }
}

error: pathspec 'example_OculusDK2/bin/data/ck/turenas-1.ck' did not match any file(s) known to git


oh damn, oscbank should have been added earlier.

public class OscBank
{
    int width;
    int height;
    int columnStep;
    int rowStep;
    string currentPatch;
    float baseFreq;
    float octaveSteps;
    UGen @ bank[][];
    Gain @ gains[][];

    fun static OscBank OscBank(int width, int height, int columnStep,
                               int rowStep, float baseFreq, float octaveSteps)
    {
        return OscBank(width, height, columnStep, rowStep, baseFreq,
                       octaveSteps, true);
    }

    fun static OscBank OscBank(int width, int height, int columnStep,
                               int rowStep, float baseFreq, float octaveSteps,
                               int autoPatch)
    {
        OscBank oscBank;
        width => oscBank.width;
        height => oscBank.height;
        columnStep => oscBank.columnStep;
        rowStep => oscBank.rowStep;
        baseFreq => oscBank.baseFreq;
        octaveSteps => oscBank.octaveSteps;
        new UGen[width][height] @=> oscBank.bank;
        new Gain[width][height] @=> oscBank.gains;

        ToneCalc.grid(width, height, columnStep, rowStep,  baseFreq, octaveSteps)
            @=> float toneMap[][];

        for(0 => int i; i < width; i++)
        {
            for(0 => int j; j < height; j++)
            {
                TriOsc s;
                toneMap[i][j] => s.freq;

                Gain g;
                0 => g.gain;
                s @=> oscBank.bank[i][j] => g @=> oscBank.gains[i][j];
            }
        }

        if(autoPatch == true)
        {
            oscBank.patch();
        }

        return oscBank;
    }

    fun int checkRange(int column, int row)
    {
        return !(column < 0
            || column >= width
            || row < 0
            || row >= height);
    }

    fun int checkRange(int column, int row, string identifier)
    {
        checkRange(column, row) => int val;
        if(!val)
            cherr <= "[Out of range in OscBank." <= identifier <= "()]\t"
                <= column <= "\t" <= row <= "\t" <= IO.newline();
        return val;
    }

    fun void setPatch(string targetPatch)
    {
        for(0 => int i; i < width; i++)
            for(0 => int j; j < height; j++)
                setPatch(targetPatch, i, j);
    }

    fun void setPatch(string targetPatch, int column, int row)
    {
        if(!checkRange(column, row, "setPatch"))
            return;

        Osc s;
        if(targetPatch == "SinOsc")
        {
            new SinOsc @=> s;
        }
        else if(targetPatch == "SqrOsc")
        {
            new SqrOsc @=> s;
        }
        else if(targetPatch == "SawOsc")
        {
            new SawOsc @=> s;
        }
        else if(targetPatch == "TriOsc")
        {
            new TriOsc @=> s;
        }
        else
        {
            cherr <= "Unrecognized targetPatch supplied in OscBank.setPatch:"
                <= targetPatch <= IO.newline();
        }

        toneMap()[column][row] => s.freq;
        0 => bank[column][row].op;
        bank[column][row] =< gains[column][row];
        s @=> bank[column][row] => gains[column][row];
    }

    fun void patch()
    {
        for(0 => int i; i < bank.size(); i++)
        {
            for(0 => int j; j < bank[0].size(); j++)
            {
                gains[i][j] => dac;
            }
        }
    }

    fun void unpatch()
    {
        for(0 => int i; i < bank.size(); i++)
            for(0 => int j; j < bank[0].size(); j++)
                unpatch(i, j);
    }

    fun void unpatch(int column, int row)
    {
        gains[column][row] =< dac;
    }

    fun void rebase(float freq)
    {
        for(0 => int i; i < bank.size(); i++)
        {
            for(0 => int j; j < bank[0].size(); j++)
            {
                bank[i][j] =< dac;
            }
        }
    }

    fun float getFreq(int column, int row)
    {
        if(checkRange(column, row))
        {
            return toneMap()[column][row];
        }
        else
            return 220.0;
    }

    fun void setGain(int column, int row, int value)
    {
        if(checkRange(column, row, "setGain"))
            value => bank[column][row].gain;
    }

    fun float getGain(int column, int row)
    {
        if(checkRange(column, row, "getGain"))
            return bank[column][row].gain();
        else
            return 0.0;
    }

    fun int getOp(int column, int row)
    {
        if(checkRange(column, row, "getOp"))
            return bank[column][row].op();
        else
            return false;
    }

    fun void setOp(int value)
    {
        if(value != 0 && value != 1 && value != false && value != true)
        {
            cherr <= "Invalid value sent to OscBank.setOp():" <= value
                <= IO.newline();
            for(0 => int i; i < width; i++)
            {
                for(0 => int j; j < height; j++)
                {
                    0 => bank[i][j].op;
                }
            }
        }
        else
        {
            for(0 => int i; i < width; i++)
            {
                for(0 => int j; j < height; j++)
                {
                    value => bank[i][j].op;
                }
            }
        }
    }

    fun float[][] toneMap()
    {
        return ToneCalc.grid(width, height, columnStep, rowStep,  baseFreq, octaveSteps);
    }
}

error: pathspec 'oscbank.ck' did not match any file(s) known to git


Create perc_electric_slapclap(PercSynC).ck

/bin/sh: 1: Syntax error: "(" unexpected


Create bassdrum_electronic_deepboom.ck

Create bassdrum_electronic_deepboom.ck

not great, but it's a start, named SynC because it should retrigger on a specific phase each time, C means it's driven by a curve. (curve not implemented in this version)

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

error: pathspec 'patches/percussion/bassdrum_electronic_deepboom.ck' did not match any file(s) known to git


Create bassdrum_electronic_nice_thud.ck

Create bassdrum_electronic_nice_thud.ck

// I would appreciate if you would link to this source if you use this patch.

public class KickSynC{

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

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

    fun void s_do_kick(){

        CurveTable c;
        [0., 1590, -7.98,
        0.017, 440, -.98,
        0.05, 140, -.98,
        .17, 114, 0,
        .61, 54, 0,
        1.8, 41.] => c.coefs;

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

        // simple adsr
        ADSR volE;
        volE.set( 0::ms, 221::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);
        1222 => boom.freq;

        // set

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

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

        1::second => now;
    }

}

/*
    Usage docs

    KickSynC kick1;

    kick1.bdmast => dac;
    kick1.bdmast => NRev blunk => dac;
    blunk.gain(0.01);
    blunk.mix(0.2);

    for(0 => int i; i<5; i++){
        kick1.trigger(4.4);
        0.5::second => now;
    }
*/

error: pathspec 'patches/percussion/bassdrum_electronic_nice_thud.ck' did not match any file(s) known to git


Create LiSa_LiveSampler_from_SndBuf.ck

Create LiSa_LiveSampler_from_SndBuf.ck

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

load_sample("hihat_04") @=> SndBuf perc_sample;
perc_sample => Gain master_sample => dac;
master_sample => Pan2 sample_pan => dac;

LiSa liveSampl1 => NRev rname => Gain big => dac;
(10*240*22)::samp => dur bigtime => liveSampl1.duration;

rname.mix(0.2);
master_sample => liveSampl1;
big.gain(4);

1 => liveSampl1.record;
for(2 => int j; j<10; j++){
    ((((j%2)*2)-1)*.9) => sample_pan.pan;
    for(0 => int i; i<240; i++){
        0.01 => master_sample.gain;
        0 + (i*j*142)=> perc_sample.pos;
        22::samp => now;
    }
}
0 => liveSampl1.record;

for(0 => int i; i<4; i++){
    0 => liveSampl1.playPos;
    -.3 => liveSampl1.rate;
    1 => liveSampl1.play;
    bigtime => now;
    0 => liveSampl1.play;
}

error: pathspec 'demo_files/LiSa_LiveSampler_from_SndBuf.ck' did not match any file(s) known to git


Chord Progression

Chord Progression

A raw chord progression file

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

error: pathspec 'chordProgression.ck' did not match any file(s) known to git


Adding a basic implementation in ChucK

Adding a basic implementation in ChucK

error: pathspec 'chuck/daisy-basic.ck' did not match any file(s) known to git


Create dBFStoGain.ck

Create dBFStoGain.ck

See source comments

/* Allows inputting a dBFS value like a normal (sound engineer)
person (e.g. -6dB for a "tame" peak value), and getting a
ChucK "gain" number out (e.g. for -6dB, 0.501187).
The results seem to indicate that ChucK's gain, calculated
using the 'Std.dbtorms()' method, conforms to amplitude
(as a ratio) as shown in the chart at the top of
http://en.wikipedia.org/wiki/Decibel.

I'd call it verified:
dBFStoGain( x ) = y
 +3 = ~1.4
  0 = 1      // Unity gain
 -6 = ~0.5
-12 = ~0.25
*/

// Not exactly rocket science >_<
fun float dBFStoGain(float dBFS){
    return Std.dbtorms( dBFS + 100 );
}

error: pathspec 'dBFStoGain.ck' did not match any file(s) known to git


sandbox script for playing with chuck filters

/*
* Script for playing with adsr
*/

4000 => int interval;

// adsr
ADSR adsr;
200 => int a;
800 => int d;
interval - a - d => int r;
adsr.set( a::ms, d::ms, 0, r::ms );

// reverb
//JCRev rvb;
//NRev rvb;
PRCRev rvb;
0.1 => rvb.mix;

// echo
Echo echo;
0.5 => echo.mix;
500::ms => echo.delay;
1000::ms => echo.max;

// chorus
Chorus chrs;
0.5 => chrs.modFreq;
0.5 => chrs.modDepth;
0.5 => chrs.mix;

// pitch shift
PitShift pts;
0.5 => pts.mix;
0.5 => pts.shift;

// sndbuf
SndBuf instrument;
me.dir() + "/dating/instruments/marvin1a.wav" => instrument.read;
instrument.samples() => instrument.pos;

// instrument => adsr => echo => rvb => dac;
instrument => echo => rvb => chrs => dac;
// instrument => pts => dac;

while(true) {
    adsr.keyOn();
    0 => instrument.pos;
    1 => instrument.gain;
    1 => instrument.rate;
    interval::ms => now;
    adsr.keyOff();
}

<<< "Done." >>>;

error: pathspec 'sandbox/filters.ck' did not match any file(s) known to git


Create vibraphoney.ck

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

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

}

error: pathspec 'patches/melodic/vibraphoney.ck' did not match any file(s) known to git


Create WaveformMixerMono.ck

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

error: pathspec 'patches/WaveformMixerMono.ck' did not match any file(s) known to git


Create chuck_midi_in_to_notes_array.ck

Create chuck_midi_in_to_notes_array.ck

a little iffy.

// MidiIn min;
// MidiMsg msg;

// // open midi receiver, exit on fail
// if ( !min.open(0) ) me.exit();

// while( true )
// {
//     // wait on midi event
//     min => now;

//     // receive midimsg(s)
//     while( min.recv( msg ) )
//     {
//         // print content
//         <<< msg.data1, msg.data2, msg.data3 >>>;
//     }
// }

MidiIn min;
MidiMsg msg;

// open midi receiver, exit on fail
if ( !min.open(0) ) me.exit();

int notes[0];
while( true )
{
    // wait on midi event
    min => now;

    // receive midimsg(s)
    while( min.recv( msg ) )
    {
        // print content
        msg.data1 => int mode;
        msg.data2 => int note;
        msg.data3 => int volume;

        if (mode == 128) notes << note;
        //else { [] @=> notes; }
    }
    if (notes.cap() > 0) {
        repr_int_array(notes);
    }
    int a[0] @=> notes;
}

//  array
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 <= "] @=> int notes[];";
    chout <= IO.newline();
}

error: pathspec 'demo_files/chuck_midi_in_to_notes_array.ck' did not match any file(s) known to git


quicksort in chuck

quicksort in chuck

/*

    Quicksort implementation in chuck.
    Copyright (C) 2016 Abram Hindle, Ge Wang

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

*/

// fill arr with values 0 to size-1
function void fillrange(int arr[], int size) {
    for (0 => int i; i < size; 1 +=> i) {
        i => arr[i];
    }
}

// reverse the order of elements in arr
function void reverse(int arr[]) {
    arr.cap() / 2 => int mid;
    arr.cap() => int s;
    int tmp;
    for (0 => int i; i < mid; i + 1 => i) {
        arr[i] => tmp;
        arr[s - 1 - i] => arr[i];
        tmp => arr[s - 1 - i];
    }
}

// quicksort, call with your arr of indices and float values
// quicksort(indices, values, 0, values.cap() - 1) sorts indices
function void quicksort(int arr[], float values[], int lo, int hi) {
    if (lo < hi) {
        partition(arr, values, lo,hi) => int p;
        quicksort(arr, values, lo, p - 1);
        quicksort(arr, values, p + 1, hi);
    }
}

function int partition(int arr[], float values[], int lo, int hi) {
    int tmp;
    values[arr[hi]] => float pivot;
    lo => int i;
    for ( lo => int j; j <= hi - 1 ; j + 1 => j) {
        if (values[arr[j]] <= pivot) {
            arr[i] => tmp;
            arr[j] => arr[i];
            tmp => arr[j];
            i + 1 => i;
        }
    }
    arr[i] => tmp;
    arr[hi] => arr[i];
    tmp => arr[hi];
    return i;
}

// fisher-yates shuffle
function void shuffle(int arr[], int size) {
    for (0 => int i; i < size -2; i + 1 => i) {
        Math.random2(i,size-1) => int j;
        arr[i] => int tmp;
        arr[j] => arr[i];
        tmp => arr[j];
    }
}

error: pathspec 'quicksort.ck' did not match any file(s) known to git


Added Solution.ck file. Configured with fixes that disable the signature.

<?xml version="1.0" encoding="utf-8"?>
<c:Solution xmlns:c="http://invenietis.net/ck-release">
  <c:Version>2</c:Version>
  <c:Name>CK-Stamp</c:Name>
  <c:Fixes>
    <c:Disabled>Standard shared key file must exist.</c:Disabled>
    <c:Disabled>Remove FileVersionAttribute in SharedAssemblyInfo.cs.</c:Disabled>
    <c:Disabled>Ensures Version Attributes in SharedAssemblyInfo.cs.</c:Disabled>
    <c:Disabled>Assembly 'CK.Stamp.Fody' must be signed.</c:Disabled>
    <c:Disabled>Assemblies that 'CK.Stamp.Fody' references must be signed.</c:Disabled>
  </c:Fixes>
  <c:Versioning c:Mode="Simple" />
  <c:InfoReleaseDatabase>
    <c:Name />
    <c:GUID />
  </c:InfoReleaseDatabase>
</c:Solution>

error: pathspec 'Solution.ck' did not match any file(s) known to git


Create to_stereo_wav_with_gainParams.ck

Create to_stereo_wav_with_gainParams.ck

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

error: pathspec 'wave_writer/to_stereo_wav_with_gainParams.ck' did not match any file(s) known to git


Create perc_electric_versatyle(PercSynC).ck


First rewrite of Panner beet

First rewrite of Panner beet

// due to the mono nature of the Gain UGen
// never connect Panner to Gain based UGens
// or Beets. Panner works best as a last
// UGen in the effects line
public class Panner extends Chubgraph {
  Pan2 panner;
  OscEvent osc_event;

  // Constructor
  {
    inlet => panner => outlet;
  }

  fun void osc_event(OscEvent e) {
    e @=> osc_event;
  }

  // private timeloop
  fun void on() {
    while(true) {
      osc_event => now;

      while(osc_event.nextMsg() != 0) {
        osc_event.getFloat() => float p;
        p => panner.pan;
      }

      100::ms => now;
    }
  }
}

error: pathspec 'lib/panner.ck' did not match any file(s) known to git


Create eletronic_snare_dumb2.ck

Create eletronic_snare_dumb2.ck

Mix2 mout => Dyno dyno => ADSR masterEnv => dac;
SinOsc sin1 => ADSR oscEnv1 => mout;
SinOsc sin2 => ADSR oscEnv2 => mout;
SinOsc detune => ADSR detuneEnv => sin2;
SawOsc detune2 => sin1;
Noise noise1 => LPF filt1_lp => ADSR lpfEnv => mout;
Noise noise2 => HPF filt2_hp => ADSR hpfEnv => mout;
2 => sin1.sync;
2 => sin2.sync;
mout.gain(0.5);

dyno.compress();
dyno.thresh(0.05);
dyno.ratio(0.4);

fun void trigger(float tune, int decay, int brightness, float snappy){

    masterEnv.set( 2::ms, (decay*17.7)::ms, 0.00, 0::ms );  //a, d, s, r
    masterEnv.gain(.15);
    masterEnv.keyOn();

    // detune of osc
    detuneEnv.set( 2::ms, decay*2::ms, 0.0, 0::ms );  //a, d, s, r
    detuneEnv.keyOn();
    6.42 => detune.freq;
    detune.gain(56.0);
    tune => sin1.freq;
    tune => sin2.freq;
    detune2.gain(222.0);
    detune2.freq(0.16);

    // two oscillator setup

    sin1.gain(.8);
    sin2.gain(.7);
    sin1.phase(pi);
    sin2.phase(pi);
    oscEnv1.set( 2::ms, decay*0.7::ms, 0.00, 35::ms );  //a, d, s, r
    oscEnv2.set( 2::ms, decay::ms, 0.00, 35::ms );  //a, d, s, r
    oscEnv1.keyOn();
    oscEnv2.keyOn();

    // noise lowpass
    lpfEnv.set( 2::ms, (decay/.317)::ms, 0.00, 35::ms );  //a, d, s, r
    lpfEnv.keyOn();
    brightness => filt1_lp.freq;

    // noise lowpass
    if (snappy > 1.0) 1.0 => snappy;
    220 => filt2_hp.freq;
    2.7 => filt2_hp.Q;
    snappy => noise2.gain;
    hpfEnv.set( 19::ms, (decay*7.25)::ms, 0.00, 35::ms );  //a, d, s, r
    hpfEnv.keyOn();

    // pass time.
    decay*5::ms => now;
    // oscEnv1.keyOff();
    // oscEnv2.keyOff();
    // lpfEnv.keyOff();
    // hpfEnv.keyOff();

}

trigger(70.0, 90, 230, .6);

1::second => now;

error: pathspec 'patches/percussion/eletronic_snare_dumb2.ck' did not match any file(s) known to git


Create bassdrum_electronic_deepboom2.ck

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

error: pathspec 'patches/percussion/bassdrum_electronic_deepboom2.ck' did not match any file(s) known to git


Create bassdrum_electronic_deepboom3.ck

Create bassdrum_electronic_deepboom3.ck

// with some example how to wire it up.

public class KickSynC{

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

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

    fun void s_do_kick(){

        CurveTable c;
        [0., 1590, -7.98,
        0.05, 240, -.98,
        .17, 114, 0,
        .61, 54, 0,
        1.8, 41.] => c.coefs;

        // frequency curve
        ADSR e => blackhole;
        e.set( 0::ms, 740::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);
        432 => boom.freq;

        // set

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

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

        1::second => now;
    }

}

KickSynC kick1;

kick1.bdmast => dac;
kick1.bdmast => NRev blunk => dac;
blunk.gain(0.01);
blunk.mix(0.2);

for(0 => int i; i<5; i++){
    kick1.trigger(4.4);
    0.5::second => now;
}

error: pathspec 'patches/percussion/bassdrum_electronic_deepboom3.ck' did not match any file(s) known to git


Create clap_simple.ck

Create clap_simple.ck

// samples.ck
NRev ae => dac;
ae.mix(0.0152);
ae.gain(0.0212);

load_sample(me.dir(-1), "clap_01") @=> SndBuf clapdata;
clap_trigger();
4::second => now;

fun void clap_trigger(){
    // seg 1
    spork ~ clap_part(0.024, 0.6, rpos());
    0.0118::second => now;
    // seg 2
    spork ~ clap_part(0.0023, 0.8, rpos());
    0.0243::second => now;
    // seg 3
    spork ~ clap_part(0.0033, 0.7, rpos());
    0.033::second=>now;
    // seg 4
    spork ~ clap_part(0.376, 1.0, rpos());
    0.7::second => now;  // tail
}

fun void clap_part(float fms, float force, int srpos){
    clapdata => ADSR t => HPF hpf => Gain dp => ae;
    t => HPF hpf2 => dp;
    dp.gain(22.0 * force);
    hpf.freq(1800);
    hpf2.freq(1300);
    hpf2.Q(2.3);

    t.set(0.2::ms, (fms)::second, 0.13, 220::ms );
    t.keyOn(1);
    srpos => clapdata.pos;
    (fms)::second => now;
    t.keyOff(1);
}

fun int rpos(){
    return Math.random2(700, 600);
}

fun SndBuf load_sample(string path, string wavname){
    // usage:  load_sample("kick_02") @=> SndBuf kick => dac;

    // turn incoming wavname into   path/wavename.wav
    SndBuf temp_buff;
    path + "/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; // optional default

    // return a reference to the new buffer object.
    return temp_buff;
}

error: pathspec 'patches/percussion/clap_simple.ck' did not match any file(s) known to git


turenas prelim

turenas prelim

// keyboard number
2 => int KB_NUM;
// light pool fade factor
.95 => float FADE_FACTOR;
// toggle
0 => int LIGHT_ONOFF;
0 => int TRAIL_ONOFF;
0 => int POOL_ONOFF;

// keyboard
Hid kb;
// hid message
HidMsg msg;

// open
if( !kb.openKeyboard(KB_NUM) ) me.exit();
<<< "KB open:", kb.name() >>>;
spork ~ kbf();

// patch
SndBuf L => dac.left;
SndBuf R => dac.right;

// envelope followers
L => OnePole envL => blackhole; L => envL; 3 => envL.op;
R => OnePole envR => blackhole; R => envR; 3 => envR.op;
.99 => envL.pole => envR.pole;

// load
me.dir() + "../audio/turenas-L.aiff" => L.read;
me.dir() + "../audio/turenas-R.aiff" => R.read;
L.samples() => L.pos;
R.samples() => R.pos;
0 => L.gain => R.gain;

SinOsc x => blackhole;
SinOsc y => blackhole;

1 => x.freq;
1.5 => y.freq;

// light pool
VREntity pool[0];
// pool index
0 => int poolIndex;
// number in pool
50 => int POOL_SIZE;
// go
for( int i; i < POOL_SIZE; i++ )
{
    // construct some lights
    VR.makeEntity("pool"+i, "light") @=> VREntity e;
    // set texture
    e.eval( "texture texture:flare-1" );
    e.eval( "rotate 2" );
    e.eval( "num 3" );
    // make transparent
    0 => e.rgba.a;
    // append
    pool << e;
    // add
    VR.root().addChild( e );
}

// construct some lights
VR.makeEntity("light1", "light") @=> VREntity light;
// trail (should to same root as the entity it's trailing)
VR.makeEntity("trail1", "trail") @=> VREntity trail;

-2 => light.loc.y;

// set texture
light.eval( "texture texture:flare-1" );
// set trail length
trail.eval( "length 200" );
trail.eval( "draw linestrip" );

// tall rotating red one
light.eval( "rotate 1" );
light.eval( "num 5" );
light.rgba.set(.25,1,.25,LIGHT_ONOFF*1);
1 => light.sca.setAll;

// color
trail.rgba.set(.25,1,.25,TRAIL_ONOFF*.5);

// add to scene
VR.root().addChild( light );
VR.root().addChild( trail );

// disable lights
VR.allLightsOff();

fun void kbf()
{
    while( true )
    {
        // wait
        kb => now;
        // wait
        while( kb.recv(msg) )
        {
            if( !msg.isButtonDown() )
                continue;

            if( msg.ascii == 48 ) // 1
            {
                0 => L.pos => R.pos;
                1 => L.gain => R.gain;
            }
            // <<< "kb:", msg.ascii >>>;
            if( msg.ascii == 49 ) // 1
            {
                !LIGHT_ONOFF => LIGHT_ONOFF;
                LIGHT_ONOFF * 1 => light.rgba.a;
            }
            else if( msg.ascii == 50 ) // 2
            {
                !TRAIL_ONOFF => TRAIL_ONOFF;
                TRAIL_ONOFF * .5 => trail.rgba.a;
            }
            else if( msg.ascii == 51 ) // 3
            {
                !POOL_ONOFF => POOL_ONOFF;
            }
        }
    }
}

// bang detector
fun void bangDetect()
{
    while( true )
    {
        if( envL.last() > 0.000001 )
        {
            // add vertex
            // trail.eval( "add", light.loc );
            // check
            if( POOL_ONOFF )
            {
                light.loc => pool[poolIndex].loc;
                light.rgba => pool[poolIndex].rgba;
                1 => pool[poolIndex].rgba.a;
                .5 => pool[poolIndex].sca.setAll;
                poolIndex++; POOL_SIZE %=> poolIndex;
            }
            <<< "BANG!!", poolIndex, now/second >>>;
            30::ms => now;
        }
        5::ms => now;
    }
}

// keyboard function
spork ~ kbf();
// detector
spork ~ bangDetect();

// loop
while( true )
{
    6 * x.last() => light.loc.x;
    6 * y.last() => light.loc.y;
    // add vertex
    trail.eval( "add", light.loc );

    // update light pool
    updatePool();

    // synch with display
    VR.displaySync() => now;
}

// update light pool
fun void updatePool()
{
    for( int i; i < POOL_SIZE; i++ )
    {
        FADE_FACTOR *=> pool[i].rgba.a;
    }
}

error: pathspec 'example/bin/data/ck/turenas-2.ck' did not match any file(s) known to git


gamut

gamut

error: pathspec 'doc/gamut/spectra.ck' did not match any file(s) known to git


Added abyss file

Added abyss file

error: pathspec 'abyss.ck' did not match any file(s) known to git


Create Useful associative array example.ck

This is actually pretty cool, especially for messing with scales in a slightly more human-readable way.
Plus the associative array examples in the ChucK docs really suck.

demo_files/Useful associative array example.ck

error: pathspec 'demo_files/Useful' did not match any file(s) known to git
error: pathspec 'associative' did not match any file(s) known to git
error: pathspec 'array' did not match any file(s) known to git
error: pathspec 'example.ck' did not match any file(s) known to git


Create dBFStoGain.ck

Create dBFStoGain.ck

by tildebyte.

error: pathspec 'utility_functions/dBFStoGain.ck' did not match any file(s) known to git


Create to_stereo_wav.ck

Create to_stereo_wav.ck

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

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

// everything in between

0 => w.record;

error: pathspec 'wave_writer/to_stereo_wav.ck' did not match any file(s) known to git