Skip to content

Instantly share code, notes, and snippets.

@hanshuebner
Created May 28, 2011 20:00
Show Gist options
  • Save hanshuebner/997173 to your computer and use it in GitHub Desktop.
Save hanshuebner/997173 to your computer and use it in GitHub Desktop.
Ableton Live MIDI controlled clip recording
// While jamming with a keyboard, I often want to record some theme into a clip.
// I find it rather disruptive to have reach out for the mouse, or find a free clip
// slot on an APC, or use a touch interface or whatever. So this script comes to the
// rescue. It listens to MIDI events that I can trigger with a foot switch and records
// clips to the currently selected track. It uses the global quantization setting to
// determine the length of the clips that are created. Three MIDI events are used,
// one to record one clip, one to record clips until stops, and one to stop recording.
// The script automatically adds clips to the end of the currently selected track.
// It requires LiveOSC and midivent, both from my github (http://github.com/hanshuebner)
// Currently, MIDI note on messages for pitch 0, 1, and 2 are used.
var MIDI = require('MIDI');
var OSC = require('osc');
var _ = require('underscore');
var toLive = new OSC.Client('localhost', 9000);
var fromLive = new OSC.Server(9001);
var midiInput = new MIDI.MIDIInput('USB Midi Cable');
var trackNumber;
var recordingClip;
var track;
var RECORDING_MODE = { ONCE: 1, MANY: 2 };
function startRecording()
{
console.log('record to clip', recordingClip);
toLive.send('/live/play/clipslot', trackNumber, recordingClip);
}
var liveOscHandlers = {
'/live/track': function (trackNumber_) {
trackNumber = trackNumber_ - 1;
console.log('track', trackNumber, 'selected');
toLive.send('/live/track/info', trackNumber);
track = [];
},
'/live/track/info': function () {
for (var i = 2; i < arguments.length; i += 3) {
var clipNumber = arguments[i];
var state = arguments[i+1];
track[clipNumber] = state;
}
},
'/live/name/clip': function (trackNumber, clipNumber, name, color) {
if (clipNumber == recordingClip) {
toLive.send('/live/stop/clip', trackNumber, clipNumber);
if (recordingMode == RECORDING_MODE.MANY) {
recordingClip++;
startRecording();
}
}
},
};
fromLive.on('message', function (message) {
console.log(message);
var address = message.shift();
if (liveOscHandlers[address]) {
liveOscHandlers[address].apply(null, message);
}
});
function recordClip(mode)
{
if (!track) {
console.log('no track selected');
return;
}
toLive.send('/live/arm', trackNumber, 1);
var freeClip = 0;
for (var i = 0; i < track.length; i++) {
if (track[i]) {
freeClip = i + 1;
}
}
recordingClip = freeClip;
recordingMode = mode;
startRecording();
}
midiInput.on('noteOn', function (pitch, velocity) {
if (velocity) {
switch (pitch) {
case 0:
recordClip(RECORDING_MODE.ONCE);
break;
case 1:
recordClip(RECORDING_MODE.MANY);
break;
case 2:
recordingMode = RECORDING_MODE.ONCE;
break;
}
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment