// NOTE: Ensure that the distFile.ck is shredded first. 120.0 => float bpm; 0 => int rootNote; 10::ms => dur internoteRest; StifKarp instrument => dac.left => dac.right; DistGetter distGetter; 128 => int NUM_NOTE_VALS; 64 => int NUM_16_NOTE_PER_CLAUSE; // Selects a note value for the next note. // 0 = root, 1 = 1 semitone above root, etc. // loc is the number of 16th notes from the first beat of the clause // (a clause is 4 measures, thus location ranges from 0 to 63) fun int noteValForLoc(int loc) { Math.random2f(0.0, 1.0) => float random; 0.0 => float totalSoFar; distGetter.getNoteDist() @=> float dist[][]; for (0 => int i; i < NUM_NOTE_VALS; i++) { dist[loc][i] +=> totalSoFar; if (totalSoFar >= random) { //<<< i % 12 >>>; return i; } } return 60; // An error occurred: return middle c. } // Similar to the above, but returns a duration in 16th notes. // output range is 1 (single 16th note) to 16 (whole note) fun int noteLengthForLoc(int loc) { Math.random2f(0.0, 1.0) => float random; 0.0 => float totalSoFar; distGetter.getDurDist() @=> float dist[][]; for (0 => int i; i < NUM_16_NOTE_PER_CLAUSE; i++) { dist[loc][i] +=> totalSoFar; if (totalSoFar >= random) { // Hacky recursive error checking. :D if (i == 0) return noteLengthForLoc(loc); return i; } } return 1; // An error occurred: return a 16th note. } // Converts a note value (relative to root) to a frequency. fun float freqForNoteVal(int noteVal) { rootNote + noteVal => int midiVal; return Std.mtof(midiVal); } // Converts a note length to a duration. fun dur durationForNoteLength(int len) { 1000.0 * 60.0 => float msPerMin; msPerMin / bpm => float msPerBeat; return ((msPerBeat / 4) * len)::ms - internoteRest; } // The main function. It plays a randomly generated melody forever fun void playMelody() { // The location of the music in the clause. 0 => int loc; while(true) { //<<< loc >>>; // Rest and reset. instrument.noteOff(1.0); internoteRest => now; // Select next note and play. noteLengthForLoc(loc) => int nextNoteLength; noteValForLoc(loc) => int nextNoteVal; // ATTEMPTING TO FORCE ASSONANCE... //if (loc + nextNoteLength >= NUM_16_NOTE_PER_CLAUSE - 16) { // nextNoteVal % 12 -=> nextNoteVal; //} <<< nextNoteVal % 12 >>>; // Attempt 2... nextNoteVal % 24 + 48 => nextNoteVal; instrument.freq(freqForNoteVal(nextNoteVal)); instrument.noteOn(0.6); // Play for selected duration. durationForNoteLength(nextNoteLength) => now; // Update location nextNoteLength +=> loc; NUM_16_NOTE_PER_CLAUSE %=> loc; } } // Main playMelody();