No internet connection
  1. Home
  2. How to

Trying to create shortcut for a certain plug in to next free insert slot...

By Robert Sörling @robertsorling
    2020-03-16 22:06:35.482Z2020-03-26 14:01:16.863Z

    I’m trying to create a Stream Deck button (or keyboard shortcut) for adding a certain plug in into the next free insert slot on selected track. I’m trying this script:

    function getFirstFreeInsertIndex() {
        var btns = sf.ui.proTools.selectedTrack.invalidate().insertButtons;
        for (var i = 0; i < 10; i++)
            if (btns[i].value.invalidate().value === "unassigned") return i;
        return -1;
    }
    
    sf.ui.proTools.selectedTrack.trackInsertOrSendSearch({
        insertOrSend: 'Insert',
        pluginNumber: getFirstFreeInsertIndex() + 1,    
    });
    
    sf.keyboard.type({
        text: "D-Verb",
    });
    
    sf.keyboard.press({
        keys: "return",
    });
    

    … but the text is not written in the search field. Any ideas?

    Still new to this. Trying to learn… :)

    thnx

    Solved in post #7, click to view

    Linked from:

    1. Script not working
    • 26 replies

    There are 26 replies. Estimated reading time: 21 minutes

      1. RRobert Sörling @robertsorling
          2020-03-24 13:49:37.863Z

          Ok. that works! Thanks.

          How ever, still trying to figure out how to paste a text via a script or macro in a search field pop up like this:

          Would be great in many situations.

          Thanks

          1. RRobert Sörling @robertsorling
              2020-03-24 18:25:40.563Z

              Ok, I solved this by simply making Multi Actions within the Stream Deck App.

              1. Hi @Muzzle1996.

                You don't have to use the popup at all if you use the actions that I linked to.
                The popup is only needed if you want the user to input text.
                If you want to select an insert completely without the popup, no need to first show it and then simulate the keyboard.

                You were using the "search" version of the script which opens the popup - but instead use the "select" version.

                This directly gives you the D-Verb insert - no popup needed:

                function getFirstFreeInsertIndex() {
                    var btns = sf.ui.proTools.selectedTrack.invalidate().insertButtons;
                    for (var i = 0; i < 10; i++)
                        if (btns[i].value.invalidate().value === "unassigned") return i;
                    return -1;
                }
                
                sf.ui.proTools.selectedTrack.trackInsertOrSendSelect({
                    insertOrSend: "Insert",
                    pluginNumber: getFirstFreeInsertIndex() + 1,
                    pluginSelector: items => items.filter(item => item.path[0] === "plug-in" && item.path.slice(-1)[0].indexOf("D-Verb") === 0)[0],
                });
                
                1. RRobert Sörling @robertsorling
                    2020-03-25 00:19:31.145Z

                    Ok, thanks. Mh, what I'm trying to do is to make shortcuts in Stream Deck for my favorite plug ins to open in the next free insert slot. I tried the linked script but the problem is that, and correct me if I'm wrong, if I use the script you posted I will have to make two D-verb shortcuts, one for stereo tracks and one for mono tracks? If I could paste the text "D-verb" in the popup instead I can do it on the fly without thinking about wether the track is mono or stereo. At this point I am doing this from within the Stream Deck by using a Multi Action. This works just fine but of course it would be better to do it all from within the soundflow app, I guess. A sidenote is also that it's very fast to set up a series of plug-in shortcuts by just copying the Multi Action within the Stream Deck app, pasting it and just changing the "search for plug-in text" in the Multi Action to whatever the new shortcut might be. Hope I'm making sense.

                    Thank you for the fantastic support and a great product!

                    1. Christian Scheuer @chrscheuer2020-03-25 00:34:42.013Z2020-03-25 00:47:57.123Z

                      Please check the script I quoted above - it doesn't require you to specify D-Verb more than once. This script above uses new features to do exactly this that came with 3.5 which was released a few days ago. Download 3.5 from here: https://soundflow.org/download

                      You could even change it like this, so it's easy to swap out the name of the plugin (first line):

                      const pluginName = 'D-Verb';
                      
                      function getFirstFreeInsertIndex() {
                          var btns = sf.ui.proTools.selectedTrack.invalidate().insertButtons;
                          for (var i = 0; i < 10; i++)
                              if (btns[i].value.invalidate().value === "unassigned") return i;
                          return -1;
                      }
                      
                      sf.ui.proTools.selectedTrack.trackInsertOrSendSelect({
                          insertOrSend: "Insert",
                          pluginNumber: getFirstFreeInsertIndex() + 1,
                          pluginSelector: items => items.filter(item => item.path[0] === "plug-in" && item.path.slice(-1)[0].indexOf(pluginName) === 0)[0],
                      });
                      

                      We don't recommend using the Stream Deck designer for your decks at all - we highly recommend that you design your Decks inside SoundFlow via the "+ New" -> "Deck" feature.

                      Please read more here:
                      https://soundflow.org/docs/how-to/stream-deck/setting-up

                      Reply1 LikeSolution
                      1. Andrew Scheps @Andrew_Scheps
                          2020-03-25 18:39:32.680Z

                          Hi Christian. I still can't get the new type of code to work in this script. My script is almost identical to the one above, I just use an array to prioritise my insert slots (I prefer slot C if they're all open).

                          sf.ui.proTools.appActivateMainWindow();
                          
                          function getFirstFreeInsertIndex() {
                              var btns = sf.ui.proTools.selectedTrack.invalidate().insertButtons;
                              let insertArray = [2, 3, 4, 5, 6, 7, 8, 9, 1, 0];
                              for (let i = 0; i < insertArray.length; i++)
                                  if (btns[insertArray[i]].value.invalidate().value === "unassigned") return (insertArray[i]);
                              throw 0;
                          }
                          
                          sf.ui.proTools.selectedTrack.trackInsertOrSendSelect({
                              insertOrSend: "Insert",
                              pluginNumber: getFirstFreeInsertIndex() + 1,
                              pluginSelector: items => items.filter(item => item.path[0] === "plug-in" && item.path.slice(-1)[0].indexOf("Scheps Omni Channel") === 0)[0],
                          });
                          

                          When I run it I get:

                          25.03.2020 18:37:52.38 <info> [Backend]: Error in line 11:
                              Could not select plugin menu item: '<selector>' (TrackSelectInsertOrSendAction)
                              No menu item was returned by menuSelector callback (PopupMenuSelectAction)
                          

                          This version still runs fine:

                          function clickPopupMenu(popupMenu, paths) {
                              for (var i = 0; i < paths.length; i++) {
                                  var path = paths[i];
                                  if (popupMenu.menuClickPopupMenu({
                                      menuPath: path,
                                      onError: 'Continue'
                                  }).success) {
                                      return;
                                  }
                              } throw "None of the provided paths were present in this popup menu";
                          }
                          
                          function addSchepsOC() {
                              var popupMenu = sf.ui.proTools.selectedTrack.trackInsertOrSendOpenMenu({
                                  insertOrSend: "Insert",
                                  pluginNumber: getFirstFreeInsertIndex() + 1,
                              }).popupMenu;
                          
                              clickPopupMenu(popupMenu, [
                                  ['plug-in', 'EQ', 'Scheps Omni Channel (mono)'],
                                  ['multichannel plug-in', 'EQ', 'Scheps Omni Channel (stereo)']
                              ]);
                          }
                          

                          Any thoughts?

                          1. Try this:
                            The script above would fail for stereo tracks since I had an error in the selector.

                            sf.ui.proTools.appActivateMainWindow();
                            
                            function getFirstFreeInsertIndex() {
                                var btns = sf.ui.proTools.selectedTrack.invalidate().insertButtons;
                                let insertArray = [2, 3, 4, 5, 6, 7, 8, 9, 1, 0];
                                for (let i = 0; i < insertArray.length; i++)
                                    if (btns[insertArray[i]].value.invalidate().value === "unassigned") return (insertArray[i]);
                                throw 0;
                            }
                            
                            sf.ui.proTools.selectedTrack.trackInsertOrSendSelect({
                                insertOrSend: "Insert",
                                pluginNumber: getFirstFreeInsertIndex() + 1,
                                pluginSelector: items => items.filter(item => item.path[0].indexOf("plug-in") >= 0 && item.path.slice(-1)[0].indexOf("Scheps Omni Channel") === 0)[0],
                            });
                            
                            1. RRobert Sörling @robertsorling
                                2020-03-26 10:25:05.356Z

                                Great, now this works! Thnks

                                1. In reply tochrscheuer:
                                  Andrew Scheps @Andrew_Scheps
                                    2020-03-26 11:05:26.939Z

                                    Hi Christian. This works but is very slow. There is about a 5 second stall while it searches the menu. I wonder if this needs caching like the other script we were working on.

                                    1. Hi Andrew

                                      Since you have the large menu, you should use the other version that I wrote for you:
                                      https://forum.soundflow.org/-1693#post-8

                                      There should be no need for you to move to the selector based approach, since it works by fetching the entire contents which in your case is slow due to the huge number of plugins.

                                      1. Andrew Scheps @Andrew_Scheps
                                          2020-03-26 11:34:53.307Z

                                          Great, that's what I thought, thanks.

                                          1. JJordon Popp @Jordon_Popp
                                              2020-05-24 05:38:38.776Z

                                              Sorry to hijack this, but is there a way to get this to function across all selected tracks?

                                              Cheers,
                                              Jordon

                                              1. Andrew Scheps @Andrew_Scheps
                                                  2020-05-24 09:26:50.059Z

                                                  You could easily use

                                                  sf.ui.protools.selectedTracks
                                                  

                                                  and put the rest inside a loop, but you would need some pretty robust error checking which is why I kept it to one track.

                                                  1. JJordon Popp @Jordon_Popp
                                                      2020-06-05 05:43:15.998Z

                                                      Thanks, Andrew! I'm going to tinker with this over the weekend. Rather new to coding, and it's all a bit overwhelming, haha.

                                                      Cheers!

                                              2. In reply toAndrew_Scheps:
                                                Nnick krill @nick_krill
                                                  2020-09-16 21:50:22.155Z

                                                  Hi Andrew,

                                                  I might have found a tip to minimize the wait time while this script looks for plug-ins. I've found that it helps if I mark the plug-ins that I want to use in the script as "Favorites" in Pro Tools by Command+Clicking the name of the plugin in the plug in list. This way the script seems to grab the plug in from that little "Favorites" section at the top of the plug in menu, and seems to insert it prettty quickly. This might help avoid having to hunt through a large plugin menus.

                                                  -nick

                                2. R
                                  In reply torobertsorling:
                                  Robert Sörling @robertsorling
                                    2020-03-26 12:41:30.842Z

                                    "We don't recommend using the Stream Deck designer for your decks at all - we highly recommend that you design your Decks inside SoundFlow via the "+ New" -> "Deck" feature."

                                    Ok! "I realise that. Now" (Frank Drebin)

                                    1. A
                                      In reply torobertsorling:
                                      Alan Saucedo @Alan_Saucedo
                                        2020-06-19 17:32:38.014Z

                                        Hello!

                                        This is my first "coding" shortcut, i'm using the FabFilter Pro-Q 3 plugin like this:

                                        preformatted text
                                        sf.ui.proTools.appActivateMainWindow();

                                        function getFirstFreeInsertIndex() {
                                        var btns = sf.ui.proTools.selectedTrack.invalidate().insertButtons;
                                        for (let i = 0; i < 10; i++)
                                        if (btns[i].value.invalidate().value === "unassigned") return i;
                                        throw 0;
                                        }

                                        sf.ui.proTools.selectedTrack.trackInsertOrSendSelect({
                                        insertOrSend: "Insert",
                                        pluginNumber: getFirstFreeInsertIndex() + 1,
                                        pluginSelector: items => items.filter(item => item.path[0].indexOf("plug-in") >= 0 && item.path.slice(-1)[0].indexOf("FabFilter Pro-Q 3 ") === 0)[0],
                                        });

                                        But i'm having troubles when running in the "Mix Window". Any advices?

                                        1. Chris Shaw @Chris_Shaw2020-06-19 22:05:52.512Z2020-06-20 04:18:17.347Z

                                          Alan,
                                          SF is designed to primarily work in the Edit window. The simple workaround would be to create an if/else decision around the code you want to execute: if the mix window is active switch to edit window, execute your script and switch back to the Mix window - Else just execute the script.

                                          Like this:

                                          sf.ui.proTools.appActivateMainWindow();
                                          
                                          // First, let's get the selected track name
                                          var originallySelectedTrackNames = sf.ui.proTools.selectedTrackNames;
                                          
                                          // This next function  makes sure the selected track is visible in the Edit Window
                                          function ensureFirstSelectedTrackIsVisible() {
                                          
                                              sf.ui.proTools.trackGetByName({
                                                  name: originallySelectedTrackNames[0],
                                                  makeVisible: true
                                              }).track.trackScrollToView();
                                          }
                                          
                                          // Next we wrap your whole script into a single function 
                                          
                                          function insertEqInFirstFreeSlot() {
                                              function getFirstFreeInsertIndex() {
                                                  var btns = sf.ui.proTools.selectedTrack.invalidate().insertButtons;
                                                  for (let i = 0; i < 10; i++)
                                                      if (btns[i].value.invalidate().value === "unassigned") return i;
                                                  throw 0;
                                              }
                                              sf.ui.proTools.selectedTrack.trackInsertOrSendSelect({
                                                  insertOrSend: "Insert",
                                                  pluginNumber: getFirstFreeInsertIndex() + 1,
                                                  pluginSelector: items => items.filter(item => item.path[0].indexOf("plug-in") >= 0 && item.path.slice(-1)[0].indexOf("FabFilter Pro-Q 3 ") === 0)[0],
                                              });
                                          }
                                          
                                          // Here we create a new function  that executes everything
                                          function main() {
                                          
                                              //Check if Mix window is visible. If not switch to Edit Window and execute your script, then switch back
                                              if (sf.ui.proTools.getMenuItem('Window', 'Mix').isMenuChecked) {
                                                  sf.ui.proTools.menuClick({
                                                      menuPath: ["Window", "Edit"],
                                                      targetValue: "Enable",
                                                  });
                                                  ensureFirstSelectedTrackIsVisible();
                                          
                                                  insertEqInFirstFreeSlot() // your script
                                          
                                                  sf.ui.proTools.menuClick({
                                                      menuPath: ["Window", "Mix"],
                                                      targetValue: "Enable",
                                                  });
                                              }
                                              /// Else if the Edit window is the main window, just execute the script
                                              else {
                                                  ensureFirstSelectedTrackIsVisible();
                                                  insertEqInFirstFreeSlot();
                                                  sf.ui.proTools.trackSelectByName({ names: originallySelectedTrackNames, deselectOthers: true });
                                              }
                                          }
                                          // Now execute main
                                          main();
                                          

                                          Now your script will work in both windows.

                                          1. Todd Burke @Todd_Burke8
                                              2020-07-04 18:09:18.916Z

                                              Woo hoo! So happy to have found this. Thanks fellas.

                                              1. Yep
                                                You just have to check which window is the main one, switch to the edit window and then back again. It’s clumsy but it works.

                                                1. Todd Burke @Todd_Burke8
                                                    2020-07-04 20:42:09.655Z

                                                    Now if I can just find an “add track to existing group” script I might get back to this mix :)

                                                    1. If you’re looking to add a new track to an existing group there’s a thread here:
                                                      https://forum.soundflow.org/-217/duplicate-tracks-without-any-media

                                                      But if you’re trying to add an already existing track to an already existing group you may have to write one yourself. Shouldn’t be that hard.

                                                      BTW - I’m going to make a slightly more elegant script for switching back and forth from the Mix window. I’ll post here when I do.

                                                      //CS//

                                                      1. Todd Burke @Todd_Burke8
                                                          2020-07-04 21:34:16.718Z

                                                          Thanks so much!

                                                          1. Here's a better implementation. This approach doesn't require you to put your entire script into a function. Just place the appropriate lines at the beginning and end of your script:

                                                            sf.ui.proTools.appActivate();
                                                            sf.ui.proTools.invalidate();
                                                            
                                                            /// Add this to the beginning of your Script ////
                                                            
                                                                   // This function ensures that the track you've selected 
                                                                   // in the Mix window will be visible in the Edit Window
                                                            
                                                            function ensureFirstSelectedTrackIsVisible() {
                                                                var originallySelectedTrackNames = sf.ui.proTools.selectedTrackNames;
                                                                sf.ui.proTools.selectedTrack.trackScrollToView();
                                                                sf.ui.proTools.trackSelectByName({ names: originallySelectedTrackNames, deselectOthers: true });
                                                            }
                                                            
                                                                  /// this determines which window is your main window - Mix or Edit
                                                                  /// and switches to the Edit window if necessary
                                                            
                                                            if (sf.ui.proTools.getMenuItem('Window', 'Mix').isMenuChecked) {
                                                                var mainWindow = "Mix";
                                                                sf.ui.proTools.menuClick({
                                                                    menuPath: ["Window", "Edit"],
                                                                });
                                                                ensureFirstSelectedTrackIsVisible();
                                                            
                                                            } else {
                                                                mainWindow = "Edit";
                                                                ensureFirstSelectedTrackIsVisible();
                                                            }
                                                            
                                                                    //////////////
                                                            /////////////////////////////
                                                            ///////YOUR SCRIPT HERE//////
                                                            /////////////////////////////
                                                                    //////////////
                                                            
                                                            
                                                            /// Insert at end of script
                                                                    //Switch back to Mix window if necessary
                                                            switch (mainWindow) {
                                                                case "Mix":
                                                                sf.ui.proTools.menuClick({
                                                                    menuPath: ["Window", "Mix"],
                                                                });
                                                                break;
                                                                case "Edit":
                                                                break;
                                                            }
                                                            

                                                            As a rule of thumb, create your scripts to work in the Edit window and use the above code to make them compatible with the Mix window.

                                              2. In reply torobertsorling:

                                                Here's a more refined way to check for and switch to the Edit window and back:

                                                // define functions at start of script
                                                
                                                function mainWindowStatus() {
                                                    if (sf.ui.proTools.getMenuItem('Window', 'Mix').isMenuChecked) {
                                                        sf.ui.proTools.menuClick({
                                                            menuPath: ["Window", "Edit"],
                                                        });
                                                        return "Mix";
                                                    } else {
                                                        return "Edit";
                                                    }
                                                }
                                                
                                                
                                                
                                                function returnToStartingMainWIndow(mainWindow) {
                                                    switch (mainWindow) {
                                                        case "Mix":
                                                            sf.ui.proTools.menuClick({
                                                                menuPath: ["Window", "Mix"],
                                                            });
                                                            break;
                                                        case "Edit":
                                                            break;
                                                    }
                                                }
                                                
                                                
                                                
                                                
                                                /// start  with this code
                                                var startingWindow= mainWindowStatus();
                                                
                                                alert("Pause")  // sample code / your code
                                                
                                                // end with this
                                                returnToStartingMainWIndow(startingWindow);