No internet connection
  1. Home
  2. How to

How to show specific automation lanes for a plug-in? (Same lanes and plug-in every time)

By Rob Byers @Rob_Byers
    2022-03-22 18:04:22.572Z

    Hello,

    Is there a way to show specific plug-in automation lanes for a selected track?

    I have the FabFilter Pro-Q-3 plug on just about every track in every project I do. Part of my workflow involves adjusting Gain and Frequency of Band 1 via track automation (via mouse).

    I access the same Band and controls on every track by clicking "show/hide automation lanes" in PT and then selecting those specific lanes. This is a bit maddening, because I have to do it many times when I first set up a session. It's a ton of clicking,

    Is there a way to use "Toggle Automation Lanes" (or another command) to show just these two automation lanes?

    It'll be the same lanes every time, but on any track in the session.

    Best,

    -R

    • 18 replies

    There are 18 replies. Estimated reading time: 19 minutes

    1. In reply toRob_Byers:
      Chris Shaw @Chris_Shaw2022-03-22 20:35:24.299Z2022-03-22 20:54:34.962Z

      This will toggle the automation lane between band 1 gain and band 1 frequency on the first instance of ProQ-3 on the selected track:

      const currentLane = sf.ui.proTools.selectedTrack.popupButtons.whoseTitle.is("Track View selector").first.value.invalidate().value
      
      var setLaneTo = (currentLane.includes("Gain"))? "Band 1 Frequency" : "Band 1 Gain"
      
      sf.ui.proTools.selectedTrack.popupButtons.whoseTitle.is("Track View selector").first.popupMenuSelect({
          menuPath: ["*FabFilter Pro-Q 3",setLaneTo],
          useWildcards: true,
      });
      
      1. In reply toRob_Byers:
        Ben Rubin @Ben_Rubin
          2022-03-31 02:47:00.513Z

          @Chris_Shaw, is there a way to make a script that will show all used automation lanes for a selected track? That could be really helpful to me.

          1. You want to show all the automation lanes in the edit window or a list of all used automation lanes like the above scripts?

            1. Ben Rubin @Ben_Rubin
                2022-03-31 03:03:24.863Z

                I'd love to be able to show all of the used automation lanes in the area when you flip the triangle (show/hide automation) on a selected track. So i can see all the automation written to any parameter on a selected track. is that clearer?

                Also just grabbed the other automation lane scripts from that other thread. thanks for those!

                1. @Ben_Rubin I'm not sure this is possible. Visually you can tell which lanes have automation on them because the automation name is either orange or in bold type. Unfortunately SF cannot read whether or not the text is bold or orange because PT accessibility / UI doesn't report it.

                  If you have other ideas… :)

                  1. Ben Rubin @Ben_Rubin
                      2022-03-31 20:50:23.079Z

                      I don't but I'l think about it.

                      1. RRob Byers @Rob_Byers
                          2022-04-01 15:02:38.780Z

                          Chris, THANK YOU for investing time in to this riddle. It's good to know it might help others as well!

                          What Ben is looking for is similar to what I was hoping for, as well — showing used automation lanes.

                          Actually, my preference would be a macro to show two specific automation lanes for the selected track (always the same two lanes) — FabFilter ProQ3 Band 1 Gain and Band 1 Frequency. Do you think that is possible?

                          1. Hey @Rob_Byers ,

                            With a lot of help from @Kitch I was able to throw this together. To change the plugin and the automation lanes you want to show just edit the first two variables in the script. (Note, as written below it will open lanes for three parameters).

                            Two things to keep in mind:

                            1. only run the script once. Repeated use on the same track(s) will just add other random automation lanes.
                            2. It will only show these lanes for the first instance of the plugin.
                            const pluginName = "FabFilter Pro-Q 3"
                            const laneSelectorNames = ["Band 1 Gain", "Band 1 Frequency","Band 2 Gain"];
                            
                            function showautomationLaness() {
                                //If any automation lane for selected tracks are hidden, show them.
                                const showautomationLanesBtn = sf.ui.proTools.selectedTrack.children.whoseTitle.is('Show/hide automation lanes').first;
                                if (showautomationLanesBtn.value.invalidate().value !== "Selected") {
                                    showautomationLanesBtn.mouseClickElement({
                                        isShift: true,
                                        isOption: true,
                                    });
                                } else {
                                    showautomationLanesBtn.mouseClickElement();
                                    showautomationLanesBtn.mouseClickElement({
                                        isShift: true,
                                        isOption: true,
                                    });
                                }
                            }
                            
                            function openAutomationLanes({ trackName, laneIndex, pluginName, laneSelectorName }) {
                                //Fist automation lane on selected track
                                let automationLane = sf.ui.proTools.mainWindow.invalidate().children.whoseTitle.endsWith("Automation Lane")
                                    .filter(f => f.title.invalidate().value.indexOf(trackName) >= 0);
                            
                                //Set the first automation lane to the first available plug-in parameter.
                                automationLane[laneIndex].popupButtons.whoseTitle.is('Lane view selector').first.popupMenuSelect({
                                    menuSelector: items => items.find(item =>
                                        item.path[0].endsWith(pluginName) &&
                                        item.path[1] === laneSelectorName),
                                });
                            }
                            
                            function getAutomationLanes(track) {
                                return sf.ui.proTools.mainWindow.children.invalidate().whoseTitle.endsWith("Automation Lane").filter(f => f.title.value.indexOf(track.title.value) === 0);
                            }
                            
                            function main() {
                                //Invalidate Pro Tools main window.
                                sf.ui.proTools.mainWindow.invalidate();
                            
                                //Get selected tracks
                                const originalTracks = sf.ui.proTools.selectedTrackNames;
                            
                                //Scroll first selected track to into view
                                sf.ui.proTools.selectedTrack.trackScrollToView();
                            
                                //Show automation Lanes
                                showautomationLaness();
                            
                                //Do for each track.
                                sf.ui.proTools.selectedTracks.trackHeaders.slice().map(track => {
                            
                                    //Select track
                                    track.trackSelect();
                            
                                    //Scroll track into View
                                    track.trackScrollToView();
                            
                                    //Fetch track title
                                    let selectedTrackTitle = track.title.invalidate().value;
                            
                                    //Select lanes
                                    for (var i = 0; i < laneSelectorNames.length; i++) {
                            
                                        openAutomationLanes({
                                            trackName: track.normalizedTrackName,
                                            laneIndex: i,
                                            pluginName,
                                            laneSelectorName: laneSelectorNames[i],
                                        });
                            
                                        if (i != laneSelectorNames.length - 1) {
                                            var addLnBtn = getAutomationLanes(track)
                                            sf.ui.proTools.mainWindow.invalidate().groups.whoseTitle.is(addLnBtn[0].title.value).first.buttons.whoseTitle.is("Add automation lane below this one").first.elementClick();
                                        }
                                    }
                                });
                            
                                //Restore previously selected tracks
                                sf.ui.proTools.trackSelectByName({ names: originalTracks });
                            }
                            
                            main();
                            
                            1. RRob Byers @Rob_Byers
                                2022-04-03 17:13:10.573Z

                                @Chris_Shaw and @Kitch thank you so much! This is exactly what I was hoping for.

                                I see what you mean about the random behavior when using the command twice. Noted!

                                I'm going to dig in to this a bit and see if it can be tweaked to add an additional lane from another plugin (Ozone Imager).

                                This is really, really great. Another example of Soundflow pulling through for its users. Thank you.

                                -R

                                1. Just replace the plugin name and parameters in the first couple of lines of code.

                                  Glad it works.

                                  1. SSeàn Frost @Sean_Frost9
                                      2022-09-26 16:26:40.468Z

                                      Hi Chris, I've just stumbled across this script and it looks really close to what I'm after. I had a go myself at modifying this to use with Slate Digital MetaTune, but couldn't get the behaviour I expected, maybe you can point me in the right direction.

                                      I assumed i could change the parameters at the top to be:

                                      const pluginName = "MetaTune"
                                      const laneSelectorNames = ["Speed", "C", "C#", "D", "D#", "E", "F", "F#/Gb", "G", "G#/Ab", "A", "A#/Bb", "B" ];

                                      It half works, but this just brings up 3 lanes for "speed, stabilize note, and C", and note the parameters i added above.

                                      I knew it couldn't be that easy but I had hoped!
                                      What should I be doing instead to make this script work for me?

                                      Many thanks in advance!

                                      1. Hey @Sean_Frost9 ,
                                        You were almost there but you didn't spell all of the automation lane names properly.
                                        try using this instead:

                                        const pluginName = "MetaTune"
                                        const laneSelectorNames = ["C", "C#/Db", "D", "D#", "E", "F", "F#/Gb", "G", "G#/Ab", "A", "A#/Bb", "B", "Speed"];
                                        
                                        1. Remember - The automation lane names must match the names of a plug-in's automation names:

                    • In reply toRob_Byers:
                      Linus Gidstedt @Linus_Gidstedt
                        2022-11-24 01:15:12.580Z

                        This is an awesome script! But it keeps breaking when it reaches the track at the bottom of the screen. It seems like it won't scroll the selected track into view. Any thought on what might be wrong?

                        1. Linus Gidstedt @Linus_Gidstedt
                            2022-11-25 19:57:26.843Z

                            Changing

                            track.trackScrollToView();
                            

                            to

                            //Scroll track into View
                            track.titleButton.popupMenuSelect({
                                    isRightClick: true,
                                    menuPath: ['Scroll Into View']
                            });
                            
                            

                            works much better. Can someone explain why? What is trackScrollToView() actually doing?

                          • In reply toRob_Byers:
                            Linus Gidstedt @Linus_Gidstedt
                              2025-02-20 09:23:30.724Z

                              Hi @Kitch and @Chris_Shaw!
                              I have used a modified version of this script that has worked perfectly until recently and I can't figure out what is wrong. I receive different error messages but mainly this one

                              20.02.2025 09:38:33.18 [Backend]: Logging unknown error in action (02) RunCommandAction: Add automation lanes: Line 96
                              !! Command Error: FabFilter Pro-Q 3 Hi/Low-cut [user:cl8xixz1k0003pc10laehwxw9:clau99uxz00003k10e2ohewuz#clawyqcaq00033k106c5tqgma]:
                              ClickButtonAction requires UIElement
                              Couldn't get item #0 as the array's parent node wasn't found - sf.ui.app('com.avid.ProTools')..groups.whoseTitle.is('SFX 5.1A - Audio Track - volume Automation Lane').first.buttons (AxElementArrayIndexedItem)

                              It is very intermittent and the script always works the second time I run it on the same track or if the first Automation lane is already correct. I don't know if it can be a problem related to folder tracks, an invalidation problem or something Avid changed in Pro Tools?

                              Here is the whole script

                              sf.ui.proTools.appActivateMainWindow();
                              
                              const { pluginName, laneSelectorNames } = event.props;
                              
                              //Set Scroll Into View Key Command
                              const scrollIntoView = () => sf.keyboard.press({ keys: "shift+ctrl+option+command+s" });
                              /* function scrollIntoView() {
                                  sf.ui.proTools.selectedTrack.titleButton.popupMenuSelect({
                                      isRightClick: true,
                                      menuPath: ["Scroll Into View"],
                                  })
                              } */
                              
                              function showautomationLaness() {
                                  //If any automation lane for selected tracks are hidden, show them.
                                  const showautomationLanesBtn = sf.ui.proTools.selectedTrack.children.whoseTitle.is('Show/hide automation lanes').first;
                                  if (showautomationLanesBtn.value.invalidate().value !== "Selected") {
                                      showautomationLanesBtn.mouseClickElement({
                                          isShift: true,
                                          isOption: true,
                                      });
                                  } else {
                                      showautomationLanesBtn.mouseClickElement();
                                      showautomationLanesBtn.mouseClickElement({
                                          isShift: true,
                                          isOption: true,
                                      });
                                  }
                              }
                              
                              function openAutomationLanes({ trackName, laneIndex, pluginName, laneSelectorName }) {
                                  //First automation lane on selected track
                                  let automationLane = sf.ui.proTools.mainWindow.invalidate().children.whoseTitle.endsWith("Automation Lane")
                                      .filter(f => f.title.invalidate().value.indexOf(trackName) >= 0);
                              
                                  //Set the first automation lane to the first available plug-in parameter.
                                  automationLane[laneIndex].popupButtons.whoseTitle.is('Lane view selector').first.popupMenuSelect({
                                      menuSelector: items => items.find(item =>
                                          item.path[0].endsWith(pluginName) &&
                                          item.path[1] === laneSelectorName),
                                      onError: "Continue"
                                  });
                              }
                              
                              /**
                              * @param {AxPtTrackHeader} track
                              */
                              function getAutomationLanes(track) {
                                  return sf.ui.proTools.mainWindow.children.invalidate().whoseTitle.endsWith("Automation Lane").filter(f => f.title.value.indexOf(track.title.value) === 0);
                              }
                              
                              function main() {
                                  //Get selected tracks
                                  const originalTracks = sf.ui.proTools.selectedTrackNames;
                                  const originalFirstTracks = [originalTracks[0]];
                              
                                  //Invalidate Pro Tools main window.
                                  sf.ui.proTools.mainWindow.invalidate();
                              
                                  //Scroll first selected track into view
                                  sf.ui.proTools.trackSelectByName({ names: originalFirstTracks });
                                  sf.ui.proTools.selectedTrack.trackScrollToView();
                                  sf.ui.proTools.trackSelectByName({ names: originalTracks });
                              
                                  //Show automation Lanes
                                  showautomationLaness();
                              
                                  //Do for each track.
                                  sf.ui.proTools.selectedTracks.trackHeaders.slice().map(track => {
                              
                                      //Select track
                                      track.trackSelect();
                              
                                      //Scroll track into View
                                      //track.trackScrollToView();
                                      scrollIntoView();
                              
                                      var removeLnBtn = getAutomationLanes(track);
                                      sf.ui.proTools.mainWindow.invalidate().groups.whoseTitle.is(removeLnBtn[0].title.value).first.buttons.whoseTitle.is("Remove this automation lane").first.elementClick();
                              
                                      //Fetch track title
                                      //let selectedTrackTitle = track.title.invalidate().value;
                              
                                      //Select lanes
                                      for (var i = 0; i < laneSelectorNames.length; i++) {
                              
                                          openAutomationLanes({
                                              trackName: track.normalizedTrackName,
                                              laneIndex: i,
                                              pluginName,
                                              laneSelectorName: laneSelectorNames[i],
                                          });
                              
                                          if (i != laneSelectorNames.length - 1) {
                                              var addLnBtn = getAutomationLanes(track)
                                              sf.ui.proTools.mainWindow.invalidate().groups.whoseTitle.is(addLnBtn[0].title.value).first.buttons.whoseTitle.is("Add automation lane below this one").first.elementClick();
                                          }
                                      }
                                  });
                              
                                  //Restore previously selected tracks
                                  sf.ui.proTools.trackSelectByName({ names: originalFirstTracks });
                                  scrollIntoView();
                                  sf.ui.proTools.trackSelectByName({ names: originalTracks });
                                  sf.ui.proTools.selectedTrack.children.whoseTitle.is('Show/hide automation lanes').first.mouseClickElement({
                                      isShift: true,
                                      isOption: true,
                                  });
                              }
                              
                              main(); 
                              
                              1. Linus Gidstedt @Linus_Gidstedt
                                  2025-02-21 14:38:35.445Z

                                  I got it to work by adding a wait right before adding a new automation lane

                                  sf.wait({ intervalMs: 100 });
                                  
                                  if (i != laneSelectorNames.length - 1) {
                                   var addLnBtn = getAutomationLanes(track)
                                   sf.ui.proTools.mainWindow.invalidate().groups.whoseTitle.is(addLnBtn[i].title.value).first.buttons.whoseTitle.is("Add automation lane below this one").first.elementClick();
                                  }
                                  

                                  Is there a better way to handle this?

                                • In reply toRob_Byers:
                                  Linus Gidstedt @Linus_Gidstedt
                                    2025-02-21 14:54:46.151Z

                                    Another question: Is there a way to check if the plugin exists as an insert before trying to select automation lanes? And skip that track if it doesn't exist.