No internet connection
  1. Home
  2. How to

Script idea/help - cut regions according to marker name

By Nick Norton @notNickNorton
    2022-12-19 01:06:39.330Z

    Hi all, I have this idea that would make work super fast, but I have no idea if it's possible or even how to approach it.

    When I am cutting backgrounds, I have markers titled "BG in" or "BG out." I lay the BG sound across the whole scene, then tab through the markers putting a cut and my little two frame fades on each one.

    Is this something I can automate with SoundFlow? Like have it delete all the space in the region between each "BG out" and next "BG In", and then add the fades?

    Any ideas appreciated!

    • 9 replies
    1. Brenden @nednednerb
        2022-12-20 05:28:46.152Z

        I haven't tried to make a cleverish script, but this works for me to do exactly what I think you describe.

        sf.keyboard.press({
            keys: "backspace, comma, g, tab, tab, period, d",
        });
        

        When nudge is set to one frame, g and d make a one-frame fade, and the commas and tab navigate to put the cursor in the right place.

        First, you make a selection on a clip, then run the command. It deletes the selection and makes a single frame fade on the two new clip edges.

        EDIT: I read your post wrong. I thought BG out and BG in were just points selected. Moving the cursor to the markers is a more complicated thing. Someone more experienced than me can probably make quick work of this.

        1. Nick Norton @notNickNorton
            2022-12-20 16:57:31.257Z

            Oh that's a cool idea. I use something similar for my two frame fade ins and outs, but individually. Gonna mess with this!!

          • In reply tonotNickNorton:
            Brenden @nednednerb
              2022-12-20 17:50:53.943Z

              Ooooooh, Check THIS out:

              The script in the first post... The last line, switching the keyword "yadda" for "BG In" and copying to make a script for "BG Out" and running each script, navigates to the very next marker in the timeline with those names.

              As a result, that part is already completed! You can sort out hopefully what you would like to do in between those moves

              :-)

              1. Nick Norton @notNickNorton
                  2022-12-20 18:39:44.098Z2022-12-20 18:47:40.027Z

                  OH MAN OH MAN OH MAN!

                  This is literally gonna save an hour per episode.

                  I combined "find next BG out marker" using this, my already existing "cut - fade out", "find next BG in" and "fade in" and...I can just hit a shortcut for two minutes and silence BGs for interviews for an hour episode.

                  Any idea how to select a length of track and loop this script through it?

                  THANK YOU

                  1. Brenden @nednednerb
                      2022-12-20 23:01:57.455Z2022-12-21 01:04:25.539Z

                      Yah!

                      Great learning experience.... Try this::

                      
                      // This following function from samuel_henriques is the real genius of this script. I admit to putting it to use!!)
                      function findLocationNameMatch(locationName) {
                      
                          const mainCounter = sf.ui.proTools.getCurrentTimecode().stringValue
                          let cleanMainCounter = mainCounter.replace(/[ :\+\|.]/g,'').trim()
                          
                          //  if main counter is bars beats, remove last three digits, since memory locations list ignores them
                          mainCounter.match(/\|/) ? cleanMainCounter = cleanMainCounter.slice(0, -3) : null
                      
                      
                      
                          const memoryLocations = sf.proTools.memoryLocationsFetch().collection.list.filter(x =>
                              x.mainCounterValue.replace(/[ :\+\|.]/g,'').trim() > cleanMainCounter &&
                              x.name.match(locationName));
                      
                          try {
                              sf.ui.proTools.memoryLocationsGoto({
                                  memoryLocationNumber: memoryLocations[0].number
                              });
                          } catch (err) { log(`End of location markers containing:\n${locationName}`)
                                          let beforeLastBG = false }
                      };
                      
                      // This separates the clip at the cursor location
                      function clipSlice() {
                              
                              sf.ui.proTools.menuClick({
                                  menuPath: ["Edit","Separate Clip","At Selection"],
                              })
                      };
                      
                      // This function is simply the select previous clip keystroke and a backspace
                      function bgDelete() {
                          sf.keyboard.press({ keys: "alt+shift+tab, backspace", });
                      };
                      
                      // This combines above functions is the sequence which will loop in the "while" below
                      // Change the names of markers IMMEDIATELY BELOW if your session varies
                      function clearCurrentBG() {
                      
                              findLocationNameMatch("BG in");
                              clipSlice();
                              findLocationNameMatch("BG out");
                              clipSlice();
                              bgDelete();
                      };
                      
                      // Running the script below:
                      
                      sf.ui.proTools.appActivateMainWindow();
                      
                      // After triggering the script, this variable assumes a clip is selected in a timeline containing pairs of markers named "BG in" and "BG out"
                      let beforeLastBG = true
                      
                      // Loop the clearing the BGs until the last set of markers
                      while (beforeLastBG) {
                      
                        // Code to be executed indefinitely
                        clearCurrentBG()
                        // Exit the loop if a certain condition is met
                        if (!beforeLastBG) {
                          break;
                        }
                      };
                      
                      
                      1. Brenden @nednednerb
                          2022-12-20 23:03:13.287Z2022-12-20 23:45:56.341Z

                          It works whether you select one clip or two clips in one selection.... I tested.... :nice:

                          Actually! If there is already a clip separation inside the BG in and out, the first part of the clip up to that separation is not deleted but it proceeds to the next. Therefore, making a clip group or consolidation would be advisable!

                          1. Nick Norton @notNickNorton
                              2022-12-21 16:25:04.636Z

                              So the ins and outs were reversed, but otherwise it worked! I tweaked it a little, and got everything working to my liking (the way I do fades), and now the only problem is that it runs indefinitely instead of to the end of the selection. Mind taking a look?

                              // This following function from samuel_henriques is the real genius of this script. I admit to putting it to use!!)
                              function findLocationNameMatch(locationName) {
                              
                                  const mainCounter = sf.ui.proTools.getCurrentTimecode().stringValue
                                  let cleanMainCounter = mainCounter.replace(/[ :\+\|.]/g,'').trim()
                                  
                                  //  if main counter is bars beats, remove last three digits, since memory locations list ignores them
                                  mainCounter.match(/\|/) ? cleanMainCounter = cleanMainCounter.slice(0, -3) : null
                              
                              
                              
                                  const memoryLocations = sf.proTools.memoryLocationsFetch().collection.list.filter(x =>
                                      x.mainCounterValue.replace(/[ :\+\|.]/g,'').trim() > cleanMainCounter &&
                                      x.name.match(locationName));
                              
                                  try {
                                      sf.ui.proTools.memoryLocationsGoto({
                                          memoryLocationNumber: memoryLocations[0].number
                                      });
                                  } catch (err) { log(`End of location markers containing:\n${locationName}`)
                                                  let beforeLastBG = false }
                              };
                              
                              
                              // This separates the clip then makes the 2 frame fade out across the cursor location
                              function fadeOut() {
                                      
                                   sf.keyboard.press({
                                    keys: "numpad plus, numpad plus, b, numpad minus, s, numpad minus, numpad minus, g",
                                   });
                              
                              };
                              
                              // This makes the fade in to the next region of background
                              function fadeIn() {
                                         
                                  sf.keyboard.press({
                                  keys: "numpad minus, a, numpad plus, numpad plus, d",
                                  });
                                  
                              };
                              
                              
                              // This combines above functions is the sequence which will loop in the "while" below
                              // Change the names of markers IMMEDIATELY BELOW if your session varies
                              function clearCurrentBG() {
                              
                                      findLocationNameMatch("BG out");
                                      fadeOut();
                                      findLocationNameMatch("BG in");
                                      fadeIn();
                                      findLocationNameMatch("BG out");
                                      fadeOut();
                              };
                              
                              // Running the script below:
                              
                              sf.ui.proTools.appActivateMainWindow();
                              
                              // After triggering the script, this variable assumes a clip is selected in a timeline containing pairs of markers named "BG in" and "BG out"
                              let beforeLastBG = true
                              
                              // Loop the clearing the BGs until the last set of markers
                              while (beforeLastBG) {
                              
                                // Code to be executed indefinitely
                                clearCurrentBG()
                                // Exit the loop if a certain condition is met
                                if (!beforeLastBG) {
                                  break;
                                }
                              };
                              
                              
                      2. In reply tonotNickNorton:
                        Brenden @nednednerb
                          2022-12-21 21:19:27.689Z2022-12-21 23:47:23.615Z

                          Hi, I got this to work alright and not keep running, except it goes past my if statement and does not break. It runs to the last BG out and BG in on timeline instead of just the selection. Perhaps someone with more experience can chime in on why this script does not stop running. Why isn't the very last bit of code and the number comparison working?

                          code that didn't work deleted
                          

                          When I run this, my logged numbers show the one number is greater than the other, so it should be valid as far as I know, but it does not stop. It continues one more time.

                          EDIT: I changed the code since I first wrote this message. It is changed above. I'm still having issues. My log is now showing the comparison as now false at script end. In my testing, I have an additional two pairs of BG markers. There is one extra iteration, and then the script stops and does not run for the last pair of BG markers. I am unsure why it runs one extra time. If you were not dealing with any extra markers in a later clip, it would work for its purpose, but I want to know why I get one extra loop iteration, for my educational self-interest!

                          EDIT x 2: Got it to stop after exceeding the selection! It navigates to the next BG out marker but does NOT write the fade. I figured out including the conditional check inside the clearCurrentBG function:

                          // This following function from samuel_henriques is the real genius of this script. I admit to putting it to use!!)
                          function findLocationNameMatch(locationName) {
                          
                              const mainCounter = sf.ui.proTools.getCurrentTimecode().stringValue
                              let cleanMainCounter = mainCounter.replace(/[ :\+\|.]/g, '').trim()
                          
                              //  if main counter is bars beats, remove last three digits, since memory locations list ignores them
                              mainCounter.match(/\|/) ? cleanMainCounter = cleanMainCounter.slice(0, -3) : null
                          
                          
                              const memoryLocations = sf.proTools.memoryLocationsFetch().collection.list.filter(x =>
                                  x.mainCounterValue.replace(/[ :\+\|.]/g, '').trim() > cleanMainCounter &&
                                  x.name.match(locationName));
                          
                              try {
                                  sf.ui.proTools.memoryLocationsGoto({
                                      memoryLocationNumber: memoryLocations[0].number
                                  });
                              } catch (err) {
                                  log(`End of location markers containing:\n${locationName}`)
                                  let beforeLastBG = false
                              }
                          };
                          
                          
                          // This separates the clip then makes the 2 frame fade out across the cursor location
                          function fadeOut() {
                          
                              sf.keyboard.press({
                                  keys: "numpad plus, numpad plus, b, numpad minus, s, numpad minus, numpad minus, g",
                              });
                          
                          };
                          
                          // This makes the fade in to the next region of background
                          function fadeIn() {
                          
                              sf.keyboard.press({
                                  keys: "numpad minus, a, numpad plus, numpad plus, d",
                              });
                          
                          };
                          
                          // This combines above functions is the sequence which will loop in the "while" below
                          // Change the names of markers BELOW if your session varies
                          function clearCurrentBG() {
                          
                              findLocationNameMatch("BG out");
                              cursorLocation = Number(sf.ui.proTools.mainWindow.counterDisplay.mainCounter.value.invalidate().value.replace(/[ :\+\|.]/g, '').trim());
                              if (cursorLocation > bgSelectionEnd) { throw 0 };
                              fadeOut();
                              findLocationNameMatch("BG in");
                              fadeIn();
                          
                          };
                          
                          ///////!! Running the script below: !!///////
                          
                          sf.ui.proTools.appActivateMainWindow();
                          sf.ui.proTools.mainWindow.invalidate();
                          
                          // This gets selectionEnd end point in order to terminate when next BG in/out exceeds initial selection.
                          const bgSelectionEnd = Number(sf.ui.proTools.selectionGet().selectionEnd.replace(/[ :\+\|.]/g, '').trim());
                          let cursorLocation = Number(sf.ui.proTools.selectionGet().selectionStart.replace(/[ :\+\|.]/g, '').trim());
                          
                          // After triggering the script, this variable assumes a clip is selected in a timeline containing pairs of markers named "BG in" and "BG out"
                          let beforeLastBG = true
                          
                          // Loop the clearing the BGs until the last set of markers
                          do {
                              log("Loc " + cursorLocation); log("Sel End " + bgSelectionEnd); log(cursorLocation < bgSelectionEnd);
                              clearCurrentBG();
                          } while (cursorLocation < bgSelectionEnd);
                          
                          

                          Give this a whirl and let me know how it goes. This was fun, haha!

                          1. Brenden @nednednerb
                              2022-12-21 23:42:22.954Z

                              Maybe it would be better to place that cursorLocation inside the findLocationNameMatch() function itself. I didn't think of that until after, but I wanted to run that line every time the Location updated, which happens in that step when I call clearCurrentBG().

                              I also thought I might not want to change that function as it was otherwise good to go.