I have a script that I have created to attempt to make my External OSC commands being sent to companion more readable. Currently it shows something along the lines of (/location/39/1/5/press), So basically the script is taking the names of the clips (DRUMS ON, TUNE C, etc.) and when it sees that name, it sends out the OSC that corresponds with it. The issues I am running into is that every 30 seconds to 5 minutes-ish it is sending the command (/location/6/0/4/press) which is triggering Waves Tune to the key of C. Also, after some time, companion appears to hang up and crash. I am currently on the latest beta and just wanted to see if anything stuck out to anyone on what could be causing the (seemingly) random firing of the one command. Thanks for any help!
let lastCues = ["", "", "", "", "", "", "", ""];
function normalizeCue(value) {
if (value == null) return null;
return String(value).trim().toUpperCase().replace(/\s+/g, " ");
}
function isCue(cue, aliases) {
return aliases.includes(cue);
}
function handleCue(rawCommand) {
const rawText = String(rawCommand ?? "").trim();
const cue = normalizeCue(rawCommand);
if (!rawText || !cue) return;
log(`PARSE | raw: "${rawText}"`);
// LIGHTING - PAGE 39
if (isCue(cue, ["DRUM LIGHTS ON", "DRUMS ON", "DRUM ON", "DRUMS UP", "DRUM UP"])) {
sendOsc("192.168.8.125:12321/location/39/0/8/press");
} else if (isCue(cue, ["DRUM LIGHTS OFF", "DRUMS OFF", "DRUM OFF", "DRUMS DOWN", "DRUM DOWN"])) {
sendOsc("192.168.8.125:12321/location/39/0/9/press");
} else if (isCue(cue, ["CHOIR LIGHTS ON", "CHOIR ON", "CHOIR UP"])) {
sendOsc("192.168.8.125:12321/location/39/0/10/press");
} else if (isCue(cue, ["CHOIR LIGHTS OFF", "CHOIR OFF", "CHOIR DOWN"])) {
sendOsc("192.168.8.125:12321/location/39/0/11/press");
} else if (isCue(cue, ["ORCHESTRA ON", "ORCHESTRA UP", "ORCH ON", "ORCH UP"])) {
sendOsc("192.168.8.125:12321/location/39/0/12/press");
} else if (isCue(cue, ["ORCHESTRA OFF", "ORCHESTRA DOWN", "ORCH OFF", "ORCH DOWN"])) {
sendOsc("192.168.8.125:12321/location/39/0/13/press");
// CG1 / PRO PRESENTER - PAGE 21
} else if (isCue(cue, ["ABLESET", "AS", "CG1", "CG1/AS", "CG1 AS", "CG1 ABLESET"])) {
sendOsc("192.168.8.125:12321/location/21/0/0/press");
// WAVES TUNE - PAGE 6 (Added "TUNE " prefix to eliminate accidental collisions)
} else if (isCue(cue, ["TUNE CHROMATIC"])) {
sendOsc("192.168.8.125:12321/location/6/0/0/press");
} else if (isCue(cue, ["TUNE A"])) {
sendOsc("192.168.8.125:12321/location/6/0/1/press");
} else if (isCue(cue, ["TUNE A#", "TUNE BB"])) {
sendOsc("192.168.8.125:12321/location/6/0/2/press");
} else if (isCue(cue, ["TUNE B"])) {
sendOsc("192.168.8.125:12321/location/6/0/3/press");
} else if (isCue(cue, ["TUNE C"])) {
sendOsc("192.168.8.125:12321/location/6/0/4/press");
} else if (isCue(cue, ["TUNE C#", "TUNE DB"])) {
sendOsc("192.168.8.125:12321/location/6/0/5/press");
} else if (isCue(cue, ["TUNE D"])) {
sendOsc("192.168.8.125:12321/location/6/0/6/press");
} else if (isCue(cue, ["TUNE D#", "TUNE EB"])) {
sendOsc("192.168.8.125:12321/location/6/0/7/press");
} else if (isCue(cue, ["TUNE E"])) {
sendOsc("192.168.8.125:12321/location/6/1/0/press");
} else if (isCue(cue, ["TUNE F"])) {
sendOsc("192.168.8.125:12321/location/6/1/1/press");
} else if (isCue(cue, ["TUNE F#", "TUNE GB"])) {
sendOsc("192.168.8.125:12321/location/6/1/2/press");
} else if (isCue(cue, ["TUNE G"])) {
sendOsc("192.168.8.125:12321/location/6/1/3/press");
} else if (isCue(cue, ["TUNE G#", "TUNE AB"])) {
sendOsc("192.168.8.125:12321/location/6/1/4/press");
// DIRECT PAGE/ROW/COLUMN ENTRY
} else if (/^\d+\/\d+\/\d+$/.test(rawText)) {
sendOsc(`192.168.8.125:12321/location/${rawText}/press`);
// GENERIC PAGE 39 NUMBER ENTRY
} else if (/^\d+$/.test(rawText)) {
sendOsc(`192.168.8.125:12321/location/39/0/${rawText}/press`);
}
}
while (true) {
// Transport Lock: Safely check if Ableton is playing
let abletonIsRolling = false;
try {
if (typeof isPlaying !== 'undefined') {
abletonIsRolling = isPlaying;
} else {
// Fallback if your specific sandbox version hides the isPlaying variable
abletonIsRolling = true;
}
} catch (e) {
abletonIsRolling = true;
}
for (let i = 0; i < 8; i++) {
const key = `companionCue${i + 1}`;
const cue = String(shared(key, "") ?? "").trim();
if (cue) {
// If the cue is different from memory...
if (cue !== lastCues[i]) {
// Lock it in so we don't spam it
lastCues[i] = cue;
// Only execute the button press if the timeline is actually moving
if (abletonIsRolling) {
handleCue(cue);
}
}
} else {
// Clear memory if the playhead rolls off the clip
lastCues[i] = "";
}
}
await sleep(20);
}