No internet connection
  1. Home
  2. How to

Pop Out Send Script?

By Philip weinrobe @Philip_weinrobe
    2024-10-09 13:56:41.383Z

    Hi Genius Folk
    I am wondering if there is a way to "pop out" a send window. I am talking about the window that comes out when you click on a send -- with the fader, mute, etc.

    I have a script that is working great in creating a new send from a track(s).
    I would love to also have it "pop out" the send window for the first of the selected tracks at the end of the process.
    The process already leaves me with the new plugin on the send track on screen...and I would love to keep that on screen as well as the corresponding send window for the first selected track. I

    I would also love for both these windows to be un-targeted so that they both persist as i click between them.

    any help is greatly appreciated!

    /**
    * @param {string} sendAssignment
    */
    function assignToNewTrack(sendAssignment) {
        const selectedTracks = sf.ui.proTools.selectedTrackNames
        sf.ui.proTools.trackGetByName({ name: selectedTracks[selectedTracks.length - 1] }).track.groups.whoseTitle.is(getGroup("Sends", sendAssignment)).first.buttons.whoseTitle.is(`Send Assignment ${sendAssignment}`).first.popupMenuSelect({
            isShift: true,
            isOption: true,
            menuPath: ["new track..."],
        });
    }
    
    function moveSendWinOutOfSlots() {
        sf.ui.proTools.invalidate()
    
        const sendWin = sf.ui.proTools.mainTrackOutputWindow.elementWaitFor().element
        const sendWinPos = sendWin.position.x
        const sendSlots = sf.ui.proTools.selectedTrack.groups.whoseTitle.is("Inserts A-E").first
        const sendSlotsPos = sendSlots.position.x
    
        if (sendWinPos - sendSlotsPos < 450 && sendSlotsPos - sendWinPos < 170) {
            sendWin.windowMove({
                position: {
                    y: sendWin.position.y,
                    x: sendSlotsPos + 450
                }
            })
        }
    }
    
    function getFirstFreeSend() {
        const selectedTracks = sf.ui.proTools.selectedTrackHeaders
        const sendLetters = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J"]
        let sendAssignmentList = []
        for (let i = 0; i < selectedTracks.length; i++) {
            let trackInfo = sf.ui.proTools.trackGetByName({ name: selectedTracks[i].normalizedTrackName })
                .track.sendButtons.filter(x => x.value.invalidate().value != "unassigned").map(x => x.title.invalidate().value.split(" ")[2])
            sendAssignmentList.push(...trackInfo)
        }
    
        const firstFreeSend = sendLetters.filter(letter => sendAssignmentList.indexOf(letter) === -1)[0]
    
        if (firstFreeSend) {
            return firstFreeSend
        } else {
            alert("Must have at least one free send, that is the same for all tracks.")
            throw 0
        };
    };
    
    
    /**
    * @param {'Insert'|'Send'} slotType
    * @param {array} [defaultUsedSlots] = [] - If parameter is not used, default is []
    */
    function getFirstFreeInsertOrSend(slotType, defaultUsedSlots) {
    
        let buttons
        slotType == "Insert" ? buttons = "insertButtons" : buttons = "sendButtons"
    
        const selectedTracks = sf.ui.proTools.selectedTrackHeaders
        const sendLetters = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J"]
        let sendAssignmentList = defaultUsedSlots || []
        try {
            for (let i = 0; i < selectedTracks.length; i++) {
                let trackInfo = sf.ui.proTools.trackGetByName({ name: selectedTracks[i].normalizedTrackName })
                    // .insertButtons or .sendButtons
                    .track[buttons].filter(x => x.value.invalidate().value != "unassigned").map(x => x.title.invalidate().value.split(" ")[2])
                sendAssignmentList.push(...trackInfo)
            }
        } catch (err) { }
        const firstFreeSend = sendLetters.filter(letter => sendAssignmentList.indexOf(letter) === -1)[0]
    
        if (firstFreeSend) {
            return firstFreeSend
        } else {
            if (slotType == "Insert") { alert(`Must have at least one free ${slotType} slot.`) }
            else if (slotType == "Send") { alert(`Must have at least one free ${slotType} slot, that is the same for selected tracks.`) }
            throw 0
        };
    };
    
    
    /**
    * @param {string} sendLetter
    * @param {'Inserts'|'Sends'} slotType
    */
    function getGroup(slotType, sendLetter) {
        let group
        sendLetter.toLowerCase().charCodeAt(0) - 97 <= 4 ? group = `${slotType} A-E` : group = `${slotType} F-J`
        return group
    }
    
    
    
    function newTrackSettings() {
        const newTrackWin = sf.ui.proTools.windows.whoseTitle.is("New Track").first.elementWaitFor().element;
        const createNextToCurrentTrackCheckbox = newTrackWin.checkBoxes.whoseTitle.is("Create next to current track").first;
    
        if (newTrackWin.children.length == 9) {
            sf.ui.proTools.windows.whoseTitle.is("New Tracks").first.popupButtons.allItems[1].popupMenuSelect({ menuPath: ["Aux Input"] });
        }
    
        ///  Popup butons to variables
        const [type, timeBase, format] = newTrackWin.invalidate().popupButtons.map(x => x);
    
        if (format.title.invalidate().value != "Stereo") { format.popupMenuSelect({ menuPath: ["Stereo"] }); }
        if (type.title.invalidate().value != "Aux Input") { type.popupMenuSelect({ menuPath: ["Aux Input"] }); }
        if (timeBase.title.invalidate().value != "Samples") { timeBase.popupMenuSelect({ menuPath: ["Samples"] }); }
    
        if (createNextToCurrentTrackCheckbox.exists) createNextToCurrentTrackCheckbox.checkboxSet({ targetValue: "Enable" });
    
        // Wait indefinitely for user to name track and press ok
        newTrackWin.elementWaitFor({ waitType: "Disappear", timeout: -1 });
        sf.ui.proTools.invalidate();
    }
    
    
    
    
    /**
     * @param {'Enable'|'Disable'} targetValue
     * @param {array} [viewsNames] = [] - If parameter is not used, default is set inside
     */
    function setWindowViews(targetValue, viewsNames) {
        let views = viewsNames || ["Inserts A-E", "Inserts F-J", "Sends A-E", "Sends F-J"]
    
        views.forEach(view => {
            sf.ui.proTools.menuClick({ menuPath: ["View", "Edit Window Views", view], targetValue: targetValue })
            // sf.ui.proTools.menuClick({ menuPath: ["View", "Mix Window Views", view], targetValue: targetValue })
        })
    }
    
    
    const getSelectedTrackOut = (trackName) => sf.ui.proTools.trackGetByName({ name: trackName }).track.outputPathButton.title.invalidate().value.split('\n')[1].trim();
    
    
    
    let insertSlot
    let firstFreeSend
    function actions() {
    
        const originalSelectedTracks = sf.ui.proTools.selectedTrackNames
    
        // Save first selected track output on variable
        const firstSelectedOut = getSelectedTrackOut(originalSelectedTracks[0])
    
        //  Get free sends
        firstFreeSend = getFirstFreeInsertOrSend("Send")
    
        // Assign new send to new track
        assignToNewTrack(firstFreeSend)
    
        // New track setting and wait for track name
        newTrackSettings()
    
        // If new send win is blocking the inserts or sends, move win away
        moveSendWinOutOfSlots()
    
        // Expand created send
        sf.ui.proTools.menuClick({ menuPath: ["View", "Expanded Sends", `Send ${firstFreeSend}`], targetValue: "Enable" })
    
        // Solo safe new Aux
        const selectedTracks = sf.ui.proTools.selectedTrackNames
        const auxTrack = sf.ui.proTools.trackGetByName({ name: selectedTracks[selectedTracks.length - 1] }).track
        auxTrack.trackSelect()
        auxTrack.trackScrollToView()
        //auxTrack.buttons.whoseTitle.is("Solo").first.mouseClickElement({ isCommand: false })
    
        // set new aux output
        if (getSelectedTrackOut(auxTrack.normalizedTrackName) != firstSelectedOut) {
            auxTrack.trackOutputSelect({ outputSelector: items => items.filter(item => item.element.title.value.includes(firstSelectedOut))[0] })
        }
    
        //MAKE VIEW CORRECT HERE
    
        // Get free insert slot after A
        insertSlot = getFirstFreeInsertOrSend("Insert", ["A"])
    
    
        // Open search...
        auxTrack.groups.whoseTitle.is(getGroup("Inserts", insertSlot)).first
            .buttons.whoseTitle.is(`Insert Assignment ${insertSlot}`)
            .first.popupMenuSelect({
                menuPath: ["search..."],
            });
    
    
        // Wait to open new plug
        while (true) {
            const plugIsOpen = auxTrack.groups.whoseTitle.is(getGroup("Inserts", insertSlot)).first
                .buttons.whoseTitle.is(`Insert Assignment ${insertSlot}`).first
                .value.invalidate().value != "unassigned"
    
            if (!plugIsOpen) {
                sf.wait({ intervalMs: 1000 })
            } else {
                break;
            }
        }
        sf.ui.proTools.trackSelectByName({ names: originalSelectedTracks })
    }
    
    
    
    
    function main() {
    
        sf.ui.proTools.appActivateMainWindow();
        sf.ui.proTools.invalidate();
    
        const isActiveInsGroupFEdit = sf.ui.proTools.getMenuItem("View", "Edit Window Views", "Inserts F-J").isMenuChecked
    
        const isActiveSendGroupFEdit = sf.ui.proTools.getMenuItem("View", "Edit Window Views", "Sends F-J").isMenuChecked
    
    
        const isEditWin = sf.ui.proTools.focusedWindow.title.value.startsWith("Edit")
        if (!isEditWin) { sf.ui.proTools.menuClick({ menuPath: ["Window", "Edit"] }) }
    
        // Close expand created sends
        sf.ui.proTools.menuClick({ menuPath: ["View", "Expanded Sends", "None"], targetValue: "Enable" })
    
        setWindowViews("Enable")
    
        try {
            actions()
        } catch (err) { }
        finally {
    
            //  Go to mix if needed
            if (!isEditWin) { sf.ui.proTools.menuClick({ menuPath: ["Window", "Mix"] }) }
    
            if (insertSlot) {
                // Close Inserts Views if not needed
                if (insertSlot.toLowerCase().charCodeAt(0) - 97 <= 4 && (!isActiveInsGroupFEdit)) {
                    if (!isActiveInsGroupFEdit) { setWindowViews("Disable", ["Inserts F-J"]) }
                }
            }
    
            if (firstFreeSend) {
                // Close Sends F-J if not needed
                if (firstFreeSend.toLowerCase().charCodeAt(0) - 97 <= 4 && (!isActiveSendGroupFEdit)) {
                    if (!isActiveSendGroupFEdit) { setWindowViews("Disable", ["Sends F-J"]) }
                }
            }
        }
    }
    
    main();
    
    • 15 replies

    There are 15 replies. Estimated reading time: 25 minutes

    1. Chad Wahlbrink @Chad2024-10-10 21:03:37.416Z

      Hi @Philip_weinrobe!

      Can you clarify any other steps you want this script to handle? For me, it's ending the script with the plugin window open and the floating track output window open, with the send on the last track in the selection targetted. Do you want that track output window to instead have its target set to the first selected track in your selection?

      Here's a quick video of me running the script currently:

      1. PPhilip weinrobe @Philip_weinrobe
          2024-10-11 16:57:40.705Z

          Hi Chad!
          That's looking great.
          I want that first send popped out (from your Audio 1)
          I also want that plugin window open.
          So just like you have it...but both un-targeted so that those windows stay open if i move around and click other stuff.

          Make sense?

          PW

          1. Chad Wahlbrink @Chad2024-10-11 17:52:29.331Z2024-10-22 16:58:57.052Z

            I think so!

            Can you give this version a go:

            /**
            * @param {string} sendAssignment
            */
            function assignToNewTrack(sendAssignment) {
                const selectedTracks = sf.ui.proTools.selectedTrackNames
                sf.ui.proTools.trackGetByName({ name: selectedTracks[selectedTracks.length - 1] }).track.groups.whoseTitle.is(getGroup("Sends", sendAssignment)).first.buttons.whoseTitle.is(`Send Assignment ${sendAssignment}`).first.popupMenuSelect({
                    isShift: true,
                    isOption: true,
                    menuPath: ["new track..."],
                });
            }
            
            function moveSendWinOutOfSlots() {
                sf.ui.proTools.invalidate()
            
                const sendWin = sf.ui.proTools.mainTrackOutputWindow.elementWaitFor().element
                const sendWinPos = sendWin.position.x
                const sendSlots = sf.ui.proTools.selectedTrack.groups.whoseTitle.is("Inserts A-E").first
                const sendSlotsPos = sendSlots.position.x
            
                if (sendWinPos - sendSlotsPos < 450 && sendSlotsPos - sendWinPos < 170) {
                    sendWin.windowMove({
                        position: {
                            y: sendWin.position.y,
                            x: sendSlotsPos + 450
                        }
                    })
                }
            }
            
            function getFirstFreeSend() {
                const selectedTracks = sf.ui.proTools.selectedTrackHeaders
                const sendLetters = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J"]
                let sendAssignmentList = []
                for (let i = 0; i < selectedTracks.length; i++) {
                    let trackInfo = sf.ui.proTools.trackGetByName({ name: selectedTracks[i].normalizedTrackName })
                        .track.sendButtons.filter(x => x.value.invalidate().value != "unassigned").map(x => x.title.invalidate().value.split(" ")[2])
                    sendAssignmentList.push(...trackInfo)
                }
            
                const firstFreeSend = sendLetters.filter(letter => sendAssignmentList.indexOf(letter) === -1)[0]
            
                if (firstFreeSend) {
                    return firstFreeSend
                } else {
                    alert("Must have at least one free send, that is the same for all tracks.")
                    throw 0
                };
            };
            
            /**
            * @param {'Insert'|'Send'} slotType
            * @param {array} [defaultUsedSlots] = [] - If parameter is not used, default is []
            */
            function getFirstFreeInsertOrSend(slotType, defaultUsedSlots) {
            
                let buttons
                slotType == "Insert" ? buttons = "insertButtons" : buttons = "sendButtons"
            
                const selectedTracks = sf.ui.proTools.selectedTrackHeaders
                const sendLetters = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J"]
                let sendAssignmentList = defaultUsedSlots || []
                try {
                    for (let i = 0; i < selectedTracks.length; i++) {
                        let trackInfo = sf.ui.proTools.trackGetByName({ name: selectedTracks[i].normalizedTrackName })
                            // .insertButtons or .sendButtons
                            .track[buttons].filter(x => x.value.invalidate().value != "unassigned").map(x => x.title.invalidate().value.split(" ")[2])
                        sendAssignmentList.push(...trackInfo)
                    }
                } catch (err) { }
                const firstFreeSend = sendLetters.filter(letter => sendAssignmentList.indexOf(letter) === -1)[0]
            
                if (firstFreeSend) {
                    return firstFreeSend
                } else {
                    if (slotType == "Insert") { alert(`Must have at least one free ${slotType} slot.`) }
                    else if (slotType == "Send") { alert(`Must have at least one free ${slotType} slot, that is the same for selected tracks.`) }
                    throw 0
                };
            };
            
            /**
            * @param {string} sendLetter
            * @param {'Inserts'|'Sends'} slotType
            */
            function getGroup(slotType, sendLetter) {
                let group
                sendLetter.toLowerCase().charCodeAt(0) - 97 <= 4 ? group = `${slotType} A-E` : group = `${slotType} F-J`
                return group
            }
            
            function newTrackSettings() {
                const newTrackWin = sf.ui.proTools.windows.whoseTitle.is("New Track").first.elementWaitFor().element;
                const createNextToCurrentTrackCheckbox = newTrackWin.checkBoxes.whoseTitle.is("Create next to current track").first;
            
                if (newTrackWin.children.length == 9) {
                    sf.ui.proTools.windows.whoseTitle.is("New Tracks").first.popupButtons.allItems[1].popupMenuSelect({ menuPath: ["Aux Input"] });
                }
            
                ///  Popup butons to variables
                const [type, timeBase, format] = newTrackWin.invalidate().popupButtons.map(x => x);
            
                if (format.title.invalidate().value != "Stereo") { format.popupMenuSelect({ menuPath: ["Stereo"] }); }
                if (type.title.invalidate().value != "Aux Input") { type.popupMenuSelect({ menuPath: ["Aux Input"] }); }
                if (timeBase.title.invalidate().value != "Samples") { timeBase.popupMenuSelect({ menuPath: ["Samples"] }); }
            
                if (createNextToCurrentTrackCheckbox.exists) createNextToCurrentTrackCheckbox.checkboxSet({ targetValue: "Enable" });
            
                // Wait indefinitely for user to name track and press ok
                newTrackWin.elementWaitFor({ waitType: "Disappear", timeout: -1 });
                sf.ui.proTools.invalidate();
            }
            
            /**
             * @param {'Enable'|'Disable'} targetValue
             * @param {array} [viewsNames] = [] - If parameter is not used, default is set inside
             */
            function setWindowViews(targetValue, viewsNames) {
                let views = viewsNames || ["Inserts A-E", "Inserts F-J", "Sends A-E", "Sends F-J"]
            
                views.forEach(view => {
                    sf.ui.proTools.menuClick({ menuPath: ["View", "Edit Window Views", view], targetValue: targetValue })
                    // sf.ui.proTools.menuClick({ menuPath: ["View", "Mix Window Views", view], targetValue: targetValue })
                })
            }
            
            const getSelectedTrackOut = (trackName) => sf.ui.proTools.trackGetByName({ name: trackName }).track.outputPathButton.title.invalidate().value.split('\n')[1].trim();
            
            let insertSlot
            let firstFreeSend
            
            function actions() {
            
                const originalSelectedTracks = sf.ui.proTools.selectedTrackNames
            
                // Close all floating plugin windows and output windows
                sf.ui.proTools.windows.allItems.filter(x => x.buttons.whoseTitle.is("Targeted").exists).forEach((x) => x.windowClose())
                sf.ui.proTools.windows.filter(x => x.popupButtons.whoseTitle.is('Insert Position selector').exists).forEach(x => x.windowClose());
            
                // Save first selected track output on variable
                const firstSelectedOut = getSelectedTrackOut(originalSelectedTracks[0])
            
                //  Get free sends
                firstFreeSend = getFirstFreeInsertOrSend("Send")
            
                // Assign new send to new track
                assignToNewTrack(firstFreeSend)
            
                // New track setting and wait for track name
                newTrackSettings()
            
                // If new send win is blocking the inserts or sends, move win away
                moveSendWinOutOfSlots()
            
                // Open the send for the first track instead of the last track in the selection
                if (originalSelectedTracks.length > 1) {
                    sf.ui.proTools.trackGetByName({ name: originalSelectedTracks[0] }).track.groups.whoseTitle.is(getGroup("Sends", firstFreeSend)).first.buttons.whoseTitle.is(`Send Assignment ${firstFreeSend}`).first.elementClick()
                }
            
                // Set the target to "Untargeted" for the track output window
                sf.ui.proTools.mainTrackOutputWindow.buttons.whoseTitle.is("Targeted").first.elementWaitFor().element.elementClick();
            
                // Expand created send
                sf.ui.proTools.menuClick({ menuPath: ["View", "Expanded Sends", `Send ${firstFreeSend}`], targetValue: "Enable" })
            
                // Solo safe new Aux
                const selectedTracks = sf.ui.proTools.selectedTrackNames
                const auxTrack = sf.ui.proTools.trackGetByName({ name: selectedTracks[selectedTracks.length - 1] }).track
                auxTrack.trackSelect()
                auxTrack.trackScrollToView()
                //auxTrack.buttons.whoseTitle.is("Solo").first.mouseClickElement({ isCommand: false })
            
                // set new aux output
                if (getSelectedTrackOut(auxTrack.normalizedTrackName) != firstSelectedOut) {
                    auxTrack.trackOutputSelect({ outputSelector: items => items.filter(item => item.element.title.value.includes(firstSelectedOut))[0] })
                }
            
                //MAKE VIEW CORRECT HERE
            
                // Get free insert slot after A
                insertSlot = getFirstFreeInsertOrSend("Insert", ["A"])
            
            
                // Open search...
                auxTrack.groups.whoseTitle.is(getGroup("Inserts", insertSlot)).first
                    .buttons.whoseTitle.is(`Insert Assignment ${insertSlot}`)
                    .first.popupMenuSelect({
                        menuPath: ["search..."],
                    });
            
            
                // Wait to open new plug
                while (true) {
                    const plugIsOpen = auxTrack.groups.whoseTitle.is(getGroup("Inserts", insertSlot)).first
                        .buttons.whoseTitle.is(`Insert Assignment ${insertSlot}`).first
                        .value.invalidate().value != "unassigned"
            
                    if (!plugIsOpen) {
                        sf.wait({ intervalMs: 1000 })
                    } else {
                        break;
                    }
                }
            
                // Click "Target Button"
                sf.ui.proTools.windows.filter(x => x.popupButtons.whoseTitle.is('Insert Position selector').exists)[0].buttons.whoseTitle.is("Target button").first.elementClick()
            
                sf.ui.proTools.trackSelectByName({ names: originalSelectedTracks })
            
            }
            
            function main() {
            
                sf.ui.proTools.appActivateMainWindow();
                sf.ui.proTools.invalidate();
            
                const isActiveInsGroupFEdit = sf.ui.proTools.getMenuItem("View", "Edit Window Views", "Inserts F-J").isMenuChecked
            
                const isActiveSendGroupFEdit = sf.ui.proTools.getMenuItem("View", "Edit Window Views", "Sends F-J").isMenuChecked
            
            
                const isEditWin = sf.ui.proTools.focusedWindow.title.value.startsWith("Edit")
                if (!isEditWin) { sf.ui.proTools.menuClick({ menuPath: ["Window", "Edit"] }) }
            
                // Close expand created sends
                sf.ui.proTools.menuClick({ menuPath: ["View", "Expanded Sends", "None"], targetValue: "Enable" })
            
                setWindowViews("Enable")
            
                try {
                    actions()
                } catch (err) { }
                finally {
            
                    //  Go to mix if needed
                    if (!isEditWin) { sf.ui.proTools.menuClick({ menuPath: ["Window", "Mix"] }) }
            
                    if (insertSlot) {
                        // Close Inserts Views if not needed
                        if (insertSlot.toLowerCase().charCodeAt(0) - 97 <= 4 && (!isActiveInsGroupFEdit)) {
                            if (!isActiveInsGroupFEdit) { setWindowViews("Disable", ["Inserts F-J"]) }
                        }
                    }
            
                    if (firstFreeSend) {
                        // Close Sends F-J if not needed
                        if (firstFreeSend.toLowerCase().charCodeAt(0) - 97 <= 4 && (!isActiveSendGroupFEdit)) {
                            if (!isActiveSendGroupFEdit) { setWindowViews("Disable", ["Sends F-J"]) }
                        }
                    }
            
            
                    if (sf.ui.proTools.mainTrackOutputWindow.exists) {
                        sf.ui.proTools.mainTrackOutputWindow.windowMove({
                            position: {
                                x: (sf.ui.proTools.invalidate().selectedTrackHeaders[0].frame.x + sf.ui.proTools.invalidate().selectedTrackHeaders[0].frame.w + 15),
                                y: (400)
                            }
                        })
                    }
            
                    sf.ui.proTools.windows.filter(x => x.popupButtons.whoseTitle.is('Insert Position selector').exists)[0]
                        .windowMove({
                            position:
                            {
                                x: sf.ui.proTools.mainTrackOutputWindow.position.x + sf.ui.proTools.mainTrackOutputWindow.frame.w + 15,
                                y: sf.ui.proTools.mainTrackOutputWindow.position.y,
                            }
                        })
                }
            }
            
            main();
            
            1. Chad Wahlbrink @Chad2024-10-11 17:54:31.102Z

              This leaves me with:

              1. PPhilip weinrobe @Philip_weinrobe
                  2024-10-11 19:52:16.641Z

                  ok!
                  so this works in that the right windows are open and both untargeted.
                  however, they are on top of each other in my script.
                  possible to open them in a way where they aren't on top of each other?

                  1. Chad Wahlbrink @Chad2024-10-11 20:12:04.752Z

                    @Philip_weinrobe,

                    Can you screenshot how it's showing up on your system? Are you saying that the send window is overlapping the plugin window?

                    1. PPhilip weinrobe @Philip_weinrobe
                        2024-10-11 20:25:28.244Z
                        1. PPhilip weinrobe @Philip_weinrobe
                            2024-10-16 21:00:05.060Z

                            hey chad
                            weirdly this script stopped working all together.
                            going back to my original script i posted in the forum works perfect (except the targeting)
                            Not sure what else changed...but wanted to let you know.

                            Your new updated script kept not making the send and then selecting the next two tracks and just stopping. weird!

                            1. Chad Wahlbrink @Chad2024-10-17 20:16:27.228Z

                              @Philip_weinrobe, that's strange!

                              I just updated the script. I added a few pieces that may make it work smoother overall. I also added some logic to move the Main Track Output Window (the sends fader) and the plugin window to a more tidy spot on the screen at the end of the script.

                              I did change it so that it closes all output and plugin windows before running the script. I think this is necessary to help it be a "clean slate" for using the "target" button each time. However, if you think this kills the flow somehow, just let me know.

                              If you run into an issue with the script again, grab a screen recording, and I can try to suss it out.

            2. P
              In reply toPhilip_weinrobe:
              Philip weinrobe @Philip_weinrobe
                2024-10-17 20:32:42.335Z
                1. PPhilip weinrobe @Philip_weinrobe
                    2024-10-17 20:38:38.370Z

                    hi chad
                    can confirm this script does work when i have multiple tracks selected.

                    fwiw: i call this script in a macro that first:

                    1 - makes selected tracks "fit to screen" for height
                    2 - creates TEMP GROUP of selected tracks (the soundflow built in temp group thing)

                    then, after the script runs

                    3 - selects all the original tracks plus the newly created aux and fits those to screen height wise

                    would be awesome to put that all in the script once we have it working!

                    1. PPhilip weinrobe @Philip_weinrobe
                        2024-10-17 20:42:28.385Z

                        the updated script is working now, btw :)

                        1. PPhilip weinrobe @Philip_weinrobe
                            2024-10-22 15:07:25.356Z

                            hi chad!
                            This script seems to fail if the insert instantiated is a hardware insert.
                            Could we make it so that if it's a hardware insert the script doesn't throw an error and is just happy?
                            Nothing bad happens when i put a HW insert in, it just kinda gets confused and throws an error and takes me out of the flow...

                            thanks!
                            Philip

                            1. Chad Wahlbrink @Chad2024-10-22 17:04:01.086Z

                              Hey @Philip_weinrobe,

                              Please copy and paste the updated code and let me know how it works! It should now work the same for plug-ins and HW I/O.