class MidiHandler { // Open MIDI Device. 0 is the first device, 1 is the second and so on. MidiIn input; 0 => int device; if(!input.open(device)) { <<< "Could not open MIDI input device." >>>; me.exit(); } // MIDI Event IDs int codes[0]; 144 => codes["NoteOn"]; 128 => codes["NoteOff"]; fun void run() { // Now handle incoming events. MidiMsg message; while(true) { input => now; while(input.recv(message)) { message.data1 => int code; if(code == codes["NoteOn"]) { spork ~ noteOn(message.data2, message.data3); } else if(code == codes["NoteOff"]) { spork ~ noteOff(message.data2, message.data3); } else { <<< "Unhandled MIDI Message: ", message.data1, message.data2, message.data3 >>>; } } } } fun void noteOn(int pitch, int velocity) { <<< "Note On: ", pitch, velocity >>>; } fun void noteOff(int pitch, int velocity) { <<< "Note Off:", pitch, velocity >>>; } } class Synth extends MidiHandler { // Initialize oscilators and set the partials relative to the fundamental SinOsc @ oscilators[6]; [ 1.0, 0.1, 0.2, 0.4, 0.1, 0.2 ] @=> float partials[]; 0 => int lastPitch; for(0 => int i; i < oscilators.cap(); i++) { SinOsc oscilator => dac; 0 => oscilator.gain; oscilator @=> oscilators[i]; } // Handle note on events fun void noteOn(int pitch, int velocity) { Std.mtof(pitch) => float frequency; velocity / 127.0 => float gain; for(0 => int i; i < oscilators.cap(); i++) { frequency * (i + 1) => oscilators[i].freq; gain * partials[i] => oscilators[i].gain; } pitch => lastPitch; } // Handle note off events fun void noteOff(int pitch, int velocity) { if(pitch == lastPitch) { for(0 => int i; i < oscilators.cap(); i++) { 0 => oscilators[i].gain; } } } } Synth mono; mono.run();