No internet connection
  1. Home
  2. How to

How to iterate through groups, selecting tracks to solo and waiting for Pro Tools to finish recording a series of stems

By Yujiro Yonetsu @Yujiro_Yonetsu
    2020-10-23 18:42:57.073Z2020-10-24 12:56:21.579Z

    I learned the following code

    function getGroup(name) {
        var groupList = sf.ui.proTools.mainWindow.tables.whoseTitle.contains('Group').first;
        return groupList.childrenByRole("AXRow").allItems.map(function (r) {
            return {
                row: r,
                selectBtn: r.childrenByRole("AXCell").first.children.first,
                name: r.childrenByRole("AXCell").allItems[1].children.first.title.value.match(/^.+ - ([^(]+)/)[1].replace(/ $/, ''),
            };
        }).filter(function (r) { return r.name == name })[0];
    }
    
    function selectGroup(name) {
        var grp = getGroup(name);
        if (!grp) { log('Error', 'Group "' + name + '" not found'); throw 0; }
        grp.selectBtn.mouseClickElement({});
    }
    
    selectGroup("AAAA");
    
    

    And after this I want to create a new playlist of tracks in the AAAA group, but it doesn't work.

    Please Help me

    Solved in post #16, click to view
    • 17 replies

    There are 17 replies. Estimated reading time: 18 minutes

    1. What have you tried?

      1. Yujiro Yonetsu @Yujiro_Yonetsu
          2020-10-23 19:00:24.747Z2020-10-24 12:56:09.041Z

          I tried the following script

          sf.ui.proTools.selectedTrack.trackScrollToView();
          sf.ui.proTools.selectedTrack.popupButtons.whoseTitle.is('Playlist selector').first.popupMenuSelect({
              menuPath: ["New..."],
          });
          
          
          sf.keyboard.press({
              keys: "numpad enter",
          });
          
          
          1. Can you be more specific in describing what doesn't work / what actually happens?

            Please follow this guide to learn how to best provide us with information that can help you:

            1. Yujiro Yonetsu @Yujiro_Yonetsu
                2020-10-24 12:38:39.792Z

                Sorry for the inconvenience.

                I would like to create a script that will automatically progress the recording of the stem mix.
                I create a group for each stem mix I want to separate in advance.

                1. Select only tracks that belong to a group
                2. Solo the selected track.
                3. Select the audio track for recording
                4. Create a new playlist of audio tracks for recording
                5. Naming (I'm fine with the default naming) , Enter.
                6. Call up the range selection markers.
                7. recording
                8. Wait for time of songs

                The plan is that multiple stems will be created automatically by repeating this action.

                now
                4. Create a new playlist of audio tracks for recording
                This behavior is not working.

                1. Yujiro Yonetsu @Yujiro_Yonetsu
                    2020-10-24 12:42:44.059Z2020-10-24 12:55:50.936Z

                    This is the script I'm currently working on.
                    Where is the problem?

                    function getGroup(name) {
                        var groupList = sf.ui.proTools.mainWindow.tables.whoseTitle.contains('Group').first;
                        return groupList.childrenByRole("AXRow").allItems.map(function (r) {
                            return {
                                row: r,
                                selectBtn: r.childrenByRole("AXCell").first.children.first,
                                name: r.childrenByRole("AXCell").allItems[1].children.first.title.value.match(/^.+ - ([^(]+)/)[1].replace(/ $/, ''),
                            };
                        }).filter(function (r) { return r.name == name })[0];
                    }
                    
                    function selectGroup(name) {
                        var grp = getGroup(name);
                        if (!grp) { log('Error', 'Group "' + name + '" not found'); throw 0; }
                        grp.selectBtn.mouseClickElement({});
                    }
                    
                    selectGroup("AAAA");
                    
                    sf.wait({
                        intervalMs: 30,
                    });
                    
                    sf.ui.proTools.selectedTrack.trackSetSolo();
                    
                    sf.wait({
                        intervalMs: 30,
                    });
                    
                    function getGroup(name) {
                        var groupList = sf.ui.proTools.mainWindow.tables.whoseTitle.contains('Group').first;
                        return groupList.childrenByRole("AXRow").allItems.map(function (r) {
                            return {
                                row: r,
                                selectBtn: r.childrenByRole("AXCell").first.children.first,
                                name: r.childrenByRole("AXCell").allItems[1].children.first.title.value.match(/^.+ - ([^(]+)/)[1].replace(/ $/, ''),
                            };
                        }).filter(function (r) { return r.name == name })[0];
                    }
                    
                    function selectGroup(name) {
                        var grp = getGroup(name);
                        if (!grp) { log('Error', 'Group "' + name + '" not found'); throw 0; }
                        grp.selectBtn.mouseClickElement({});
                    }
                    
                    selectGroup("StemRecTrack");
                    
                    
                    sf.ui.proTools.selectedTrack.trackScrollToView();
                    sf.ui.proTools.selectedTrack.popupButtons.whoseTitle.is('Playlist selector').first.popupMenuSelect({
                        menuPath: ["New..."],
                    });
                    
                    
                    sf.keyboard.press({
                        keys: "numpad enter",
                    });
                    
                    
                    sf.ui.proTools.memoryLocationsGoto({
                        memoryLocationNumber: 325,
                    });
                    
                    
                    sf.keyboard.press({
                        keys: "f12",
                    });
                    
                    
                    
                    sf.wait({
                        intervalMs: 180000,
                    });
                    
                    
                    
                    1. This is good progress!

                      Couple of things:

                      You don't need to define the functions twice, you can get rid of the 2nd time this is in your script:

                      function getGroup(name) {
                          var groupList = sf.ui.proTools.mainWindow.tables.whoseTitle.contains('Group').first;
                          return groupList.childrenByRole("AXRow").allItems.map(function (r) {
                              return {
                                  row: r,
                                  selectBtn: r.childrenByRole("AXCell").first.children.first,
                                  name: r.childrenByRole("AXCell").allItems[1].children.first.title.value.match(/^.+ - ([^(]+)/)[1].replace(/ $/, ''),
                              };
                          }).filter(function (r) { return r.name == name })[0];
                      }
                      
                      function selectGroup(name) {
                          var grp = getGroup(name);
                          if (!grp) { log('Error', 'Group "' + name + '" not found'); throw 0; }
                          grp.selectBtn.mouseClickElement({});
                      }
                      

                      The second thing is, you're using keyboard simulation to press enter. I would instead suggest using UI automation.
                      You can learn more about how to use UI automation instead of keyboard simulation in the following 2 videos:

                      1. Instead of using a manual wait time of 3 minutes, you should consider adding a while loop that waits until Pro Tools is no longer playing.

                        1. Yujiro Yonetsu @Yujiro_Yonetsu
                            2020-10-24 14:51:25.059Z

                            Thanks. Using UI automation based on your advice is working out well for me!

                            It seems to work fine for one lap.
                            I'd really want to follow your advice and include a script that starts the next action when Protools stops.
                            How do that?

                            1. You should be able to use something like this:

                              
                              function waitUntilProToolsStopsPlaying() {
                                  while (true) {
                              
                                      sf.engine.checkForCancellation();
                              
                                      if (!sf.ui.proTools.isPlaying)
                                          break;
                              
                                      sf.wait({ intervalMs: 500 });
                                  }
                              }
                              
                              waitUntilProToolsStopsPlaying();
                              
                              1. Yujiro Yonetsu @Yujiro_Yonetsu
                                  2020-10-24 15:18:29.891Z

                                  Thank you!

                                  My life is already very, very happy.

                                  If I had to include more hope, I would say
                                  Now it's going to be [AAAA], [BBBB], [CCCC], and increasing for every stem I want to create.

                                  I used to think of it this way until yesterday. 'I'll just make the basic script up to [GGGG].'

                                  But is it possible that this number of times can also be derived from the circumstances of the session?

                                  For example, if the number is small, the script may end at [CCCC], or if
                                  In other cases, when there are a large number of them, it seems to last until [MMMMM]...

                                  1. can also be derived from the circumstances of the session

                                    How should it calculate this? Can you give an example on how it could know the number of stems? Is there a specific naming pattern of tracks that we could use as the basis?

                                    1. Yujiro Yonetsu @Yujiro_Yonetsu
                                        2020-10-24 15:41:11.013Z

                                        So, let's name the group.
                                        01_Stem
                                        02_Stem
                                        03_Stem
                                        04_Stem
                                        What if I only let the first number add up, as in

                                        1. In that case, you could use something like this to get the number:

                                          function getGroupsContaining(name) {
                                              var groupList = sf.ui.proTools.mainWindow.tables.whoseTitle.contains('Group').first;
                                              return groupList.childrenByRole("AXRow").allItems.map(function (r) {
                                                  return {
                                                      name: r.childrenByRole("AXCell").allItems[1].children.first.title.value.match(/^.+ - ([^(]+)/)[1].replace(/ $/, ''),
                                                  };
                                              }).filter(function (r) { return r.name.includes(name) });
                                          }
                                          
                                          let numberOfStems = getGroupsContaining('_Stem').length;
                                          
                                          

                                          Now that you'll then have the number of stems in a number, you could use a for loop to loop code X number of times:

                                          for (let i=0; i<numberOfStems; i++) {
                                              //Insert the code to repeat in here
                                          }
                                          
                                          1. Yujiro Yonetsu @Yujiro_Yonetsu
                                              2020-10-24 15:46:50.391Z

                                              Thank you

                                              This is what the code looks like for the one lap I just finished, but where do I put the code I was just taught?

                                              function getGroup(name) {
                                                  var groupList = sf.ui.proTools.mainWindow.tables.whoseTitle.contains('Group').first;
                                                  return groupList.childrenByRole("AXRow").allItems.map(function (r) {
                                                      return {
                                                          row: r,
                                                          selectBtn: r.childrenByRole("AXCell").first.children.first,
                                                          name: r.childrenByRole("AXCell").allItems[1].children.first.title.value.match(/^.+ - ([^(]+)/)[1].replace(/ $/, ''),
                                                      };
                                                  }).filter(function (r) { return r.name == name })[0];
                                              }
                                              
                                              function selectGroup(name) {
                                                  var grp = getGroup(name);
                                                  if (!grp) { log('Error', 'Group "' + name + '" not found'); throw 0; }
                                                  grp.selectBtn.mouseClickElement({});
                                              }
                                              
                                              selectGroup("01_Stem");
                                              
                                              sf.wait({
                                                  intervalMs: 30,
                                              });
                                              
                                              
                                              sf.ui.proTools.appActivateMainWindow();
                                              
                                              sf.ui.proTools.mainWindow.counterDisplay.mouseClickElement({
                                                  relativePosition: { x: 299, y: 67 }
                                              });
                                              sf.keyboard.press({ keys: 'shift+s' });
                                              
                                              sf.wait({
                                                  intervalMs: 30,
                                              });
                                              
                                              
                                              selectGroup("StemRecTrack");
                                              
                                              sf.wait({
                                                  intervalMs: 30,
                                              });
                                              
                                              
                                              sf.ui.proTools.selectedTrack.trackScrollToView();
                                              sf.ui.proTools.selectedTrack.popupButtons.whoseTitle.is('Playlist selector').first.popupMenuSelect({
                                                  menuPath: ["New..."],
                                              });
                                              
                                              
                                              sf.wait({
                                                  intervalMs: 50,
                                              });
                                              
                                              
                                              sf.ui.proTools.windows.whoseTitle.is('').first.buttons.whoseTitle.is('OK').first.elementClick();
                                              
                                              
                                              sf.ui.proTools.memoryLocationsGoto({
                                                  memoryLocationNumber: 325,
                                              });
                                              
                                              
                                              sf.wait({
                                                  intervalMs: 50,
                                              });
                                              
                                              
                                              sf.ui.proTools.mainWindow.groups.whoseTitle.is('Transport View Cluster').first.groups.whoseTitle.is('Normal Transport Buttons').first.buttons.whoseTitle.is('Record Enable').first.elementClick();
                                              
                                              sf.ui.proTools.mainWindow.groups.whoseTitle.is('Transport View Cluster').first.groups.whoseTitle.is('Normal Transport Buttons').first.buttons.whoseTitle.is('Play').first.elementClick();
                                              
                                              
                                              
                                              
                                              
                                              function waitUntilProToolsStopsPlaying() {
                                                  while (true) {
                                              
                                                      sf.engine.checkForCancellation();
                                              
                                                      if (!sf.ui.proTools.isPlaying)
                                                          break;
                                              
                                                      sf.wait({ intervalMs: 500 });
                                                  }
                                              }
                                              
                                              waitUntilProToolsStopsPlaying();
                                              
                                              
                                              
                                              1. You could rearrange things like this:

                                                
                                                function getGroup(name) {
                                                    var groupList = sf.ui.proTools.mainWindow.tables.whoseTitle.contains('Group').first;
                                                    return groupList.childrenByRole("AXRow").allItems.map(function (r) {
                                                        return {
                                                            row: r,
                                                            selectBtn: r.childrenByRole("AXCell").first.children.first,
                                                            name: r.childrenByRole("AXCell").allItems[1].children.first.title.value.match(/^.+ - ([^(]+)/)[1].replace(/ $/, ''),
                                                        };
                                                    }).filter(function (r) { return r.name == name })[0];
                                                }
                                                
                                                function selectGroup(name) {
                                                    var grp = getGroup(name);
                                                    if (!grp) { log('Error', 'Group "' + name + '" not found'); throw 0; }
                                                    grp.selectBtn.mouseClickElement({});
                                                }
                                                
                                                function waitUntilProToolsStopsPlaying() {
                                                    while (true) {
                                                
                                                        sf.engine.checkForCancellation();
                                                
                                                        if (!sf.ui.proTools.isPlaying)
                                                            break;
                                                
                                                        sf.wait({ intervalMs: 500 });
                                                    }
                                                }
                                                
                                                function getGroupsContaining(name) {
                                                    var groupList = sf.ui.proTools.mainWindow.tables.whoseTitle.contains('Group').first;
                                                    return groupList.childrenByRole("AXRow").allItems.map(function (r) {
                                                        return {
                                                            name: r.childrenByRole("AXCell").allItems[1].children.first.title.value.match(/^.+ - ([^(]+)/)[1].replace(/ $/, ''),
                                                        };
                                                    }).filter(function (r) { return r.name.includes(name) });
                                                }
                                                
                                                function makeStem(stemName) {
                                                    selectGroup(stemName);
                                                
                                                    sf.wait({
                                                        intervalMs: 30,
                                                    });
                                                
                                                    sf.ui.proTools.appActivateMainWindow();
                                                
                                                    sf.ui.proTools.mainWindow.counterDisplay.mouseClickElement({
                                                        relativePosition: { x: 299, y: 67 }
                                                    });
                                                    sf.keyboard.press({ keys: 'shift+s' });
                                                
                                                    sf.wait({
                                                        intervalMs: 30,
                                                    });
                                                
                                                    selectGroup("StemRecTrack");
                                                
                                                    sf.wait({
                                                        intervalMs: 30,
                                                    });
                                                
                                                    sf.ui.proTools.selectedTrack.trackScrollToView();
                                                    sf.ui.proTools.selectedTrack.popupButtons.whoseTitle.is('Playlist selector').first.popupMenuSelect({
                                                        menuPath: ["New..."],
                                                    });
                                                
                                                    sf.wait({
                                                        intervalMs: 50,
                                                    });
                                                
                                                    sf.ui.proTools.windows.whoseTitle.is('').first.buttons.whoseTitle.is('OK').first.elementClick();
                                                
                                                    sf.ui.proTools.memoryLocationsGoto({
                                                        memoryLocationNumber: 325,
                                                    });
                                                
                                                    sf.wait({
                                                        intervalMs: 50,
                                                    });
                                                
                                                    sf.ui.proTools.mainWindow.groups.whoseTitle.is('Transport View Cluster').first.groups.whoseTitle.is('Normal Transport Buttons').first.buttons.whoseTitle.is('Record Enable').first.elementClick();
                                                
                                                    sf.ui.proTools.mainWindow.groups.whoseTitle.is('Transport View Cluster').first.groups.whoseTitle.is('Normal Transport Buttons').first.buttons.whoseTitle.is('Play').first.elementClick();
                                                
                                                    waitUntilProToolsStopsPlaying();
                                                }
                                                
                                                function main() {
                                                    let stemGroupNames = getGroupsContaining('_Stem').map(g => g.name);
                                                
                                                    stemGroupNames.forEach(makeStem);
                                                }
                                                
                                                main();
                                                
                                                ReplySolution
                                                1. Yujiro Yonetsu @Yujiro_Yonetsu
                                                    2020-10-24 16:05:22.616Z

                                                    This is Perrrrrrrrfect!!!!!!!!!!!!!!!

                                                    Thank you!

                                                    1. In reply tochrscheuer:
                                                      TThomas Gloor @Thomas_Gloor
                                                        2022-07-15 22:39:14.668Z

                                                        Hey @chrscheuer ! I hope you're well.

                                                        I'm struggling to find a way to determine a track's group assignements.

                                                        Is there a way to do such a thing?

                                                        Best,
                                                        T.