Skip to content

Instantly share code, notes, and snippets.

@zeffii
Forked from anonymous/foa4k.ck
Created November 16, 2013 23:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zeffii/7507071 to your computer and use it in GitHub Desktop.
Save zeffii/7507071 to your computer and use it in GitHub Desktop.
// event driven tracker.
0.5 => dac.gain;
[
["0.228", "note 1"],
["0.252", "chord 1"],
["0.084", "note 1"],
["0.249", "chord 1"],
["0.097", "note 1"],
["0.289", "chord 1"],
["0.079", "note 1"],
["0.243", "chord 1"],
["0.086", "note 1"],
["0.247", "chord 1"],
["0.105", "note 2"],
["0.143", "note 2"],
["0.241", "chord 2"],
["0.104", "note 2"],
["0.293", "chord 2"],
["0.257", "note 3"],
["0.283", "chord 3"],
["0.109", "note 3"],
["0.336", "chord 3"],
["0.238", "note 4"],
["0.236", "chord 4a"],
["0.095", "note 4"],
["0.241", "chord 4a"],
["0.093", "note 4"],
["0.239", "chord 4b"],
["0.125", "note 4"],
["0.245", "chord 4b"],
["0.114", "note 4"],
["0.213", "chord 4b"],
["0.234", "note 4"],
["0.251", "chord 4a"],
["0.103", "note 4"],
["0.249", "chord 4a"],
["0.118", "note 4"],
["0.096", "chord 4b"],
["0.229", "chord 4b"],
["0.263", "chord 4b"],
["0.099", "note 4"],
["0.239", "chord 4b"],
["0.239", "note 4" ],
["0.245", "chord 4a"],
["0.105", "note 4"],
["0.253", "chord 4a"],
["0.100", "note 4"],
["0.258", "chord 4b"],
["0.113", "note 4"],
["0.228", "chord 4b"],
["0.104", "note 4"],
["0.236", "chord 4b"],
["0.232", "note 4"],
["0.250", "chord 4a"],
["0.103", "note 4"],
["0.230", "chord 4a"],
["0.111", "note 4"],
["0.114", "chord 4c"],
["0.212", "chord 4c"],
["0.249", "chord 4c"],
["0.097", "note 4"],
["0.253", "chord 4c"]] @=> string durations[][];
fun float midicpt(int midi_index){
return Std.mtof(midi_index + 60);
}
[ "note 1", "chord 1", "note 2", "chord 2",
"note 3", "chord 3", "note 4", "chord 4a",
"chord 4b", "chord 4c"
] @=> string trigger_names[];
// multi-dimensional array of midi notes.
4 => int polyphony;
trigger_names.cap() => int num_triggers;
int note_array_midis[num_triggers][polyphony];
// associative array
string note_array[0];
"D-4 ... ... ..." => note_array["note 1"];
"... A-4 C#5 E-5" => note_array["chord 1"];
"C-4 ... ... ..." => note_array["note 2"];
"... D-5 B-4 G-4" => note_array["chord 2"];
"A-3 ... ... ..." => note_array["note 3"];
"... E-5 C#5 A-4" => note_array["chord 3"];
"E-4 ... ... ..." => note_array["note 4"];
"... D-5 B-4 G-4" => note_array["chord 4a"];
"... D-5 G-4 C-5" => note_array["chord 4b"];
"G-4 C-5 D-5 G-5" => note_array["chord 4c"];
// store midi arrays
for(0 => int t; t<num_triggers; t++){
trigger_names[t] => string trigger_name;
note_array[trigger_name] => string keys;
toMidi(keys) @=> note_array_midis[t];
}
// MIDI events
// use command line "chuck --probe" to find
// which devices chuck can send to. Here i'm using 1,
// your see a few listed in square brackets. try those.
MidiOut mout;
mout.open(1);
MidiMsg msg;
// check if port is open
if( !mout.open( 1 ) ){
<<< "doesn't seem to be open" >>>;
me.exit();
}
// Main event loop.
int midi_notes[];
4 => int repeats;
for(0 => int rep; rep<repeats; rep++){
for(0 => int t; t<durations.cap(); t++){
durations[t][1] => string trigger;
find(trigger, trigger_names) => int index;
note_array_midis[index] @=> midi_notes;
<<< note_array[trigger] >>>;
// note-on, rests, and note-offs are dealt with by
// set_notes_and_triggers()
durations[t][0] => Std.atof => float timing;
// fill the buffer with messages in pairs of three
// msg : type : function
// data1 : 144 : is note on
// data2 : 0-127 : midi note
// data3 : 0-127 : volume
// more can be found:
// http://www.ccarh.org/courses/253/handout/midiprotocol/
// http://www.midi.org/techspecs/midimessages.php
for(0 => int note; note<midi_notes.cap(); note++){
midi_notes[note] => int midi_note;
if (midi_note <= -1) {
continue; // skip this
}
144 => msg.data1; // note on, midi note.
midi_note => msg.data2; // pitch
30 => msg.data3; // volume
mout.send( msg );
}
timing::second => now;
// could send note offs here.
}
}
// UTLITY FUNCTIONS
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 string[] split(string arr, string token){
// you trim arr before feeding it to this function
string return_array[0];
string collect;
string ch;
// a slightly unintuitive approach, but it works.
// if you'd like me to explain this function let me know.
for(0 => int i; i<arr.length(); i++){
arr.substring(i, 1) => ch;
if (ch == token){
return_array << collect.substring(0);
"" => collect;
}
else { ch +=> collect; }
}
return_array << collect;
return return_array;
}
fun int[] charArrayToMidi(string key_characters[]){
// start with empty array
int midi_values[0];
// key_characters might look like:
// ["G-4", "C-5", "D-5", "G-5"]
for(0 => int i; i<key_characters.cap(); i++){
// to_note is used to convert
// "C-5" (string) to 60 (int)
to_note(key_characters[i]) => int key;
// add this value to the array
midi_values << key;
}
// seems this went ok, return the array.
return midi_values;
}
fun int[] toMidi(string keys){
// "G-4 C-5 D-5 G-5" (input string will be formatted so)
// split the string on spaces, hence " "
split(keys, " ") @=> string key_characters[];
// ["G-4", "C-5", "D-5", "G-5"] (key_characters will look like this)
// this converts that string array inti an int array of midi notes
// ..something like [55,60,62,67] .. good we can work with those!
charArrayToMidi(key_characters) @=> int key_values[];
return key_values;
}
fun string repr(int arr[]){
/*
this returns a string representation of an int array,
usage: repr([12,23,24,25]) or repr(some_array)
result: "[12,23,24,25]""
*/
"[" + Std.itoa(arr[0]) => string s;
for (1 => int i; i < arr.cap(); i++){
"," + Std.itoa(arr[i]) +=> s;
}
return s + "]";
}
fun int inArray(string item, string arr[]){
for(0 => int i; i<arr.cap(); i++){
if (arr[i] == item) return 1;
}
return 0;
}
fun int find(string item, string arr[]){
for(0 => int i; i<arr.cap(); i++){
if (arr[i] == item) return i;
}
return -1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment