No internet connection
  1. Home
  2. How to

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,
});
  • 28 replies

There are 28 replies. Estimated reading time: 14 minutes

  1. Vladimir @poterukha
      2019-03-14 20:12:42.640Z

      I’ve been busy these days, I can try it tomorrow

      1. No worries :) All in your own time - I just got really excited about this feature request!

      2. In reply tochrscheuer:

        Preliminary support for a Clip Leveler app is coming:

        1. samuel henriques @samuel_henriques
            2020-11-18 08:46:04.107Z2020-11-18 09:34:13.201Z

            hello, 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

            1. Hi Samuel

              This is not currently public, no.

          • N
            In reply tochrscheuer:
            N Leyers @NickLeyers_old_acc
              2019-03-15 07:21:24.269Z

              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.

              1. That's exactly what we do :)

                1. And yes BS1770 / EBU-R128 etc. would be great to get implemented.

                2. In reply tochrscheuer:
                  Vladimir @poterukha
                    2019-03-15 12:41:39.745Z

                    I have updated to 2.1.3pr6 today and "checkForCancellation" is underlined with red in this build

                    1. Right, @poterukha, my apologies. That's a 2.2 feature. You can just skip that line for now.

                      1. Vladimir @poterukha
                          2019-03-16 12:40:17.499Z

                          I'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: DoMainCounterAction

                          16.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:cjta1pa4g00006310928ezx2n

                          16.03.2019 13:27:34.37 [BackendConnection]: Received msg from backend: { name: '/commands/completed', args: { r: 0, e: 20 } }

                          1. Thanks!

                            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

                      2. ?
                        In reply tochrscheuer:
                        @anon6770933309
                          2019-03-19 18:04:10.599Z

                          Excuse my ignorance but what are the Defaulter and Clip Leveler plug-ins? Is this documented anywhere?

                          1. This thread came from @poterukha's question in this thread:
                            https://forum.soundflow.org/-473/clip-gain-value#post-4

                            He 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 :)

                            1. @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.

                              1. NN Leyers @NickLeyers_old_acc
                                  2019-03-20 08:58:19.384Z

                                  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?...

                                  1. @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".

                                    1. NN Leyers @NickLeyers_old_acc
                                        2019-03-21 10:59:11.063Z

                                        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?... ;-)

                                        1. Well 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... :)

                                          1. NN Leyers @NickLeyers_old_acc
                                              2019-03-21 13:03:42.138Z

                                              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...

                                              1. @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.

                                                1. NN Leyers @NickLeyers_old_acc
                                                    2019-03-24 08:31:31.568Z

                                                    Looking forward ;-)

                                      • In reply tochrscheuer:
                                        ?@anon6770933309
                                          2019-03-21 16:57:57.052Z

                                          IC, thx.

                                      • In reply tochrscheuer:
                                        Ingo Pusswald @ingo_luftrausch
                                          2020-04-16 19:21:55.979Z

                                          Any news on this? I think that feature would be dam powerful!

                                          1. Thanks Ingo! I agree - I'll see if I can get somebody on this.

                                          2. M
                                            In reply tochrscheuer:
                                            Martin Pavey @Martin_Pavey
                                              2022-02-12 16:02:32.397Z

                                              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!

                                              1. B
                                                In reply tochrscheuer:
                                                Ben Rauscher @Ben_Rauscher
                                                  2025-01-28 16:54:57.349Z2025-01-28 17:29:52.061Z

                                                  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.

                                                  1. B
                                                    In reply tochrscheuer:
                                                    Ben Rauscher @Ben_Rauscher
                                                      2025-01-30 23:38:51.588Z2025-01-31 02:42:34.379Z

                                                      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();