// 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[] randomArray_from(int arr[], int length){}
    fun int[] range(int start, int end){}
    fun int[] narray(int start, int next, int up_to){}
    fun int[] expand_scale(int scale[], int start_stop[]){
    fun int[][] stepify(string sequence_data[]){}

    fun float average(int arr[]){}

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

    fun SndBuf load_sample(string wavname){}

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

*/

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

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

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

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

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

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

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

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

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

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

fun string repr(string arr[]){

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

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

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

fun void repr_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;

}

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

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

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

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

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

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

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

fun string repr(string arr[]){

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

fun SndBuf load_sample(string wavname){

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

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

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

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

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

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

}

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

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

Update common_functions.ck

Update common_functions.ck

added   `fun int[] set_from(int arr[])`


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

/*
    definitions

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

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

    fun float average(int arr[]){}

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

    fun SndBuf load_sample(string wavname){}

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

*/

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

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

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

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

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

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

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

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

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

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

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

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

fun string repr(string arr[]){

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

fun SndBuf load_sample(string wavname){

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

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

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

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

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

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

}

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

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

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

Update common_functions.ck

Update common_functions.ck


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

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

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

// everything in between gets recorded.

0 => w.record;
w.fileClose();

Update to_stereo_wav_with_gainParams.ck

Update to_stereo_wav_with_gainParams.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;
}

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

}

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

Update bassdrum_electronic_deepboom3.ck

Update bassdrum_electronic_deepboom3.ck


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

SndBuf buf_1;
SndBuf buf_2;
me.dir() + "/../sounds/ptaszek.wav"  => buf_1.read;
me.dir() + "/../sounds/c1_atlas.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;

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;

test files names changed

test files names changed


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

Update chuck_midi_in_to_notes_array.ck

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

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

Update to_stereo_wav.ck

Update to_stereo_wav.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[] 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[] randomArray_from(int arr[], int length){
    // return new array of capacity length chosing elements from arr
    int generated_arr[0];
    for(0 => int i; i<length; i++){
        generated_arr << random_from(arr); // append element
    }
    return generated_arr;
}

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

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

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

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

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

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

fun string repr(string arr[]){

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

fun SndBuf load_sample(string wavname){

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

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

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

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

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

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

}

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

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

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

/*
    definitions

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

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

    fun float average(int arr[]){}

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

    fun SndBuf load_sample(string wavname){}

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

*/

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

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

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

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

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

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

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

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

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

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

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

fun string repr(string arr[]){

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

fun SndBuf load_sample(string wavname){

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

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

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

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

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

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

}

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

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

Update common_functions.ck

Update common_functions.ck

join_int_array


public class MalTimeMs extends MalSubr
{
    fun MalObject call(MalObject args[])
    {
        // HACK: Std.system returns the status code only...
        "/tmp/chuck-date." + Std.rand2(1000,9999) => string temp_file;
        Std.system("date +%s%3N > " + temp_file);

        FileIO f;
        f.open(temp_file, FileIO.READ);
        f => int timestamp;
        f.close();

        return MalInt.create(timestamp);
    }
}

public class MalTimeMs extends MalSubr
{
    fun MalObject call(MalObject args[])
    {
        // HACK: Std.system returns the status code only...
        "/tmp/chuck-date." + Std.rand2(1000,9999) => string temp_file;
        Std.system("date +%s%3N > " + temp_file);

        FileIO f;
        f.open(temp_file, FileIO.READ);
        f => int timestamp;
        f.close();

        Std.system("rm " + temp_file);

        return MalInt.create(timestamp);
    }
}

Remove temp file

Remove temp file


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

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

Update common_functions.ck

Update common_functions.ck


Support backspace in readline implementation


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;

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

Debug strings added

Debug strings added


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

add chuck

add chuck


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

Create picking_oscillators.ck

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

Create bassdrum_electric_thud.ck

Create bassdrum_electric_thud.ck


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

}

Create common_functions.ck

Create common_functions.ck

i've used these a lot already.


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

Create MidiIn2Notes.ck

Create MidiIn2Notes.ck


// Assignment 7 drumCircleDSP

public class KickSynC{

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

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

    fun void s_do_kick(float volume){

        3850 => float frequency;

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

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

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

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

        44100/frequency => float grain;

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

            grain::samp => now;

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

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

    }

}

KickSynC kick1;

kick1.trigger(0.5);

1::second => now;

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)


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

Create bassdrum_electronic_nice_thud.ck

Create bassdrum_electronic_nice_thud.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;
}

Create LiSa_LiveSampler_from_SndBuf.ck

Create LiSa_LiveSampler_from_SndBuf.ck


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

Create dBFStoGain.ck

Create dBFStoGain.ck

See source comments


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;

}

Create vibraphoney.ck

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

Create WaveformMixerMono.ck

Create WaveformMixerMono.ck


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

Create chuck_midi_in_to_notes_array.ck

Create chuck_midi_in_to_notes_array.ck

a little iffy.


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

Create to_stereo_wav_with_gainParams.ck

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

Create eletronic_snare_dumb2.ck

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

Create bassdrum_electronic_deepboom2.ck

Create bassdrum_electronic_deepboom2.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;
}

Create bassdrum_electronic_deepboom3.ck

Create bassdrum_electronic_deepboom3.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;
}

Create clap_simple.ck

Create clap_simple.ck


Create dBFStoGain.ck

Create dBFStoGain.ck

by tildebyte.


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

Create to_stereo_wav.ck

Create to_stereo_wav.ck