Title
ableton toggle active track states
What do you expect to happen when you run the script/macro?
toggle track active buttons on 2 tracks in ableton project
Are you seeing an error?
system argument out of range exception. unsupported expression (parameter: expression)
What happens when you run this script?
error message
How were you running this script?
I used a Stream Deck button
How important is this issue to you?
5
Details
{ "inputExpected": "toggle track active buttons on 2 tracks in ableton project", "inputIsError": true, "inputError": "system argument out of range exception. unsupported expression (parameter: expression)", "inputWhatHappens": "error message", "inputHowRun": { "key": "-MpfwmPg-2Sb-HxHQAff", "title": "I used a Stream Deck button" }, "inputImportance": 5, "inputTitle": "ableton toggle active track states" }
Source
(async () => {
try {
// Get current Live set
const set = await sf.abletonLive.getCurrentSet();
const tracks = set.tracks;
// EDIT THESE NAMES EXACTLY to match your Ableton track names
const nameA = "Nyx Bass Guitar Guide";
const nameB = "Nyx Bass Guitar Live";
const tA = tracks.find(t => t.name === nameA);
const tB = tracks.find(t => t.name === nameB);
if (!tA || !tB) {
const found = tracks.map(t => t.name).slice(0,40).join(", ");
sf.ui.showToast(`Tracks not found. First tracks: ${found}`);
sf.log("Tracks present:", tracks.map(t => t.name));
return;
}
// Toggle their 'isActive' states
await tA.set("isActive", !tA.isActive);
await tB.set("isActive", !tB.isActive);
sf.ui.showToast(`Toggled: ${tA.name} / ${tB.name}`);
} catch (err) {
sf.ui.showToast("Error: " + (err.message || err));
sf.log(err);
}
})();
Links
User UID: 90VwGojZF3hvy2smqFsCCR3UQhl2
Feedback Key: sffeedback:90VwGojZF3hvy2smqFsCCR3UQhl2:-O_l0q0Q-RMUPvcIWqX8
Feedback ZIP: XmqrTSepaJYgDllZSh2YcPS28QZZZirR5JkEoVuis/5o53KTsJeriyy4dwPS5Dh7BHRycjqRy819Uw3Lts+VC2kqaD0FH50SXmEnoYYp7r7ncoG4GoR0q/3eP63C3LOwQHJwSNNNYt4kdTL/x2wQ+wEeTb//sslzl6P0eR8T2SMOHVEBdjY7tZH626O57eIPP18iBfYV4Dm/dPopE50z2ssllUBtS4S/VWQNN2Tr7svQX7CYe7aTUY456lavt7e80gXN4IGz/9fulCWJmzqcG7UXLT88aT3Xk1CAGsoESpERI2nAFIM17f7JseAYDDeDKXf1wR9Bkm5z4O8Not2seg==
- Chad Wahlbrink @Chad2025-09-24 01:22:24.729Z
Hi, @Micha,
Thanks for the question! This is a great use case for using SoundFlow with Ableton.
The code you shared is generating errors because it uses elements that don't exist in the SoundFlow API. In the SoundFlow Editor, you'll notice that the script has some red underlines:
These underlined sections are bits of code that can't compile because they don't exist within SoundFlow's API.
I'm going to assume this likely came from an AI tool, which is totally okay. This is a common reason for code not executing in SoundFlow.
ChatGPT or other AI tools are great at coding JavaScript, AppleScript, and Shell scripts, but these tools often don't fully understand SoundFlow, and thus, AI can struggle to produce accurate code.
No worries, though. Here's a quick video showing where I ended up:
https://www.loom.com/share/60e6297200fc417dabea5a1a655e4a02
And here is the code that is working on my system for toggling two tracks active state in Ableton:
// Bail out if Ableton is not running if (!sf.ui.abletonLive.isRunning) throw `Ableton Live is not running`; // Define the Track Names const nameA = "Nyx Bass Guitar Guide"; const nameB = "Nyx Bass Guitar Live"; // Store the tracks in the current set. let tracks = sf.app.abletonLive.song.tracks.invalidate(); // Get the track objects let trackA = tracks.find(track => track.name.stringValue === nameA); let trackB = tracks.find(track => track.name.stringValue === nameB); // Set the Mute States to the Opposite for Each Track trackA.mute.setValue({ value: !trackA.mute.boolValue }) trackB.mute.setValue({ value: !trackB.mute.boolValue })
If you have any trouble getting this to run, let me know. Note that you will need to have the SoundFlow Control Surface assigned in your Link, Tempo & MIDI settings for this script to work. See this article for more detail:
https://soundflow.org/docs/getting-started/ableton-live#installing-the-ableton-live-integration
- MIn reply toMicha⬆:Micha @Micha
Hey Chad,
Thank you so much for your help on this! I have managed to take the code ever further by getting the value of the first track & applying some logic that makes sure the other track is always in the opposite state. Here is the code if anyone finds it useful:
// Bail out if Ableton is not running if (!sf.ui.abletonLive.isRunning) throw `Ableton Live is not running`; // Define the Track Names const nameA = "Nyx Bass Guitar Guide"; const nameB = "Nyx Bass Guitar Live"; // Get all tracks let tracks = sf.app.abletonLive.song.tracks.invalidate(); // Find the track objects let trackA = tracks.find(track => track.name.stringValue === nameA); let trackB = tracks.find(track => track.name.stringValue === nameB); if (!trackA || !trackB) throw "Could not find one or both tracks"; // Read current state of Track A const aCurrent = trackA.mute.boolValue; // Set Track B to match Track A’s current state trackB.mute.setValue({ value: aCurrent }); // Toggle Track A trackA.mute.setValue({ value: !aCurrent });
- MIn reply toMicha⬆:Micha @Micha
Additonal to this, I read in the forum that it's still not possible to change the colour of the button based on the value of the mute button. I really I'd like the track button to go red or some other colour to show when the live input track is active or green when the guide track is playing. This application is for a live band project where there are recorded guide tracks - so for example if I need my bass guitar guide to carry on playing for me while I check on something & then to be able to quickly press the button again and continue playing when done. Are there any visual options possible at all - eg text colour change, icon change, or any other kind of visual identification on the buttons?
Chad Wahlbrink @Chad2025-10-15 20:57:22.645Z
Hi, @Micha,
Currently, dynamic button states are not supported for the deck editor. You can read more about the reasons we have yet to implement this from Christian here:
There are some semi-dynamic options for SoundFlow, like the Generic Button Commands - but this wouldn't exactly satisfy what you are after.
That said, I will note this down as an idea for future implementation in the official Ableton Live Package, as I do think it would be possible to implement this functionality from the developer side.
I'll follow up with you here if we do implement this in any way.
- MIn reply toMicha⬆:Micha @Micha
Additionally, I wanted to create a second row of buttons that just mute / unmutes the guide recording - thats for say the odd occasion if I wanted the guide recording to play as well as the live input track being active so I can check how I am supposed to be playing a part & try play along. For this I just copied the code from above & removed the second track from the script. It does work but just wondering if the code can be simplified - or if this is fine? Does more lines of code mean a button takes longer to action the script? If not then I don't think it matters that much - because as I say, it is working.
Here is the code for the mute / unmute button:
// Bail out if Ableton is not running if (!sf.ui.abletonLive.isRunning) throw `Ableton Live is not running`; // Define the Track Names const nameA = "Crow Vox Guide"; // Store the tracks in the current set. let tracks = sf.app.abletonLive.song.tracks.invalidate(); // Get the track objects let trackA = tracks.find(track => track.name.stringValue === nameA); // Set the Mute States to the Opposite for Each Track trackA.mute.setValue({ value: !trackA.mute.boolValue })
Chad Wahlbrink @Chad2025-10-15 21:18:39.241Z
The script you shared is perfect in this scenario!
The only way to make it "faster" would be to remove the
invalidate()
call, as shown in the code below. Invalidation essentially refreshes the "cache" of tracks in the session. You technically only need to do this once, whenever you're adding or removing tracks from the session, to ensure the new track is cached.Lengthier discussion on this here:
When to use invalidate() #post-2Example without invalidation:
// Bail out if Ableton is not running if (!sf.ui.abletonLive.isRunning) throw `Ableton Live is not running`; // Define the Track Names const nameA = "Crow Vox Guide"; // Store the tracks in the current set - .invalidate() removed let tracks = sf.app.abletonLive.song.tracks; // Get the track objects let trackA = tracks.find(track => track.name.stringValue === nameA); // Set the Mute States to the Opposite for Each Track trackA.mute.setValue({ value: !trackA.mute.boolValue })
- SIn reply toMicha⬆:SoundFlow Bot @soundflowbot
This issue is now tracked internally by SoundFlow as SF-3026