Hi all,
Very new to soundflow and just experimenting with combining a few existing scripts. I've been trying to write little script to open my three most used sends in Send slots 1/2/3 in Pro Tools, based off the Select Track Insert/Send macros with a few added scripts to allow it to work on multiple channels at once and fire from both the edit and mix window.
It's working quite well, however I run into an error if the Edit window is zoomed out enough that not all 3 sends are visible. When this occurs I get a 'Could not open popup menu error', with the log telling me 'Could not open popup menu
Popup menu was not found
Popup window was not found after waiting 2000 ms'
I'm assuming the workaround is to build in a 'Zoom In' function for the edit window, but if I was doing this to multiple tracks it may be a little crazy!
Thanks
- AAlistair McLean @Alistair_McLean
Current script is here, please ignore the placeholders copied over from the other scripts I've pirated... still trying not to get lost in the scripts!
sf.ui.proTools.invalidate(); // Place the following two functions at the top of your script: // #1 function mainWindowStatus() { if (sf.ui.proTools.getMenuItem('Window', 'Mix').isMenuChecked) { sf.ui.proTools.menuClick({ menuPath: ["Window", "Edit"], }); return "Mix"; } else { return "Edit"; } } //#2 function returnToStartingMainWIndow(mainWindow) { if (mainWindow =="Mix") { sf.ui.proTools.menuClick({ menuPath: ["Window", "Mix"], }); } } /// Place this line at the top of your script let startingWindow = mainWindowStatus(); function doForAllSelectedTracks(action) { var originallySelectedTrackNames = sf.ui.proTools.selectedTrackNames; try { sf.ui.proTools.selectedTrackHeaders.forEach(track => { track.trackSelect(); action(track); }); } finally { sf.ui.proTools.trackSelectByName({ names: originallySelectedTrackNames }); } } /**@param {AxPtTrackHeader} track */ function trackFunc(track) { sf.ui.proTools.selectedTrack.trackInsertOrSendSelect({ insertOrSend: "Send", pluginNumber: 1, pluginPath: ["bus","StereoVerb (Stereo)"], selectForAllSelectedTracks: true, }); sf.ui.proTools.selectedTrack.trackInsertOrSendSelect({ insertOrSend: "Send", pluginNumber: 2, pluginPath: ["bus","LongVerb (Stereo)"], selectForAllSelectedTracks: true, }); sf.ui.proTools.selectedTrack.trackInsertOrSendSelect({ insertOrSend: "Send", pluginNumber: 3, pluginPath: ["bus","MonoVerb (Mono)"], selectForAllSelectedTracks: true, }); log(track.normalizedTrackName); } doForAllSelectedTracks(trackFunc); // end your script with this line returnToStartingMainWIndow(startingWindow);```
Chris Shaw @Chris_Shaw2023-01-05 18:05:05.539Z
What the script needed was an extra command to scroll the selected track into view (line 36):
sf.ui.proTools.invalidate(); // Place the following two functions at the top of your script: // #1 function mainWindowStatus() { if (sf.ui.proTools.getMenuItem('Window', 'Mix').isMenuChecked) { sf.ui.proTools.menuClick({ menuPath: ["Window", "Edit"], }); return "Mix"; } else { return "Edit"; } } //#2 function returnToStartingMainWIndow(mainWindow) { if (mainWindow =="Mix") { sf.ui.proTools.menuClick({ menuPath: ["Window", "Mix"], }); } } /// Place this line at the top of your script let startingWindow = mainWindowStatus(); function doForAllSelectedTracks(action) { var originallySelectedTrackNames = sf.ui.proTools.selectedTrackNames; try { sf.ui.proTools.selectedTrackHeaders.forEach(track => { track.trackSelect(); track.trackScrollToView() // <====== This wil scroll each track into view action(track); }); } finally { sf.ui.proTools.trackSelectByName({ names: originallySelectedTrackNames }); } } /**@param {AxPtTrackHeader} track */ function trackFunc(track) { sf.ui.proTools.selectedTrack.trackInsertOrSendSelect({ insertOrSend: "Send", pluginNumber: 1, pluginPath: ["bus","StereoVerb (Stereo)"], selectForAllSelectedTracks: true, }); sf.ui.proTools.selectedTrack.trackInsertOrSendSelect({ insertOrSend: "Send", pluginNumber: 2, pluginPath: ["bus","LongVerb (Stereo)"], selectForAllSelectedTracks: true, }); sf.ui.proTools.selectedTrack.trackInsertOrSendSelect({ insertOrSend: "Send", pluginNumber: 3, pluginPath: ["bus","MonoVerb (Mono)"], selectForAllSelectedTracks: true, }); log(track.normalizedTrackName); } doForAllSelectedTracks(trackFunc); // end your script with this line returnToStartingMainWIndow(startingWindow);
Chris Shaw @Chris_Shaw2023-01-05 18:38:04.761Z
Once you've scrolled to the first selected track theres no need to use
doForAllSelectedTracks
because thetrackInsertOrSendSelect
has aselectForAllSelectedTracks
parameters . The script will run much faster since it only has to instantiate each send once:
(I've also changed the way it scrolls to the first selected track so that it's more robust - sometime if the first selected track is the top track in the edit window it won't scroll properly)sf.ui.proTools.invalidate(); // Place the following two functions at the top of your script: // #1 function mainWindowStatus() { if (sf.ui.proTools.getMenuItem('Window', 'Mix').isMenuChecked) { sf.ui.proTools.menuClick({ menuPath: ["Window", "Edit"], }); return "Mix"; } else { return "Edit"; } } //#2 function returnToStartingMainWIndow(mainWindow) { if (mainWindow == "Mix") { sf.ui.proTools.menuClick({ menuPath: ["Window", "Mix"], }); } } /// Place this line at the top of your script let startingWindow = mainWindowStatus(); //Get selected Tracks const selectedTracks = sf.ui.proTools.selectedTrackNames //Scroll to first selected track sf.ui.proTools.trackSelectByName({ names: [selectedTracks[0]] }) sf.ui.proTools.selectedTrack.trackScrollToView(); //Reselect Tracks sf.ui.proTools.trackSelectByName({names:selectedTracks}) // Insert Sends sf.ui.proTools.selectedTrack.trackInsertOrSendSelect({ insertOrSend: "Send", pluginNumber: 1, pluginPath: ["bus", "StereoVerb (Stereo)"], selectForAllSelectedTracks: true, }); sf.ui.proTools.selectedTrack.trackInsertOrSendSelect({ insertOrSend: "Send", pluginNumber: 2, pluginPath: ["bus", "LongVerb (Stereo)"], selectForAllSelectedTracks: true, }); sf.ui.proTools.selectedTrack.trackInsertOrSendSelect({ insertOrSend: "Send", pluginNumber: 3, pluginPath: ["bus", "MonoVerb (Mono)"], selectForAllSelectedTracks: true, }); // end your script with this line returnToStartingMainWIndow(startingWindow);
Chris Shaw @Chris_Shaw2023-01-05 18:58:37.016Z
Finally you could create an object that contains the send numbers and bus paths and loop through that object and instantiate the sends:
sf.ui.proTools.invalidate(); // Place the following two functions at the top of your script: // #1 function mainWindowStatus() { if (sf.ui.proTools.getMenuItem('Window', 'Mix').isMenuChecked) { sf.ui.proTools.menuClick({ menuPath: ["Window", "Edit"], }); return "Mix"; } else { return "Edit"; } } //#2 function returnToStartingMainWIndow(mainWindow) { if (mainWindow == "Mix") { sf.ui.proTools.menuClick({ menuPath: ["Window", "Mix"], }); } } /// Place this line at the top of your script let startingWindow = mainWindowStatus(); //Get selected Tracks const selectedTracks = sf.ui.proTools.selectedTrackNames //Scroll to first selected track sf.ui.proTools.trackSelectByName({ names: [selectedTracks[0]] }) sf.ui.proTools.selectedTrack.trackScrollToView(); //Reselect Tracks sf.ui.proTools.trackSelectByName({ names: selectedTracks }) // Define sendsToInstanatiate object const sendsToInstanatiate = { 1: ["bus", "StereoVerb (Stereo)"], 2: ["bus", "LongVerb (Stereo)"], 3: ["bus", "MonoVerb (Mono)"] } // Insert sends for (const send in sendsToInstanatiate) { sf.ui.proTools.selectedTrack.trackInsertOrSendSelect({ insertOrSend: "Send", pluginNumber: +send, pluginPath: sendsToInstanatiate[send], selectForAllSelectedTracks: true, }); } // end your script with this line returnToStartingMainWIndow(startingWindow);
- AAlistair McLean @Alistair_McLean
Thanks for such a quick and detailed reply Chris (and I think I pinched most of the existing code from things you had posted too!).
That is mostly working very well now, I'm still occasionally getting a 'could not make send slot visible' error which seems to be caused by small track heights in the edit window (and if the track heights are set very small I get a 'could not find selected track's insert/send selector button for the specified plugin').
The easy workaround is to set all track heights to jumbo or extreme and then set them back to their original size- is there a simple way to include that in the code?
Thanks for your help!
Chris Shaw @Chris_Shaw2023-01-05 23:43:49.998Z2023-01-06 00:35:10.820Z
Try this (a lot more code :) )
///////////////////////////////////////////// /// F U N C T I O N S & C O N S T A N T S // ///////////////////////////////////////////// // Define track size lookup object {height in pixels : size name} const trackSizes = { 16: 'micro', 23: 'mini', 43: 'small', 97: 'medium', 192: 'large', 300: 'jumbo', }; function setTrackSize(size) { const f = sf.ui.proTools.selectedTrack.frame; let popupMenu = sf.ui.proTools.selectedTrack.popupMenuOpenFromElement({ relativePosition: { x: f.w - 10, y: 5 }, isOption: true, isShift: true, }).popupMenu; popupMenu.menuClickPopupMenu({ menuPath: [size] }); } // Place the following two functions at the top of your script: // #1 function mainWindowStatus() { if (sf.ui.proTools.getMenuItem('Window', 'Mix').isMenuChecked) { sf.ui.proTools.menuClick({ menuPath: ["Window", "Edit"], }); return "Mix"; } else { return "Edit"; } } //#2 function returnToStartingMainWIndow(mainWindow) { if (mainWindow == "Mix") { sf.ui.proTools.menuClick({ menuPath: ["Window", "Mix"], }); } } /////////////// /// M A I N /// /////////////// sf.ui.proTools.invalidate(); // Determine which window is focused (Mix / Edit) let startingWindow = mainWindowStatus(); //Get selected Tracks const selectedTracks = sf.ui.proTools.selectedTrackNames //Scroll to first selected track sf.ui.proTools.trackSelectByName({ names: [selectedTracks[0]] }) sf.ui.proTools.selectedTrack.trackScrollToView(); //determine size of first selected track const selectedTrackHeight = sf.ui.proTools.selectedTrack.frame.h; // Get original track size and whether it is too small const originalTrackSize = trackSizes[selectedTrackHeight] || 'extreme'; const isTrackTooSmall = selectedTrackHeight < 43 //resize track if necessary if (isTrackTooSmall) setTrackSize("medium"); //Reselect Tracks sf.ui.proTools.trackSelectByName({ names: selectedTracks }) // Define sendsToInstanatiate object const sendsToInstanatiate = { 1: ["bus", "StereoVerb (Stereo)"], 2: ["bus", "LongVerb (Stereo)"], 3: ["bus", "MonoVerb (Mono)"] } // Instantiate sends for (const send in sendsToInstanatiate) { sf.ui.proTools.selectedTrack.trackInsertOrSendSelect({ insertOrSend: "Send", pluginNumber: +send, pluginPath: sendsToInstanatiate[send], selectForAllSelectedTracks: true, }); } // Reset height of first selected track if necessary if (isTrackTooSmall) { sf.ui.proTools.trackSelectByName({ names: [selectedTracks[0]] }) setTrackSize(originalTrackSize) } // Reselect selected tracks sf.ui.proTools.trackSelectByName({ names: selectedTracks }) // Refocus Edit or Mix window returnToStartingMainWIndow(startingWindow);
Chris Shaw @Chris_Shaw2023-01-06 00:19:07.149Z
I've refactored the above script - much more concise.
- AIn reply toAlistair_McLean⬆:Alistair McLean @Alistair_McLean
Amazing Chris, working perfectly on big and small sessions! Really appreciate it. How do I buy you a beer or coffee to say thank you!
- AIn reply toAlistair_McLean⬆:Alistair McLean @Alistair_McLean
A bit of a zombie thread, but with a recent PT update this script is now broken for me.
When using it I get some variation of the following:'29.10.2024 15:04:42.05 [Backend]: Logging error in action (01) TrackSelectInsertOrSendAction: Could not select plugin menu item: 'bus: Long Verb (Stereo)'
!! Command Error: Add Sends V3 [user:default:clcjtdkc0000ttm10ue3gnabr]:
Could not select plugin menu item: 'bus: Long Verb (Stereo)' (Add Sends V3: Line 93)
Could not open popup menu
Popup menu was not found
Popup window was not found after waiting 2000 ms'This is not always consistent and sometimes will create a send in slot 1 but fail on slot 2, sometimes will fail straightaway, sometimes will create a send in slot 3 but no others! I presume there has been a change in the way PT identifies busses but I'm a bit lost!