No internet connection
  1. Home
  2. Support

panning mono tacks to specific values in pro tools

By nick krill @nick_krill
    2020-08-22 21:56:01.392Z

    hi there,

    is it possible to make a script or macro to pan pro tools tracks to specific values? i saw the post about setting stereo values, but havn't been able to figure out a way to do mono tracks.

    my ideal end goal would be to have a few buttons set on a soundflow surface that could snap a selected track's pan to a handful of specific values i use regularly.

    thanks for any sugestions.

    -nick

    Solved in post #8, click to view
    • 13 replies

    There are 13 replies. Estimated reading time: 19 minutes

    1. Hi Nick.

      Can you link us to the thread you found? Then perhaps we can help adapt that script (we've got thousands of forum entries so can be hard to know which one you're referring to without a link).

      You may also be able to find inspiration in my package "Pro Tools Clip Panning" in the Store.

      1. Nnick krill @nick_krill
          2020-08-23 16:36:50.017Z

          Hi Christian,

          Thanks for the quick reply, sorry for not linking to the post i referenced.

          The stereo track script I was experimenting with is the first one mentioned in this post:

          https://forum.soundflow.org/-181

          I actually had a bit of trouble tweaking values on it though...if I set the pan value in the script to 38, when the script ran would put the pan at 35.

          I'll try to experiment with your clip pan package and see what I can come up with too. In the thread I linked to above, is that second script the same one that is found in your panning package?

          -nick

        • N
          In reply tonick_krill:
          nick krill @nick_krill
            2020-08-23 20:20:04.707Z2020-08-25 16:21:01.591Z

            Hi again Christian,

            I just figured out how to do this using UI automation! Got it working on mono tracks pretty smoothly.

            Here is a copy of my macro as a script (sorry I can't seem to figure out how to format it like the scripts other people post):

            sf.ui.proTools.appActivateMainWindow();
            
            sf.ui.proTools.selectedTrack.trackOutputToggleShow();
            
            sf.ui.proTools.mainTrackOutputWindow.textFields.whoseTitle.is('Front Pan Numerical').first.elementWaitFor();
            
            sf.ui.proTools.mainTrackOutputWindow.textFields.whoseTitle.is('Front Pan Numerical').first.elementClick();
            
            sf.keyboard.type({
                text: "-100",
            });
            
            sf.keyboard.press({
                keys: "numpad enter",
            });
            
            sf.ui.proTools.mainTrackOutputWindow.getElement('AXCloseButton').elementClick();
            
            sf.ui.proTools.mainTrackOutputWindow.groups.whoseTitle.is('LEAD_1 - Audio Track ').first.elementWaitFor({
                waitType: "Disappear",
            });
            

            Two quick follow up questions:

            • If the selected tracks output window is aready open, the toggle function closes it and the marco doesn't work. Are there any solutions for this?

            • Seems like with the above UI automation method i'll need to make separate macros for stereo or mono tracks. Is there a simple bit of code or macro to check if the track is mono or stereo first, and then decide which macro to run? So kinda one umbrella macro that would check track type and then trigger the appropriae actions?

            Sorry if these are basic questions that I should not be buggin you with (feel free to let me knwo if they are!!), I'm just begining to learn the world of macros and java.

            -nick

            1. Nnick krill @nick_krill
                2020-09-07 21:15:30.079Z

                Hi Everyone,

                I was able to make a script that will work on both mono and stereo tracks using an If / Else construct based on if SoundFlow sees a UI element that is only contained in a stereo track output window. Figured I'd share it here in case it is useful for anyone else. Also, this is my first script...so if anyone has any feedback on ways to clean it up, or make it smoother, I'm all ears.

                sf.ui.proTools.appActivateMainWindow();

                sf.ui.proTools.selectedTrack.trackOutputToggleShow();

                if (sf.ui.proTools.mainTrackOutputWindow.buttons.whoseTitle.is('Link').exists)

                {sf.ui.proTools.mainTrackOutputWindow.textFields.whoseTitle.is('Front Pan Numerical').first.elementWaitFor();

                /* sf.ui.proTools.mainTrackOutputWindow.buttons.whoseTitle.is('Link').first.elementClick(); */

                /* sf.ui.proTools.mainTrackOutputWindow.buttons.whoseTitle.is('Inverse Pan').first.elementClick(); */

                sf.ui.proTools.mainTrackOutputWindow.textFields.whoseTitle.is('Front Pan Numerical').first.elementClick();

                sf.keyboard.type({
                text: "-100",
                });

                sf.keyboard.press({
                keys: "numpad enter",
                });

                sf.ui.proTools.mainTrackOutputWindow.textFields.whoseTitle.is('Front Pan Numerical').allItems[1].elementClick();

                sf.keyboard.type({
                text: "100",
                });

                sf.keyboard.press({
                keys: "numpad enter",
                });

                sf.ui.proTools.mainTrackOutputWindow.getElement('AXCloseButton').elementClick();

                sf.ui.proTools.mainTrackOutputWindow.groups.whoseTitle.is('LEAD_1 - Audio Track ').first.elementWaitFor({
                waitType: "Disappear",
                });
                }

                else

                {
                sf.ui.proTools.mainTrackOutputWindow.textFields.whoseTitle.is('Front Pan Numerical').first.elementWaitFor();

                sf.ui.proTools.mainTrackOutputWindow.textFields.whoseTitle.is('Front Pan Numerical').first.elementClick();

                sf.keyboard.type({
                text: "-100",
                });

                sf.keyboard.press({
                keys: "numpad enter",
                });

                sf.ui.proTools.mainTrackOutputWindow.getElement('AXCloseButton').elementClick();

                sf.ui.proTools.mainTrackOutputWindow.groups.whoseTitle.is('LEAD_1 - Audio Track ').first.elementWaitFor({
                waitType: "Disappear",
                });
                }

                -nick

                PS - I still haven't been sucsessful in any of my attempts to make a script that checks to see if the Track Output window is already open. If anyone has some thoughts I'd love to hear em.

                1. Nnick krill @nick_krill
                    2020-09-07 21:33:37.919Z

                    Hi @chrscheuer,

                    Thanks for recomending your clip panning package..it did lead to some helpful discoveries.

                    In particular I found the follwing line that seems to check if the track output window is open,

                    if (sf.ui.proTools.selectedTrack.outputWindowButton.value.invalidate().value !== 'open')

                    I added this to my script, and it seemed to do the trick.

                    One quick follow up, rigth now in my script, it closes the track output window as the final step. Do you have any advice on a line of code that would leave the track output window open, if that window was already open when the script was triggered?

                    thanks,
                    nick

                    1. Hi Nick,
                      Great to see you had some progress with this.

                      You can store the open state in the beginning of your script with something like:

                      var wasOpen = sf.ui.proTools.selectedTrack.outputWindowButton.value.invalidate().value === 'open';
                      

                      Then in the bottom where you close it, make sure to not close it if it was open:

                      if (!wasOpen) {
                          //Only close it within this if
                      }
                      
                      1. Nnick krill @nick_krill
                          2020-09-16 21:35:56.026Z

                          Thanks for your help! This works great.

                          Here is an updated panning script in case it is ever useful to anyone else. In Pro Tools it allows for panning selected tracks that are either mono or stero to preset values using the pan in the track output window.

                          This version is for a 100% Left Pan on a mono track, or a symetrical 100% Left / Right pan on a stereo track. Change the pan values in the script to make whatever pan preset is useful.

                          sf.ui.proTools.appActivateMainWindow();
                          
                          var wasOpen = sf.ui.proTools.selectedTrack.outputWindowButton.value.invalidate().value === 'open';
                          
                          if (sf.ui.proTools.selectedTrack.outputWindowButton.value.invalidate().value !== 'open')
                             
                          
                          sf.ui.proTools.selectedTrack.trackOutputToggleShow();
                          
                          if (sf.ui.proTools.mainTrackOutputWindow.buttons.whoseTitle.is('Link').exists)
                          
                          {sf.ui.proTools.mainTrackOutputWindow.textFields.whoseTitle.is('Front Pan Numerical').first.elementWaitFor();
                          
                          /* sf.ui.proTools.mainTrackOutputWindow.buttons.whoseTitle.is('Link').first.elementClick(); */
                          
                          /* sf.ui.proTools.mainTrackOutputWindow.buttons.whoseTitle.is('Inverse Pan').first.elementClick(); */
                          
                          sf.ui.proTools.mainTrackOutputWindow.textFields.whoseTitle.is('Front Pan Numerical').first.elementClick();
                          
                          sf.keyboard.type({
                              text: "-100",
                          });
                          
                          sf.keyboard.press({
                              keys: "numpad enter",
                          });
                          
                          sf.ui.proTools.mainTrackOutputWindow.textFields.whoseTitle.is('Front Pan Numerical').allItems[1].elementClick();
                          
                          sf.keyboard.type({
                              text: "100",
                          });
                          
                          sf.keyboard.press({
                              keys: "numpad enter",
                          });
                          
                          if (!wasOpen) {
                          sf.ui.proTools.mainTrackOutputWindow.getElement('AXCloseButton').elementClick();
                          
                          sf.ui.proTools.mainTrackOutputWindow.groups.whoseTitle.is('LEAD_1 - Audio Track ').first.elementWaitFor({
                              waitType: "Disappear",
                          });}
                          
                          }
                          
                          
                          else
                          
                          
                          
                          
                          {
                          sf.ui.proTools.mainTrackOutputWindow.textFields.whoseTitle.is('Front Pan Numerical').first.elementWaitFor();
                          
                          sf.ui.proTools.mainTrackOutputWindow.textFields.whoseTitle.is('Front Pan Numerical').first.elementClick();
                          
                          sf.keyboard.type({
                              text: "-100",
                          });
                          
                          sf.keyboard.press({
                              keys: "numpad enter",
                          });
                          
                          
                          if (!wasOpen) {
                          sf.ui.proTools.mainTrackOutputWindow.getElement('AXCloseButton').elementClick();
                          
                          sf.ui.proTools.mainTrackOutputWindow.groups.whoseTitle.is('LEAD_1 - Audio Track ').first.elementWaitFor({
                              waitType: "Disappear",
                          });}
                          }
                          

                          -nick

                          Reply4 LikesSolution
                          1. DDaniel Knobler @Daniel_Knobler
                              2023-04-07 02:47:38.763Z

                              Any chance someone could modify this so that it gives a pop up and you can type in the pan value you'd like the track set to?

                              1. Brenden @nednednerb
                                  2023-04-08 18:27:02.671Z

                                  I will tell you how, but you can do the work ; )

                                  Change where relevant the

                                  sf.keyboard.type({
                                      text: "-100",
                                  });
                                  

                                  for example, to

                                  sf.keyboard.type({
                                      text: prompt("Enter your value for THIS STEP"),
                                  });
                                  

                                  That should be it. Maybe you have to make a variable just above the sf.keyboard.type line

                                  Such as:

                                  const leftPannerValue = prompt("Enter value for Left channel:");
                                  
                                  sf.keyboard.type({
                                       text: leftPannerValue,
                                  });
                                  
                      2. A
                        In reply tonick_krill:
                        Alex Gamble @Alex_Gamble
                          2021-06-21 21:50:52.834Z

                          Hey there! Trying to expand on this script and iterate this operation across several selected tracks. Is this possible somehow?

                          1. AAlex Gamble @Alex_Gamble
                              2021-06-21 22:27:48.509Z

                              Hey! Actually with some playing around, I got this to work myself.

                              Often I'm given a large volume of tracks that make up a single sound (group vocals, claps, stomps, etc). For size, I pan things off semi-randomly but for upwards of 20 tracks it's time consuming.

                              I expanded on this script to randomize the panning of a selection of tracks. The wait times is because sometimes it misses a mouse click when working so fast on so many tracks.

                              sf.ui.proTools.appActivateMainWindow();
                              
                              var tracks = sf.ui.proTools.selectedTrackHeaders;
                              var num_of_tracks = sf.ui.proTools.selectedTrackNames.length;
                              
                              for (var i = 0; i < num_of_tracks; i++) {
                              
                                  if (tracks[i].outputWindowButton.value.invalidate().value !== 'open')
                              
                                      tracks[i].trackOutputToggleShow();
                              
                                  sf.ui.proTools.mainTrackOutputWindow.textFields.whoseTitle.is('Front Pan Numerical').first.elementClick();
                              
                                  var randompan_left = -100 + Math.floor(Math.random() * 201);
                                  sf.wait({ intervalMs: 20 });
                                  var randompan_right = -100 + Math.floor(Math.random() * 201);
                                  sf.wait({ intervalMs: 20 });
                                  var rpl = randompan_left.toString();
                                  sf.wait({ intervalMs: 20 });
                                  var rpr = randompan_right.toString();
                                  sf.wait({ intervalMs: 20 });
                              
                                  sf.keyboard.type({ text: rpl, });
                                  sf.wait({ intervalMs: 20 });
                              
                                  sf.keyboard.press({ keys: "numpad enter", });
                                  sf.wait({ intervalMs: 20 });
                              
                                  if (sf.ui.proTools.mainTrackOutputWindow.buttons.whoseTitle.is('Link').exists) {
                              
                                      sf.ui.proTools.mainTrackOutputWindow.textFields.whoseTitle.is('Front Pan Numerical').allItems[1].elementClick();
                              
                                      sf.keyboard.type({ text: rpr, });
                                      sf.wait({ intervalMs: 20 });
                              
                                      sf.keyboard.press({ keys: "numpad enter", });
                                      sf.wait({ intervalMs: 20 });
                                  }
                              
                              }
                              
                            • J
                              In reply tonick_krill:
                              Joe Kearns @Joe_Kearns
                                2022-04-21 16:41:49.226Z

                                Hey Guys,

                                This is really great! Alex particular like the random panner element. I was wondering if you could help me make a version that takes the number of selected tracks and divides that by total pan values and spreads them evenly if that makes sense?

                                thanks so much in advance!
                                Joe.

                                1. J
                                  In reply tonick_krill:
                                  Joe Kearns @Joe_Kearns
                                    2022-04-22 13:18:02.983Z

                                    Here's where Ive got to with auto spread panner. Sometimes the roundup function seems to work and sometimes not? Any help much appreciated to make this more solid/effective etc please!
                                    Im also not sure how im applying the panning to the Stereo channels is the best way to do it but it does work....

                                    sf.ui.proTools.appActivateMainWindow();
                                    
                                    var tracks = sf.ui.proTools.selectedTrackHeaders;
                                    var num_of_tracks = sf.ui.proTools.selectedTrackNames.length;
                                    var originterval = Math.floor(200 / (num_of_tracks - 1));
                                    var interval = Math.floor(200 / (num_of_tracks - 1));
                                    var pan = Math.floor(-100 - originterval)
                                    
                                    for (var i = 0; i < num_of_tracks; i++) {
                                    
                                        if (tracks[i].outputWindowButton.value.invalidate().value !== 'open')
                                    
                                            tracks[i].trackOutputToggleShow();
                                    
                                        sf.ui.proTools.mainTrackOutputWindow.textFields.whoseTitle.is('Front Pan Numerical').first.elementClick();
                                    
                                        function round(x) {
                                            return Math.ceil(x / 5) * 5;
                                        }
                                    
                                        var pan1 = pan + interval;
                                        (round(pan1));
                                        sf.wait({ intervalMs: 20 });
                                    
                                        var pan2 = pan1
                                    
                                        sf.wait({ intervalMs: 20 });
                                    
                                        var pl = pan1.toString();
                                        sf.wait({ intervalMs: 20 });
                                        var pr = pan2.toString();
                                        sf.wait({ intervalMs: 20 });
                                    
                                    
                                        sf.keyboard.type({ text: pl, });
                                        sf.wait({ intervalMs: 20 });
                                    
                                        sf.keyboard.press({ keys: "numpad enter", });
                                        sf.wait({ intervalMs: 20 });
                                    
                                        var interval = Math.floor(originterval + interval);
                                    
                                    
                                        if (sf.ui.proTools.mainTrackOutputWindow.buttons.whoseTitle.is('Link').exists) {
                                    
                                            sf.ui.proTools.mainTrackOutputWindow.textFields.whoseTitle.is('Front Pan Numerical').allItems[1].elementClick();
                                    
                                            sf.keyboard.type({ text: pr, });
                                            sf.wait({ intervalMs: 20 });
                                    
                                            sf.keyboard.press({ keys: "numpad enter", });
                                            sf.wait({ intervalMs: 20 });
                                    
                                    
                                        }
                                    
                                    }
                                    
                                    

                                    thanks so much in advance