How to process multiple clips via Defaulter plugin
@poterukha, this script should get you started:
function processClip() {
sf.engine.checkForCancellation();
var defaulterAsWin = sf.ui.proTools.getAudioSuiteWindow('Defaulter');
if (!defaulterAsWin || !defaulterAsWin.exists) throw 'Please open Defaulter plugin first';
defaulterAsWin.buttons.whoseTitle.is('Analyze').first.elementClick();
}
sf.ui.proTools.clipDoForEachSelectedClip({
action: processClip,
});
Vladimir @poterukhaI’ve been busy these days, I can try it tomorrow
Christian Scheuer @chrscheuer2019-03-14 20:16:01.087ZNo worries :) All in your own time - I just got really excited about this feature request!
In reply tochrscheuer⬆:Christian Scheuer @chrscheuer2019-03-15 00:03:18.883ZPreliminary support for a Clip Leveler app is coming:

samuel henriques @samuel_henriqueshello, is this available in the store?
I made a script that adjusts clip gain to a designated maximum volume, but can't find a way to get the volume of the selected clip. And searching the forum I found this.
Thank you
Christian Scheuer @chrscheuer2020-11-18 11:41:45.172ZHi Samuel
This is not currently public, no.
- NIn reply tochrscheuer⬆:N Leyers @NickLeyers_old_acc
Awesome!
Maybe you can implement the BS1770 loudness as a target into this? I would use the sample peaks more to avoid clipping.Will this nudge the clip gain step by step as the defaulter does?
Another solution can be to automate the volume track first (like in latch mode) and then convert the volume automation to clip gain. That will speed up the proces.- In reply toNickLeyers_old_acc⬆:
Christian Scheuer @chrscheuer2019-03-15 20:27:33.975ZThat's exactly what we do :)
- In reply toNickLeyers_old_acc⬆:
Christian Scheuer @chrscheuer2019-03-15 20:34:43.072ZAnd yes BS1770 / EBU-R128 etc. would be great to get implemented.
In reply tochrscheuer⬆:Vladimir @poterukhaI have updated to 2.1.3pr6 today and "checkForCancellation" is underlined with red in this build
Christian Scheuer @chrscheuer2019-03-15 19:54:35.616ZRight, @poterukha, my apologies. That's a 2.2 feature. You can just skip that line for now.
Vladimir @poterukhaI've tried a little bit the script without checkForCancellation, everything working just fine but sometimes I receive this error message at the end:
16.03.2019 13:27:34.12 [Backend]: Logging error in action (01) DoMainCounterAction: Selecting a full clip failed
Error in action (00) DoForEachClipAction: DoMainCounterAction
Error in action (00) DoForEachSelectedClipAction: DoMainCounterAction16.03.2019 13:27:34.12 [Backend]: Script error at line 11
Selecting a full clip failed (DoMainCounterAction)16.03.2019 13:27:34.12 [BackendConnection]: Received msg from backend: { name: '/commands/error',
args:
{ command: 'user:default:cjta1pa4g00006310928ezx2n',
commandName: 'Defaulter Test',
error:
'Script error at line 11\n Selecting a full clip failed (DoMainCounterAction)\n' } }
16.03.2019 13:27:34.37 [Backend]: << Command: user:default:cjta1pa4g00006310928ezx2n16.03.2019 13:27:34.37 [BackendConnection]: Received msg from backend: { name: '/commands/completed', args: { r: 0, e: 20 } }
Christian Scheuer @chrscheuer2019-03-16 19:23:33.048ZThanks!
I believe this is a known bug in clipDoForEach, that it somehow comes up with an error when it's otherwise done, but we've not been logging it.
Let's group your bug with this:
https://forum.soundflow.org/-447/clipdoforeachclipintrack-incorrectly-handles-certain-clips-with-fades
- ?In reply tochrscheuer⬆:@anon6770933309
Excuse my ignorance but what are the Defaulter and Clip Leveler plug-ins? Is this documented anywhere?
Christian Scheuer @chrscheuer2019-03-19 18:26:38.631ZThis thread came from @poterukha's question in this thread:
https://forum.soundflow.org/-473/clip-gain-value#post-4He was asking for a way to use the Defaulter (https://quietart.co.nz/defaulter/) plugin on all selected clips.
The Clip Leveler is a prototype SoundFlow app I was just demonstrating to showcase that similar functionality is coming to SF. We'll talk more about this once it's ready to test :)
Christian Scheuer @chrscheuer2019-03-19 18:28:35.205Z@NickLeyers I've implemented BS1770 / EBUR128. For now I'm not entirely sure if it's using the gate or not though (so not sure which exact version of the standards it's using), but we're getting results close to about 0,2 dB from iZotope RX's measurement.
- NN Leyers @NickLeyers_old_acc
More than good, thanks. This is something for premix stage (in my opinion) so it will save time and inaccurate gain levels before they go into dynamic plugins. The gate in R128, isn't that only working when there is no audio at all?...
Christian Scheuer @chrscheuer2019-03-20 09:05:46.025Z@NickLeyers I honestly don't know (or remember) the actual details on this. I think the gate kicks in at a certain threshold meaning below that it won't count in the integrated loudness measurement. This should matter across overall program content, for instance if you have sequences of very silent material due to the gate those silent passages won't balance out very loud passages. As far as I remember.
For levelling clips there are many other factors, such as determining if it even contains dialogue. You wouldn't want clips that don't contain dialogue at all to be LUFS measured at -80 and turned up 60 dB. So that's why I put a manual threshold in there that basically says, "if what we gauged your clip to be measured under this threshold, we won't alter the clip gain".- NN Leyers @NickLeyers_old_acc
Just checked it, it was 10LU when the gate kicks in.
Correct, Nugen and iZotope have this dialogue recognition algorithm. But I don't think it's easy to implement that. In a way, clipgaining already exists in RX. If there is a way to transfer the gain-line that RX creates to non destructive clip gain in Protools, that would be even better?... ;-)
Christian Scheuer @chrscheuer2019-03-21 12:34:22.789ZWell we could use the momentary or short term loudness computations to derive our own algo to create the gain line for you. And possibly do that even while still at the AAF stage so it would be done before you import... :)
- NN Leyers @NickLeyers_old_acc
Hmm, indeed. But 'before importing' does not look like a solid idea I'm afraid. I'm having lots of problems with gain structures from video cutters who export an AAF from premiere. Especially when they use effects. So AAF's are fine as long as they do not contain to much information. But maybe that's more a problem caused by premiere.
I would like to use this levelling on my sync-sounds only and therefore, I would like to check first if everything is on the tracks they should be?
Besides that, many editors are clipgaining all the way down on the clips they don't like to use. Resetting that will cause a lot more work for myself. Or sometimes they used clip gain allready and that can stay as a startpoint...
Christian Scheuer @chrscheuer2019-03-22 00:57:31.129Z@NickLeyers yea I know. I agree that on its own just applying clip gain to the AAF wouldn't work, for the reasons you describe. I have something bigger in mind in this space that takes this into account. Can't wait to show it but still some months of work to go.
- NN Leyers @NickLeyers_old_acc
Looking forward ;-)
In reply tochrscheuer⬆:Ingo Pusswald @ingo_luftrauschAny news on this? I think that feature would be dam powerful!
Christian Scheuer @chrscheuer2020-04-16 20:43:39.586ZThanks Ingo! I agree - I'll see if I can get somebody on this.
- MIn reply tochrscheuer⬆:Martin Pavey @Martin_Pavey
Just found this thread.
Did anything ever happen with this feature?
I'm still struggling to automate Defaulter to level clips to LKFS.
The package on the store that says it works with clips with fades, which more and more Editors
are sending through now, doesn't work any more.
Or at least I can't get it to work.
It would be a really great and useful feature! - BIn reply tochrscheuer⬆:Ben Rauscher @Ben_Rauscher
What's the latest on this? Defaulter is obviously great, but pinning down the wait times for it to finish processing a clip is difficult.
- BIn reply tochrscheuer⬆:Ben Rauscher @Ben_Rauscher
Here's an updated SDK revision of the Defaulter package in the Store. I can't find a dynamic way to handle the wait time for a clip gain to finish processing. There's also no way to capture the "Defaulter output" and utilize pasteSpecial().
// USER VARIABLES const asPlugin = { category: "Other", name: "Defaulter" }; const triggerBatchProcess = "ctrl"; // ctrl+alt+shift+cmd const waitTimeBetweenClips = 5000; // milliseconds // FUNCTIONS function Mouse_Hover_Click() { sf.app.proTools.setEditTool({ editTool: "GrabberTime" }); let mousePosition = sf.mouse.getPosition().position; sf.mouse.click({ position: mousePosition }); sf.app.proTools.setEditTool({ editTool: "SmartTool" }); } // Not working function Monitor_Clip_Gain_For_Changes () { let currentClipGain = sf.app.proTools.copySpecial({ automationData: "ClipGain" }); //log(currentClipGain); // doesn't log a value sf.wait({ intervalMs: 100 }); let newClipGain = sf.app.proTools.copySpecial({ automationData: "ClipGain" }); //log(newClipGain); return currentClipGain === newClipGain; // true when clip gain stops changing } function Single_Process_Defaulter() { sf.ui.proTools.windows.whoseTitle.contains(asPlugin.name).first.buttons.whoseTitle.is("Analyze").first.elementClick(); sf.ui.proTools.waitForNoModals(); sf.wait({ intervalMs: waitTimeBetweenClips }); //sf.waitFor({ callback: Monitor_Clip_Gain_For_Changes }); } function Batch_Process_Defaulter() { selectedClips.forEach(clip => { sf.app.proTools.setTimelineSelection({ inTime: clip.startTime.toString(), outTime: clip.endTime.toString() }); sf.wait({ intervalMs: 100 }); sf.app.proTools.selectTracksByName({ trackNames: [clip.trackName] }); sf.wait({ intervalMs: 100 }); Single_Process_Defaulter(); }); } // FINAL EXECUTION sf.app.proTools.invalidate(); let inputKeyboardModifier = event.keyboardState.asString; if (inputKeyboardModifier == "") { Mouse_Hover_Click(); } const timelineSelection = sf.app.proTools.getTimelineSelection(); if (timelineSelection.inTime == timelineSelection.outTime ) { log ("No clips selected."); throw 0; } const selectedClips = sf.app.proTools.getSelectedClipInfo().clips.filter(clip => clip.startTime.toString() >= timelineSelection.inTime && clip.endTime.toString() <= timelineSelection.outTime && !clip.clipName.toLowerCase().includes("fade") // Omit (fade in) and (fade out) ); sf.ui.proTools.audioSuiteOpenPlugin({ category: asPlugin.category, name: asPlugin.name }).window; let asWin = sf.ui.proTools.getAudioSuiteWindow(asPlugin.name); asWin.audioSuiteSetOptions({ // Defaulter cannot properly operate with ClipByClip enabled processingInputMode: "EntireSelection", processingOutputMode: "CreateContinuousFile", inputMode: "MultiInput", }); sf.wait({ intervalMs: 100 }); if (inputKeyboardModifier == triggerBatchProcess) { Batch_Process_Defaulter(); } else { Single_Process_Defaulter(); } asWin.windowClose();