Cycle Send Plugins
By Sreejesh Nair @Sreejesh_Nair
This is a variation of the brilliant script by @samuel_henriques to open the plugins of a send. This modified script cycles through the sends on a track. Because the target windows of the plugins are disabled, cycling will leave the plugins open on the screen. It skips inactive sends.
sf.ui.proTools.appActivate();
sf.ui.proTools.invalidate();
function getSelectedSendIndex() {
sf.ui.proTools.invalidate();
const outputWin = sf.ui.proTools.mainTrackOutputWindow;
const outputViewSelector = outputWin.buttons.whoseTitle.is("Output View selector").first;
// Check if a send is currently open and convert letter to a numeric index
if (outputWin.exists && outputViewSelector.value.invalidate().value.startsWith("send")) {
const sendLetter = outputViewSelector.value.value.replace("send ", "").toLowerCase();
const sendIndex = sendLetter.charCodeAt(0) - 96; // Convert 'a' to 1, 'b' to 2, ..., 'j' to 10
return sendIndex;
} else {
// Start from the first send if no send is open
return 0; // Return 0 to indicate no send is currently open
}
}
try {
let origTrack = sf.ui.proTools.selectedTrack.normalizedTrackName;
// Determine the current or next send slot to open
let currentSendSlot = getSelectedSendIndex();
let nextSendSlot = (currentSendSlot === 0) ? 1 : (currentSendSlot < 10 ? currentSendSlot + 1 : 1);
// Find the next active or assigned send, looping if necessary
let foundActiveSend = false;
for (let i = 0; i < 10; i++) { // Limit to 10 iterations
const sendButton = sf.ui.proTools.selectedTrack.sendSelectorButtons[nextSendSlot - 1];
if (sendButton.value.value !== "unassigned" && !sendButton.invalidate().value.value.startsWith("inactive")) {
foundActiveSend = true;
break;
}
// Increment send slot and wrap around if necessary
nextSendSlot = nextSendSlot < 10 ? nextSendSlot + 1 : 1;
}
if (foundActiveSend) {
// Toggle send to show it
sf.ui.proTools.selectedTrack.trackSendToggleShow({
sendNumber: nextSendSlot,
});
// Navigate to the return track for the active send slot
sf.ui.proTools.selectedTrack.trackSendGotoReturn({
sendNumber: nextSendSlot,
});
const returnTrack = sf.ui.proTools.selectedTrackHeaders[0];
// Open insert plugins on the aux return track
openInsertWin(returnTrack, ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]);
// Return to the original track
sf.app.proTools.selectTracksByName({
trackNames: [origTrack],
});
} else {
sf.interaction.notify({
title: "No Active Sends",
message: "No active or assigned sends were found.",
});
}
} catch (error) {
sf.interaction.notify({
title: "Error processing sends",
message: error.message,
});
}
function getInsertWin(track, insertChar) {
const trackName = track.normalizedTrackName;
return sf.ui.proTools.windows.whoseTitle.startsWith('Plug-in:').filter(w => {
if (w.popupButtons.whoseTitle.is('Track Selector').first.value.value !== trackName) return false;
if (w.popupButtons.whoseTitle.is('Insert Position selector').first.value.value !== insertChar) return false;
return true;
})[0];
}
function openInsertWin(track, inserts) {
const insertChars = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'];
for (let i = 0; i < inserts.length; i++) {
const insertN = insertChars.indexOf(inserts[i]);
if (!track.insertButtons[insertN].invalidate().exists) continue;
if (track.insertButtons[insertN].value.value === "unassigned" || track.insertSelectorButtons[insertN].invalidate().value.value.startsWith("inactive")) continue;
let pluginWin = getInsertWin(track, inserts[i]);
if (!pluginWin) {
track.insertButtons[insertN].elementClick();
while (true) {
pluginWin = getInsertWin(track, inserts[i]);
if (pluginWin) break;
sf.wait({ intervalMs: 100 });
}
const targetBtn = pluginWin.buttons.whoseTitle.is('Target button').first;
targetBtn.elementClick(); // Disable target mode
}
}
}
Linked from: