What's New in Live 11, Part 2
The release of Ableton Live 11 introduced a number of new features for working with MIDI notes:
- Support for MPE
- Note probability
- Support for velocity deviation
- Support for release velocity
The Max for Live API has been updated to provide access to this new data in Live, and to allow for manipulating notes without discarding this new data.
The second part of our look at what’s new in Live for Max for Live users will provide a brief overview of the new features in the Live notes API.
We’re also including a pair of example Max for Live devices which contain snippets that you can copy and paste to help you hit the ground running as you learn to use these new features.
And don’t worry if you’re not really familiar with dictionaries (dicts) or note IDs in Max — two mechanisms in Max you’ll be using when you work with the notes API — we’ve tried to walk you through how dicts and note IDs are used in the example device snippets.
Click here to download the example Max for Live devices
Before and after
For those of you who are already familiar with working with the notes API in Live 10 (or for those of you who’d rather read patches than text), let’s start with a device from the download (Notes API - Before and After.amxd) that will give you a side-by-side comparison of how common tasks used to be done, and the new Live 11 notes API ways of doing them:
Note: the Notes API - Before and After device is frozen. After unfreezing, you can find its frozen abstractions and javascript files in your Documents folder, in Max 8/Max for Live Devices/Notes API - Before and After Project.
You’ll find examples here of all the common API-based notes operations you already know (getting, adding, removing, modifying (all notes or selected notes), duplicating and observing) with examples of the new notes API versions you can copy, paste, and modify as needed to quickly add the new functionality to your own devices.
The API specification
You will find the full specification for the notes API in the Live Object Model document listed as part of the Clip specification.
The new features of the Live 11 notes API involves working with note IDs and dictionaries in Max (for more details on this, see below).
The new notes API methods are:
- get_notes_extended: returns a dict with all notes in a specified time and pitch range
- get_selected_notes_extended: returns a dict with all selected notes
- add_new_notes: accepts a notes dict without note IDs to add new notes
- apply_note_modifications: accepts a notes dict with note IDs of notes to modify
- remove_notes_extended: removes all notes in a pitch and time range
- get_notes_by_id: gets a note for a certain note ID
- remove_notes_by_id: removes a note with a certain note ID
To see exactly what parameters to provide to each of these methods and what they return, please refer to the specification in the Live Object Model document.
The old notes API methods are still available under conditions
The old note access methods are still available for legacy devices in Live 11, but using them is discouraged by warnings in the Max Window.
- get_notes
- set_notes
- get_selected_notes
To prevent unintentionally removing new note data like MPE, the following old methods that remove notes will show a warning popup:
- remove_notes
- replace_selected_notes
The warning pop-ups can be permanently silenced by the user by choosing Don't show again.
Accessing the API with dicts
The dict (short for “dictionary") object family in Max provides versatile access to all kinds of data. A dict represents series of key-value pairs in a leveled structure. The structure of these dicts follow that of the JSON format, which will be helpful for those of you who are familiar with web development: a key can point to a string, float or int, or to another dict.
Additionally, a key can point to an array of any of these things.
The Notes API Basics.amxd Max for Live device included in the download provides a basic example of how to use the notes API with Max dict objects:
The order of key/value pairs in a dict is not fixed, nor is the number of keys and values. This is crucial to the new notes API, because it needs to be extendible; we’ll want older devices to continue to work without modifications if new note information is added in the future.
Dicts are passed by reference
When outputting a dict to another object, instead of copying all the data over a patch cord, a reference to this data is transmitted. That is why you see something like dictionary u944000887 when you show a dict in a message box.
Note: Modifying a dict will affect all subsequent usages of this dict. To avoid problems, you should make a copy of a dict before modifying it. You can find a demonstration of this in the IntroToDict subpatcher you’ll find in the Notes API - Before and After device.
For more information about dicts, take a look at the more in-depth dict reference in the Max documentation.
Keeping track of notes with note IDs
The previous method for modifying a note in Live 11 involved getting the note’s properties, removing them, and then adding a new note with similar properties. Adding MPE support meant that this old method would result in discarding all per-note MPE data.
Live 11 guarantees that all note data is preserved by letting you provide new values for an existing note ID when you perform modification rather than removing and replacing note IDs.
Note IDs are simply integers that uniquely identify a note within a clip. You cannot generate these IDs yourself; you can only find out about them by getting existing notes from a clip.
The new procedure for modifying a note with the API looks like this:
- Get current notes with get_notes_extended, which provides you with a dict of all the notes.
- Get the note_id of the note you need to modify from the resulting dict.
- Create a new dict containing the new note values that retains the existing note_id.
- Send this new dict back to the Clip with apply_note_modifications.
Note IDs are different from other references in Max
Note IDs are different from existing reference types in Max, like Live Object Model IDs (e.g, id 56) or uuids (e.g., dictionary u48298492). These references are always globally unique and have a keyword prepended, whereas note IDs are unique only within a clip and are just ints (3). For more details, see the IntroToNoteIDs subpatcher in the Before and After device.
The notes API in Javascript
Javascript is uniquely well-equipped for dealing with the new notes API in Live 11 — the notes data is structured as JSON, and JSON is invented for Javascript. All new notes API operations are available to you; take a look at the Before and After example device, in the Javascript subpatcher for bits of example code that are ready to be copied into your own device patches.
We hope that these articles have given you a good first look at the improvements and new features in Live 11 for Max for Live users, and we’re excited to see what you’ll make using them!
Corrections
2021-04-22: In a previous version of Notes API - Before and After.amxd, a pitch span of 127 was used when the intention was to apply an operation to the full pitch range. This has now been updated to 128.
2021-05-28: Added examples for outputting notes data from Javascript to dict and for inputting notes data from dict to Javascript.