No internet connection
  1. Home
  2. How to

(Pro Tools) Code to apply macros to only highlighted track?

By Matt Cahill @Matt_Cahill
    2023-01-12 14:47:54.363Z

    Hi peeps,

    I am unsure exactly how to word this, I have made a simple macro to follow a command for dropping samples on the transient in Pro Tools, but is there a way to make it so I could highlight the audio track that I wanted the sample dropped too, and then it would automatically go through and do the dropping for me?

    the simple macro was basically "tab ; v p" as a way to skip along, dropping one sample at a time to an audio track underneath the original sample, but this involves sitting and pressing the button over and over again so would love to automate the process.

    thanks!

    Solved in post #7, click to view
    • 11 replies

    There are 11 replies. Estimated reading time: 15 minutes

    1. O

      Hey Matt,

      Here's a new working version that will run on all clips highlighted. A good rule of thumb with Soundflow is anytime you can use menu click instead of key presses your script will be a lot more robust. You can see here that I've swapped out the track navigation and the paste command from key presses to their associated menu clicks. Here's a quick video of the script in action, obviously be sure to load the appropriate sample into your clipboard before running.

      Here's the script:

      /// Kitch Code to Navigate up or down a selected ammount - Best way to avoid key presses for going up and down between tracks
      function navigateTrack({ direction, repetitions }) {
          for (let i = 0; i < repetitions; i++) {
              if (direction === 'Up') {
                  sf.ui.proTools.getMenuItem("Edit", "Selection", "Extend Edit Up").elementClick();
                  sf.ui.proTools.getMenuItem("Edit", "Selection", "Remove Edit from Bottom").elementClick();
              }
              if (direction === 'Down') {
                  sf.ui.proTools.getMenuItem("Edit", "Selection", "Extend Edit Down").elementClick();
                  sf.ui.proTools.getMenuItem("Edit", "Selection", "Remove Edit from Top").elementClick();
              }
          }
      }
      
      /// Paste Function - Use menu clicks whenever possible to avoid Key presses
      const pasteIt = () => sf.ui.proTools.menuClick({menuPath: ["Edit", "Paste"],});
      
      /// Key press full repacement -- This is your single script without key presses for stablity
      function processClip(){
          navigateTrack({direction : 'Down', repetitions : 1})
          pasteIt()
          navigateTrack({direction: 'Up', repetitions: 1})
      }
      
      /// Do to all clips -- this is how you package it to do it to all highlight clips
      sf.ui.proTools.clipDoForEachSelectedClip({
              action: processClip
          });
      

      Bests,
      Owen

      1. Chris Shaw @Chris_Shaw2023-01-12 20:48:06.526Z2023-01-17 16:33:01.813Z

        Hey @Owen_Granich_Young ,
        You script is good but I believe Matt wants to tab to each transient and paste for drum replacement. Your script replaces clips.

        This script will tab to transients and paste a sample to a destination track until it reaches the end of the audio in the source track

        function checkForSingleTrack(selectedTrack, sourceOrDest) {
            while (selectedTrack.length != 1) {
                alert(`Only one track can be used as a ${sourceOrDest} track. Please select one track and click OK`);
                selectedTrack = sf.ui.proTools.selectedTrackNames
            }
        }
        
        const tabToNextTransient = () => sf.keyboard.press({ keys: "tab" });
        
        /////////////
        // M A I N //
        /////////////
        
        sf.ui.proTools.appActivateMainWindow();
        sf.ui.proTools.mainWindow.invalidate();
        
        //Get Original Selection and tracks
        const originalSelection = sf.ui.proTools.selectionGetInSamples();
        const originallySelectedTracks = sf.ui.proTools.selectedTrackNames;
        
        //Instruct user to select source and destination tracks
        sf.interaction.displayDialog({
            title: "Select Source",
            prompt: `Before proceeding be sure to have copied your
        sample into the clipboard. Then select source
        track and click OK.
        
        Source track should be consolidated or else
        samples will be placed at clip boundaries.
        
        (You can copy sample and  consolidate 
        before clicking OK)`,
            buttons: ["Cancel", "OK"],
            defaultButton: "OK"
        });
        
        var sourceTrack = sf.ui.proTools.selectedTrackNames;
        
        // Verify that a single source track has been selected
        checkForSingleTrack(sourceTrack, "source")
        
        // Have user select destination track
        sf.interaction.displayDialog({
            title: "Destination Track",
            prompt: `Select destination track and hit OK.
        (Click on track title, not in the editor)`
        })
        
        var destinationTrack = sf.ui.proTools.selectedTrackNames;
        
        // // Verify that a single destination track has been selected
        // checkForSingleTrack(destinationTrack, "destination")
        
        //Check to make sure source and destination tracks are not the same
        // or verify that the user is pasting to multiple tracks
        var isDestinationConfirmed
        while (!isDestinationConfirmed) {
            if (destinationTrack[0] == sourceTrack[0] || destinationTrack.length != 1) {
                let answer = sf.interaction.displayDialog({
                    prompt: `You have either selected the same track for
        source and destination or have selected more
        than one destination track.
        
        If you are pasting to multiple tracks then the
        samples in your clipboard must match the
        number of tracks, track width, and track order
        you are pasting to - proceed with caution.
        
        If needed, reselect destinations tracks.
        
        Press OK to continue`,
                    buttons: ["Cancel", "OK"],
                    defaultButton: "OK"
                }).button
                isDestinationConfirmed = answer == "OK" ? true : false
            }
        }
        destinationTrack = sf.ui.proTools.selectedTrackNames
        //Reselect Source track
        sf.ui.proTools.trackSelectByName({ names: sourceTrack })
        
        //Ask if user want to paste samples for whole track or just selection
        var selectionAnswer = sf.interaction.displayDialog({
            title: "Selection Length",
            prompt: "Do you want to paste samples for the whole track or just your selection?",
            buttons: ["Cancel", "Selection", "Whole Track"],
            defaultButton: "Whole Track"
        }).button
        
        // Adjust selection based on answer
        if (selectionAnswer == "Whole Track") {
            // Get start and end times of audio on source track 
            sf.ui.proTools.menuClick({ menuPath: ["Edit", "Select All"] });
        }
        
        const allAudioSelection = sf.ui.proTools.selectionGetInSamples();
        const endOfAudio = allAudioSelection.selectionEnd;
        const startOfAudio = allAudioSelection.selectionStart;
        
        //Move edit cursor to beginning of audio
        sf.ui.proTools.selectionSetInSamples({ selectionStart: startOfAudio, selectionLength: 1 })
        
        //Reselect source track
        sf.ui.proTools.trackSelectByName({ names: sourceTrack })
        
        // Ensure Tab to Transient is enabled
        sf.ui.proTools.menuClick({ menuPath: ["Options", "Tab to Transient"], targetValue: "Enable" })
        
        // Ensure Link Track and Edit selection is enabled
        sf.ui.proTools.menuClick({ menuPath: ["Options", "Link Track and Edit Selection"], targetValue: "Enable" })
        
        var currentPosition = sf.ui.proTools.selectionGetInSamples().selectionStart
        
        // Tab to transient and paste as long as insert point is earlier than end of selection
        while (true) {
            tabToNextTransient();
        
            // Get current position of edit cursor
            currentPosition = sf.ui.proTools.selectionGetInSamples().selectionStart
        
            // check if cursor is at end of audio - stop if it is
            if (currentPosition >= endOfAudio) break;
        
            //If not at end of audio, paste sample in destination track
            sf.ui.proTools.trackSelectByName({ names: destinationTrack });
            sf.ui.proTools.menuClick({ menuPath: ["Edit", "Paste"] })
            sf.ui.proTools.trackSelectByName({ names: sourceTrack });
        }
        
        //Restore original selection
        sf.ui.proTools.selectionSetInSamples({
            selectionStart: originalSelection.selectionStart,
            selectionEnd: originalSelection.selectionEnd
        })
        
        //Reselect originally selected tracks
        sf.ui.proTools.trackSelectByName({ names: originallySelectedTracks })
        
        log("FINISHED!")
        1. Ohhh right, Tab to trans, I almost never have that in my world lol, makes way more sense!

          1. MMatt Cahill @Matt_Cahill
              2023-01-13 13:10:26.459Z

              @Owen_Granich_Young and @Chris_Shaw You guys are incredible! this is definitely going in the right direction, it doesn't seem to want to play nice yet though, it seems to not be picking up on the transients yet and is currently pasting to the source track, I have attached a video to show what happens, please let me know if it's my own ignorance in not using it correctly!

              1. ahh - your source is a stereo track - let me take another stab at it.

                1. Thanks for the video, it was helpful.
                  However, to use the script, you'll need to have "Link Track and Edit" enabled.
                  This is a common requirement for SF scripts.
                  I've made sure that it's enabled in the script above.
                  Let me know if there are any other issues.

                  //CS//

                  Reply1 LikeSolution
                  1. MMatt Cahill @Matt_Cahill
                      2023-01-13 17:06:33.602Z

                      Absolutely stunning, works perfectly, thank you so very much Chris you are an angel!

                      1. I made one more change to the script above:

                        Now it will ask if you want to paste samples for the whole track or just the selection
                        //CS//

                        1. In reply toChris_Shaw:
                          MMatt Cahill @Matt_Cahill
                            2023-01-17 12:06:13.762Z

                            Hi again Chris,

                            just run into a roadblock with this code that I hadn't considered until a moment ago, I completely forgot to factor in that I am usually dropping 2 or more kicks (grouped) on the transients, is there any way to make it so it drops to the group? at the moment it asks me to select one track to drop too,

                            cheers!

                            1. I reedited the code above to account for multiple sample / tracks.

                              When pasting to multiple tracks, the samples in your clipboard must match the destination tracks.
                              So if the samples in your clipboard are stereo, mono , and stereo then the destination tracks must have the same track width (stereo, mono, stereo). They don't have to be adjacent, just the same track width.

                              1. MMatt Cahill @Matt_Cahill
                                  2023-01-17 16:51:29.485Z

                                  Amazing, you are a literal wizard, thank you!