AbleSet Icon

AbleSet

AbleSet Documentation

Last updated: 2025-10-26

This page contains the entirety of AbleSet's documentation in one place.
Feel free to save it as a PDF or print it for offline reference.

Introduction to AbleSet

Welcome to AbleSet!

Getting started using the app is simple. AbleSet lives as a little icon in your menu bar. Click on it to open the main window.

To open the AbleSet interface on your computer, click "Open AbleSet" in the menu bar window. Your browser will open with the local address of your AbleSet. If you want to open AbleSet on your phone or tablet, make sure they are on the same network as your computer and open the same address in their browser.

You can always see the address of AbleSet in its menu bar window:

AbleSet Menu Bar Window

AbleSet uses Ableton's locators (markers) to convert your session into a setlist. The easiest way to set up a setlist is to place a marker at the beginning of each track and give it the song's name. If you want to know more about what you can do with markers in AbleSet, check out the Cue Notation documentation.

If you have any questions, please feel free to contact me.

Frequently Asked Questions

Compatibility

What version of Live is AbleSet compatible with?

AbleSet works with all editions of Live 10, 11, and 12, though some features like section clips and lyrics tracks require Live 11 or 12. If you want to use the Max for Live controller, you either need Live Suite or the Max upgrade for Live Standard.

What version of macOS can AbleSet run on?

I've tested and officially support AbleSet on macOS Catalina (10.15.7) and higher but you might be able to get it working on older versions as well.

What version of Windows can AbleSet run on?

AbleSet can run on Windows 10 and 11.

What version of iOS or iPadOS is AbleSet compatible with?

AbleSet is officially compatible with iOS 15 and newer, but you might be able to use it on versions as old as iOS 12. If your iPhone or iPad supports iOS 13, it can also be updated to iOS 15. You can find a list of all supported iPads and iPhones on Wikipedia.

Some features, like the Canvas, will likely not work on versions below iOS 15.

What version of Android is AbleSet compatible with?

I've tested AbleSet on Android 7 and higher, but you might be able to run it on older versions of Android as well.

License

How many computers can a license be activated on?

You can activate each AbleSet license on two computers. If you've upgraded from AbleSet 1, you can activate it on four computers.

To see the status of your licenses and how many computers they can, be activated on, go to your account page.

How can I deactivate my license on a computer?

If you still have access to your computer, open AbleSet, then click the settings icon in AbleSet's status window and select "Deactivate Machine". This will reset AbleSet into the demo mode on that computer and open up a slot for activating your license on another computer.

How long is a license valid?

AbleSet licenses don't expire and come with one year of free updates. If you want to update to a version that was released more than a year after you bought your license, you can renew it from your account page.

How much does it cost to renew my license?

Renewing your license costs $75 and gives you an additional year of updates.

Why does a license only come with one year of free updates?

I've thought about the licensing scheme for AbleSet for a long time. I don't like subscription models where you lose access to the software you're paying for as soon as you stop paying, but working on new features takes a lot of work, so I decided to use this hybrid model instead.

If you're not interested in the new updates that get released more than one year after you bought your license, you don't have to renew it and can continue using the version you own for as long as you like. If you like the new features, you can renew your license at any point in time to receive another year of updates.

What are the limitations of AbleSet's free trial?

The free trial of AbleSet lets you test all features for as long as you want, with the only limitation being that you have to restart the app every 15 minutes for it to continue working.

Where can I get an invoice or a receipt for my license?

The payment confirmation email you received when purchasing AbleSet contains a link to your receipt. The linked page also allows you to generate an invoice.

Network

Does AbleSet have to be connected to the internet to work?

No, since AbleSet runs its own web server on your computer, you can use it without an internet connection. Just make sure all your devices are on the same network and you're good to go.

How can I create a network on stage?

There are multiple ways to create a network on stage. Check out this guide for more information on this topic.

What port does AbleSet run on?

AbleSet runs on port 80 by default. Since this is the default port for websites, you don't have to enter it in your browser to access the web app. If AbleSet can't start on port 80, e.g. when it's already in use by another program, it will look for a free port starting with port 3000 and display that port in the status window.

Redundant Setup / AbleNet

Does AbleNet have the same 1024 bar limitation Live's sync has?

AbleNet doesn't have any limitation regarding the length of the set.

Troubleshooting

AbleSet is stuck on "Connecting to Ableton..."

This is a sign that AbleSet can't establish a connection to its Ableton and can have multiple causes. Try those steps to fix it:

  • Is Live running and is the AbleSet plugin selected in the MIDI preferences?
    • If you don't see the AbleSet plugin, it might not be installed. Go to AbleSet's settings menu, click on "Add AbleSet Plugin to Ableton", and then follow the assistant to install and configure the plugin.
  • Do you see any error messages in the status bar of Live?

I see "Cannot bind to ('127.0.0.1', 39041), port in use. Trying again..." in Live's status bar

This can happen if another program is already using the port Live uses to communicate with AbleSet, or if the port wasn't closed properly by the operating system before.

To fix this, please try restarting your computer. This resets all open ports and should allow Live to connect to AbleSet again.

Ableton Live doesn't jump to the next song or section in time

While Live is playing, AbleSet jumps to a song or section by activating its locator a short time before the jump is supposed to happen which respects Live's global quantization. You can simulate this by clicking on that locator in the arrangement view yourself while Live is playing.

If clicking on the same locator yourself also shows the same behavior, that's a good sign that the locator isn't placed on the quantization grid. You can fix this either by moving the locator onto the quantization grid or by decreasing the global quantization – 1/2 and 1/4 should work well.

I'm getting a "Playhead is Lagging" error notification

AbleSet's plugin runs on the same thread as Live's user interface. If you're working in a large project and it's zoomed out all the way, the plugin isn't able to send the playhead position to AbleSet at a regular interval which can cause all kinds of issues, like jumps to other songs not happening in time, loop brackets not being enabled, etc.

The easiest workaround is to zoom in your timeline so only one or two songs are visible at a time. This means Live doesn't have to render as many elements which frees up resources for AbleSet's plugin.

Alternatively, if you have access to Max for Live, you can add the AbleSet Controller to your project. This device runs independently of Live's user interface and can send the playhead position to AbleSet at a higher frequency.

I can't connect to AbleSet from my Android device

To connect to AbleSet from your Android phone, please make sure that it's on the same network as your computer and then enter the Remote or Host address shown in AbleSet's status window into your browser on Android.

If this doesn't help, sometimes disabling mobile data might do the trick as that forces Android to look for the IP address on your local network instead of trying to access it over the internet.

How can I report a bug?

You can send bug reports to support@ableset.app. To help me understand and reproduce the bug on my end, you can include the following information:

  • A description of the bug and steps that led to it
  • AbleSet's log package (Settings -> Create Log Package) including the project file
  • Pictures or videos of the bug

AbleSet's Locator Notation

Locators from Ableton to AbleSet

AbleSet uses Ableton's locators to determine where songs start and end. The simplest form of a locator contains just the song title and is located at the song's beginning:

Never Gonna Give You Up. Using this locator will lead to that title appearing as a song in AbleSet.

To ensure that playback runs smoothly, you should always place locators on a beat, if possible on a downbeat. If you place the locator between two beats, Ableton's quantization will not always work as expected.

To give AbleSet more information on what a marker means, you can use a more advanced locator notation:

Section Locators

A section locator starts with a

> followed by the name – for example
> Verse 2
. You can use it to divide a song into multiple sections. These can then be triggered from AbleSet.

If you want a section to be quickly accessible within performance view, you can prefix it with

>> – for example
>> Chorus
.

Sections can also be defined using MIDI clips on a Sections track starting with Live 11. This causes less visual clutter in your arrangement view. You can learn more about it here.

Locator Descriptions

Everything written in curly brackets is interpreted as a description. You can use this feature to add information like the song's key, tempo, and length. Example:

Follow Night {Tuning: C, Capo 1}

You can also add descriptions to section locators.

Stop Markers

There are two ways to get AbleSet to automatically stop playback after a song. If you place a locator named

STOP or
AUTOSTOP
in your set, AbleSet will automatically stop playback there.

If you place all songs directly next to each other, you can add a dot to the beginning of the song locator that follows the song after which you want playback to stop (for example:

. Follow Night). AbleSet will stop playback when it reaches this locator.

Both ways only work with normal locators, not with section locators, but can be combined as desired. So one song can be stopped by a

STOP locator while the next song can be stopped by a dot locator. Depending on how you want to structure your live set, it might make more sense to use one or the other.

Normally, AbleSet will either jump to the next song's locator or stay at the stop locator upon reaching it depending on the "Autojump to the Next Song" setting, but you can override this behavior by adding either a

+JUMP or
+STAY
flag to the stop locator – for example
STOP +JUMP
tells AbleSet to automatically jump to the next song's locator when the stop marker is reached.

Pause Markers

Using pause markers, you can tell AbleSet to pause playback at a certain section. To do that, you can add a

+PAUSE flag to the locator – for example
> Chorus +PAUSE
.

Song End Markers

If you want to mark the end of a song but don't want playback to stop, you can place a locator named

SONG END where your song ends. When this locator is reached, AbleSet will directly jump to the next song in the setlist if there is one.

Loop Markers

If you want to loop a section of your song, you can do so by adding

+LOOP to the end of the locator where you want the loop to start. AbleSet will then loop from this locator until the next locator until you skip to the next marker in the web app.

If you want AbleSet to always finish a loop before jumping to the next locator, you can use

+LOOPFULL instead of
+LOOP
.

If you're using a Sections track to define your song sections, and there's no locator at the end of a looped section, both

+LOOPFULL and
+LOOP
will behave in the same way, always just disabling the loop bracket and waiting for the current section to end.

To add a pre-defined maximum number of loops, you can append a number to the loop flag. For example,

+LOOP:4, will automatically disable the loop bracket after the third loop so the section plays four times.

Tags

You can add tags to your songs by appending them to the locator, e.g.

Follow Night #rock #crossings. These tags are displayed in the performance view and you can search for them when you're building your setlist.

When you're in the setlist editor, you can add all songs with a given tag to your setlist at once. To do this, click the "+" button on the bottom right, search for your tag, and click on "Add all songs with #tag".

Song Durations

If you want to set the duration of a song manually, you can do so by adding it to the end of the locator in square brackets. For example,

Follow Night [3:20] will set the song's duration to 3:20 minutes.

Colors

This feature is supported since 1.9.0. To color-code locators, you can add a color name to the locator in square brackets – e.g.

Galvanize [blue].

By default, section locators use the same color as the song they're assigned to, but you can override the color by adding a color name to the section locator – e.g.

> Verse [red].

The following colors are supported:

  • Gray
  • Red
  • Orange
  • Amber
  • Yellow
  • Lime
  • Green
  • Emerald
  • Teal
  • Cyan
  • Sky
  • Blue
  • Indigo
  • Violet
  • Purple
  • Fuchsia
  • Pink
  • Rose

Automatic Jumps / Transitions

To tell AbleSet what section it should jump to after a section, you can use the

>>> transition notation. For example, to jump to the first verse after the intro of your song, you can name your intro clip
Intro >>> Verse 1
given that there's a section called "Verse 1".

The target section needs to be defined with a locator or, if you're using section clips, have a locator at the same position as the section clip defining the section.

If you'd like the song to end after a given section, you can also use

>>> SONG END. This skips all sections after the song and jumps to the next song if there is one.

Here's a quick video that shows the feature in action: Automatic Jumps

Skipping Sections

To skip a section, add the

+SKIP flag to it and make sure that the section following it has a locator so AbleSet can jump to it. If you're skipping multiple sections in a row, only the section after the last skipped section needs to have a locator.

When you skip one or more sections at the beginning of a song, jumping to that song will place the playhead at the beginning of the first unskipped section.

Class Names

If you'd like to style certain songs using Custom CSS, you can give them custom class names. For example,

Why We Are [.bold] would add the bold class to every element representing this song on the web app.

Ignored Locators

If you want AbleSet to ignore a locator, just prefix it with a

*. This might be interesting for making notes in your live session:
* Check automation

AbleSet also ignores Clyphx locators, like

[STOP] SETSTOP; MIDI NOTE 3 1 127; so they don't clutter up your setlist.

Controlling AbleSet with Your MIDI Controller

If you prefer controlling your setlist via MIDI instead of a phone or tablet, you can either use AbleSet's built-in MIDI mapping or AbleSet's Max for Live device.

MIDI Mapping Settings

MIDI Mapping Settings in AbleSet

To start mapping incoming MIDI to functions in AbleSet, go to the settings page and click on "Edit MIDI Mapping". This will open a page showing a list of all connected MIDI devices, like in the image above.

To map a MIDI button to a function of AbleSet, click "Add New Mapping" under the device you'd like to map, then press the desired button. AbleSet captures the incoming MIDI and adds a new mapping that you can customize by choosing which function the MIDI should be mapped to.

Currently, MIDI notes and CC values can be mapped to functions in AbleSet.

A Note About Using MIDI Mapping on Windows

On Windows, only one application can access a given MIDI input at a time. This means that when you map a MIDI device in AbleSet, Ableton Live can't access it anymore, and the other way around.

The AbleNet Toggle

Each MIDI input has its own AbleNet toggle that defines whether MIDI commands should be forwarded to other AbleSet instances on the network. If you don't run a redundant playback setup, you can leave this toggle turned off.

If you use a redundant setup where each computer receives the same MIDI signals from your controller, you should also leave this turned off to prevent commands from being executed twice.

If you're using a redundant setup where just one computer receives MIDI from your controller, you should turn this toggle on to make sure that commands are executed on your other computers as well.

Custom OSC

If you'd like to customize the mapping of your buttons further, you can map them to the "Custom OSC" function. This allows you to enter any list of OSC commands for AbleSet to run, delimited by a semicolon. For example, to stop playback and jump to the next song, you'd enter /global/stop; /setlist/jumpBySongs 1. A list of all supported OSC commands is available here.

If you'd like AbleSet to wait before sending the next command, you can add a //sleep statement. For example, to sleep 2.5 seconds between stopping and jumping to the next song: /global/stop; //sleep 2500; /setlist/jumpBySongs 1. You can find a list of all control flow statements here.

OSC commands can also be sent to external servers. This allows you, for example, to control digital mixers or light desks. To send a command to an external OSC server, simply add its IP address and port to the beginning of the command, for example: 192.168.1.25:10023/ch/01/mix ON. You can combine those commands with AbleSet commands. For example: /global/play; 192.168.1.25:10023/ch/01/mix ON.

Max for Live Device

AbleSet's Max for Live device

If you prefer controlling your setlist via MIDI instead of a phone or tablet, you can use AbleSet's Max for Live device.

With AbleSet 2, you can find the controller by going to AbleSet's settings and clicking on "Get AbleSet Controller". If you're using a AbleSet 1, you can download the legacy controller device here.

To use this device, just drag it on any audio or MIDI track in your Ableton session. The controller will connect to AbleSet automatically. You can then map any of the functions to your MIDI controller as you're used to.

The Play, Pause, Next Song, and Prev. Song buttons are self-explanatory, but the Play Cued Song button has a special behavior. It only plays the next song after playback has been stopped by a

STOP (or
.
) marker, or the current song if playback is stopped and the playhead is on the start marker of a song. This is a safety measure that prevents accidental skips to the next song while the current song is still playing. In the most minimal setup, you only need to map this button to your MIDI controller.

In addition to the control functions, the controller sends more detailed playhead information to AbleSet 2 which is used to improve the position display in AbleSet.

Connecting to AbleSet From Other Devices

AbleSet hosts its own server which you can access from any other device's browser as long as it is on the same network as your computer. This doesn't require an internet connection, so you can set up your own local network on stage.

There are a few different ways to create a network, and some might suit your setup more than others.

Connect an iPhone or iPad to your Mac

If you don't use AbleNet and just want to connect to AbleSet from an iPhone or iPad with a wired connection and without any extra dongles, this is the easiest way.

First, connect your iPhone or iPad to your Mac via USB. If you're using macOS Monterey or older, open your Sharing preferences and go to "Internet Sharing" in the sidebar:

Sharing Preferences
  1. Make sure that "Share your connection from" is set to Wi-Fi. Your WiFi doesn't need to be connected to any network for this to work, but for some reason choosing Wi-Fi here works best.
  2. In the list of "To computers using", check your iPhone's or iPad's connection – it should be called "iPhone USB" or "iPad USB".
  3. Then check the checkbox next to "Internet Sharing" to turn sharing on.

You can now connect to AbleSet using the .local domain or the remote IP address that is shown in AbleSet's menu bar window.

If you're using macOS Ventura or newer, you'll find these settings by clicking on "General" in the sidebar, then clicking on "Sharing" and then clicking on the little info icon next to "Internet Sharing". You should see a dialog that looks like this:

Sharing Preferences on macOS Ventura or newer
  1. Click on the toggle at the top to enable the sharing settings, confirm the warning message if necessary.
  2. Set "Share your connection from" to "Wi-Fi". Your WiFi doesn't need to be connected to any network for this to work, but for some reason choosing Wi-Fi here works best.
  3. In the list of "To devices using", check your iPhone's or iPad's connection – it should be called "iPhone USB" or "iPad USB".
  4. Click "Done" to close the dialog.

Create a Network Using a Router

If you want to connect to AbleSet from multiple devices, you can use a router. This is one of the most common setups for on-stage networks and any simple router with or without Wi-Fi can be used for this.

Follow your router's instruction manual to set it up and then connect both your computer and the devices you want to use to connect to AbleSet to it. Most routers will automatically assign IP addresses so you don't need to worry about that.

Once all devices are connected, you can access AbleSet using either the .local domain or the remote IP address shown in the app's menu bar window.

Although it is possible to connect to AbleSet using Wi-Fi, I'd recommend using a wired Ethernet connection on stage since there will likely be lots of wireless interference from microphones, IEM systems, and other devices.

There are Lightning/USB-C to Ethernet dongles available if you want to connect a phone or tablet to your network with a wired connection.

Create a Network Using a Switch

This is similar to setting up a network using a router, except that switches often don't assign IP addresses to your devices automatically. You can manually assign IP addresses to your devices by going to the device's network settings and setting the "Configure IPv4" option to "Manually", or similar depending the device you use.

When choosing an IP address, make sure that the first three parts match on all devices. For example, you could use the IP address 192.168.1.100 for your first device, 192.168.1.101 for the second, and so on.

Make sure that the subnet mask is set to 255.255.255.0 on all devices.

Connect Two Devices Directly Using Ethernet

Instead of using a switch, you can also connect two devices directly using Ethernet. This is useful if you only have two devices and don't want to use a router or switch.

If you connect two Apple devices – iPhone/iPad/Mac – directly using Ethernet, they should automatically assign IP addresses. If this doesn't happen or you're not using Apple devices, you can set your devices' IP addresses manually using the steps described in the previous section.

Redundant Playback Setup with AbleNet

AbleNet is available since AbleSet 1.6.0. It allows you to control two or more computers in a redundant playback setup. AbleNet is decentralized, so any computer in the setup can crash or lose connection – as long as one computer is still online, AbleSet will continue working.

I've created a short video that explains the basic steps:

In short, to setup AbleNet, open the same Ableton session and enable AbleNet in the settings menu of AbleSet on all computers. The computers will automatically connect to each other and can now be controlled simultaneously with AbleSet.

You can open AbleSet in the browser or on your mobile device using either computer's IP address. When the computer you're currently connected to goes offline, AbleSet will automatically redirect you to the next available computer.

To connect two computers to the same output channels, you could use iConnectivity's PlayAUDIO12. This audio interface allows you to connect two computers and automatically switches to the backup computer when it detects that the main one isn't outputting audio anymore.

Automatic Drift Correction

Sometimes, your instances of Live might not start playback exactly at the same time, either because of network or disk latency. AbleNet offers an Automatic Drift Correction that takes care of nudging your computers back into sync.

To do this, AbleSet uses Live's Phase Nudge buttons to slightly slow down or speed up playback until all computers are in sync. You'll see the buttons flash while this happens:

In most cases, you might only want to enable this setting on your backup computer so that it can sync to your main computer and your main computer doesn't speed up or slow down playback, even if just slightly, to get in sync with the backup one.

For Automatic Drift Correction to work correctly, all audio clips have to be warped so they can follow the slight tempo changes caused by the Phase Nudge adjustments. Unwarped audio clips will continue playing at normal speed and get out of sync with Live's metronome.

I'd recommend using the Texture or Beats warp mode for audio clips as they both don't alter the audio output at all while playing at normal speed.

Custom IP Addresses

AbleNet uses Apple's Bonjour protocol to automatically detect other instances of AbleSet on the network. This will work in most cases, but if it doesn't, you can manually specify a list of IP addresses that AbleSet should connect to.

To do that, go to AbleSet's Settings page and scroll down to the AbleNet section. In a setup with two computers, you can enter the IP address of the other computer respectively in the "Connect to Custom IPs" field:

Custom IP Addresses Settings Window

Giving your computers static IP addresses simplifies this setup since you don't have to update this setting every time your computers get automatically assigned a new one. You can read more about this on the Network docs.

If AbleSet is running on a custom port, you can add it to the IP address, e.g. 192.168.198.20:3005.

Sync Playback Now

In case one of your computers or Ableton crashes, you can use the "Sync Playback Now" option to synchronize its playhead position with the one of your other computer and start playback so that both sessions are playing in sync again. This usually takes just a few seconds.

Tips for Using AbleNet

  • Ideally, you should connect all computers via Ethernet. That way, they're not susceptible to wireless interference which could cause latency issues.
  • Make sure that you're loading the exact same set on all computers. Otherwise, the computers might behave differently when jumping between songs.

Using AbleSet With Redundant Audio Interfaces

AbleSet supports a variety of redundant audio interfaces from different manufacturers:

  • iConnectivity: PlayAUDIO12 and PlayAUDIO1U
  • DirectOut: EXBOX.MD, PRODIGY (MC, MP, MX), MAVEN.A
  • DAD: Core256, AX64, AX Center

These interfaces are automatically detected when they're connected to your computer via USB (iConnectivity) or the network (DirectOut/DAD) and will appear in AbleSet so you can view their state and control them.

You can also control connected audio interfaces via OSC. See here for a list of supported commands.

Hiding Audio Interfaces

You might not always want to see all connected audio interfaces in AbleSet. To hide specific ones, open AbleSet's settings page and scroll to the "Audio Interfaces" section and click the toggle next to the audio interfaces you'd like to hide.

Interface Tips

iConnectivity

AbleSet communicates with iConnectivity audio interfaces via MIDI using the USB connection. This happens automatically as soon as it is connected.

When connecting two or more iConnectivity interfaces to your computer, please make sure to give them distinct names in Auracle. Otherwise, AbleSet might have trouble correctly communicating with all interfaces.

DirectOut

AbleSet communicates with DirectOut interfaces via Ethernet. They are automatically detected as soon as they're on the same network as your computer running AbleSet.

DAD

DAD interfaces are automatically discovered on the network. Currently, AbleSet doesn't support communicating with them using Thunderbolt.

By default, AbleSet shows all enabled presets from your DAD devices, but you can hide presets by adding +HIDE to their name, e.g. Keys +HIDE. If you have a long list of presets and only want AbleSet to show a few, you can instead add the +SHOW flag to the ones you want to see, e.g. Playback +SHOW +MAIN. AbleSet will then hide all others.

By default, the scene toggle button toggles all shown presets between set 1 and 2, and if one or more presets is not on set 1, the indicator becomes red. If you'd like AbleSet to only take specific presets into account while still being able to see and manually control others, you can add the +MAIN flag to their name.

Jump Modes

AbleSet 2 allows you to choose between four different modes when jumping between songs and sections. You can choose your preferred jump mode in AbleSet's settings:

  • Quantized: Jumps to the selected song or section while respecting your global quantization setting in Ableton Live
  • End of Section: Jumps when the end of the current section is reached, giving you more time to select what section to play next
  • End of Song: Jumps when the current song has ended. If the song ends with a
    STOP
    marker, playback stops. If it ends with a
    SONG END
    marker, the selected song will immediately play
  • Manual: Jumps only when playback stops, e.g. when a
    STOP
    marker is reached or when you manually press pause/stop

Lyrics in AbleSet

Since version 2, AbleSet supports displaying synchronized lyrics with your songs. This requires Live 11 or higher to work properly.

Each track that contains the +LYRICS flag is recognized as a lyrics track. To get started, create a MIDI track called Vocals +LYRICS that contains one clip per lyrics line. AbleSet will automatically create a synchronized lyrics view based on this.

Creating these lyrics clips manually can be a chore, so I've created a tool that allows you to paste your lyrics, synchronize them to your backing track, and download them as a Live project containing a track with your synchronized lyrics:

If you already have LRC files with synchronized lyrics, you can use this tool to convert them to Ableton project files that can be imported into your project:

Multiple Lyrics Tracks

AbleSet supports multiple lyrics tracks, so you could create a Lead Vocals +LYRICS track for your lead singer, a Backing Vocals +LYRICS track for your backing singers, and a Chords +LYRICS track for other musicians.

If multiple tracks are available, each device can choose which one they'd like to see on the web app.

Styling

The lyrics view supports basic Markdown to make parts of your lyrics bold or italic. To make a part of your lyrics italic, wrap it in single asterisks, e.g. *italic line*. To make a part of your lyrics bold, wrap it in double asterisks, e.g. **bold line**.

To give a line a color, you can add it in square brackets to the beginning of the line, e.g. [blue] Why We Are. The following colors are available:

  • Gray
  • Red
  • Orange
  • Amber
  • Yellow
  • Lime
  • Green
  • Emerald
  • Teal
  • Cyan
  • Sky
  • Blue
  • Indigo
  • Violet
  • Purple
  • Fuchsia
  • Pink
  • Rose

If you want all lines of a lyrics track to have the same color, you can add it to the track name in square brackets, e.g. Vocals +LYRICS [blue].

If you add either the

+CLIPCOLORS or
+CC
flag to the lyrics track name, AbleSet will use the color of your clips for the lines. Each column of Live's color picker corresponds to one color in AbleSet:

The text size can be changed using [large], [small], or [tiny], and the alignment can be changed using [left] or [center]. If you prefer a monospaced font, you can add the [mono] attribute.

Other available styling options include [nofade] to disable fading inactive lines, [nozoom] to disable zooming out inactive lines, [nosections] to hide section headers, and [linemarker] to show a marker next to the current line.

If you'd like to align the current lyrics line to the top of the page, you can add the [top] attribute. To show a number of lines before the current line, you add that number to the attribute, e.g. [top+2] to show 2 previous lines before the current line.

You can also use [progress] to display a progress bar on each line as it's playing:

You can combine these attributes, e.g: Vocals +LYRICS [blue] [small] [left]

Chords

To add chords to your lyrics, you can use the ChordPro syntax. As soon as one line contains chords, the entire song's lyrics track is recognized as a lyrics&chords track which changes the layout of lyrics, automatically aligning all lines to the left for better readability. For example:

[F] I know you tried so many ti[Am]mes
To be [G]who you used to be
[F] I know you tried so many ti[Am]mes [G]

Gets turned into:

F                            Am
  I know you tried so many times
      G
To be who you used to be
F                            Am  G
  I know you tried so many times

These chords can be transposed on a per-song level. Just add the number of semitones you'd like to transpose to the song's locator, e.g.

Follow Night [+2] or
Follow Night [-3]
.

You can also transpose all chords on a track by adding the number of semitones to your lyrics track's name in square brackets, e.g. Vocals +LYRICS [+2].

If you transpose chords up, AbleSet will display sharps and if you transpose them down, flats will be used.

If you'd like to change the color of the chords, you can add a color attribute to the track name, like [chords:red].

You can also hide all chords on a lyrics track using the [nochords] attribute.

Images

Starting with AbleSet 2.4.0, you can insert images into your lyrics. To do this, create a "Lyrics" folder in your Ableton project folder and add some images to it. The folder could look like this:

Lyrics Folder

You can then reference those images in your lyrics clips using their relative path name. For example, you could reference the image located at "atw/atw 1.png" by creating a lyrics clip named [img:atw/atw 1.png].

By default, images always try to take up as much width as possible without growing larger than the height of 3 lyrics lines. If you'd like images to fill the entire screen, you can add the [full] attribute, e.g. [img:atw/atw-bass-1.png] [full]. This is useful for displaying sheet music pages, for example.

If you'd like all images on a lyrics track to fill the entire screen, you can also add the [full] attribute to the lyrics track name, e.g. Vocals +LYRICS [full].

This feature supports PNG, JPEG, GIF, SVG, and WEBP images.

If you'd like to generate lyrics clips from a PDF, e.g. with sheet music, you can use the Lyrics Image Generator:

Line Breaks

You can insert line breaks into lyrics lines using the \ character – e.g. Line 1 \ Line 2. This allows you to have multiple lines in the same MIDI clip which all get highlighted at the same time.

All Songs Mode

By default, AbleSet only displays the lyrics of the current song, but you can add the [allsongs] attribute to your lyrics track name to make it display the lyrics of all songs on one continuous page.

This can be useful if songs are flowing into each other and you already want to read the first line of the next song before it starts.

Lines Crossing Sections

In some cases, a line might cross a section. By default, if more than half of the line is after the section start, AbleSet will display the line after the section header. The line will be displayed before the section header.

If you'd like to override this behavior for a line, you can add an attribute to its name, e.g. [<] Line to display the line before the section header and [>] Line to display it after the section header.

Time Delay

If you know your video or audio signal will have a certain delay, you can add that to the lyrics track to offset the lyrics display.

For example, if you know that your audio has a delay of 150ms, you can add [+150ms] to the track name which delays lyrics by that time.

If you're streaming the lyrics window over the network and you know there will be a 200ms video latency, you can add a negative delay, like [-200ms] instead to offset the latency and ensure the lyrics stay in sync with your song.

You can also delay the lyrics track by a number of beats, e.g. [+1n] to delay it by one beat, of [-2n] to show the next line two beats earlier.

Delays are only applied while Live is playing.

Guide Tracks

AbleSet 2 introduces support for managing your guide tracks. There are two types of supported guide tracks:

  • +GUIDE
    • Tracks containing the +GUIDE flag are active by default and only muted when you're jumping to another section or the current section is being looped
  • +LOOPGUIDE
    • Tracks containing the +LOOPGUIDE flag are muted by default and only unmuted when you loop the current section. This allows you to add an audio cue announcing that the same section will be played again
  • +JUMPGUIDE
    • Tracks containing the +JUMPGUIDE flag are muted by default and only unmuted while a section other than the one following the current section is cued

Please note that these flags are case-sensitive and need to be added to the track name exactly as shown here.

Both audio and MIDI tracks can be marked as guide tracks. Just add one of the guide track flags to the track's name to let AbleSet manage it.

Here's a video showing the feature in action:

Creating and Controlling Track Groups With AbleSet's Mixer

AbleSet 2.8 introduces support for creating and controlling track groups. These track groups can consist of multiple tracks and can be controlled on the fly from the web app or via OSC.

Mixer Page

If you have tracks named Click or containing +CLICK, those are automatically added to a "Click" group. To create other groups, add +G: or +GROUP: followed by the name of the group you'd like the track to belong to to the track's name, for example: +G:VOX.

Please note that the group name must be written in uppercase and can only contain letters, digits, and dashes.

Tracks can belong to multiple groups, so you could assign a track both to a VOX and to a BACKINGS group (e.g. Vox 1 +G:VOX +G:BACKINGS), while another track is assigned to a BASS and the same BACKINGS group (e.g. Synth Bass +G:BASS +G:BACKINGS). This allows you, for example, to mute both tracks at once using the BACKINGS group while still being able to mute them individually using their own groups.

The +NEVERMUTE Flag

Some tracks should never be muted – for example, if they output a control signal to a redundant audio interface. By adding the +NEVERMUTE or +NM flag to the name of those tracks, AbleSet ensures that they will always be audible. When you solo a track group, all +NEVERMUTE tracks are soloed as well.

Using Multi-File Projects

AbleSet's multi-file project feature allows you to split your Ableton Live project into one project file per song. This is especially useful if you have a lot of songs and handling them all in one session either gets too messy or you notice Live struggling to keep up.

To enable the multi-file project mode, go to AbleSet's settings menu and click on Multi-File Project -> Choose Project Folder...

You can then select a folder containing all songs that should be loaded into the setlist. This could be a Live project folder containing multiple project files, or a normal folder containing multiple Live projects – the folder structure doesn't really matter.

The filename of your songs can contain cue notation like notes, colors, and the song duration – for example: Why We Are {some notes} [blue] [3.42].als

Since file systems don't support the : character in filenames, it can be replaced with a . for durations, as shown in the example above.

Here's an example:

Example Folder Structure

Each project file needs to contain at least one marker at the start of the song and one

STOP marker at the end of the song.

Options

The Save Changes Before Loading Project option allows you to decide whether the current project file should be saved when loading a new song. By default, this is enabled to prevent data loss, but if you're sure you don't want any changes to be saved, you can disable this to speed up switching between songs.

The ableset.json File

This file is stored in the folder you selected as the multi-file project root and contains information about the current setlist, e.g. the order of songs, the setlist name, etc.

Caveats

  • Since Live projects can take a little while to load, jumping from one song to another is possible when playback is stopped. As such,
    SONG END
    markers will be interpreted as
    STOP
    markers.
  • One project file can currently only contain one song. Since AbleSet doesn't know about the contents of a project file until it's opened in Live, it has to treat each file as one song.

Using a MIDI Track to Define Song Sections

Since version 1.9.0, you can use a MIDI track in Live 11 to define song sections. This cleans up the session since you have to use fewer markers.

This feature requires Live 11 or higher to work properly.

To get started, create a MIDI track called "Sections" and add empty MIDI clips to it where the song sections are. It might look a bit like this:

MIDI Clips on the Sections Track

AbleSet will recognize these clips as section markers and add them to your song. The clip duration doesn't matter – each section ends where the next one begins.

Recognized Sections

Alternatively, you can give the track any other name and include a +SECTIONS flag. You can also use the cue notation syntax to add comments and set a color for a marker.

If you like, you can combine the use of section locator and clips in your songs. If there's a locator and a section clip at the same time, AbleSet will prioritize the information stored in the locator.

Due to some limitations with Ableton Live's API, sections defined by clips can only be jumped to when Live isn't currently playing. If you need that functionality, you can place locators named

> at the same position as the section clip you'd like to be able to jump to.

As a workaround, AbleSet offers the ability to automatically place locators at each section clip. To access it, open the settings page, scroll down to the "Tools" section, and then click "Place Locators on Section Clips" to start this process. To reverse it, click "Remove Automatically Placed Locators".

The locators will use Live's default naming, which is just an increasing number. You can rename the locators to

> for consistency, or
>>
if you'd like to mark the section as a quick jump section. You can also rename the locators to the section name, just remember to add a
>
at the beginning, e.g.
> Chorus
.

Even with these limitations, section clips are a great way for defining sections that you want to jump to during rehearsals – combined with the count-in function, this is a great way to practice certain sections of a song.

Using Clip Colors For Sections

If you add either the

+CLIPCOLORS or
+CC
flag to the section track name, AbleSet will use the color of your clips for the sections. Each column of Live's color picker corresponds to one color in AbleSet:

Using Measure Tracks in AbleSet

Since version 2.7.0, AbleSet allows you to add a measure track to your timeline to define the measures in your songs:

Measure Track

The measure track needs to be called "Measures" and can contain one MIDI clip per measure for your songs. The title of each clip represents the measure that AbleSet will display. This is usually a number, but you can give these clips any name you like.

Creating these clips for all measures in your songs is tedious, so you can use this tool to create measure clips for a number of measures in any time signature:

If AbleSet doesn't detect any measure clip at a given time, it falls back to Live's internal measure.

Using AbleSet's Count-In Feature

Since version 1.8, AbleSet has a Count-In feature which allows you to start playback of sections a few bars before the section starts. This is helpful for practice situations where you want to work on a specific section.

Count-In Settings

The menu allows you to choose between a 1-bar, 2-bar, or 4-bar count-in. You can also choose to solo the click track during the count-in. AbleSet will look for the first track or group that contains "click" as the click track.

Tracks named "Lifesine" will always be soloed as well so if you're using a redundant audio interface like the PlayAUDIO12 or PlayAUDIO1U, it won't failover to your backup computer.

You can mark additional tracks as click tracks by adding the +CLICK flag to their name. These tracks will also be soloed during count-ins.

For count-in to work reliably in versions of Live older than 11.1.5, make sure that you set Live's grid size to a fixed "1 bar" or lower. Otherwise, AbleSet will not be able to correctly position the playhead, and you'll get a warning message.

Importing, Exporting, and Printing Setlists

AbleSet allows you to save setlists for later use. This might be useful if you often switch between a few setlists or to make a backup of your setlist.

Exporting

To export your setlist, click the edit button and then the download button on AbleSet's setlist page:

Exporting a Setlist

Importing

To import a setlist, click the edit button and then drag the file into the page. In addition to AbleSet's own file format, the importer supports Strange Electronic's SETLIST file format, so you can easily import those setlists as well.

Printing

To print your setlist, open the print dialog by pressing CMD+P or CTRL+P or selecting "Print" in your browser's menu bar. You can then either print the setlist directly or save it as a PDF:

Print Dialog in Google Chrome

Song colors are included in the printed setlist.

I'd recommend using Chrome, Edge, or Opera to print your setlists as those give you more options to customize the size and page layout of the printed setlist, but Safari should generally work as well.

Keyboard Shortcuts

If you're using AbleSet with a keyboard, you can use these shortcuts to control it:

Global:

  • SPACE: Play/pause
  • LEFT: Previous Song
  • RIGHT: Next Song / escape current loop
  • UP: Previous Section
  • DOWN: Next Section
  • L: Toggle Loop
  • SHIFT+L: Toggle device lock

In Setlist and Performance Views:

  • CMD+K or CTRL+K: Open the dialog for adding songs
  • TAB: Toggle between setlist and performance view

When Lyrics Are Shown:

  • .: Next lyrics line
  • ,: Previous lyrics line
  • M: Jump to next lyrics line and pin it
  • N: Jump to previous lyrics line and pin it
  • SHIFT+M: Toggle lyrics pinning

Controlling AbleSet via OSC

AbleSet listens to OSC commands on port 39051, so you can remote-control it from any other app that supports OSC.

Here's a list of all available commands:

Global

  • /global/play starts playback
  • /global/pause pauses playback
  • /global/stop stops playback
  • /global/startPlaying starts playback from the last cursor position
  • /global/continuePlaying continues playing from the current playhead position
  • /global/playPause toggles playback between play and pause
  • /global/playStop toggles playback between play and stop
  • /global/startRecording starts recording, and starts playback when Live isn't already playing
  • /global/stopRecording stops recording, but doesn't stop playback
  • /global/toggleRecording starts recording and playing, or stops recording
  • /global/reEnableAutomation re-enables all disabled automation in Live
  • /global/quantization [quantization] sets the global quantization of your project
    • Allowed values: 8, 4, 2, 1, 1/2, 1/2T, 1/4, 1/4T, 1/8, 1/8T, 1/16, 1/16T, 1/32, none
  • /global/tempo [tempo] sets the tempo of your project, overriding any automation
  • /global/tempo/adjust [delta] adjusts the tempo by the given number of BPM
    • The delta can be positive to increase the tempo or negative to decrease it
  • /global/tempo/reset resets the tempo to the automation of your project

Loop

  • /loop/enable enables Live's loop bracket
  • /loop/escape disables Live's loop bracket
    • if the current loop was enabled using the +LOOP flag, this will also jump to the next section
  • /loop/toggle toggles Live's loop bracket

Setlist

  • /setlist/jumpToTime [time] jumps to the given time, in beats
  • /setlist/jumpToSong [number, name, or RANDOM] jumps to the song at the given position in the setlist
    • /setlist/jumpToSong 2 jumps to the 2nd song
    • /setlist/jumpToSong -2 jumps to the 2nd-last song
    • /setlist/jumpToSong SongTitle jumps to the first song named "SongTitle"
    • /setlist/jumpToSong RANDOM jumps to a random song
  • /setlist/jumpBySongs [steps] jumps by given number of songs
    • /setlist/jumpBySongs 1 jumps to the next song, /setlist/jumpBySongs -1 jumps to the previous one or to the beginning of the current song when the playhead isn't at the start of the song
    • Adding a force=true parameter when jumping back a song (e.g. /setlist/jumpBySongs -1 force=true) ignores the playhead's current position inside the song and always jumps to the previous song
  • /setlist/jumpToSection [number or name] jumps to the section at the given position in the current song
    • /setlist/jumpToSection 2 jumps to the 2nd section
    • /setlist/jumpToSection -2 jumps to the 2nd-last section
    • /setlist/jumpToSection Chorus jumps to the first section named "Chorus"
    • /setlist/jumpToSection Chorus true jumps to the first section whose name includes the word "Chorus"
  • /setlist/jumpToQuickPlaySection [number] jumps to the nth quick play section of the current song
    • /setlist/jumpToQuickPlaySection 2 jumps to the 2nd quick play section
    • /setlist/jumpToQuickPlaySection -2 jumps to the 2nd-last quick play section
  • /setlist/jumpBySections [number] [boolean] jumps by a given number of sections
    • /setlist/jumpBySections 1 jumps to the next section in the current song
    • By default, AbleSet prevents you from jumping beyond the bounds of the current song. To override this, set the 2nd argument to true. For example, /setlist/jumpBySections 1 true will jump to the first section of the next song when the playhead is positioned in the last section of the current song
    • Adding a force=true parameter when jumping back a section (e.g. /setlist/jumpBySongs -1 force=true) ignores the playhead's current position inside the section and always jumps to the previous one
  • /setlist/jumpByBeats [number] [boolean] jumps forward or backward by a given number of beats
    • By default, AbleSet prevents you from jumping beyond the bounds of the current song. To override this, set the 2nd argument to true.
  • /setlist/jumpByBars [number] [boolean] jumps forward or backward by a given number of bars
    • By default, AbleSet prevents you from jumping beyond the bounds of the current song. To override this, set the 2nd argument to true.
  • /setlist/jumpByMeasures [number] [boolean] jumps forward or backward by a given number of measures, always snapping to the beginning of the measure
    • By default, AbleSet prevents you from jumping beyond the bounds of the current song. To override this, set the 2nd argument to true.
    • When jumping back one measure while the playhead isn't at the beginning of a measure, AbleSet jumps to the beginning of the current measure first. To override this, add a force=true argument.
  • /setlist/jumpToQueued [boolean] jumps to the queued song or section
    • if the first argument is true, AbleSet jumps instantly, without respecting Live's global quantization
  • /setlist/playCuedSong plays the next song after the current song has finished
    • if autoplay is disabled, this will jump to the next song first, and start playback when it's called again
  • /setlist/go is a command that does different things based on the current state of your set:
    • When stopped at the end of a song, jumps to the next song
    • When stopped at the beginning of a song, starts playback
    • When playing in a loop, escapes the loop
    • When playing while a song or section is queued, instantly jumps to it
  • /setlist/setLocatorsFromClips places a locator at each section clip
  • /setlist/removeClipLocators removes automatically placed locators at section clips
  • /setlist/load [string] loads a saved setlist by its name
  • /setlist/removeSong [string] removes a song from the setlist by its name
  • /setlist/toggleStop toggles whether AbleSet should stop at the end of the current song
    • This only works for songs that end with a
      SONG END
      locator

Lyrics

  • /lyrics/jumpByLines [string] [integer] jumps by the given number of lines
    • The first parameter is the slug of the lyrics track, the second defines the number of lines AbleSet should jump by.
    • /lyrics/jumpByLines leo 2 jumps ahead two lyrics lines in the lyrics track called "Leo +LYRICS"
    • /lyrics/jumpByLines backing-vox -2 jumps back two lyrics lines in the lyrics track called "Backing Vox +LYRICS"

Mixer

  • /click/mute [boolean or toggle] mutes or unmutes all click tracks
  • /click/solo [boolean or toggle] soloes or unsoloes all click tracks
  • /mixer/[group name]/mute [boolean or toggle] mutes or unmutes all tracks in the given track group
  • /mixer/[group name]/solo [boolean or toggle] soloes or unsoloes all tracks in the given track group
  • /mixer/[group name]/fadeOut [duration] fades the given track group out
    • the duration can be omitted, a default of 2000ms is used then
  • /mixer/[group name]/fadeIn [duration] fades the given track group in
    • the duration can be omitted, a default of 2000ms is used then
  • /mixer/[group name]/volume [number] sets the track group's volume
    • the volume can be between 0 and 1, with 0 being all group tracks at -Inf dB and 1 being all tracks at their maximum of 6dB

Audio Interfaces

  • /audioInterfaces/setScene [1, 2, A, or B] sets the active scene on the connected audio interfaces
    • /audioInterfaces/setScene 1 sets the active scene to scene A
    • /audioInterfaces/setScene B sets the active scene to scene B
  • /audioInterfaces/toggleScene toggles the active scene between A and B on the connected audio interfaces
  • /audioInterfaces/arm arms the failover system of all audio interfaces
    • For iConnectivity devices, this enables the "Arm" mode
    • For DirectOut devices, this sets the port priority to Auto and resets all force settings

Commands for iConnectivity PlayAUDIO Devices

  • /audioInterfaces/playaudio/setScene [serial] [scene] sets active scene of the device
    • scene can be either 1 or 2
  • /audioInterfaces/playaudio/setArmed [serial] [armed] sets whether the failover system is armed
    • armed can be either 0 or 1

You can find the serial number of your PlayAUDIO devices in Auracle.

Commands for DirectOut EXBOX.MD Devices

  • /audioInterfaces/exbox/setPriority [host] [port] [priority] sets the priority of a port on the given host
    • priority can be either Inactive, Main, Backup, or Auto
  • /audioInterfaces/exbox/setForce [host] [port] [force] sets the priority of a port on the given host
    • force can be either None, Main, or Backup

For both commands, host is the hostname of your EXBOX.MD, and port can be either SFP, BNC, SC, or NET. All values are case-sensitive.

Commands for DirectOut PRODIGY/ANDIAMO Devices

  • /audioInterfaces/prodigy/setPriority [host] [port] [priority] sets the priority of a port on the given host
    • priority can be either Inactive, Main, Backup, or Auto
  • /audioInterfaces/prodigy/setForce [host] [port] [force] sets the priority of a port on the given host
    • force can be either None, Main, Backup, or Disaster Recovery

For both commands, host is the hostname of your EXBOX.MD, and port can be either MADI 1, MADI 2, NET 1 A, NET 1 B, NET 2 A, or NET 2 B. All values are case-sensitive.

Commands for DAD Devices

  • /audioInterfaces/dad/setOverride [serial] [preset ID] [override ID] overrides the active source set for a given preset
    • The override ID can be 1-4 for a source set or 0 to disable the override

Floating Setlist Window

  • /floatingWindow [show|hide|toggle] shows, hides, or toggles the floating setlist window

Settings

Boolean values can be an actual boolean or 0 / 1. You can also set them to toggle to toggle the setting.

  • /settings/ableNet [boolean] enables or disables AbleNet
  • /settings/ableNetDriftCorrection [boolean] enables or disables automatic drift correction
  • /settings/autoplay [boolean] sets the autoplay option
  • /settings/alwaysStopOnSongEnd [boolean] sets whether AbleSet should stop playback at the end of all songs
  • /settings/autoJumpToNextSong [boolean] sets whether AbleSet should automatically jump to the next song at the end of a song
  • /settings/allowJumpBackToBeginning [boolean] sets whether AbleSet should jump to the beginning of the current song first before jumping to the previous song
  • /settings/autoLoopCurrentSection [boolean] sets whether AbleSet should automatically move the loop bracket to be around the current section
  • /settings/autoReEnableAutomationOnSongJump [boolean] sets whether AbleSet should automatically re-enable all automation when jumping to a new song
  • /settings/disableLoopWhenJumping [boolean] sets whether AbleSet should automatically disable the loop bracket when jumping to another song or section
  • /settings/removePlayedSongs [boolean] sets whether AbleSet should automatically remove played songs from the setlist
  • /settings/countIn [boolean] enables or disables the Count-In feature
  • /settings/countInSoloClick [boolean] sets whether the click track should be soloed during count-in
  • /settings/countInDuration [1, 2, or 4] sets the count-in duration in bars
  • /settings/jumpMode [quantized, end-of-section, end-of-song, or manual] sets the jump mode
  • /settings/safeMode [boolean] enables or disables the Safe Mode feature

AbleNet

To enable or disable AbleNet or the automatic drift correction, see settings OSC commands.

  • /ableNet/syncToRemote brings this machine back in sync with others on the network if it's paused, see AbleNet docs

Device Control

You can use these OSC commands to control the AbleSet web app in the browser. If you'd like a command to run on all devices, pass all as the first parameter. Otherwise, set the first parameter to either the IP address or host name of the device you'd like to control. The host name is case-insensitive. Multiple devices can be passed separated by commas.

  • /devices/showPage [devices] [page] navigates to the given page
    • The page parameter corresponds to the path you see in the browser's URL bar
    • /devices/showPage all performance navigates to the performance page on all connected devices
    • /devices/showPage leos-ipad lyrics/leo opens the lyrics page for the lyrics track called Leo on the device called leos-ipad
    • /devices/showPage 192.168.1.10 setlist opens the setlist page on the device with the IP address 192.168.1.10
  • /devices/setSetting [devices] [setting] [value] sets a device-specific setting
    • Settings can be viewed by going to Settings -> Debug -> Device Settings
    • /devices/setSetting all performance.showSectionProgress true enables the section progress bar on all devices
    • For boolean settings, you can send toggle instead of the value to toggle the setting
  • /devices/lock [devices] locks the given device
  • /devices/unlock [devices] unlocks the given device
  • /devices/toggleLock [devices] toggles the lock on the given device
  • /devices/pressKey [devices] [key] simulates a keypress on the given devices
    • This is experimental and doesn't cover all cases yet
    • Use this website to get the code of any pressed key
    • To add Shift or CMD/CTRL modifiers, prepend them to the key code
    • /devices/pressKey all Shift+M presses Shift + M, which toggles pinning in the lyrics view on all devices
  • /devices/showSections [devices] [boolean or toggle] shows or hides the sections of the current song in the setlist
  • /devices/hideAllSections [devices] hides the sections of all songs in the setlist

Notifications

These OSC commands display a notification on one or more devices. If you'd like the notification to be displayed on all devices, pass all as the first parameter. Otherwise, set the first parameter to either the IP address or host name of the device you'd like to control. The host name is case-insensitive. Multiple devices can be passed separated by commas.

  • /notify/toast [devices] [title] [description] [duration] displays a toast notification on all browsers
    • Description and duration are both optional parameters
    • The toast duration is specified in milliseconds
  • /notify/big [devices] [message] [duration] [color] displays a message that fills the entire screen on all browsers
    • Duration can be omitted and will default to 5000 ms
    • The message duration is specified in milliseconds, but users can also hide it by tapping on it
    • The color can be any of the supported colors in AbleSet
    • The message can contain simple markdown for bold, italic, and underlined text
  • /notify/cue [devices] [duration] [color] displays a colored cue light along the edge of the screen
    • The cue duration is specified in milliseconds
    • The color can be any of the supported colors in AbleSet

You can also clear notifications:

  • /notify/big/clear [devices] clears a big notification
  • /notify/cue/clear [devices] clears a cue light

Sending MIDI

AbleSet can send MIDI data to any output port using OSC. You can use these commands to send notes:

  • /midi/send/note [output] [channel] [note] [velocity] [duration] sends a note on followed by a note off to the specified output
    • Velocity is optional, the default value is 127
    • Duration is specified in milliseconds, the default value is 100
  • /midi/send/noteOn [output] [channel] [note] [velocity] sends a note on with the given velocity to the specified output
    • Velocity is optional, the default value is 127
  • /midi/send/noteOff [output] [channel] [note] [velocity] sends a note off with the given velocity to the specified output
    • Velocity is optional, the default value is 0

The note can either be a number between 0 and 127, or a string like E#0 or Cb-1.

To send CC and PC, you can use these commands:

  • /midi/send/cc [output] [channel] [controller] [value] sends a CC to the given output
    • Controller and value must both be numbers between 0 and 127
  • /midi/send/pc [output] [channel] [program] sends a PC to the given output
    • Program must be between 0 and 127

You can also send raw MIDI data to any output, for example for SysEx:

  • /midi/send/raw [output] [data]
    • Data can either be a list of numbers, or a string like F0 03 A3 F7

Shared Variables

AbleSet allows you to set shared variables which are accessible from all devices and persisted across restarts. This is especially useful for setting state via MIDI mapping or in canvases.

To set a shared variable, send an OSC command to /shared/[variable name] with its value or values. For example:

  • /shared/controlsEnabled true sets the controlsEnabled variable to true
  • /shared/items 1 2 sets the shared items variable to an array of [1, 2]

Variable names can contain slashes as well:

  • /shared/canvas/color blue sets the canvas/color variable to blue

Control Flow Statements

When writing OSC commands in AbleSet's MIDI mapping and Canvas, you can use control flow statements to delay or skip the next commands. Here's a list of all available control flow statements:

  • //sleep [duration] sleeps for the given duration in milliseconds before running the next commands
  • //awaitJump waits for Live to jump to the queued section before running the next commands
  • //awaitFileLoad waits for Live to load the project file before running the next commands
  • //if [condition] only runs the next commands if the condition is met
    • Currently, the condition can be either playing, recording, or looping
    • You can negate a condition by adding a ! at the beginning, e.g. !playing
    • If the condition isn't met, all following commands are skipped until an //endif or another //if statement
    • You can't combine multiple conditions at this time
    • To make the command a bit easier to read, you can use a colon (//if playing:) instead of a semicolon (//if playing;) to delimit it from the next command
    • Example: //if !playing: /setlist/jumpBySections 1 only jumps to the next section if Live isn't currently playing

AbleNet Parameters

If you're using OSC commands in a setup with multiple computers connected via AbleNet, AbleSet automatically forwards commands to all other connected computers. For additional redundancy, you should send the same command to all computers.

For this to work well, each command you send to AbleSet via OSC should have its own UUID. You can append it as a string parameter to any OSC command, for example uuid=1234abcd where "1234abcd" is a random string for each command.

When AbleSet receives multiple commands with the same UUID, it will only execute the first one and discard all others.

If you don't want AbleSet to forward OSC commands, you can add the string ableNet=false to any OSC command that you send to AbleSet. In that case, the UUID parameter isn't necessary.

Finding the AbleSet OSC Server on Your Network

AbleSet announces its OSC server on the network using Bonjour. Apps like TouchOSC can find it automatically using the "Browse" function so you don't have to enter the IP address and port manually.

If you're writing your own OSC client, you can use any Bonjour library to look for _osc._udp. on the network. AbleSet's OSC server has a TXT value of server=ableset, so in case there are other applications announcing their OSC servers on the network as well, you can look for that value to find AbleSet.

Receiving Updates from AbleSet

AbleSet can send updates on its current state to other OSC servers. This can be used to update the state of your control surfaces in real time.

To register your OSC server with AbleSet, send the /subscribe command with the IP address and port, and optionally a name – e.g.:

/subscribe 127.0.0.1 8000 TouchOSC

If you set the IP address to auto or omit the parameter, AbleSet will use the IP address the request came from to register the OSC server, e.g.:

/subscribe 8000 TouchOSC or /subscribe auto 8000 TouchOSC

This is useful for setups where you don't always know your IP address, like using TouchOSC on a machine that gets a new IP every time it connects to the network.

To receive fine value updates, e.g. for the playhead position or song/section progress, add an additional argument to the call:

/subscribe 8000 TouchOSC true

Please note that these fine updates are sent up to 30 times per second and might be taxing on low-end devices receiving them.

You'll see a notification that the device has been connected, and from this point on, AbleSet will send updates for all events to your server. You can register multiple servers with AbleSet if you want to connect multiple control surfaces. To unsubscribe from events, send /unsubscribe to AbleSet.

If you'd only like to receive updates for specific values, you can add those to the /subscribe command as well:

/subscribe 8000 TouchOSC true "/global/isPlaying" "/setlist/activeSongName"

This reduces the network traffic and is especially useful for OSC clients that can't handle a lot of messages at once.

The value filter supports excludes and wildcards using the glob syntax. For example, /mixer/*/volume would include /mixer/click/volume, /mixer/bass/volume, etc. while /mixer/** would include all values starting with /mixer.

To exclude values from updates, prepend an exclamation mark to the filter, e.g. !/setlist/** to exclude all updates from values starting with /setlist.

These filters can be combined so you can tune the updates to your liking.

In addition to value events, AbleSet will send a /heartbeat every 2 seconds. You can use this to check if the connection is still up. If you'd like to trigger a heartbeat yourself, you can send a /getHeartbeat command to AbleSet.

To get the current state of all values, send /getValues to AbleSet. If you've already subscribed to value updates, this sends results to the same port as these updates. You can override this by providing a port or a host and a port:

/getValues 8000 or /getValues 127.0.0.1 8000

If you've set up a filter when subscribing, you only get the values that are included in this filter. You can override this by adding the addresses of values you'd like to receive to the command:

/getValues "/global/*" "/setlist/activeSongName"

Here's a list of all values that get sent to registered servers:

Global

  • /global/isConnected [0|1] whether AbleSet is connected to Live
  • /global/isLoadingFile [0|1] whether Live is loading a new song file
  • /global/beatsPosition [float] the current position in beats, floored to whole numbers while Live is playing
  • /setlist/finePosition [float] the current position
    • Requires the fine flag to be set when subscribing to updates
  • /global/humanPosition [float] [float] the current position in bars and beats
  • /global/currentMeasure [string] [float] [float] the current measure from a measure track, if available, along with the current beat and the total number of beats in the current measure
  • /global/tempo [float] the current tempo
  • /global/isPlaying [0|1] whether Live is currently playing
  • /global/timeSignature [integer] [integer] the time signature
  • /global/quantization [quantization] the global quantization of your project
    • Possible values: 8, 4, 2, 1, 1/2, 1/2T, 1/4, 1/4T, 1/8, 1/8T, 1/16, 1/16T, 1/32, none
  • /global/canReEnableAutomation whether any automation in Live is currently disabled

Setlist

  • /setlist/name [string] the setlist name
  • /setlist/songs [...string] a list of all song names in the setlist
  • /setlist/songColors [...string] a list of all songs' colors in the setlist
  • /setlist/songDurations [...float] a list of all songs' durations in the setlist in seconds
  • /setlist/sections [...string] a list of all sections of the current song
  • /setlist/sectionColors [...string] a list of all sections' colors of the current song
  • /setlist/activeSongName [string] the name of the current song
  • /setlist/activeSongDescription [string] the description of the current song
  • /setlist/activeSongIndex [string] can be referenced to the list of songs
  • /setlist/activeSongStart [float] the song's start position in beats
  • /setlist/activeSongEnd [float] the song's end position in beats
  • /setlist/activeSongDuration [float] the song's duration in seconds
  • /setlist/activeSongColor [string] [string] the color of the song, as a color name and as a hex string
  • /setlist/activeSongProgress [float] the song's progress from 0 to 1
    • Requires the fine flag to be set when subscribing to updates
  • /setlist/activeSongStopDescription [string] the song's stop description
  • /setlist/activeSectionName [string] the name of the current section
  • /setlist/activeSectionDescription [string] the description of the current section
  • /setlist/activeSectionIndex [float] the index of the current section in the current song
  • /setlist/activeSectionStart [float] the section's start position in beats
  • /setlist/activeSectionEnd [float] the section's end position in beats
  • /setlist/activeSectionColor [string] [string] the color of the section, as a color name and as a hex string
  • /setlist/activeSectionLoopMode [loop|loopfull] the section's loop mode
  • /setlist/activeSectionLoopCount [integer] the pre-defined number of loops
  • /setlist/activeSectionDuration [float] the section's duration in seconds
  • /setlist/activeSectionProgress [float] the section's progress from 0 to 1
    • Requires the fine flag to be set when subscribing to updates
  • /setlist/nextSectionName [string] the name of the next section
  • /setlist/nextSectionDescription [string] the description of the next section
  • /setlist/nextSectionIndex [float] the index of the next section in the current song
  • /setlist/nextSectionStart [float] the next section's start position in beats
  • /setlist/nextSectionEnd [float] the next section's end position in beats
  • /setlist/nextSectionColor [string] [string] the color of the next section, as a color name and as a hex string
  • /setlist/nextSectionDuration [float] the next section's duration in seconds
  • /setlist/queuedName [string] [string] the name of the queued song and section
  • /setlist/queuedIndex [float] [float] the index of the queued song and section
  • /setlist/nextSongName [string] the next song's name
  • /setlist/nextSongDescription [string] the next song's description
  • /setlist/nextSongIndex [float] the next song's index
  • /setlist/nextSongDuration [float] the next song's duration in seconds
  • /setlist/nextSongColor [string] [string] the color of the next song, as a color name and as a hex string
  • /setlist/loopEnabled [0|1] whether the loop bracket is enabled
  • /setlist/loopStart [float] the loop's start position in beats
  • /setlist/loopEnd [float] the loop's end position in beats
  • /setlist/loopCounter [integer] the current number of repetitions in the loop
  • /setlist/isInActiveSectionLoop [0|1] whether the playhead is currently in an active section loop
  • /setlist/isCountingIn [0|1] whether AbleSet is currently counting in
  • /setlist/remainingTimeInSong [float] remaining time in the current song, in seconds
  • /setlist/remainingTimeInSet [float] remaining time in the set, in seconds

Lyrics

  • /lyrics/[slug]/previous the previous lyrics line's text
  • /lyrics/[slug]/current the current lyrics line's text
  • /lyrics/[slug]/next the next lyrics line's text

Mixer

  • /mixer/[group name]/muted whether the track group is currently muted
  • /mixer/[group name]/soloed whether the track group is currently soloed
  • /mixer/[group name]/volume the track group's current volume between 0 and 1
  • /mixer/[group name]/isFading whether the track group is currently fading in or out

Shared Variables

When you set a shared variable via OSC or scripting, that variable is forwarded to all subscribed OSC clients.

Audio Interfaces

  • /audioInterfaces/connected [0|1] whether an audio interface is connected
  • /audioInterfaces/all/scene [1|2] the current scene – 1 for the main and 2 for the backup computer
  • /audioInterfaces/names [...string] the names of all connected audio interfaces
  • /audioInterfaces/scenes [...1|2] the interfaces' current scenes – 1 for the main and 2 for the backup computer
  • /audioInterfaces/status [...string] the status of each connected audio interface
    • Can be armed, sceneA, sceneB, or alarm

Updates for iConnectivity PlayAUDIO Devices

  • /audioInterfaces/playaudio/[serial]/scene the active scene – 1 for the main and 2 for the backup computer
  • /audioInterfaces/playaudio/[serial]/armed whether the failover system is armed to automatically switch – can be 0 or 1
  • /audioInterfaces/playaudio/[serial]/armed whether the failover system is currently in alarm mode
  • /audioInterfaces/playaudio/serial/main/signal the signal state of the main input
  • /audioInterfaces/playaudio/serial/backup/signal the signal state of the backup input

Signal values are as follows:

  • 0: Not connected
  • 1: Connected
  • 2: Sending audio
  • 3: Sending audio & sine

Updates for DirectOut EXBOX.MD Devices

  • /audioInterfaces/exbox/[host]/[port]/backupPort the selected backup port
  • /audioInterfaces/exbox/[host]/[port]/priority the selected port priority
    • Can be either Inactive, Main, Backup, or Auto. If the priority is Inactive, EARS for this port is disabled
  • /audioInterfaces/exbox/[host]/[port]/force the forced port
    • Can be either None, Main, or Backup
  • /audioInterfaces/exbox/[host]/[port]/active the port that is currently active
    • Can be either Main or Backup
  • /audioInterfaces/exbox/[host]/[port]/signal the kind of signal received on the port
    • Can be either BLDS, Pilot, or None

The host is your EXBOX's hostname on the network. The port can be SFP, BNC, SC, or NET. For signal, the NET port is split into NET1 and NET2.

Updates for DirectOut PRODIGY/ANDIAMO Devices

  • /audioInterfaces/prodigy/[host]/[port]/backupPort the selected backup port
  • /audioInterfaces/prodigy/[host]/[port]/priority the selected port priority
    • Can be either Inactive, Main, Backup, or Auto. If the priority is Inactive, EARS for this port is disabled
  • /audioInterfaces/prodigy/[host]/[port]/force the forced port
    • Can be either None, Main, Backup, or Disaster Recovery
  • /audioInterfaces/prodigy/[host]/[port]/active the port that is currently active
    • Can be either Main, Backup, or Disaster Recovery
  • /audioInterfaces/prodigy/[host]/[port]/signal the kind of signal received on the port
    • Can be either BLDS, Pilot, or None

For all updates, host is the hostname of your PRODIGY or ANDIAMO, and port can be either MADI 1, MADI 2, NET 1 A, NET 1 B, NET 2 A, or NET 2 B. All values are case-sensitive.

Updates for DAD Devices

  • /audioInterfaces/dad/[serial]/[preset ID]/name the name of the preset
  • /audioInterfaces/dad/[serial]/[preset ID]/activeSourceSet the currently active source set
    • If this is 0, no source set is selected
  • /audioInterfaces/dad/[serial]/[preset ID]/sourceSetOverride the source set override
    • If this is 0, the source set override is disabled
  • /audioInterfaces/dad/[serial]/[preset ID]/sourceSets/[set ID]/name the source set's name
  • /audioInterfaces/dad/[serial]/[preset ID]/sourceSets/[set ID]/triggers/[trigger ID]/signal the signal state of a trigger's input

Sending Timed OSC Commands with OSC Tracks

Since version 2.7.0, AbleSet allows you to send timed OSC commands from a MIDI track. These commands can either be sent to AbleSet or external apps or devices that support OSC – for example TouchOSC, audio consoles, light desks or video players.

To get started, create a new MIDI track and make sure that its name contains +OSC, e.g. AbleSet +OSC. All clips placed on this track will now trigger OSC commands that you add to their name as soon as Live's playhead reaches them.

By default, OSC commands are sent to AbleSet. You can find a list of all available OSC commands here. For example, to trigger a big notification on all connected devices, you can create a clip with the following command:

AbleSet OSC Track

To send OSC commands to external apps or devices, you can add their IP or hostname and port to the OSC command, e.g. 192.168.1.5:3000/scene 2.

Multiple commands can be separated by semicolons. If you'd like to add a delay between two commands, you can use the //sleep command. For example, to wait 2.5 seconds between stopping and jumping to the next song:

/global/stop; //sleep 2500; /setlist/jumpBySongs 1.

You can find a list of all control flow statements here.

Available Attributes

The behavior of OSC tracks can be altered using attributes on the track name.

If you'd like all OSC commands to be sent to a specific target, you can add it to the track name in square brackets, e.g. External +OSC [192.168.1.25:3000].

You can also set a prefix which is added to each OSC command. For example, if you'd like to create an OSC track that triggers notifications in AbleSet, you can add the prefix in square brackets, e.g. Notify +OSC [/notify/big all].

This prefix can contain multiple arguments and you can specify multiple arguments in the MIDI clips on this track. So, for example, if a clip on this track was named Test 1000, the command sent to AbleSet would be /notify/big all Test 1000 which would make the text "Test" appear on screen for 1000 ms.

If you'd like AbleSet to interpret the name of clips as a single argument instead, add the [single] attribute to the track name in addition to the prefix. With this in place, if a clip on the track was named Test 1000, the command sent to AbleSet would be /notify/big all "Test 1000".

You can also combine the prefix attribute with the target attribute, e.g. External +OSC [192.168.1.25:3000/fxsend/mix].

To send OSC commands only while Live is playing, add the [playing] attribute to the track name.

OSC Syntax

Each OSC command starts with an address followed by an optional list of arguments, which is separated by spaces, e.g. /notify/big all Test.

AbleSet automatically detects integer, float, and boolean arguments, so /test 10 1.5 true would send a /test OSC command with an integer, a float, and a boolean argument. All other arguments are interpreted as strings, so /test hello would send a /test OSC command with a string argument.

If you'd like AbleSet to interpret an argument as a string, or if a string argument needs to contain spaces, you can wrap it in quotes. For example, /test "true" "Test Message" would send a /test OSC command with two string arguments – "true" and "Test Message".

You can use either ", ', or ` as quotes. If you'd like to use the quote character you used to define the string inside the string as well, you can escape it using a backslash, e.g. "Some \"quotes\" in a string".

AbleSet's Scripting API

AbleSet's canvas allows you to write scripts that are triggered by pressing a button, moving a slider, etc. The script editor provides autocompletion for available functions and variables and automatically highlights incorrect code.

These scripts are written in JavaScript and support all features of ES2023. If you're already familiar with writing JavaScript, you can skip the next section and go straight to the list of available functions.

JavaScript Basics

Your First Script

The following script prints "Hello World!" to the console. The log function is a handy tool to debug your scripts by showing values while your script runs.

log("Hello World!");

This is a function call. Each function call consists of the function name, and braces containing arguments. These arguments depend on which function you call. In this case, we're passing the text "Hello World!" to the log function.

You can end each function call with a semicolon (recommended) or write one function call per line without semicolons.

Comments

If you'd like to add comments to your code, you can do so like this:

// This is a single-line comment

/*
  This is a multi-line comment
*/

Variables

To store and re-use values in your scripts, you can define variables. There are two types of variables, const and let. Use const when the value won't change (recommended), and let when you need to modify it later:

// This variable can be re-assigned
let name = "Léo";
name = "The other Léo";

// This one can't be re-assigned - use this when possible
const answer = 42;
answer = 41; // <- this would result in an error

// Variables can't be defined twice
const app = "AbleSet";
const app = "AbleSet 2"; // <- this would fail

Variables only exist while your script runs and will be cleared afterwards. If you need to store values between script runs, use the setLocal and local functions described here.

Primitive Data Types

JavaScript supports a range of primitive data types: number, string, boolean, undefined, and null:

// A number:
const num = 1234.56;

// Strings can use double or single quotes:
const hello = "Hello";
const world = 'World';

// Booleans are either true or false:
const yes = true;
const no = false;

The values undefined and null are special values representing no data.

Template Strings

Template strings are a special string type that use backticks (`) as quotes and allow you to include variables:

const name = "Léo";
const message = `Hello, ${name}!`;

Operators

Operators allow you to manipulate and check data and variables:

// You can use +, -, *, /, and % (modulo) on numbers
const result = (3 + 5) / 2; // <- result will be 4

// To modify number variables, you can use ++, --, +=, -=, *=, and /=
let num = 3;
num++; // num is increased by 1
num--; // num is decreased by 1
num += 3; // 3 is added to num, same as num = num + 3
num -= 2; // 2 is subtracted from num, same as num = num -3

// Use + to concatenate a string with other variables
const message = "The result is " + result;

To compare two or more values with each other, you can use these operators:

const name = "Léo";
const answer = 42;

// Use === (equal) and !== (not equal) to compare two values
const equal = answer === 42; // <- will be true
const unequal = name !== "Tom"; // <- will also be true

// Use && (AND), || (OR), and ! (NOT) to combine comparisons
const and = equal && name === "Léo"; // <- will be true
const or = equal || name === "Tom"; // <- will also be true
const not = !equal; // <- will be false

Conditional Statements

Conditional (if) statements allow you to decide which code to run based on given conditions:

const song = "Roads";
const artist = "Small Strides";

if (song === "Follow Night") {
  log("The song is Follow Night");
} else if (artist === "Small Strides") {
  // This code will run since the song condition wasn't satisfied,
  // but this one (artist) was
  log("The song is not Follow Night, but the artist is Small Strides");
} else {
  log("Neither song nor artist match");
}

Ternary Operator

The ternary operator allows you to get a value based on a condition:

const number = 9001;

// This message variable will be "It's over 9000!".
const message = number > 9000 ? "It's over 9000!" : "Value is too small";

// Ternary operators can be used anywhere, e.g. in arguments:
const answer = 42;
log(answer === 42 ? "Correct" : "Wrong");

Loops

To run a block of code multiple times, you can use loops:

// This runs the loop 10 times, starting with 1
// and increasing the variable i by 1 each time
for (let i = 1; i <= 10; i++) {
  log(`Hello, number ${i}`); // Logs "Hello, number 1", "Hello, number 2", etc.
}

Note that we have to use let i = 1 instead of const i = 1 here because the variable needs to be modified on each run.

Alternatively, you can use while and do...while loops, but I'll skip them here for brevity.

Arrays

Arrays allow you to store a list of values in a variable. They can contain all primitive data types and other arrays.

// This is how you define an array:
const songs = ["Roads", "Follow Night", "Why We Are"];

// Accessing array items can be done like this. Note that the index starts at 0:
const firstSong = songs[0]; // <- "Roads"
const lastSong = songs[2]; // <- "Why We Are"

// You can also access the length of the array:
const songCount = songs.length; // <- 3

Further Information

To learn more about JavaScript, you might find the Mozilla Docs helpful.

Available Functions

When writing scripts in AbleSet, you can access all objects and functions available in JavaScript, including Math, Date, and JSON. You can find an overview here.

Additionally, AbleSet offers a number of built-in functions to interact with the app and other devices.

Here's a list of them. Arguments marked with a ? are optional, a ... before arguments means you can add as many arguments of this type as you like.

Basics

  • log(...values) logs all values to the console
  • await sleep(time) waits for the given number of milliseconds

Local Variables

To store values between script runs and access them from other scripts and components, you can use these functions:

  • setLocal(key, value, persist?) stores the given value under the given key
    • If persist is true, the value is stored in your browser's storage and persisted between page refreshes
  • local(key, fallback?) returns the value at the given key
    • If there's no value stored at key yet, fallback is returned
  • resetLocal(key?) deletes the variable stored at key
    • If no key is defined, all local variables are deleted

Example:

// Gets a counter and increases it by 1
const counter = local("counter", 0);
setLocal("counter", counter + 1);

OSC

  • osc(key, index?) returns the OSC value for the given key
    • By default, it returns the first argument of the OSC value, but you can specify the index using the index argument
    • To get an array all arguments, set index to "all"
  • sendOsc(command, ...args) sends an OSC command with the given arguments
    • This can either be an internal (e.g. "/global/play") or an external (e.g. "127.0.0.1:3000/test") command
  • await waitForOscChange(key) waits until the value for the given key changes

Example:

// Jumps to the next song if AbleSet isn't playing, waits
// for the name to change, and logs the value of the new song
if (!osc("/global/isPlaying")) {
  sendOsc("/setlist/jumpBySongs", 1);
  await waitForOscChange("/setlist/activeSongName");
  log("New song:", osc("/setlist/activeSongName"));
}

A list of all available OSC values and commands is available here.

MIDI

These functions are aliases for the /midi/send OSC commands. You can use these commands to send notes:

  • sendMidiNote(output, channel, note, velocity?, duration?) sends a MIDI note on followed by a note off to the given output
    • Velocity is optional, the default value is 127
    • Duration is specified in milliseconds, the default value is 100
  • sendMidiNoteOn(output, channel, note, velocity?) sends a note on with the given velocity to the specified output
    • Velocity is optional, the default value is 127
  • sendMidiNoteOff(output, channel, note, velocity?) sends a note off with the given velocity to the specified output
    • Velocity is optional, the default value is 0

The note can either be a number between 0 and 127, or a string like E#0 or Cb-1.

To send CC and PC, you can use these commands:

  • sendMidiCc(output, channel, controller, value) sends a CC to the given output
    • Controller and value must both be numbers between 0 and 127
  • sendMidiPc(output, channel, program) sends a PC to the given output
    • Program must be between 0 and 127

You can also send raw MIDI data to an output, for example for SysEx:

  • sendMidiRaw(output, ...data)
    • Data can either be a list of numbers, or a string like "F0 03 A3 F7"

Browser Control

  • navigate(path) navigates the browser to the given path
    • The path can either be relative (e.g. "/lyrics") or absolute (e.g. "https://ableset.app")
  • pathname contains the current pathname (e.g. "/canvas/main")

Utility Functions

  • formatDuration(seconds) formats a given number of seconds into a more readable string
    • For example, formatDuration(135) returns "02:15"

Controlling AbleSet With a Stream Deck

AbleSet offers support for Elgato's Stream Deck using BitFocus Companion.

This allows you to create a control surface that's completely customized to your needs. Buttons can display a variety of information about your set.

Here's a tutorial on how to set it up:

Controlling AbleSet with an Oakboard Floor Vista

AbleSet officially supports Oaktone's Oakboard Floor Vista, a MIDI controller with an integrated display that allows you to see and control your setlist on stage.

By default, when you connect your Floor Vista to your computer via USB, AbleSet will automatically detect it, set up default MIDI mappings, and show the current setlist on its display. You can change the MIDI mappings in AbleSet's settings if you like.

Oaktone and iConnectivity

You can also use the Floor Vista to control AbleSet in a redundant setup. For AbleSet to recognize the controller, the names of its MIDI input and output ports need to include "Oakboard". You can rename the MIDI ports of your PlayAUDIO12, PlayAUDIO1U, mioXM, or mioXL by opening Auracle, clicking "MIDI Mapping", and then clicking the pencil icon next to the MIDI port your Floor Vista is connected to.

MIDI Routing in Auracle

In some cases, macOS might not recognize the changed name right away. To fix this, unplug your MIDI interface, remove it from Audio MIDI Setup, and then plug it back in.

Add Custom Styles to AbleSet using CSS

If you're familiar with CSS, AbleSet 2 allows you to easily add custom styles to the web app. You can find the custom CSS file by clicking on "Show Custom Styles" in AbleSet's settings menu.

AbleSet will automatically apply your styles when you save changes to this file.

I've tried to give most elements and states in the web app meaningful class names, but if you find yourself trying to add a style to an element that doesn't have a good class name, feel free to reach out to me!

This is an experimental feature and your styles could break the layout of the web app, so you should know what you're doing. If you want to reset your custom styles, just delete all lines from the file and save it.

User Styles

Check out the User Styles category on the AbleSet forum for a collection of styles you can use to customize AbleSet.

Examples

Custom Fonts

This simple example changes the font of all elements on the performance page:

.performance {
  font-family: Georgia, "Times New Roman", Times, serif;
}

Your browser will use the first font in the list that is available. The snippet above would look like this on macOS:

Performance Page with Custom Fonts

Custom Backgrounds

All files in the global "custom-styles" folder are served under the "/custom-styles" path, so you could add a background image called bg.jpg to the styles folder and load it like this to show it behind the lyrics, for example:

.lyrics-page {
  background-image: url("/custom-styles/bg.jpg");
  background-size: cover;
}

This results in the lyrics page looking like this:

Lyrics Page with Background Image

To files stored in your project's "Custom Styles" folder are served under the "/custom-styles/project" path, so an image file called bg.jpg that is stored there could be used as a background like this:

.lyrics-page {
  background-image: url("/custom-styles/project/bg.jpg");
  background-size: cover;
}

Custom Scripts

AbleSet lets you add custom JavaScript using the scripts.js file in the styles folder. This file is loaded after all other scripts on the web app have been loaded.

Since version 2.4.0, AbleSet exposes an ableset object on the window that you can access. This gives you access to the current state, sockets, and more.

For example, to get the current setlist state, you can call:

ableset.queryClient.getQueryData(["setlist"]);

// Use this to get a list of all queries:
console.log(ableset.queryClient.queryCache.queriesMap);

To observe changes in the state, you can use the QueryObserver object:

const observer = new ableset.QueryObserver(ableset.queryClient, {
  queryKey: ["setlist"],
});

observer.subscribe((result) => console.log(result.data));

To get access to sockets, e.g. to listen to changes in real-time, you can call:

// Listen to all events
ableset.getSocket("setlist").onAny((event, data) => console.log(event, data));

// Listen to specific event
ableset.getSocket("global").on("songTime", (time) => console.log(time));

The following sockets are available:

  • global
  • setlist
  • lyrics
  • ablenet
  • playaudio12
  • timecode
  • settings
  • midiMapping

Feel free to experiment with the events each of these sockets receives.