Skip to content

Instantly share code, notes, and snippets.

@zeffii
Last active December 28, 2015 13:18
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/7506339 to your computer and use it in GitHub Desktop.
Save zeffii/7506339 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];
}
// Sound Wiring
Gain master => dac;
ADSR pEnv[polyphony];
SawOsc pOsc[polyphony];
Pan2 pPan[polyphony];
// Fill the chains
for(0 => int n; n<polyphony; n++){
pOsc[n] => pEnv[n] => pPan[n]=> dac;
(((n%2)*2)-1) * 0.3 => pPan[n].pan;
pOsc[n].gain(0.11);
}
// 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;
set_notes_and_triggers(midi_notes, timing);
timing::second => now;
}
}
// UTLITY FUNCTIONS
fun void set_notes_and_triggers(int midi_notes[], float timing){
for(0 => int j; j<midi_notes.cap(); j++){
midi_notes[j] => int trigger_value;
// no real error checking for now
// ( possible values to handle are -1..-5 )
if (trigger_value >= 0) {
Std.mtof(trigger_value) => float f;
pOsc[j].gain(0.21);
f => pOsc[j].freq;
pEnv[j].set(16::ms, (timing*1.12)::second, 0.2, 20::ms);
pEnv[j].keyOff();
pEnv[j].keyOn();
// cycle pans around a little
Math.random2(0,1) => int offset;
((((j + offset)%2)*2)-1) * 0.2 => pPan[j].pan;
};
if (trigger_value < -1){
pEnv[j].keyOff();
}
}
}
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