No internet connection
  1. Home
  2. How to

Script to automate volume automation dips.

By Daniel Lee @Daniel_Lee
    2020-03-11 08:02:01.015Z

    Hey guys!

    I just started my SF trial. Loving the functionalities and possibilities so far! However I’m a java noob so I’m looking forward to learning from you guys.

    Some of my work is for documentaries, so for a start i was thinking if it’s possible to create a script that dips the the volume automation of the DME bus under the VO?
    This will give me a good starting point and from there I can proceed to fine tune the automation as I go through my mix passes.

    If I were to list it out as steps, it will be something like this:

    1. Go to the VO track, and select the first clip.
    2. With the same edit selection, go to DME bus and bring down the volume automation by -6dB.
    3. Go to the start of the new volume node added create 2 other nodes 20 frames before and after.
    4. Delete original node (so the volume automation is a smooth fade of 40 frames).
    5. Repeat step 3 & 4 with the end node of step 2.
    6. Select the next clip on the VO track and repeat steps 2 - 6 until the end of the session.

    I've added a screenshot of how it should be. Do you guys think it’s possible?

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

    There are 11 replies. Estimated reading time: 18 minutes

    1. Hi Daniel

      Welcome aboard :)

      You've chosen a quite complicated workflow for your first thing to try out, so this script will probably not be an easy way to learn how to get started. So I wouldn't recommend this for trying to learn to script SF via Javascript - I would probably start with some simpler workflows.

      However - this script did the job for me on some initial testing.

      
      const DME_BUS_NAME = "a DME";
      const AUTOMATION_DIALOGS_ENABLED = true;
      const VOLUME = '-6';
      const FADE_SAMPLE_LENGTH = 76800; //40 frames at 25fps at 48 kHz
      
      function setVolume() {
          if (sf.ui.proTools.selectedTrack.outputWindowButton.value.invalidate().value !== 'open')
              sf.ui.proTools.selectedTrack.outputWindowButton.elementClick();
      
          var win = sf.ui.proTools.floatingWindows.allItems.filter(function (w) {
              return w.children.whoseTitle.is('Volume').exists;
          })[0];
      
          win.textFields.whoseTitle.is('Volume Numerical').first.elementClick();
          sf.keyboard.type({ text: VOLUME });
          sf.keyboard.press({ keys: 'enter' });
      
          sf.ui.proTools.automationWindow.writeAutoToSelectionButton.proToolsAutomationClickButton({ autoConfirmation: AUTOMATION_DIALOGS_ENABLED });
      }
      
      function processClip() {
          //Save the name of the originally selected track
          //And the selection
          var originalTrackName = sf.ui.proTools.selectedTrackNames[0];
          var selection = sf.ui.proTools.selectionGetInSamples();
      
          //Select the DME_BUS_NAME
          sf.ui.proTools.trackSelectByName({ names: [DME_BUS_NAME] });
      
          //Set the volume
          setVolume();
      
          //Make cut on left side
          sf.ui.proTools.selectionSetInSamples({
              selectionStart: selection.selectionStart - FADE_SAMPLE_LENGTH + 5,
              selectionEnd: selection.selectionStart + 5,
          });
          sf.ui.proTools.getMenuItem('Edit', 'Cut').elementClick();
      
          //Make cut on right side
          sf.ui.proTools.selectionSetInSamples({
              selectionStart: selection.selectionEnd - 5,
              selectionEnd: selection.selectionEnd + FADE_SAMPLE_LENGTH + 5,
          });
          sf.ui.proTools.getMenuItem('Edit', 'Cut').elementClick();
      
          //Select original selection
          sf.ui.proTools.selectionSetInSamples({
              selectionStart: selection.selectionStart,
              selectionEnd: selection.selectionEnd,
          });
      
          //Select original track again
          sf.ui.proTools.trackSelectByName({ names: [originalTrackName] });
      }
      
      function ensureSettings() {
          //Make sure we have 10 frames as nudge value
          sf.ui.proTools.nudgeSet({ value: '00:00:00:10.00' });
      
          //Make sure Preview is enabled
          sf.ui.proTools.automationPreview({ targetValue: 'Enable' }, "Couldn't enable Preview mode");
      
          //Make sure Volume is turned on in Automation Window
          if (sf.ui.proTools.automationWindow.enableVolumeAutoButton.value.invalidate().value !== "Selected")
              sf.ui.proTools.automationWindow.enableVolumeAutoButton.elementClick();
      
          //Make sure DME_BUS_NAME track is in touch mode
          var autoBtn = sf.ui.proTools.trackGetByName({ name: DME_BUS_NAME }).track.automationModeButton;
          if (autoBtn.value.invalidate().value !== "touch")
              autoBtn.popupMenuSelect({}, `Could not set track ${DME_BUS_NAME} to touch mode`);
      }
      
      function main() {
          ensureSettings();
      
          //Iterate through all selected clips
          sf.ui.proTools.clipDoForEachSelectedClip({
              action: processClip,
          });
          //processClip();
      }
      
      main();
      

      You should configure the script in the first few lines.
      Set the value of AUTOMATION_DIALOGS_ENABLED to true if you have warning dialogs for automation enabled, and to false if not.
      Choose the name of the DME bus in the first line.

      Again since this script is so fairly complicated, if it doesn't work it's going to be hard to service it, which is why I wouldn't necessarily start here - but if it can help you the way it is now that's great :)

      Reply2 LikesSolution
      1. DDaniel Lee @Daniel_Lee
          2020-03-11 17:31:13.193Z

          Hey Christian, Thanks so much for this! Really appreciate your help!

          Unfortunately it couldnt work for me. I spent quite a few hours trying to break the code down to have some of the functions run on its own just to see if it works. But yup i guess like what you said it's too complex for a beginner like myself. I guess this will be a project that I'll work towards.

          Thanks again! Looking forward to learning more and creating more scripts!

          1. Andrew Scheps @Andrew_Scheps
              2020-03-11 20:40:47.733Z2020-03-11 21:13:51.115Z

              I've made a few changes and this works great though I'm sure there are screw cases I'm not taking into account. I got a syntax error if I un-commented the original version that would do it for all selected clips. It complains that you can't have an action as the argument of sf.ui.proTools.clipDoForEachSelectedClip. Soooo, I came up with a very clumsy way of stepping through all the clips on a track by comparing the previous selectionStart with the current one and if they're the same bail on the script. It works but I'm sure there's a better way to do it.

              The other changes were adding the Number function to the selection start and end when doing math on it. Not sure why it would be happy with it standalone but not when you perform arithmetic, but there you go. Another thing I changed is the method for setting the track to Touch mode. I didn't recognise the one that was there and it was giving an error so I put in the possibly older, but functional one.

              Anyway, try this and see if it works!

              sf.ui.proTools.appActivateMainWindow();
              
              const DME_BUS_NAME = "a DME";
              const AUTOMATION_DIALOGS_ENABLED = true;
              const VOLUME = '-6';
              const FADE_SAMPLE_LENGTH = 76800; //40 frames at 25fps at 48 kHz
              
              function setVolume() {
                  if (sf.ui.proTools.selectedTrack.outputWindowButton.value.invalidate().value !== 'open')
                      sf.ui.proTools.selectedTrack.outputWindowButton.elementClick();
              
                  var win = sf.ui.proTools.floatingWindows.allItems.filter(function (w) {
                      return w.children.whoseTitle.is('Volume').exists;
                  })[0];
              
                  win.textFields.whoseTitle.is('Volume Numerical').first.elementClick();
                  sf.keyboard.type({ text: VOLUME });
                  sf.keyboard.press({ keys: 'enter' });
              
                  sf.ui.proTools.automationWindow.writeAutoToSelectionButton.proToolsAutomationClickButton({ autoConfirmation: AUTOMATION_DIALOGS_ENABLED });
              }
              
              function processClip() {
                  //Save the name of the originally selected track
                  //And the selection
                  var originalTrackName = sf.ui.proTools.selectedTrackNames[0];
                  var selection = sf.ui.proTools.selectionGetInSamples();
              
                  //Select the DME_BUS_NAME
                  sf.ui.proTools.trackSelectByName({ names: [DME_BUS_NAME] });
              
                  //Set the volume
                  setVolume();
              
                  //Make cut on left side
              
                  sf.ui.proTools.selectionSetInSamples({
                      selectionStart: Number(selection.selectionStart) - FADE_SAMPLE_LENGTH + 5, //CHANGED
                      selectionEnd: Number(selection.selectionStart) + 5, //CHANGED
                  });
                  sf.ui.proTools.getMenuItem('Edit', 'Cut').elementClick();
              
                  //Make cut on right side
                  sf.ui.proTools.selectionSetInSamples({
                      selectionStart: Number(selection.selectionEnd) - 5, //CHANGED
                      selectionEnd: Number(selection.selectionEnd) + FADE_SAMPLE_LENGTH + 5, //CHANGED
                  });
                  sf.ui.proTools.getMenuItem('Edit', 'Cut').elementClick();
              
                  //Select original selection
                  sf.ui.proTools.selectionSetInSamples({
                      selectionStart: selection.selectionStart,
                      selectionEnd: selection.selectionEnd,
                  });
              
                  //Select original track again
                  sf.ui.proTools.trackSelectByName({ names: [originalTrackName] });
              }
              
              function ensureSettings() {
                  //Make sure we have 10 frames as nudge value
                  sf.ui.proTools.nudgeSet({ value: '00:00:00:10.00' });
              
                  //Make sure Preview is enabled
                  sf.ui.proTools.automationPreview({ targetValue: 'Enable' }, "Couldn't enable Preview mode");
              
                  //Make sure Volume is turned on in Automation Window
                  if (sf.ui.proTools.automationWindow.enableVolumeAutoButton.value.invalidate().value !== "Selected")
                      sf.ui.proTools.automationWindow.enableVolumeAutoButton.elementClick();
              
                  //Make sure DME_BUS_NAME track is in touch mode
                  var autoBtn = sf.ui.proTools.trackGetByName({ name: DME_BUS_NAME }).track.automationModeButton;
                  if (autoBtn.value.invalidate().value !== "touch") { }
                  //autoBtn.popupMenuSelect({}, `Could not set track ${DME_BUS_NAME} to touch mode`);         //CHANGED
                  sf.ui.proTools.trackGetByName({ name: DME_BUS_NAME }).track.automationModeSet({             //CHANGED
                      automationModeName: "touch",                                                            //CHANGED
                  });                                                                                         //CHANGED
              }
              function main() {
                  ensureSettings();
                  // Select the first clip on the source track
                  sf.keyboard.press({
                      keys: "return, control+tab",
                  });
                  // Set up variables used to see if we've processed the last clip on the track
                  var currentSelectionStart = sf.ui.proTools.selectionGetInSamples().selectionStart;
              var previousSelectionStart = currentSelectionStart + 1;
                  // While the selection changes keep on trucking
                  while (currentSelectionStart !== previousSelectionStart) {
                      processClip();
                      previousSelectionStart = Number(currentSelectionStart);
                      sf.keyboard.press({
                          keys: "control+tab",
                      });
                      currentSelectionStart = sf.ui.proTools.selectionGetInSamples().selectionStart;
                  };
              
              }
              
              
              main();
              
              
              1. Thanks Andrew!

                I got a syntax error if I un-commented the original version that would do it for all selected clips. It complains that you can't have an action as the argument of sf.ui.proTools.clipDoForEachSelectedClip

                This is due to a beta bug, it's just reporting it wrong, it should work.
                But I like your approach as well, looks very clean.

                1. Andrew Scheps @Andrew_Scheps
                    2020-03-11 21:06:35.036Z

                    My method will break if the first clip starts at sample 0, so I should get the the start of the first clip into a variable and then initialize the other to that start time plus 1 before entering the while Loop. Editing the script now...

                    1. You should be able to set it to -1 and that potential bug would disappear

                      1. Andrew Scheps @Andrew_Scheps
                          2020-03-11 21:43:14.571Z

                          Ha, or that.

                          1. DDaniel Lee @Daniel_Lee
                              2020-03-12 08:48:40.216Z

                              IT WORKS!!

                              Thanks for your help & guiding me through this Christian & The Great Mr. Andrew Scheps! (PS: It was a pleasant surprise to see you on the forums, you are a huge inspiration!)

                              Thank you guys once again!!!

                    2. In reply toDaniel_Lee:

                      If it didn't work, here's the best way to get help in those cases:

                      • Tell us what you did (in this case for example, you assigned a trigger to the script, switched to Pro Tools, selected track X, made a selection, hit the trigger)
                      • Tell us what you expected to happen
                      • Tell us what did happen (this is the most crucial part)
                      • Possibly click the Log and show us the specific error that occured (click SF icon, drag left or click right blue dot, click Open Log File)

                      The more descriptive the steps, (imagine we'll have to repeat them to get the same result), the better.

                      In cases where it's hard to describe what happened, a quick screen recording is often helpful and can be faster than trying to explain.
                      For what did happen, avoid saying "it didn't work", and instead tell us for example "nothing happened" or "I got an error, the error was this: ...." or "the volume didn't switch to -6, it switched to -10" etc.

                      The more descriptive of the actual steps that you took, what you expected, and what actually happened, the quicker help you'll get :)
                      Again - welcome to the forum!

                      1. DDaniel Lee @Daniel_Lee
                          2020-03-12 09:01:15.156Z

                          Thanks Christian!

                          Got it! Will try to be more descriptive in future.

                          I just had a weird encounter. The first time i tried Andrew's script it ran perfectly, but after changing
                          const AUTOMATION_DIALOGS_ENABLED = false; to speed up the process since i had the warning suppressed, it stopped working (nothing was happening, nothing registering on the log as well).
                          I was trigging it by pressing the the script by pressing the "Run Command" key in the SF editor page.
                          But after doing a restart on the SF app the script is working well again.

                          Not sure if it's a bug or i had to press something to update the script. But anyway it works great now! I'll need to study and digest the script. Thank you guys.

                    3. U
                      In reply toDaniel_Lee:

                      Hello Guys

                      Amazing community here! Thanks for all the effort.

                      If I may raise a question here:

                      I am trying to make your script run, and before that i tried to make this script run: Script for quick volume automation dip

                      In both cases I seem to have the same problem: Whenever the script wants to press "Enter", it throws my selector to the start of the session instead of, lets say, confirming the new volume level. And therefore messing up the script. I looked around about "disabling" the return hotkey, but it seems not possible.
                      How is it that I encounter this and appearantely no one else?

                      Any help is appreciated, all the best

                      Markus