No internet connection
  1. Home
  2. How to

Needing a script for "Open all inserts on Selected Track"

By Jagori Tanna @Jagori_Tanna
    2021-04-16 14:43:32.322Z

    Needing a script for "Open all inserts on Selected Track"

    System Information

    SoundFlow 4.2.5

    OS: darwin 18.7.0

    ProductName: Mac OS X
    ProductVersion: 10.14.6
    BuildVersion: 18G103

    Steps to Reproduce

    Expected Result

    The same result as holding Shift while opening each insert which turns off the plug in's target mode

    Actual Result

    Workaround

    No I have not. For now I have commands to open each insert slot individually.

    Other Notes

    This seems like something everybody would require as an add on to the existing scripts of opening inserts. I have searched the forum already for a workaround.


    Links

    User UID: 3bQltHdjljNOhJpGv5cktiTJW8h1

    Feedback Key: sffeedback:3bQltHdjljNOhJpGv5cktiTJW8h1:-MYQ7l4PFLVbj32dk6iE

    Feedback ZIP

    Solved in post #2, click to view
    • 21 replies

    There are 21 replies. Estimated reading time: 19 minutes

    1. Kitch Membery @Kitch2021-04-17 23:35:56.334Z

      Hi @Jagori_Tanna,

      Here is a script that @chrscheuer put together to "Open all plug-in windows on a selected track";

      let track = sf.ui.proTools.selectedTrack;
      
      function getInsertWin(track, insertIndex) {
          const insertChars = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'];
          const insertChar = insertChars[insertIndex];
          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];
      }
      
      for (let i = 0; i < 10; i++) {
      
          if (!track.insertButtons[i].invalidate().exists) continue;
          if (track.insertButtons[i].value.value === "unassigned") continue;
      
          let pluginWin = getInsertWin(track, i);
      
          if (!pluginWin) {
              track.insertButtons[i].elementClick();
      
              while (true) {
                  pluginWin = getInsertWin(track, i);
                  if (pluginWin) break;
                  sf.wait({ intervalMs: 100 });
              }
      
              //Disable target mode on newly opened window
              pluginWin.buttons.whoseTitle.is('Target button').first.elementClick();
          }
      }
      

      Rock on!

      Reply1 LikeSolution
      1. TTristan Hoogland @Tristan
          2022-11-17 00:00:59.214Z

          Hey Kitch!

          This is the closest script I've found to what I might be needing. I'm trying to get soundflow to, after selecting a bunch of tracks, open just a single plugin. Ideally the first within the chain so long as it contains the term "UAD".

          Don't suppose you have a quick tip for this? I've been scratching my head all day on it!

          1. Kitch Membery @Kitch2022-11-17 00:34:07.745Z

            Try this @Tristan_Hoogland

            const pluginSearchString = "UAD"
            
            const insertButtonInfo = sf.ui.proTools.selectedTrack.insertButtons.map((btn, index) => ({
                button: btn,
                value: btn.value.invalidate().value,
                insertSlotNumber: index + 1,
            }));
            
            const firstUadPluginSlotIndex = insertButtonInfo.find(btn => btn.value.includes(pluginSearchString)).insertSlotNumber;
            
            sf.ui.proTools.appActivateMainWindow();
            
            if (firstUadPluginSlotIndex !== undefined) {
                sf.ui.proTools.selectedTrack.trackInsertToggleShow({
                    insertNumber: firstUadPluginSlotIndex,
                });
            }
            
            1. TTristan Hoogland @Tristan
                2022-11-17 00:38:26.080Z

                hell yea. Thanks K!!!

                1. In reply toKitch:
                  TTristan Hoogland @Tristan
                    2022-11-17 00:43:07.033Z

                    I'll be sharing the script soon, mate for help on those things we talked about earlier. I definitely am nearing that point of needing your help! Plus it'd be good to share it back (and many others I've got in the pipeline that are a bit of a mess, still).

                    1. In reply toKitch:
                      TTristan Hoogland @Tristan
                        2022-11-19 21:02:49.809Z

                        Hey Kitch. What would be the best way to make pluginSearchString = "UAD" into a searchable array? I feel like I should be considering some kind of loop function. Right now this is what I want to do:

                        const pluginSearchString = ['UAD UA 1176LN Rev E", "UAD UA 1176 Rev A", "UAD UA 1176AE"] //etc etc
                        
                        const insertButtonInfo = sf.ui.proTools.selectedTrack.insertButtons.map((btn, index) => ({
                            button: btn,
                            value: btn.value.invalidate().value,
                            insertSlotNumber: index + 1,
                        }));
                        
                        const firstUadPluginSlotIndex = insertButtonInfo.find(btn => btn.value.includes(pluginSearchString)).insertSlotNumber;
                        
                        sf.ui.proTools.appActivateMainWindow();
                        
                        if (firstUadPluginSlotIndex !== undefined) {
                            sf.ui.proTools.selectedTrack.trackInsertToggleShow({
                                insertNumber: firstUadPluginSlotIndex,
                            });
                        }
                        

                        Currently when it gets to btn.value.includes(pluginSearchString)).insertSlotNumber pluginSearchString becomes invalid. I'm trying to work out the best way of searching that array. Any tips? I'm deep in javascript land in the meantime trying to solve my issue on my own I promise!

                        1. Kitch Membery @Kitch2022-11-19 21:29:57.862Z

                          Because you are looking for the possibility of a match to "UAD" with the risk of not finding one, you could do something like this;

                          const pluginSearchString = "UAD"
                          
                          //Map info from insert slots
                          const insertButtonInfo = sf.ui.proTools.selectedTrack.insertButtons.map((btn, index) => ({
                              button: btn,
                              value: btn.value.invalidate().value,
                              insertSlotNumber: index + 1,
                          }));
                          
                          //Filter to get all insert slots whose name includes the pluginSearchString
                          const matchingInsertSlots = insertButtonInfo.filter(btn => btn.value.includes(pluginSearchString));
                          
                          sf.ui.proTools.appActivateMainWindow();
                          
                          //Loop through the matchingInsertSlots
                          matchingInsertSlots.forEach(insert => {
                          
                              sf.ui.proTools.selectedTrack.trackInsertToggleShow({
                                  insertNumber: insert.insertSlotNumber,
                              });
                          
                          });
                          

                          This script filters the plugin names for "UAD" and stores them in an array named uadInsertSlots. If the script can't find any matches, the filter method will return an empty array.

                          The script will then loop through the uadInsertSlots using the forEach method.

                          Inside the forEach loop is where you can do all the fun stuff. :-)

                          1. TTristan Hoogland @Tristan
                              2022-11-19 21:49:25.641Z

                              Thanks K!

                              Playing with it now, I'm not entirely sure it's going to work as I was hoping. One bit of knowledge I've left in the realm of assumption is that there are only a handful of UAD and UADx compatible plugins right now. There are like ~100 UAD plugins and only ~15 UADx plugins. So I need to specify what those UADx plugins because otherwise it'll cycle through other UAD plugins that don't have a native companion. Does that make sense?

                              1. Kitch Membery @Kitch2022-11-19 22:22:54.567Z

                                Yes of course.

                                const uadXpluginLookup = [
                                    {
                                        uadPluginName: "UAD UA 1176LN Rev E",
                                        uadXPluginName: "UADx UA 1176LN Rev E Compressor",
                                    },
                                    {
                                        uadPluginName: "UAD UA 1176LN Rev A",
                                        uadXPluginName: "UADx UA 1176LN Rev A Compressor",
                                    },
                                ];
                                
                                //Get an array of usable UAD plugin names
                                const usablePluginNames = uadXpluginLookup.map(item => item.uadPluginName);
                                
                                //Map info from insert slots
                                const insertButtonInfo = sf.ui.proTools.selectedTrack.insertButtons.map((btn, index) => ({
                                    button: btn,
                                    value: btn.value.invalidate().value,
                                    insertSlotNumber: index + 1,
                                }));
                                
                                //Filter to get all insert slots whose name includes any of the usablePluginNames
                                const matchingInsertSlots = insertButtonInfo.filter(btn => usablePluginNames.some((name) => name === btn.value));
                                
                                sf.ui.proTools.appActivateMainWindow();
                                
                                //Loop through the matchingInsertSlots
                                matchingInsertSlots.forEach(insert => {
                                
                                    sf.ui.proTools.selectedTrack.trackInsertToggleShow({
                                        insertNumber: insert.insertSlotNumber,
                                    });
                                
                                    //For demo purpose only
                                    sf.wait({ intervalMs: 1000 });
                                
                                });
                                

                                This uses the some method to get the matching plugins based on the lookup array. :-)

                                Let me know if that makes sense.

                                1. TTristan Hoogland @Tristan
                                    2022-11-19 22:30:35.278Z

                                    PERFECT!

                                    Kitch to the rescue once again. I'm not sure I've come across the .some function before. I thought something like the array thing would have been the way to go.

                                    By the way got it working very well otherwise - updated with use of percentages etc. Just throwing this in, tweaking it so it ignores inactive states and then will find an edge case session for it! ha.

                                    Thanks man.

                                    1. Kitch Membery @Kitch2022-11-19 22:51:32.073Z

                                      Noice!

                                      A couple of edge cases I can think of:

                                      • Make sure that insert slots a-e and f-j are open.

                                      • Make sure the track heights allow for all insert slots to be visible (Otherwise the script will fail.)

                                      • Ensure that the edit window is focused

                                      • Make sure that all plugin windows are closed at the start of the script.

                                      Rock on!

                                      1. TTristan Hoogland @Tristan
                                          2022-11-19 23:00:16.089Z

                                          Thanks man!

                                          That's some great stuff to remember, particularly remembering to keep all insert slots visible (I always have them open so it gets me a few times on other systems!). I think the rest of it is accounted for, I'll send it over for your review soon.

                                          While I'm cleaning it up, I'm utilizing while (true) for my convert function after this gold you've given here, however, while it's working great - currently it scans through all the plugins going from insert A through to J and then calls the 'convert to uadx' function on the last plugin (I guess because it's no longer found any UADx compatible plugins).

                                          Ideally once the script finds a plugin, it'd be good if it breaks and then moves to the 'convert uadx' function and then goes through again, so on and so forth - does that make sense? Currently it's working, just in reverse lol.

                                          In essence it's effectively like running the soundflow open insert by name macro in a loop (it always finds and launches the first instance of any given plugin).

                                          Anyway, punching away. fun times.

                                          1. Kitch Membery @Kitch2022-11-19 23:05:02.143Z

                                            Ahh I see... You'll need to move all the actions that are performed to each of the matched plugins into the forEach loop otherwise it will only work on the last slot that opens.

                                            1. TTristan Hoogland @Tristan
                                                2022-11-19 23:20:22.523Z

                                                You know, I tried that for 15 mins and it turned out my internet dropped out so it kept running an old script!! Now working as expected. Thanks K!

                                                1. Kitch Membery @Kitch2022-11-20 00:06:04.312Z

                                                  Awesome!!!

                                                  1. TTristan Hoogland @Tristan
                                                      2022-11-29 03:48:13.606Z

                                                      Hey @Kitch
                                                      I'm assuming this should be a pretty easy one, but I'm just not sure how to interject it into your script snippet here.

                                                      How would I go about ignoring inserts that are inactive, but have "UAD" in them? In some edge cases I'll have something like a track that has 2 UAD inserts active, but 1 UAD insert inactive, and when repeating the open/copy/paste process it'll still try to do it to the inactive plugins and in turn fail.

                                                      Getting the value/inactive state via the insertSelector is easy, just thinking of how to exclude them during the cycling process.

                                                      Thanks!

                                                      1. Kitch Membery @Kitch2022-11-29 04:36:25.113Z

                                                        Will circle back to this tomorrow, legend.

                                                        Rock on!

                                                        1. TTristan Hoogland @Tristan
                                                            2022-11-29 04:54:01.150Z

                                                            make sure you're wearing the cape this time, hero!

                                                            1. Kitch Membery @Kitch2022-11-29 20:45:56.841Z

                                                              Well hi there @Tristan_Hoogland,

                                                              function getInsertsInfo() {
                                                                  const insertInfo = Array(10).fill(0).map((_, index) => {
                                                              
                                                                      const track = sf.ui.proTools.selectedTrack;
                                                              
                                                                      const insertButton = track.invalidate().insertButtons[index];
                                                                      const insertButtonValue = insertButton.value.invalidate().value;
                                                              
                                                                      const insertSelectorButton = track.invalidate().insertSelectorButtons[index]
                                                                      const insertSelectorButtonValue = insertSelectorButton.value.invalidate().value;
                                                              
                                                                      return {
                                                                          insertButton,
                                                                          insertButtonValue,
                                                                          insertSelectorButton,
                                                                          insertSelectorButtonValue,
                                                                          insertIndex: index,
                                                                          pluginName: insertButtonValue,
                                                                          //isBypassed: insertSelectorButtonValue.includes('bypassed'),
                                                                          isActive: !insertSelectorButtonValue.includes('inactive'),
                                                                      };
                                                                  });
                                                              
                                                                  return insertInfo;
                                                              }
                                                              
                                                              const uadXpluginLookup = [
                                                                  {
                                                                      uadPluginName: "FabFilter Pro-C 2",
                                                                      uadXPluginName: "UADx UA 1176LN Rev E Compressor",
                                                                  },
                                                                  {
                                                                      uadPluginName: "UAD UA 1176LN Rev A",
                                                                      uadXPluginName: "UADx UA 1176LN Rev A Compressor",
                                                                  },
                                                              ];
                                                              
                                                              //Get an array of usable UAD plugin names
                                                              const usablePluginNames = uadXpluginLookup.map(item => item.uadPluginName);
                                                              
                                                              const insertsInfo = getInsertsInfo();
                                                              
                                                              //Filter to get all insert slots whose name includes any of the usablePluginNames
                                                              const matchingInsertSlots = insertsInfo.filter(btn => {
                                                                  return usablePluginNames.some((name) => name === btn.pluginName) && btn.isActive === true;
                                                              });
                                                              
                                                              log(matchingInsertSlots);
                                                              

                                                              Something like this will filter out the inactive inserts. :-)

                                                              1. TTristan Hoogland @Tristan
                                                                  2022-11-29 23:31:14.768Z

                                                                  @Kitch this one is going into the save-for-later folder. Amazing.

                                                                  The only thing I needed to amend on my end was to increment the insertIndex with a + 1 on the end later in the matchingInserts section ;)

                                                                  function getInsertsInfo() {
                                                                      const insertInfo = Array(10).fill(0).map((_, index) => {
                                                                  
                                                                          const track = sf.ui.proTools.selectedTrack;
                                                                  
                                                                          const insertButton = track.invalidate().insertButtons[index];
                                                                          const insertButtonValue = insertButton.value.invalidate().value;
                                                                  
                                                                          const insertSelectorButton = track.invalidate().insertSelectorButtons[index]
                                                                          const insertSelectorButtonValue = insertSelectorButton.value.invalidate().value;
                                                                  
                                                                          return {
                                                                              insertButton,
                                                                              insertButtonValue,
                                                                              insertSelectorButton,
                                                                              insertSelectorButtonValue,
                                                                              insertIndex: index,
                                                                              pluginName: insertButtonValue,
                                                                              //isBypassed: insertSelectorButtonValue.includes('bypassed'),
                                                                              isActive: !insertSelectorButtonValue.includes('inactive'),
                                                                          };
                                                                      });
                                                                  
                                                                      return insertInfo;
                                                                  }
                                                                  
                                                                  const uadXpluginLookup = [
                                                                      {
                                                                          uadPluginName: "FabFilter Pro-C 2",
                                                                          uadXPluginName: "UADx UA 1176LN Rev E Compressor",
                                                                      },
                                                                      {
                                                                          uadPluginName: "UAD UA 1176LN Rev A",
                                                                          uadXPluginName: "UADx UA 1176LN Rev A Compressor",
                                                                      },
                                                                  ];
                                                                  
                                                                  //Get an array of usable UAD plugin names
                                                                  const usablePluginNames = uadXpluginLookup.map(item => item.uadPluginName);
                                                                  
                                                                  const insertsInfo = getInsertsInfo();
                                                                  
                                                                  //Filter to get all insert slots whose name includes any of the usablePluginNames
                                                                  const matchingInsertSlots = insertsInfo.filter(btn => {
                                                                      return usablePluginNames.some((name) => name === btn.pluginName) && btn.isActive === true;
                                                                  });
                                                                  
                                                                      sf.ui.proTools.appActivateMainWindow();
                                                                  
                                                                      //Loop through the matchingInsertSlots
                                                                      matchingInsertSlots.forEach(insert => {
                                                                  
                                                                          sf.ui.proTools.selectedTrack.trackInsertToggleShow({
                                                                              insertNumber: insert.insertIndex + 1,
                                                                          })
                                                                      });
                                                                  }
                                                                  

                                                                  Just about ready!

                                                                  1. Kitch Membery @Kitch2022-11-29 23:55:42.782Z

                                                                    Awesome! :-)