No internet connection
  1. Home
  2. How to

How do you extend the selection by 1 second on both sides of the selection?

By Danny @Danny_van_Spreuwel
    2020-07-24 17:52:12.084Z2020-07-25 22:40:02.422Z

    I guess you'll have to do that with the "Get Selection" action and then do JavaScript magic.

    (The solution has a bonus to extend the automation of a selection by 1 sec.)

    Solved in post #25, click to view
    • 33 replies

    There are 33 replies. Estimated reading time: 14 minutes

    1. Kitch Membery @Kitch2020-07-24 20:54:24.237Z

      Hi Danny,

      Can you explain your full workflow? As there may be a better way to achieve what you are after. The more detail the better. :-)

      Rock on!

      1. Danny @Danny_van_Spreuwel
          2020-07-24 20:59:02.394Z

          I have a selection. Most of the time this selection is made by double clicking a clip. To write automation with a bit of slack before and after the selection I extend the selection and then write the automation.

          1. Kitch Membery @Kitch2020-07-24 22:25:49.004Z

            I see.. One more quick question before I answer... Is your main counter set to "Mins:sec"?

            1. Kitch Membery @Kitch2020-07-24 22:31:31.046Z

              If your "Main Counter" is in Mins:Secs mode then this should do the trick;

              function extendSelection() {
                const originalSelection = sf.ui.proTools.selectionGet();
                const counterValue = sf.ui.proTools.mainWindow.counterDisplay.mainCounter.value.invalidate().value;
              
                let clipStartPoint = originalSelection.selectionStart;
                let clipEndtPoint = originalSelection.selectionEnd;
              
                function timeAdjust(selectionTime) {
                  let startTime = {
                    mins: selectionTime.split(':')[0],
                    secs: selectionTime.split(':')[1].split('.')[0],
                    ms: selectionTime.split('.')[1],
                  }
              
                  return {
                    start: startTime.mins + ':' + (Number(startTime.secs) - 1) + '.' + startTime.ms,
                    end: startTime.mins + ':' + (Number(startTime.secs) + 1) + '.' + startTime.ms,
                  }
                }
              
                sf.ui.proTools.selectionSet({
                  selectionStart: timeAdjust(clipStartPoint).start,
                  selectionEnd: timeAdjust(clipEndtPoint).end,
                });
              }
              
              extendSelection();
              
              1. Dustin Harris @Dustin_Harris
                  2020-07-25 03:00:08.597Z

                  Ohh that is lovely. .split(“:”)[x] is so much nicer than a bunch of .slice(x,y). I’ll be updating a bunch of scripts in the morning :)

                  1. In reply toKitch:
                    Danny @Danny_van_Spreuwel
                      2020-07-25 07:25:30.535Z

                      Wow. Thank you for this script. My main counter is set to TC. Does that make the calculation more complicated? I can image that subtracting 1 sec of a TC 01:00:00:00 would be a challenge.

                      1. Kitch Membery @Kitch2020-07-25 08:51:47.161Z

                        Yes and I think the same thing might occur in my script above. I did not think of that scenario. I may need a few days to think about it. Sorry bout that Danny.

                        1. Danny @Danny_van_Spreuwel
                            2020-07-25 09:02:22.857Z

                            No need for sorry. You already made a fantastic first draft in a zippy.

                            Maybe we need to use Pro Tools to do the time calculation. Meaning that we might need to skip the JavaScript and use keyboard keys to enter the selection fields. I thought it would be more safer to dive into JavaScript instead of the key simulations.

                            What I found, and also reported to the SoundFlow company, is that I think Pro Tools changed the way of working of the calculation method in the selection fields. The default "select between macros" action isn't working properly anymore in PT 2020.5. When entering a timecode in the selection field ("/") and use "+ 2 0 0 / " it doesn't automatically calculates anymore. You need to "enter" first and then go to the next field with "/". Unfortunately after the "enter" command the cursor exits the selection fields.

                            1. Andrew Scheps @Andrew_Scheps
                                2020-07-25 22:01:04.989Z

                                I have a feeling the better way to do this is check the session's sample rate and then you can easily add 1 second's worth of samples to either side of the selection no matter what time format you like to display. And if you always work at one sample rate then you can just set a constant and don't have to open the session setup window to look.

                                1. Kitch Membery @Kitch2020-07-25 22:06:50.741Z

                                  Good call!

                                  1. Andrew Scheps @Andrew_Scheps
                                      2020-07-25 22:10:38.487Z

                                      Something like:

                                      const oneSec = 48000;
                                      var selection = sf.ui.proTools.selectionGetInSamples();
                                      
                                      
                                          sf.ui.proTools.selectionSetInSamples({
                                              selectionStart: Number(selection.selectionStart) - oneSec,
                                              selectionEnd: Number(selection.selectionStart) + oneSec
                                          });
                                      
                                      1. Kitch Membery @Kitch2020-07-25 22:11:37.701Z

                                        Bam!!!!

                                        1. In reply toAndrew_Scheps:
                                          Kitch Membery @Kitch2020-07-25 22:14:51.355Z

                                          Small correction;

                                          The selectioinEnd was calculating from the selectionStart.

                                          const oneSec = 48000;
                                          var selection = sf.ui.proTools.selectionGetInSamples();
                                          
                                          
                                              sf.ui.proTools.selectionSetInSamples({
                                                  selectionStart: Number(selection.selectionStart) - oneSec,
                                                  selectionEnd: Number(selection.selectionEnd) + oneSec
                                              });
                                          
                                          1. Andrew Scheps @Andrew_Scheps
                                              2020-07-25 22:15:39.670Z

                                              Duh, thanks for fixing!

                                              1. Kitch Membery @Kitch2020-07-25 22:19:26.305Z

                                                Your global thinking solved the riddle!

                                              2. In reply toKitch:
                                                Danny @Danny_van_Spreuwel
                                                  2020-07-25 22:27:27.278Z2020-07-25 22:35:35.064Z

                                                  Kitch and Andrew, this is fantastic. Great work guys. My script of extending the selection and write automation would be something like this:

                                                  var selection = sf.ui.proTools.selectionGetInSamples();
                                                  
                                                  sf.keyboard.press({
                                                      keys: "shift+slash",
                                                  });
                                                  
                                                  sf.ui.proTools.selectionSetInSamples({
                                                      selectionStart: Number(selection.selectionStart) - oneSec,
                                                      selectionEnd: Number(selection.selectionEnd) + oneSec
                                                  });
                                                  
                                                  sf.ui.proTools.menuClick({
                                                      menuPath: ["Edit","Automation","Write to All Enabled"],
                                                  });
                                                  
                                                  sf.keyboard.press({
                                                      keys: "shift+slash",
                                                  });
                                                  1. Danny @Danny_van_Spreuwel
                                                      2020-07-25 22:28:19.142Z

                                                      Mmmm, how do you get that fancy code formatting in your post?

                                                      1. Kitch Membery @Kitch2020-07-25 22:32:12.702Z

                                                        Check this post regarding formatting.
                                                        https://forum.soundflow.org/-1468#post-9

                                                      2. Kitch Membery @Kitch2020-07-25 22:33:10.523Z

                                                        Nice one. What does "Shift+Slash" do?

                                                        1. Danny @Danny_van_Spreuwel
                                                            2020-07-25 22:34:15.075Z

                                                            It links and breaks the Timeline and Edit selection.

                                                            1. Kitch Membery @Kitch2020-07-25 22:38:13.022Z

                                                              Is it activating or deactivating the the "Link timeline and Edit Selection" in this script?

                                                              1. Danny @Danny_van_Spreuwel
                                                                  2020-07-25 22:42:46.868Z

                                                                  It's deactivating. Actually the shift-slash toggles this mode. In most cases the link is activated. Otherwise you need to check first what the status is of this function.

                                                                  1. Kitch Membery @Kitch2020-07-25 22:50:17.668Z2020-07-25 23:01:55.375Z

                                                                    Gotya! It's best to replace the key press with UI scripting for stability :-)

                                                                    So... To activate;

                                                                    const btn = sf.ui.proTools.mainWindow.cursorToolCluster.buttons.whoseTitle.is('Link Timeline and Edit Selection').first;
                                                                    
                                                                    //This will activate the button
                                                                    if (btn.value.invalidate().value !== 'Selected') {
                                                                      btn.elementClick();
                                                                    }
                                                                    

                                                                    &

                                                                    To inactive;

                                                                    const btn = sf.ui.proTools.mainWindow.cursorToolCluster.buttons.whoseTitle.is('Link Timeline and Edit Selection').first;
                                                                    
                                                                    
                                                                    //This will deactivate the button
                                                                    if (btn.value.invalidate().value === 'Selected') {
                                                                      btn.elementClick();
                                                                    }
                                                                    
                                                                    1. Danny @Danny_van_Spreuwel
                                                                        2020-07-25 23:06:48.543Z

                                                                        It's getting better and better. Here's the version with the UI element:

                                                                        const oneSec = 48000;
                                                                        const btn = sf.ui.proTools.mainWindow.groups.whoseTitle.is('Cursor Tool Cluster').first.buttons.whoseTitle.is('Link Timeline and Edit Selection').first;
                                                                        var selection = sf.ui.proTools.selectionGetInSamples();
                                                                        
                                                                        //Deactivate link Timeline and Edit selection
                                                                        if (btn.value.invalidate().value === 'Selected') {
                                                                          btn.elementClick();
                                                                        }
                                                                        
                                                                        sf.ui.proTools.selectionSetInSamples({
                                                                            selectionStart: Number(selection.selectionStart) - oneSec,
                                                                            selectionEnd: Number(selection.selectionEnd) + oneSec
                                                                        });
                                                                        
                                                                        sf.ui.proTools.menuClick({
                                                                            menuPath: ["Edit","Automation","Write to All Enabled"],
                                                                        });
                                                                        
                                                                        //Activate link Timeline and Edit selection
                                                                        if (btn.value.invalidate().value !== 'Selected') {
                                                                          btn.elementClick();
                                                                        }
                                                                        Reply1 LikeSolution
                                                                        1. Kitch Membery @Kitch2020-07-25 23:09:59.879Z

                                                                          Yes you got it! My most recent post just wraped it in a reusable function :-)

                                                                      • Kitch Membery @Kitch2020-07-25 23:08:29.288Z

                                                                        All together it should look like this (I've not tested it though);

                                                                        function writeToBufferedSelection() {
                                                                          const oneSec = 48000;
                                                                          const btn = sf.ui.proTools.mainWindow.cursorToolCluster.buttons.whoseTitle.is('Link Timeline and Edit Selection').first;
                                                                          const selection = sf.ui.proTools.selectionGetInSamples();
                                                                        
                                                                          if (btn.value.invalidate().value === 'Selected') {
                                                                            btn.elementClick();
                                                                          }
                                                                        
                                                                          sf.ui.proTools.selectionSetInSamples({
                                                                            selectionStart: Number(selection.selectionStart) - oneSec,
                                                                            selectionEnd: Number(selection.selectionEnd) + oneSec
                                                                          });
                                                                        
                                                                          sf.ui.proTools.menuClick({
                                                                            menuPath: ["Edit", "Automation", "Write to All Enabled"],
                                                                          });
                                                                        
                                                                          if (btn.value.invalidate().value !== 'Selected') {
                                                                            btn.elementClick();
                                                                          }
                                                                        }
                                                                        
                                                                        writeToBufferedSelection();
                                                                        
                                                                        1. Danny @Danny_van_Spreuwel
                                                                            2020-07-25 23:11:14.878Z

                                                                            You mean this function can be used in other SoundFlow scripts?

                                                                            1. Kitch Membery @Kitch2020-07-25 23:13:54.426Z

                                                                              Not quite... The function can be called multiple times by using the call ie writeToBufferedSelection(); but the function code still needs to live within the comand that you are using.

                                                                              1. Danny @Danny_van_Spreuwel
                                                                                  2020-07-25 23:17:12.853Z

                                                                                  Aha. Check. I was wondering how to make snippets of reusable codes. Can you call a script within a script?

                                                                                  1. Kitch Membery @Kitch2020-07-25 23:32:13.469Z

                                                                                    Yes you can do this by using a "Run Command" action from the "Macro Editor" by copying and pasting the "Command ID" you want to use from the Command menu in SoundFlow.

                                                                                    Then by clicking the "Copy as Javascript" ie "..." you can paste the code into the command you want to add it to.

                                                        2. In reply toKitch:
                                                          Dustin Harris @Dustin_Harris
                                                            2020-07-26 03:15:47.216Z

                                                            FWIW, I did make a function for adding and subtracting timecode.. I'm sure there is a slicker way to code it, but here it is if it helps anyone:

                                                            function timeCodeAddSubtract(time, offset) { //offset is whole number in seconds
                                                            
                                                                var hours = time.slice(0, 2);
                                                                var minutes = time.slice(3, 5);
                                                                var seconds = time.slice(6, 8);
                                                                var frames = time.slice(09, 11);
                                                            
                                                                seconds = (+seconds + +offset);
                                                                if (seconds < 0) {
                                                                    minutes = (+minutes - 1);
                                                                    seconds = (60 + seconds);
                                                                } else if (seconds >= 60) {
                                                                    minutes = (+minutes + 1);
                                                                    seconds = (seconds - 60);
                                                                }
                                                            
                                                                if (minutes < 0) {
                                                                    hours = (hours - 1);
                                                                    minutes = (60 + minutes);
                                                                } else if (minutes >= 60) {
                                                                    hours = (hours + 1);
                                                                    minutes = (minutes - 60);
                                                            
                                                                }
                                                            
                                                                seconds = String(seconds);
                                                                minutes = String(minutes);
                                                                hours = String(hours);
                                                            
                                                                function AddZeros(value) {
                                                            
                                                                    if (value.length == 1) value = String(`0${value}`);
                                                                    return value;
                                                                }
                                                            
                                                                seconds = AddZeros(seconds);
                                                                minutes = AddZeros(minutes);
                                                                hours = AddZeros(hours);
                                                            
                                                                var output = (`${hours}:${minutes}:${seconds}:${frames}`);
                                                                return output;
                                                            }
                                                            
                                                            1. Kitch Membery @Kitch2020-07-26 03:16:48.694Z

                                                              Great stuff!

                                                              1. Dustin Harris @Dustin_Harris
                                                                  2020-07-26 03:25:00.785Z

                                                                  ostensibly I could turn this:

                                                                      var hours = time.slice(0, 2);
                                                                      var minutes = time.slice(3, 5);
                                                                      var seconds = time.slice(6, 8);
                                                                      var frames = time.slice(9, 11);
                                                                  

                                                                  into this?

                                                                      var hours = time.split(':')[0];
                                                                      var minutes = time.split(':')[1];
                                                                      var seconds = time.split(':')[2];
                                                                      var frames = time.split(':')[3];
                                                                  

                                                                  (I should check if it throws a ';' in for drop frame though)