Script idea/help - cut regions according to marker name
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!
- Brenden @nednednerb
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.
Nick Norton @notNickNorton
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
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
:-)
Nick Norton @notNickNorton
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
Brenden @nednednerb
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; } };
Brenden @nednednerb
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!
Nick Norton @notNickNorton
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; } };
- In reply tonotNickNorton⬆:Brenden @nednednerb
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!
Brenden @nednednerb
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.