For multi-song Playback sessions, I like to have the stems for each Song Grouped, so they can be folded / collapsed - and only unfold / expand the particular song playing. I like to see the waveforms of the current song. I do as much Playback work in Pro Tools as Ableton, and there it’s very easy to arrange for the playing song to automatically unfold it’s tracks on screen, and all the other song ‘folders’ (equivalent to Ableton Groups) to fold down. This is because Pro Tools locator markers can store track visibility as well as timeline position. I can’t find a way to achieve this in Ableton. Wondering if this is something Ableset could do - if the song Group names matched the Song Start locator names?
Hey @njrsound,
AbleSet doesn’t do this natively, but you can get there with AbletonOSC and a Project Script.
Setup
- Install AbletonOSC and select it as a Control Surface in Live’s Link/Tempo/MIDI preferences.
- In AbleSet, go to Settings → MIDI Mapping, OSC & Scripting → OSC Settings → Add New Connection. Name it
AbletonOSC, Send Address127.0.0.1:11000, Listen Port11001. - Name each Group Track exactly like its Song Start locator.
- Paste this into Settings → MIDI Mapping, OSC & Scripting → Project Script:
const OSC = ":AbletonOSC";
const NAMES_KEY = OSC + "/live/song/get/track_names";
let trackMap = {};
let managed = new Set();
let activeSong = null;
function updateFolding(song) {
const current = new Set(Object.values(trackMap));
// Fold anything that dropped out of the map (renamed or deleted)
for (const i of managed) {
if (!current.has(i)) sendOsc(OSC + "/live/track/set/fold_state", int(i), int(1));
}
// Unfold the active song's group, fold the rest
for (const [name, index] of Object.entries(trackMap)) {
sendOsc(OSC + "/live/track/set/fold_state", int(index), int(name === song ? 0 : 1));
}
managed = current;
}
// Runs when Live replies with the track list
onOscChange(NAMES_KEY, (names) => {
const songs = osc("/setlist/songs", "all") ?? [];
trackMap = {};
(names ?? []).forEach((name, i) => {
if (songs.includes(name)) trackMap[name] = i;
});
if (activeSong) updateFolding(activeSong);
}, true);
onOscChange("/setlist/activeSongName", ([name]) => {
activeSong = name;
if (!name) return;
updateFolding(name);
sendOsc(NAMES_KEY); // refresh the list in case tracks changed
}, true);
sendOsc(NAMES_KEY);
Restart AbleSet after saving. From then on, switching songs unfolds the matching group and folds all the others.
Limitations
- Group Tracks only. Live’s API exposes
fold_stateon foldable tracks, so a loose track named after a song won’t do anything — there’s nothing to fold. Your stems need to actually be inside a group. - Names must match exactly, and without AbleSet flags. In particular, don’t use
+Gas a prefix — that’s an AbleSet flag that assigns a track to a Mixer Track Group, which is a different thing entirely. - Renames take effect on the next song change, since the script refreshes its name-to-index map at that point. Not an issue once your session is built.
- If you already have a Project Script running, append this to it rather than replacing it.
One note on scripting in general: avoid await sleep() at the top level of a Project Script. It silently halts execution, so anything registered after it never runs. Keep things event-driven with onOscChange() like above. There’s a good overview of the Project Script in the official tutorial.
Give it a run and let me know how it goes!
1 Like
wow, thanks Agustin - I’ll give it a try when I get some free time.