Tutorial: Using the JavaScript Live API in Max for Live
I've been writing a series of articles that explain how to hack on Ableton Live with JavaScript through Max for Live and the Live API.
After some initial groundwork, it takes you through building a Live device to "humanize" (randomize) the timing and velocity of notes in a MIDI clip.
I hope this is useful to someone!
compusition.com/writings/js-live-api[UPDATE: I let compusition.com domain expire because I'm not maintaining the site anymore. Don't use it anymore. If you want to see these tutorials, use http://web.archive.org/web/20220117221726/http://compusition.com/writings/js-live-api]
[UPDATE 2: New tutorials for Live 11+ are here: https://cycling74.com/forums/updated-javascript-live-api-tutorials . Please leave feedback on them on that thread.]
Also note the MIDI API changed in Live 11 and the MIDI examples don't work in the latest version of Live. I might update these tutorials one day, in which case I'll try to remember to update this post with a new URL.]
I'm still writing the last article which is just some miscellaneous advanced topics. Not sure when that will be done. Let me know if you have any suggestions or would like to see other topics covered in the future.
Cheers,
Adam
Thank you Adam! A very helpful tutorial.
this is awesome, thanks!!
thats great Adam , fantastic work .
considering one of the covered topics (Note I/O). Is it safe to manipulate note placement within triplet time grid ?
Im asking because i came to the point where i had to deal with the float precision issue due to decimal fractions required for triplets inside bar/time grid .
Lets say that im in need to grab and duplicate a note that has length of a triplet duration , or even duplicate a note of fixed/whole duration but from triplet position . or move .
In such cases im dealing with decimal offests that doesnt make me feel safe enough . Also reading positions of triplets from piano-roll doesnt give the same fraction results on every triplet (tried toFixed(100)) which is quite logic as we are dealing with just the "computer" anyway .
I gave up on this because i had to introduce some sort of inaccuracy/error threshold which was actually working rather as a psychological aspect than any sort of cure .
Do u have some experiences with such scenarios ?
@DO...WHILE: No, I haven't spent much time generating notes in a triplet grid. And you are right, you can run into issues with floating point numbers not being accurate enough.
The accuracy of floating point is better for low values. So 1/3 is going to be a lot more accurate than, say, 100000000000000/3. So I imagine that things are good enough to work with the triplet grid in Max for Live and JavaScript. Probably any inaccuracies are going to be so small you wouldn't even be able to tell when you are listening to the music.
One area where I think you could run into trouble is if you are generating repeated legato notes. For example, if a note with the same pitch starts every 1/3 of a beat and is also 1/3 of a beat in duration. It seems possible the inaccuracies in floating point could cause the end of one note to overlap the beginning of another, causing a note to be lost. If this were to happen, I would just make the duration slightly less than 1/3 of a beat, so it still seems workable to me.
Another thing to consider is you can set the clip quantization value and quantize the clip via the Live API, so you could generate some notes in JavaScript and then quantize them.
Hi Adam ,thanks for the response !
Probably any inaccuracies are going to be so small you wouldn’t even be able to tell when you are listening to the music.
well , i thought that too , but ive been in scenarios where ive been able to notice while listening or been able to spot sync problems (long edits) . for example while manipulating BAR loop range forth and back which i tried to make possible . I lost interest :)
As for Notes ,overlapping lengths did play its game here ,and as u said shorting it up helped a lot in those days
I can think of note quantization as a part solution (not quite sure right now , wondering if i can quantize selected note through the API ? ) , but sometimes i dont want to quantize them , so perhaps i could quantize a note and add its computed offset again . yeah maybe ...
maybe adding computed offset at the last stage of sending data would work for all of the issues . like counting everything from most accurate grid division first . dont know .. just brainstorming
how people builds their daw's then :)
i will give up on this
This is amazing coming from a web dev background. Thanks Adam!
I have always wanted to learn how to manipulate Live from javascript. Thank you Adam ... you got me motivated to finally start :)
Couldn't have gotten started without this tutorial. Thanks Adam!
Just saw this - great stuff! I'm going to steal some parts of your log
function particularly.
Have you thought of checking some of this in to github or some other open source system?
I have a pretty huge library of Javascript for Max rooted here - let me know if you want a tour...
With regards to the float precision thing, if using simple floats is a problem, and all you have are floats to work with, consider some 'integer plus fraction' solution.
In javascript, have an object of the form:
var obj = { i: 47, f: 0.3 };
to represent 47.3. The i member is the integer part, the f member is the fraction part. The 32bit float type can represent integers _exactly_ between -2^24 and 2^24 (that is, between -16m and +16m). Splitting like this means all of the bits of the f member can be used to represent the fractional part (not as efficient as a double, but if you're stuck with floats, you're stuck with floats). Then
function addf(x,y) { var z = {i: x.i + y.i, f:x.f + y.f}; if( z.f = 1 ) { z.f -= 1; z.i += 1; } }
and similar for other arithmetic operations. A bit of a chore to write, but if you need additional precision and all you have are floats, this is the kind of thing you need to do.
If someone has a max for live patch using javascript and float precision is causing a problem, and they don't mind me having a copy to play with, I have a background in pure maths (that is, way back when I did a PhD in it) and an interest in all those nitty gritty detaily things (though these days I only explore them for a hobby).
It is already a couple of years ago that you wrote it, but I still want to thank you for these articles! I am starting with Max and Max for Live and working on my first project. It is not working correctly yet and that is why I am going to rewrite my first project using Javascript and your tutorials are very helpful for that. Thanks!
Just so you know this is the best article i've read on the matter. thanks adam.
Wow, wow Adam,
great work. Love it!!
wr
udo
Just to note, Chalisque's post above (Jul 06 2016) has an error in the code in which there is an assignment in a conditional expression, instead of a comparison: function addf(x,y) { var z = {i: x.i + y.i, f:x.f + y.f}; if( z.f = 1 ) { z.f -= 1; z.i += 1; } }
"(z.f = 1)"
Should probably be: function addf(x,y) { var z = {i: x.i + y.i, f:x.f + y.f}; if( z.f >= 1 ) { z.f -= 1; z.i += 1; } }
Don't know if JS would raise a fuss over the syntax. Java does, but it's valid code in C/C++ and will always evaluate to true.
Adam, thanks for the tutorial. I'd been wanting to get JS and better ways to control the liveapi, nearly completed my first device using JS.
Hey! Thank you so much for this post, it was very helpful to me, even in 2020. Thanks especially for pointing out that Live will complain if you use floating point numbers with too many decimals—I never would have figured out to use toFixed. One small thing I'll point out is that 4 decimal positions of accuracy doesn't seem to be quite enough. I had to go up to 8 to get my triplets to line up with Live's.
Hope that's useful to someone in 2020 :)
Hi everyone, this is kinda of a noobie post :p. I followed part of the tutorial and I was wondering if someone could help me understand why I cannot get access to the LiveAPI object (via : new LiveAPI("live_set")) which is always an empty object with no information on the set whatsoever.
I've copied code as is and also tried alternative ways like sending a bang (with the bang method defined in js). As well as adding or not a callback to the "new LiveAPI()".. Also tried different paths like "live_set tracks 0" and so on. And used defer or deferlow objects.
Here's my js code :
function log() {
for(var i=0,len=arguments.length; i<len; i++) {
var message = arguments[i];
if(message && message.toString) {
var s = message.toString();
if(s.indexOf("[object ") >= 0) {
s = JSON.stringify(message);
}
post(s);
}
else if(message === null) {
post("<null>");
}
else {
post(message);
}
}
post("\n");
}
log("___________________________________________________");
log("Reload:", new Date);
function bang() {
var api = new LiveAPI(null, "live_set")
log(api.info);
}
I connected a live.thisdevice to the (first) inlet and when I click it it always logs "undefined". This is a midi max patch.
Am I missing something ? I'm using Live 10.1.30 with Max 8.1.7 64 bit on windows 10.
Really baffled about this one ..
Thanks !
Well false alert, I reinstalled all the stock midi remote scripts and everything seems to work now !
Guess I must have removed some core ableton python files by mistake when doing remote script dev :)
WARNING: Do not go to OP's link!! It's a spam site and hopefully not a bunch of malware for me :(
Edit: If anyone is able to figure out how malicious clicking on the link is and let me know if I need to do anything I would be grateful!
Looks like the domain expired and has been taken over. Points to IP 160.124.171.90 which appears to be in China. I wouldn't be too worried if you visited it. Thanks for the warning though!
The original page is available on the Wayback Machine - https://web.archive.org/web/20160912175646/http://compusition.com/writings/js-live-api
Maybe a mod could edit the link in the original post.
Hey everyone. I stopped maintaining the site compusition.com a while ago and didn't want to keep paying to keep it up, so I let the domain expire and I don't own it anymore.
I realize the JS Live API tutorials were useful to a lot of folks, and I would like to restore them at some point. The problem is there was a whole bunch of content on working with MIDI, but starting in Live 11 when MPE was introduced, the API changed in a non-backward compatible way and my tutorials on MIDI didn't work anymore.
As a result, I started rewriting the entire set of tutorials. I am planning to re-host them on my newer personal blog, but I ran out of steam and never finished. I will post here with a new URL if I ever end up finishing it.
If you want to find the original tutorials, use the web archive: http://web.archive.org/web/20220117221726/http://compusition.com/writings/js-live-api
I was still able to update my original post. I updated the link. Sorry for the confusion.
That was fast! Cool, thanks for the links!
Just wanted to say this tutorial was everything to me on a project I was working. Full jumpstart into max4live because I like to code instead of using nodes. It Got me into JavaScript which lead to other realizations about programming languages. thank you!!
Hello! It took a bit longer than I had hoped, but I finally released updated JS Live API tutorials that work with Live 12 (and Live 11)! Content for Max 9 and v8 is on its way too.
I decided to start a fresh thread so I can keep it focused on the new content. Check it out, and if you have any feedback, let me know over there. Cheers!
https://cycling74.com/forums/updated-javascript-live-api-tutorials
Even if you are familiar with the original tutorials, these have been redesigned from the ground up. A few chapters are still pretty similar, but everything's been expanded and updated, and there's a couple brand new in-depth projects for making devices to manipulate MIDI in realtime and offline. They might be fun to try even for experienced people.