Created
May 28, 2011 20:00
-
-
Save hanshuebner/997173 to your computer and use it in GitHub Desktop.
Ableton Live MIDI controlled clip recording
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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