JavaScript (V8) in Ableton Live Overview

Table of Contents

  1. JavaScript (V8) in Ableton Live Overview (this page)
  2. Getting Started
  3. Real Time MIDI Processing
  4. The Max Console
  5. The Live API
  6. Generating MIDI Clips
  7. Max Console Part 2: Better Logging for Objects

Overview

These pages are a series of Max for Live tutorials on using JavaScript to extend Live's functionality with Max 9's new built-in V8 JavaScript engine and its Live API.

These tutorials specifically cover the use of the v8 object. v8 is a modern alternative to the older js object. The original JavaScript in Live Overview explains why there are two JavaScript objects and what it means as a user of Max.

As I complete the remaining tutorials for v8, I will expand the content on this page.

Limitations

Let's set some expectations about JavaScript running in Live. Real time music applications like Live need to crunch numbers very quickly, and JavaScript isn't consistently fast enough, at least not the way it runs inside Max and Live. It doesn't matter that the new v8 object is much faster than the old js object. The Max docs talk about how JavaScript doesn't run in Max's high priority thread:

Max schedules events using a high priority thread for events that require high timing accuracy, like MIDI, and a low priority thread for long-running operations like decompressing video. The JavaScript engine in Max always executes code in the low priority thread. That means that if a JavaScript object receives a message from a MIDI object, or from any other object that schedules events on the high priority queue, that event will be deferred to the low priority queue.

Elsewhere, the Max docs talk about high and low priority in the scheduler:

other events are low priority events. Max tries to process these as fast as possible, but not at any specific time. These are also called queue events, since Max doesn't decide when to process them based on timing information, but by processing them in first-in-first-out order.

The main implication is we cannot expect to process an audio stream in real time in JavaScript. You can't build synthesizers or audio FX in JavaScript, at least not in Live. And, importantly:

Even when we're working with something that happens at a reasonably slow rate, like MIDI data, JavaScript cannot be relied on for consistent, accurate timing at all times.

Because of the situation with the high and low priority thread, Max is not guaranteed to run any JavaScript code fast enough to keep things in time with the rest of the MIDI data being processed by Ableton Live. Most of the time it may work fine, maybe even 99.9% of the time. But it's not guaranteed, so you shouldn't rely on it for live performance scenarios. Your operating system might suddenly decide to do something like check for OS updates, which could cause work queued in any low priority threads to get deferred by a noticeable amount and throw off musical timing. You never know when something like this can happen, even on a fast computer.

Real time processing in JavaScript in Max for Live should not be relied on for live performance scenarios (unless timing sloppiness and unpredictable latency is acceptable for the style of music). Extensive testing before live performance usage is highly recommended.

I strongly recommend against trying to make commercial products with JavaScript that do real time processing in Max for Live. You can't expect it to work perfectly all the time on random people's computers.

Personally, I like to use JavaScript in Live in a composition and production context in a place like my home studio where I am trying out ideas. Practically all of the time, timing with real time processing of MIDI is fine for my needs. Since I'm doing studio work, if there is the occasional glitch or spike in latency, I can edit it manually to fix it or quantize the timing.

I also think it's reasonable to prototype real time processors in JavaScript, with the understanding you might need to port it to a Max patch, or gen~, or C++/JUCE, or something else that has guarantees for accurate timing. If you are very comfortable with JavaScript, it may be fastest to try out your ideas in JS, and then decide if they are worth pursuing further.

One last point: You aren't making a huge compromise by choosing to use JavaScript in Live. It's not all bad! JavaScript in Live seems particularly well-suited to build Max for Live MIDI Tools (Generators and Transformers). These are "offline" tools that aren't in the audio signal path in Live, so none of these limitations are a concern in this context. I will try to write more about this later. These tutorials should help prepare you to build such devices even if none of them specifically cover this topic.

Next Steps

Read "Getting Started" to learn how to setup a Max for Live device with JavaScript.

Table of Contents:
  1. JavaScript (V8) in Ableton Live Overview
  2. Getting Started
  3. Real Time MIDI Processing
  4. The Max Console
  5. The Live API
  6. Generating MIDI Clips
  7. Max Console Part 2: Better Logging for Objects