No internet connection
  1. Home
  2. How to

Show Send lvl on selected track Prompt which send

By Owen Granich-Young @Owen_Granich_Young
    2022-03-24 16:05:57.601Z2022-03-24 16:47:42.331Z

    How could you adapt this script so you press one button and it shows a prompt to pick which send you want send lvl to show on selected track and then it does it, I'd rather have one button and one click do this then 4-5 buttons to do each one.... thoughts?

    Might be nice to have a 'do to all tracks' option on a modifer key too?

    sf.ui.proTools.selectedTrack.displaySelectorButton.popupMenuSelect({
        menuPath: ["*(snd b)*","level"],
        useWildcards: true,
    });
    
    Solved in post #12, click to view
    • 23 replies

    There are 23 replies. Estimated reading time: 19 minutes

    1. Chris Shaw @Chris_Shaw2022-03-24 16:55:41.696Z2022-03-24 17:10:21.488Z

      This will let you choose the send via a list:

      const sends = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]
      
      var chosenSend = sf.interaction.popupSearch({
          title: "Choose send to display",
          items: sends.map((send) => ({ name: send }),),
          onCancel: 'Abort'
      }).item.name
      
      
      try {
          sf.ui.proTools.selectedTrack.displaySelectorButton.popupMenuSelect({
              menuPath: [`*(snd ${chosenSend})*`, "level"],
              useWildcards: true,
          });
      } catch (err) { log(`Send ${chosenSend} does not exist on this track`) }
      
      
      
      

      And this one will let you enter the send from the keyboard:

      var chosenSend = sf.interaction.displayDialog({
          prompt: "Which send do you wish to display?",
          defaultAnswer: "<enter a-j>"
      }).text
      try {
          sf.ui.proTools.selectedTrack.displaySelectorButton.popupMenuSelect({
              menuPath: [`*(snd ${chosenSend})*`, "level"],
              useWildcards: true,
          });
      } catch (err) { log(`Send ${chosenSend} does not exist on this track`) }
      
      1. You da best!

        1. I edited the second script to add error checking code.

        2. In reply toChris_Shaw:

          I Deff like Option A better. A while back you helped me here have the prompts have more text then the final output.

          Trying to figure out how to adapt that to this case so I can name each send. (of course dyanmic reading of the selected track sends would be the super ideal, but that seems pretty in depth, and more importantly maybe would slow the whole process down.)

          1. const sends = ["a = Int Reverb", "b = Ext Reverb", "c = Dzn Reverb", "d = Boom"]
            
            var chosenSend = sf.interaction.popupSearch({
                title: "Choose send to display",
                items: sends.map((send) => ({ name: send }),),
                onCancel: 'Abort'
            }).item.send
            
            var sendLetter = chosenSend.split(" = ")[0]
            
            sf.ui.proTools.selectedTrack.displaySelectorButton.popupMenuSelect({
                menuPath: [`*(snd ${sendLetter})*`, "level"],
                useWildcards: true,
            });
            

            Hmm what am I missing boss? I'm getting this error : TypeError: Cannot read property 'split' of undefined
            (Show Send LVL line 9) :

            1. Ha, thought I got it, but I didn't....

              1. const sends = ["a = Int Reverb", "b = Ext Reverb", "c = Dzn Reverb", "d = Boom"];
                
                var chosenSend = sf.interaction.popupSearch({
                    title: "Choose send to display",
                    items: sends.map((send) => ({ name: send }),),
                    onCancel: 'Abort'
                }).item.name
                
                var sendLetter = chosenSend.split(" = ")[0]
                
                try {
                    sf.ui.proTools.selectedTrack.displaySelectorButton.popupMenuSelect({
                        menuPath: [`*(snd ${sendLetter})*`, "level"],
                        useWildcards: true,
                    });
                } catch (err) { log(`Send ${chosenSend} does not exist on this track`) }
                

                Got it... not sure what I did differently...

          2. In reply toChris_Shaw:

            If anybody feels inspired to 'get track info' and pull the send names from that to show up in the prompt that's the dream version.... but it seems like a LOT of coding. Also I do wonder if it would be slow.

            1. Chris Shaw @Chris_Shaw2022-03-24 18:25:53.217Z2022-03-24 18:33:44.011Z

              Here you go:

              // Get all items from display seelect popup menu
              const displayPopupItems = sf.ui.proTools.selectedTrack.displaySelectorButton.popupMenuFetchAllItems().menuItems;
              
              //filter items to get sends
              var sends = displayPopupItems.filter(i=>i.names[0].includes("(snd")&& i.names[1].includes("mute")).map(i=>i.path[0])
              
              //Display available sends
              var chosenSend = sf.interaction.popupSearch({
                  title: "Click / Choose send to display",
                  items: sends.map((send) => ({ name: send }),),
                  onCancel: 'Abort'
              }).item.name
              
              // Open selected send level playlist
              var sendLetter = chosenSend.split("(snd ")[1].charAt(0)
              sf.ui.proTools.selectedTrack.displaySelectorButton.popupMenuSelect({
                  menuPath: [`*(snd ${sendLetter})*`, "level"],
                  useWildcards: true,
              });
              
              1. Well hawt daymn! you fast!

                One more tweak if you have the time.... If multiple tracks are selected 'hold option+shift' so it does the same to all the selected tracks?

                1. This should do it:

                  // Get all items from display seelect popup menu
                  const displayPopupItems = sf.ui.proTools.selectedTrack.displaySelectorButton.popupMenuFetchAllItems().menuItems;
                  
                  //filter items to get sends
                  var sends = displayPopupItems.filter(i=>i.names[0].includes("(snd")&& i.names[1].includes("mute")).map(i=>i.path[0])
                  
                  //Display available sends
                  var chosenSend = sf.interaction.popupSearch({
                      title: "Click / Choose send to display",
                      items: sends.map((send) => ({ name: send }),),
                      onCancel: 'Abort'
                  }).item.name
                  
                  // Open send level playlist
                  var sendLetter = chosenSend.split("(snd ")[1].charAt(0)
                  
                  sf.ui.proTools.selectedTrack.displaySelectorButton.popupMenuSelect({
                      isShift: true,
                      isOption: true,
                      menuPath: [`*(snd ${sendLetter})*`, "level"],
                      useWildcards: true
                  });
                  
                  ReplySolution
                  1. You rule bud! Thanks!

                    1. Also duh, just always press shift and option, no need to check if there is or isn't more tracks selected. Don't know why I didn't think of that.

                      1. Chris Shaw @Chris_Shaw2022-03-24 22:18:28.630Z2022-03-24 22:50:13.861Z

                        Here's another handy one:
                        Open selected Plugin automation display.
                        (Definitely adding this to one of my decks)

                        sf.ui.proTools.selectedTrack.trackScrollToView()
                        
                        // Get all items from display select popup menu
                        const displayPopupItems = sf.ui.proTools.selectedTrack.displaySelectorButton.popupMenuFetchAllItems({dismissMenu:true}).menuItems;
                        sf.wait({intervalMs:50});
                        
                        //filter items to get fx automation paths
                        var fxAutomation = displayPopupItems.filter(i => i.names[0].includes("(fx")).map(i => [i.path[0], i.path[1]]);
                        
                        // Exit if there ins't plugin automation 
                        if (fxAutomation.length == 0) {
                            log("Open Plugin Automation View","There are no automated plugin parameters");
                            throw 0
                        };
                        
                        //Display available automation
                        var chosenFxKey = sf.interaction.popupSearch({
                            title: "Click / Choose automation to display",
                            items: fxAutomation.map((fx) => ({ name: `${fx[0]} ${fx[1]}` }),),
                            onCancel: 'Abort'
                        }).key;
                        
                        // Open plug-in automation playlist
                        sf.ui.proTools.selectedTrack.displaySelectorButton.popupMenuSelect({
                            isShift: true,
                            isOption: true,
                            menuPath: [fxAutomation[chosenFxKey][0], fxAutomation[chosenFxKey][1]],
                        });
                        
                        
                        1. Haha right?! I don't do a TON of mouse mixing, for the most part I try to keep hands on faders and knobs, but when I do it's a pain in the ass to naviage that menu, the prompt menu is so much friendlier!

                          This is great!

                2. In reply toChris_Shaw:
                  TThomas Gloor @Thomas_Gloor
                    2022-05-06 12:16:11.175Z

                    Hey @Chris_Shaw
                    I'm still working on a prepping/mix end script and I'm looking to list send NAMES (busses basically), so I could store each one of them to set of variables or an array.

                    Basically I'd want my script to look for a specific set of send names (being my hardware FX) so it can setup print tracks. For example, looking for "PCM60-" and if it finds one send from this track to "PCM60-" it will then create a "Trackname-PCM60 PRINT" track.

                    Would the this be the start of it?

                    //filter items to get sends
                    var sends = displayPopupItems.filter(i=>i.names[0].includes("(snd")&& i.names[1].includes("mute")).map(i=>i.path[0])
                    

                    Thank you lots!

                    1. Chris Shaw @Chris_Shaw2022-05-06 22:58:42.434Z2022-05-06 23:35:53.805Z

                      This was a challenge but I think I got it.
                      This will search through all visible tracks and create an array of print tracks names for any tracks that have any of the send names listed in the hwSends array.

                      The script cranks through every send on every track that can have sends so it takes a while to complete on big sessions - hence the dialog when the script is run

                      This will only work on visible tracks

                      sf.ui.proTools.mainWindow.invalidate()
                      const hwSends = ["EMT 250", "PCM 60", "224XL"]
                      const hwPrintTracks = []
                      
                      sf.interaction.displayDialog({
                          title: "Are you sure",
                          prompt: "If you have a lot of sends / tracks then this may take a minute.\n\nDo you want to continue?",
                          buttons: ["Cancel", "Yes"],
                          defaultButton:"Yes"
                      });
                      
                      // Filter and select all visible tracks types that can have sends
                      const tracksWithSends = sf.ui.proTools.visibleTrackHeaders.filter(i => !i.title.value.includes("Master Track"))
                          .filter(i => !i.title.value.includes("VCA Track"))
                          .filter(i => !i.title.value.includes("Basic Folder Track"))
                      
                      // Iterate through these tracks and find tracks that have sends to H/W
                      hwSends.forEach(send => {
                          log("Looking for tracks with a send to " + send)
                          const filteredTracks = tracksWithSends.map(t => {
                              for (var i = 0; i < 10; i++) {
                                  const isSendInactive = t.sendSelectorButtons[i].invalidate().value.value.includes("inactive");
                                  if (isSendInactive) { continue }
                                  if (t.sendButtons[i].value.value == send) {
                                      return t.normalizedTrackName
                                  }
                              }
                          });
                      
                          //Filter out undefined sends, create H/W pint track names, and push them into hwPrintTracks
                          filteredTracks.filter(i => {
                              if (i != undefined) {
                                  hwPrintTracks.push(i + " - " + send)
                              }
                          })
                      });
                      
                      log ("Finished!")
                      
                      //Log track names for HW send print tracks
                      log(hwPrintTracks)
                      
                      

                      You just need to write a script that creates a new track for each name in the hwPrintTracks array 😀

                      1. TThomas Gloor @Thomas_Gloor
                          2022-05-07 08:02:19.177Z

                          Thank you so much @Chris_Shaw

                          I’m trying to understand at which point I should have my “create tracks according to hw send” function thought

                          I’m not super comfortable with arrays yet :/

                          Should I déstructure the array in separate variables, then do a if statement like ‘’’if (hwSend1 < 1) { myFunction};’’’ ?

                      2. In reply toChris_Shaw:

                        @Chris_Shaw Hey boss, been using this a lot, and wanted to request an iteration if and when you have a moment.

                        How would one still use this prompt functionality but instead of showing the send lvl of the selected send the script opens the plugin window of the first insert on the return?

                        So same prompt to pick the send (so it only has to be one button instead of one for each send) and then mashed into this:

                        /** @param {{ sendNumber?: number, insertNumber?: number }} args */
                        function openInsertOfSelectedTrackSendReturnTrack({ sendNumber = 1, insertNumber = 1 } = {}) {
                            sf.ui.proTools.appActivateMainWindow();
                            sf.ui.proTools.mainWindow.invalidate();
                        
                            const selectedTrackSendName = sf.ui.proTools.selectedTrack.sendButtons[sendNumber - 1].value.value;
                        
                            const firstTrackWithSelectedTrackSendAsInput = sf.ui.proTools.visibleTracks.trackHeaders.find(track => {
                                if (track.inputPathButton.exists) {
                                    return track.inputPathButton.value.value === selectedTrackSendName;
                                }
                            });
                        
                            if (!firstTrackWithSelectedTrackSendAsInput) throw `No track with input "${selectedTrackSendName}" found.`
                        
                            firstTrackWithSelectedTrackSendAsInput.trackInsertToggleShow({ insertNumber });
                        }
                        
                        openInsertOfSelectedTrackSendReturnTrack({
                            sendNumber: 1,
                            insertNumber: 1
                        });
                        

                        Bests,
                        Owen

                        1. You could probably leverage the built in SF command "Go to return track of Send" to do this.
                          I'm a bit busy at the moment to code it.

                          1. So basiccally

                            // Get all items from display seelect popup menu
                            const displayPopupItems = sf.ui.proTools.selectedTrack.displaySelectorButton.popupMenuFetchAllItems().menuItems;
                            
                            //filter items to get sends
                            var sends = displayPopupItems.filter(i=>i.names[0].includes("(snd")&& i.names[1].includes("mute")).map(i=>i.path[0])
                            
                            //Display available sends
                            var chosenSend = sf.interaction.popupSearch({
                                title: "Click / Choose send to display",
                                items: sends.map((send) => ({ name: send }),),
                                onCancel: 'Abort'
                            }).item.name
                            
                            // Open send level playlist
                            var sendLetter = chosenSend.split("(snd ")[1].charAt(0)
                            
                            

                            Combined with this

                            
                            sf.ui.proTools.selectedTrack.trackSendGotoReturn({
                              sendNumber: sendLetter,
                            });
                            
                            sf.ui.proTools.selectedTrack.trackInsertToggleShow({
                              insertNumber: 1,
                            });
                            

                            But our var is giving a send Letter, and the TrackSendGotoReturn is asking for a Send Number. So some conversion of letter to number is needed in between yeah?

                            Busy is good! No rush here, if you have time in the future to circle around let me know. Or if somebody else can close this out ideas welcome.

                            Bests,
                            Owen

                            1. just use something like this to get the send number:

                              const allSendLetters = "abcdefghij"
                              
                              var sendLetter = "c"
                              
                              var sendNumber = allSendLetters.indexOf(sendLetter) + 1
                              
                              log (sendNumber)
                              
                              1. GET BACK TO WORK!

                                Just kidding :) Thanks for this! I'll put it together when I have some time and post it here final'd for when it's working.

                                you rock!
                                Owen