Midi into spreadsheet

(
// 'note' data structure will be an event:
// (time: absolute time, midinote: num, amp: velocity/127, sustain: dur)
// you could use an array here too
~notes = Array(256);
~rows = Array(256);

t = TreeView(nil, Rect(600, 100, 400, 600)).front;
t.columns = ["Time", "Note", "Velocity", "Duration"];
4.do { |i| t.setColumnWidth(i, 100) };

MIDIdef.noteOn(\on, { |vel, num|
	var time = TempoClock.beats;
	~notes = ~notes.add((time: time, midinote: num, amp: vel / 127));
	defer {
		var row;
		row = t.addItem([time.round(0.01).asString, num, vel, "--"]);
		~rows = ~rows.add(row);
		t.currentItem = row;  // scroll to bottom
	};
});

MIDIdef.noteOff(\off, { |vel, num|
	var time = TempoClock.beats;
	var i = ~notes.detectIndex { |note|
		note[\midinote] == num and: { note[\sustain].isNil }
	};
	if(i.isNil) {
		"Could not find note-on for note-off %".format(num).warn;
	} {
		~notes[i][\sustain] = time - ~notes[i][\time];
		defer {
			~rows[i].strings = ~rows[i].strings
			.put(3, ~notes[i][\sustain].round(0.01).asString);
		};
	};
});

t.onClose = {
	MIDIdef(\on).free;
	MIDIdef(\off).free;
};
)

Now ~notes is something you could play back directly, and save to / load from disk, etc.

hjh

1 Like