-
-
Save zeffii/7507078 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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