Bruce Murphy wrote:
You or others might find the midi stuff at
As kind of a tangent, I also started writing a MIDI wrapper, though mine was more concerned with handling incoming events (and thusfar only does note-on and note-off). Mine's more OO style, though since ChucK only lets you export one class per file, I've been doing way too much copying and pasting it into stuff. A basic example of how to use it is something like: fun void noteOnHandler(MidiHandler handler) { while(true) { handler.noteOn => now; <<< "Note On - Pitch: ", handler.noteOn.pitch, " Velocity: ", handler.noteOn.velocity >>>; } } MidiHandler handler; spork ~ noteOnHandler(handler); // do other stuff Sending a note-on is then: NoteOnEvent on; 1 => on.pitch; handler.send(on); This would be a bit cleaner if ChucK had constructors -- something like handler.send(NoteOnEvent(1, 127)); -Scott class MidiEvent extends Event { int id; fun void setData(int data1, int data2) { // Don't do anything in the default. } fun int[] data() { return [ 0, 0 ]; } } class NoteEvent extends MidiEvent { int pitch; int velocity; fun void setData(int data1, int data2) { data1 => pitch; data2 => velocity; } fun int[] data() { return [ pitch, velocity ]; } } class NoteOnEvent extends NoteEvent { 144 => id; 100 => velocity; } class NoteOffEvent extends NoteEvent { 128 => id; 0 => velocity; } class MidiHandler { // Members MidiIn input; MidiOut output; NoteOnEvent noteOn; NoteOffEvent noteOff; false => int running; MidiEvent events[2]; 0 => int inputDevice; 0 => int outputDevice; // Constructor if(!input.open(inputDevice)) { <<< "Could not open MIDI input device." >>>; me.exit(); } if(!output.open(outputDevice)) { <<< "Could not open MIDI output device." >>>; me.exit(); } noteOn @=> events[0]; noteOff @=> events[1]; spork ~ start(); // Functions fun void start() { true => running; MidiMsg message; while(running) { input => now; while(input.recv(message)) { 0 => int i; while(i < events.cap() && events[i].id != message.data1) { 1 +=> i; } if(i < events.cap()) { events[i].setData(message.data2, message.data3); events[i].broadcast(); } else { <<< "Unhandled MIDI Message: ", message.data1, message.data2, message.data3 >>>; } } } } fun void stop() { running => false; } fun void send(MidiEvent event) { event.data() @=> int data[]; if(data.cap() == 2) { MidiMsg message; event.id => message.data1; data[0] => message.data2; data[1] => message.data3; output.send(message); } else { <<< "Invalid data() for MidiEvent." >>>; } } }