No internet connection
  1. Home
  2. Script Sharing

Session Sorting Script

By Gabriel Lundh @Gabriel_Lundh
    2021-02-15 10:53:14.812Z2021-05-25 11:25:07.376Z

    Hi!
    This script is done through compiling code together from this fantastic forum and it is highly adaptable to insert any prefered sorting or routing done to groups of tracks.
    It is calling a lot of the great packages found here as the Kitch Template collection, Andrew Scheps Session Prep and Chris Shaws Track Move script, so to make it work it needs some adjusting for your needs and of course to your desired workflow. This is just the beginning of the script, after these lines, I repeat the script for the next group of tracks like GTR, PERC, KEYS etc. (if any found). Hope it helps and gives some ideas to your own sorting scripts!

    See it in action here:
    https://vimeo.com/512461179/49ac36244f

    
    sf.ui.proTools.invalidate();
    sf.ui.proTools.appActivate();
    
    //Set views for PT Session using Kitch Memberys Template collection
    
    //Set Transport Controls
    
    sf.soundflow.runCommand({
        commandId: 'user:ckf5ufmkx0001hs10awq5qn8d:ckdti4p7g000ejw10bhbap4t4',
        props: {
            universe: "Disable",
            clipEffects: "Disable",
            trackList: "Enable",
            clipList: "Disable",
            mIDIEditor: "Disable",
            mIDIInputDisplay: "Disable",
            zoomControls: "Disable",
            transport: "Enable",
            mIDIControls: "Enable",
            synchronization: "Enable",
            abletonLink: "Disable",
            outputMeters: "Enable",
            expandedTransport: "Enable",
        }
    });
    
    // Set Edit Window View
    sf.soundflow.runCommand({
        commandId: 'package:ckhqsnlyq000c29106dfhgwjq',
        props: {
            viewComments: "Disable",
            viewMicPreamps: "Disable",
            viewInstruments: "Disable",
            viewInsertsAE: "Enable",
            viewInsertsFJ: "Enable",
            viewSendsAE: "Enable",
            viewSendsFJ: "Enable",
            viewIO: "Enable",
            viewObject: "Enable",
            viewRealTimeProperties: "Disable",
            viewTrackColor: "Enable",
            trackNumber: "Disable",
        }
    });
    
    //Drums sorting
    
    //Look for drum tracks 
    let namesToSelect = sf.ui.proTools.trackNames.filter(n => n.startsWith('DR_'));
    sf.ui.proTools.trackSelectByName({
        names: namesToSelect,
    });
    
    //If any drum tracks found, sort them.
    if (namesToSelect.length > 0) {
    
        //Set colour
        sf.ui.proTools.colorsSelect({
            colorNumber: 8,
        });
        
        //Make Group, Using Andrew Scehps Group Package
        sf.soundflow.runCommand({
        commandId: 'user:ckhtp21v40000w510c45vabx9:ckf4cv3ei000oy410dgixx1tu',
        props: {
            groupName: "DRMGRP",
            groupNumber: "4",
            letter: "a",
            createVCA: false,
        }
        });
    
        //Move the tracks to the place holder by calling Chris Shaws script, but edited with DRMSVCA as the specified track to move it to
        sf.soundflow.runCommand({
        commandId: 'package:ckk9qkdc80007qx10yyebxx8w',
        props: {}
        });
    
        // Assigning the VCA input
        var popupMenu = sf.ui.proTools.trackOpenListPopupMenu().popupMenu;
        popupMenu.menuClickPopupMenu({
        menuPath: ["Show Only", "VCA Masters"],
        });
    
        sf.ui.proTools.invalidate()
    
        sf.ui.proTools.appActivateMainWindow();
    
        sf.ui.proTools.trackGetByName({ name: "DRMSVCA", makeVisible: true }).track.trackScrollToView();
    
        sf.ui.proTools.selectedTrack.groups.whoseTitle.is('VCA IO').first.buttons.whoseTitle.startsWith('Group Assignment selector').first.popupMenuSelect({
        menuPath: ['4a - DRMGRP'],
        useWildcards: true,
        timeout: 10000,
        });
    
        sf.ui.proTools.trackListMenu({
        menuItemName: "Show All Tracks",
        });
        
    
    
    } else { //If no drum tracks found, make the place holder VCA inactive
        sf.ui.proTools.trackSelectByName({
        names: ["DRMSVCA"],
        });
        //Updates Pro Tools Menu items to avoid error
        sf.keyboard.press({ keys: 'left' });
    
        if (sf.ui.proTools.getMenuItem('Track', 'Make Inactive').exists) {
        sf.ui.proTools.trackSetActive({
            targetValue: "Disable",
        });
        }
    
    }
    
    sf.ui.proTools.invalidate()
    
    // Bas Sorting
    let namesToSelect = sf.ui.proTools.trackNames.filter(n => n.startsWith('BAS_'));
    sf.ui.proTools.trackSelectByName({
        names: namesToSelect,
    });
    
    if (namesToSelect.length > 0) {
        sf.ui.proTools.colorsSelect({
            colorNumber: 14,
        });
        
         sf.soundflow.runCommand({
        commandId: 'user:ckhtp21v40000w510c45vabx9:ckf4cv3ei000oy410dgixx1tu',
        props: {
            groupName: "BASSGRP",
            groupNumber: "4",
            letter: "b",
            createVCA: false,
        }
        });
    
        sf.soundflow.runCommand({
        commandId: 'package:ckk9qmjek0008qx10sw6h5obd',
        props: {}
        });
    
    
        var popupMenu = sf.ui.proTools.trackOpenListPopupMenu().popupMenu;
        popupMenu.menuClickPopupMenu({
        menuPath: ["Show Only", "VCA Masters"],
        });
    
    
        sf.ui.proTools.invalidate()
    
        sf.ui.proTools.trackGetByName({ name: "BASSVCA", makeVisible: true }).track.trackScrollToView();
    
        sf.ui.proTools.selectedTrack.groups.whoseTitle.is('VCA IO').first.buttons.whoseTitle.startsWith('Group Assignment selector').first.popupMenuSelect({
        menuPath: ['4b - BASSGRP'],
        useWildcards: true,
        timeout: 10000,
        });
    
        sf.ui.proTools.trackListMenu({
        menuItemName: "Show All Tracks",
        });
        
    
    } else {
        sf.ui.proTools.trackSelectByName({
        names: ["BASSVCA"],
        });
    
        sf.keyboard.press({ keys: 'left' });
    
        if (sf.ui.proTools.getMenuItem('Track', 'Make Inactive').exists) {
        sf.ui.proTools.trackSetActive({
            targetValue: "Disable",
        });
        }
      
    
    }
    • 14 replies

    There are 14 replies. Estimated reading time: 21 minutes

    1. Kris Crunk @Kris_Crunk
        2021-02-19 02:44:25.083Z

        This is great - this inspired me to use the code to find my instrument group tracks (DR_ ...etc) and I added that to a workflow I had been using with Raphael’s macros. I can have a session, that with just some labeling (working on automating that), it will group - label the group - color code - create routing folders - bring in my stem aux presets - that are routed out to my Track aux. With. One. Button.

        Working out a few things but excited about this one

        1. GGabriel Lundh @Gabriel_Lundh
            2021-02-19 10:14:02.855Z

            Wow, looks great Kris! Its such a time saver, and as you've done, one can add endless routing and sorting automation in this structure!
            The selection code is courtesy of the great Christian!

            All the best,
            Gabriel

          • In reply toGabriel_Lundh:

            Nice work!

            1. In reply toGabriel_Lundh:
              Kitch Membery @Kitch2021-02-23 00:57:14.582Z

              Nice one, @Gabriel_Lundh !!!

              1. T
                In reply toGabriel_Lundh:
                Thomas Gloor @Thomas_Gloor
                  2022-04-17 17:54:05.912Z

                  Hey @Gabriel_Lundh !

                  Thank you for sharing this. I'm in the process of building something similar and I have one little question regarding this part of the code.

                      //Move the tracks to the place holder by calling Chris Shaws script, but edited with DRMSVCA as the specified track to move it to
                      sf.soundflow.runCommand({
                      commandId: 'package:ckk9qkdc80007qx10yyebxx8w',
                      props: {}
                      });
                  

                  How did you edit @Chris_Shaw's script so it moves a specified track? Are we talking about the MOVE TRACKS command that is in the TRACK DATA UTILITIES package?

                  Best,

                  Thomas

                  1. GGabriel Lundh @Gabriel_Lundh
                      2022-04-17 19:51:16.519Z

                      Hi @Thomas_Gloor !
                      Glad you're building something similar - this script has helped me save so much time! Although, I would re-write it today when I have a lot more knowledge about scripting. Regarding Chris script - You can just have it in your script and then run

                      moveTracks("DRMGRP");
                      

                      Whenever you want it to be run. And you just change DRMGRP to the track you want it to move to.
                      The full script can be found here, although I take no credit for it - It is all @Chris_Shaw 's masterpiece.

                      sf.ui.proTools.appActivate();
                      sf.ui.proTools.invalidate();
                      sf.ui.proTools.menuClick({ menuPath: ["Options", "Link Track and Edit Selection"], targetValue: 'Enable' });
                      var inputTrackName;
                      var destinationTrack
                      function mainWindowStatus() {
                          if (sf.ui.proTools.getMenuItem('Window', 'Mix').isMenuChecked) {
                              sf.ui.proTools.menuClick({
                                  menuPath: ["Window", "Edit"],
                              });
                              return "Mix";
                          } else {
                              return "Edit";
                          }
                      }
                      
                      function returnToStartingMainWindow(mainWindow) {
                          switch (mainWindow) {
                              case "Mix":
                                  sf.ui.proTools.menuClick({
                                      menuPath: ["Window", "Mix"],
                                  });
                                  break;
                              case "Edit":
                                  break;
                          }
                      }
                      function showAllTracks() {
                          sf.ui.proTools.trackListMenu({
                              menuItemName: "Show All Tracks",
                          });
                      }
                      
                      function showOnlySelectedTracks() {
                          sf.ui.proTools.trackListMenu({
                              menuItemName: "Show Only Selected Tracks",
                          });
                      }
                      function deleteTempMemLocation() {
                          sf.ui.proTools.memoryLocationsShowWindow();
                          sf.ui.proTools.memoryLocationsWindow.popupButtons.whoseTitle.is('Memory Locations').first.popupMenuSelect({
                              menuSelector: items => items.filter(i => i.names[0].match(/^Clear \"/))[0]
                          });
                      }
                      function navigateTrack(direction) { // 'up' or 'down'
                          if (direction === 'up') {
                              sf.ui.proTools.menuClick({ menuPath: ["Edit", "Selection", "Extend Edit Up"], });
                              sf.ui.proTools.menuClick({ menuPath: ["Edit", "Selection", "Remove Edit from Bottom"], });
                          }
                          if (direction === 'down') {
                              sf.ui.proTools.menuClick({ menuPath: ["Edit", "Selection", "Extend Edit Down"], });
                              sf.ui.proTools.menuClick({ menuPath: ["Edit", "Selection", "Remove Edit from Top"], });
                          }
                      }
                      function getTrackIndex() {
                          var trackName = sf.ui.proTools.selectedTrackNames[0];
                          var visibleIndex = sf.ui.proTools.visibleTrackNames.indexOf(trackName);
                          return visibleIndex
                      }
                      function getDestinationTrack(MemLocation) {
                      
                          function selectDestinationTrack() {
                              let selectDestinationTrack = (sf.interaction.displayDialog({
                                  defaultButton: "OK",
                                  buttons: ["Top of Session", "Cancel", 'OK'],
                                  onCancel: 'Continue',
                                  prompt: "Select a destination track and click OK.\n \n(Your tracks will be moved below this track)",
                              })).button;
                      
                              if (selectDestinationTrack == null) {
                                  log("Please wait…", "Cleaning up");
                                  sf.ui.proTools.memoryLocationsGoto({
                                      memoryLocationNumber: +MemLocation
                                  });
                                  deleteTempMemLocation();
                                  throw 0;
                              } if (selectDestinationTrack == 'Top of Session') {
                                  return 'Top'
                      
                              } if (selectDestinationTrack == "OK")
                                  return sf.ui.proTools.selectedTrackNames;
                          }
                          var checkDestinationTrack = selectDestinationTrack();
                      
                          function checkForSingleDestinationTrack() {
                              while (checkDestinationTrack.length != 1) {
                                  if (checkDestinationTrack == 'Top') {
                                      break;
                                  }
                                  alert("Select a •SINGLE• track below which you'd like to move your tracks to then click ok")
                                  checkDestinationTrack = sf.ui.proTools.selectedTrackNames;
                              }
                              return checkDestinationTrack
                          }
                          var getDestinationTrack = checkForSingleDestinationTrack();
                      
                          return getDestinationTrack.slice()
                      }
                      
                      function createTempMemLoc() {
                          sf.ui.proTools.memoryLocationsShowWindow();
                      
                          sf.ui.proTools.memoryLocationsWindow.popupButtons.whoseTitle.is('Memory Locations').first.popupMenuSelect({
                              menuPath: ["New Memory Location..."],
                              targetValue: "Enable",
                          });
                          sf.ui.proTools.newMemoryLocationDialog.elementWaitFor();
                          sf.ui.proTools.newMemoryLocationDialog.radioButtons.whoseTitle.is('None').first.elementClick();
                          var cb = sf.ui.proTools.newMemoryLocationDialog.checkBoxes.whoseTitle
                          cb.is('Zoom Settings').first.checkboxSet({ targetValue: 'Disable' });
                          cb.is('Pre/Post Roll Times').first.checkboxSet({ targetValue: 'Disable' });
                          cb.is('Track Visibility').first.checkboxSet({ targetValue: 'Enable' });
                          cb.is('Track Heights').first.checkboxSet({ targetValue: 'Enable' });
                          cb.is('Group Enables').first.checkboxSet({ targetValue: 'Disable' });
                          cb.is('Window Configuration').first.checkboxSet({ targetValue: 'Disable' });
                          sf.keyboard.type({
                              text: "SF Temp",
                          });
                          sf.ui.proTools.newMemoryLocationDialog.textFields.whoseTitle.is('').allItems[2].elementClick();
                          sf.ui.proTools.menuClick({
                              menuPath: ["Edit", "Copy"],
                          });
                          sf.ui.proTools.newMemoryLocationDialog.buttons.whoseTitle.is('OK').first.elementClick();
                          return sf.clipboard.getText().text
                      }
                      
                      function getFirstTrackInSession() {
                          sf.ui.proTools.trackListMenu({
                              menuItemName: "Show All Tracks",
                          });
                          var getFirst = sf.ui.proTools.visibleTrackNames[0]
                          return getFirst
                      
                      }
                      
                      ///////////////////////////////////////////
                      ///////////////////////////////////////////
                      ////// M A I N  F U N C T I O N ///////////
                      ///////////////////////////////////////////
                      ///////////////////////////////////////////
                      
                      function moveTracks(destinationInput) {
                          inputTrackName = destinationInput
                          var startingWindow = mainWindowStatus();
                          var tracksToMove = sf.ui.proTools.selectedTrackNames.slice();
                          var tracksToMoveLength = tracksToMove.length;
                          var tempMemLocation = createTempMemLoc();
                          showAllTracks();
                          var moveTrackIndex = getTrackIndex();
                          if (inputTrackName == undefined) {
                              destinationTrack = getDestinationTrack(tempMemLocation)[0]
                          } else {
                              destinationTrack = inputTrackName;
                              sf.ui.proTools.trackSelectByName({names: [destinationTrack]})
                          }
                          var destinationTrackIndex = getTrackIndex();
                      
                          if (moveTrackIndex > destinationTrackIndex && destinationTrack != 'T') {
                              navigateTrack('down');
                              destinationTrack = sf.ui.proTools.selectedTrackNames[0];
                          }
                      
                          switch (destinationTrack) {
                              case 'T':
                                  destinationTrack = getFirstTrackInSession();
                                  break;
                          }
                          sf.ui.proTools.trackSelectByName({
                              names: [destinationTrack],
                              deselectOthers: true,
                          });
                      
                          sf.ui.proTools.trackSelectByName({
                              names: tracksToMove,
                              deselectOthers: false,
                          });
                      
                          showOnlySelectedTracks();
                          sf.ui.proTools.trackSelectByName({
                              names: tracksToMove,
                          });
                          var destinationIndex = getTrackIndex();
                      
                      
                          switch (destinationIndex) {
                              case 0:
                                  var dragDirection = 'down';
                                  break;
                              case 1:
                                  var dragDirection = 'up';
                                  break;
                          }
                      
                          // Drag Tracks
                          var tracksToMove = sf.ui.proTools.selectedTrackNames
                          var tracksToMoveLength = tracksToMove.length
                      
                          switch (dragDirection) {
                              case 'up':
                                  var trackToDragSelect = 0;
                                  sf.keyboard.press({
                                      keys: "home",
                                  });
                                  var a = -1, b = -20
                                  break;
                              case 'down':
                                  trackToDragSelect = tracksToMoveLength - 1;
                                  sf.keyboard.press({
                                      keys: "end",
                                  });
                                  var a = 1, b = 20
                                  break;
                          }
                          try {
                              var trackToDrag = tracksToMove[trackToDragSelect].slice()
                              function getNextTrack() {
                                  var trackName = trackToDrag;
                                  var visibleIndex = sf.ui.proTools.visibleTrackNames.indexOf(trackName);
                                  return sf.ui.proTools.visibleTracks.trackHeaders[visibleIndex + a];
                              }
                              sf.ui.proTools.trackSelectByName({
                                  names: [trackToDrag],
                              });
                              var thisButtonFrame = sf.ui.proTools.selectedTrack.titleButton.frame;
                              var nextTrack = getNextTrack();
                              var nextFrame = nextTrack.frame;
                              sf.ui.proTools.trackSelectByName({
                                  names: tracksToMove,
                              });
                              sf.mouse.simulateDrag({
                                  startPosition: { x: thisButtonFrame.x + thisButtonFrame.w / 2, y: thisButtonFrame.y + thisButtonFrame.h / 2 },
                                  endPosition: { x: thisButtonFrame.x + thisButtonFrame.w / 2, y: nextFrame.y + nextFrame.h / 2 + b }
                              });
                          }
                          catch (err) {
                              alert("Your destination is a Folder Track, \n inside a Folder Track, \n or a track being moved. \n \n Please try again.");
                          }
                          log("Please wait…", "Cleaning up")
                          sf.ui.proTools.memoryLocationsGoto({
                              memoryLocationNumber: +tempMemLocation
                          });
                      
                          deleteTempMemLocation();
                          returnToStartingMainWindow(startingWindow);
                      
                      
                      }
                      //To specify track without using dialog insert track name in the next 
                      //command between the parenthesis - moveTracks("Snare")
                      moveTracks("DRMGRP");
                      
                      

                      Good luck!
                      All the best,
                      Gabriel

                      1. TThomas Gloor @Thomas_Gloor
                          2022-04-17 20:31:04.960Z

                          Hey @Gabriel_Lundh !

                          Thank you so much for sharing this! Please excuse me as I'm really a begginer, but if I understood correctly.

                          . I could only copy this script from

                          ///////////////////////////////////////////
                          ///////////////////////////////////////////
                          ////// M A I N  F U N C T I O N ///////////
                          ///////////////////////////////////////////
                          ///////////////////////////////////////////
                          

                          and save it as a script that I would call in my own script then trigger the script by adding

                          moveTracks("DRMGRP");
                          

                          and it will drag the track, Am I right?

                          I had no idea it had so much going on under the hood!

                          Thank you!

                          1. GGabriel Lundh @Gabriel_Lundh
                              2022-04-18 08:05:35.520Z

                              Hi @Thomas_Gloor !
                              You need to copy the entire script located in my above post - and then in your own "main" script - with all the actions from the script - you can call the

                              moveTracks("DRMGRP");
                              

                              And it should do the trick!

                              Hope it helps!
                              All the best,
                              Gabriel

                              1. TThomas Gloor @Thomas_Gloor
                                  2022-04-18 14:37:48.724Z

                                  @Gabriel_Lundh thank you for the clarification. this script is AMAZING. Thanks to
                                  @Chris_Shaw for writing it!

                                  1. TThomas Gloor @Thomas_Gloor
                                      2022-04-19 10:48:00.548Z

                                      @Gabriel_Lundh

                                      The script is working perfectly, and it really helps my progress!

                                      I have a last question for you.

                                      I'd like to use it to move some auxes that are part of my template next to the KICK track and the same for the SNARE track. So here is the complication

                                      . Not all sessions have a kick (yup. weird isn't it). But when there is one it is ALWAYS called KICK. Maybe with a suffix, but there is always KICK in the beggining.
                                      . Is there a way to tell the script to look for a track that starts with KICK and move the selected tracks to it?
                                      . If there is no KICK track, I'd like the script to move the tracks elsewhere and then hide and incativate them.

                                      I'd like to do this for the snare aswell, but there is one more pickle. The backbeat isn't necessarily a SNARE. Can be Clap, Snap, Snare, Ping, whatever.
                                      . Is there a way to tell the script to look for several names (Snare, Clap, Snap...) and move the tracks to the first in the list?

                                      Thank you so much for your time.

                                      Best,

                                      T.

                                      1. TThomas Gloor @Thomas_Gloor
                                          2022-04-19 22:19:11.871Z

                                          @Gabriel_Lundh

                                          Do you think something like that is a good start?

                                          moveTracks("Kick");
                                          
                                          if (!"Kick") 
                                              throw `"This song has no kick!"`;
                                              sf.ui.proTools.trackHideAndMakeInactiveSelected();
                                              movetracks("Destination track of hidden/inactive tracks")
                                          
                                          else moveTracks("Kick");
                                          
                                          1. GGabriel Lundh @Gabriel_Lundh
                                              2022-04-27 14:35:53.801Z

                                              Hey @Thomas_Gloor !
                                              I would really like to help you here - but I have not had time to look at it yet.
                                              I'll try to do it soon, please bear with me!

                                              1. TThomas Gloor @Thomas_Gloor
                                                  2022-04-27 14:43:12.529Z

                                                  Hi @Gabriel_Lundh,

                                                  No problem. I'm progressing! Unfortunately I don't have access to soundflow now, but will post the solution I found later! Turns out it was easier that what I tought, because I could use a script by @raphaelsepulveda you'll find under this link:

                                                  I modified it a bit to make it an if/else statement, taking advantage of the detection of the prefix he implemented.

                                                  I hope this will be useful to someone! The session prep script I'm working on is pretty custom made to my template, but when done, I'll try to split it in parts and share it.

                                                  1. GGabriel Lundh @Gabriel_Lundh
                                                      2022-04-27 15:33:07.444Z

                                                      So glad to hear @Thomas_Gloor !
                                                      Would love to see the solution later!

                                                      All the best,
                                                      Gabriel