Audiosuite - Defaulter - Analyze not Render
Hi All
I'm trying to create a macro that will open the Audiosuite: Defaulter 2 by Quiet Art. It is a plugin that will edit the clip gain to make a clip fit a set RMS. The way it works is open the audiosuite, select analyze and the plugin then sends key commands to protools to trim the clip gain in 0.5dB increments until it is the desired level. You can't hit render in this plugin as then it won't do anything.
I've managed to get the plugin to open hit Analyse, then it processes the clip just fine. However, I'm having no success with WAIT commands after thatr before going into the next process. What I want to do is close that window when the process has finished, but because it does have a progress bar, the wait for no modals doesn't have anything to look for, and the wait for X TIME is so variable - sometimes the plugin takes 20 seconds to process, sometimes 5 seconds.
This is my latest version of the script - essentially trying to get the process to action on all selected clips, then to close defaulter. I didn't include any of the WAIT elemenets here as they aren't working
sf.ui.proTools.audioSuiteOpenPlugin({
category: "Quiet Art Ltd.",
name: "Defaulter",
});
function DefaulterClip() {
sf.ui.proTools.firstAudioSuiteWindow.audioSuiteSetOptions({
processingInputMode: "ClipByClip",
processingOutputMode: "CreateIndividualFiles",
});
sf.ui.proTools.windows.whoseTitle.is("Audio Suite: Defaulter").first.buttons.whoseTitle.is("Analyze").first.elementClick();
}
sf.ui.proTools.clipDoForEachSelectedClip({ action: DefaulterClip });
sf.ui.proTools.windows.whoseTitle.is("Audio Suite: Defaulter").first.getElement("AXCloseButton").elementClick();
Any help on approaches for this task are appreciated
- In reply toPete_Watson⬆:Dustin Harris @Dustin_Harris
I think I figured out a way! When Defaulter is set with 'Fire Macro Keys' enabled, it will move to the next clip once it has finished. I used this feature to make a 'wait' in SoundFlow by checking the clip's start time in samples every 100ms. If it has changed (which is does when Defaulter is done adjusting clip gain) Sound Flow then knows the process is finished and can move on to the next clip.
SO... for this to work, save a preset with all of your level settings, and make sure that preset includes enabling the 'fire macro keys' button, and save that preset as 'Fire Macro Keys'... and this script should work :)
function getPreviousMainCounter() { // Get Main Counter so we can change it back when we're done let menuItems = sf.ui.proTools.getMenuItem('View', 'Main Counter').children.first.children.allItems for (let i = 0; i < menuItems.length; i++) { let currentMenuItem = menuItems[i] if (currentMenuItem.isMenuChecked) { return currentMenuItem.title.value } } } function openAndSetDefaulter() { let defaulterWin = sf.ui.proTools.getAudioSuiteWindow('Defaulter') if (!defaulterWin.exists) { const category = (sf.ui.proTools.getMenuItem('AudioSuite', 'Quiet Art Ltd.').exists) ? 'Quiet Art Ltd.' : 'Other'; defaulterWin = sf.ui.proTools.audioSuiteOpenPlugin({ category, name: 'Defaulter' }).window } defaulterWin.audioSuiteSetOptions({ processingInputMode: "ClipByClip", processingOutputMode: "CreateIndividualFiles", }) defaulterWin.audioSuiteSelectPreset({ presetMenuPath: ['Fire Macro Keys'] }) } function processWithDefaulter() { const defaulterWin = sf.ui.proTools.getAudioSuiteWindow('Defaulter') const {selectionStart, selectionEnd} = sf.ui.proTools.selectionGet(); defaulterWin.buttons.whoseTitle.is('Analyze').first.elementClick(); //this checks if Defaulter has moved to the next clip while (selectionStart === sf.ui.proTools.selectionGet().selectionStart) sf.wait({ intervalMs: 100 }) //return clip to original selection so the doForEachSelectedClip action is not interrupted sf.ui.proTools.selectionSet({selectionStart, selectionEnd}) } function main() { sf.ui.proTools.appActivateMainWindow(); openAndSetDefaulter(); const originalMainCounterSetting = getPreviousMainCounter(); sf.ui.proTools.mainCounterSetValue({ targetValue: 'Samples' }) try { sf.ui.proTools.clipDoForEachSelectedClip({action: processWithDefaulter}) } finally { sf.ui.proTools.mainCounterSetValue({targetValue: originalMainCounterSetting}) } alert('Defaulter Processing has Finished'); } main();
Let me know how it goes!
- PPete Watson @Pete_Watson
Ah you are a superstar! Can't believe people put so much time in to helping each other out with scripts, it's really humbling :)
I should say - that inbetween posting and you posting a solution, I did discover that with "fire macros" enabled, what Defaulter is actually doing is sending key commands to Keyboard Maestro to trigger macros. So I downloaded the demo, nabbed the key commands it's using and remade it in Soundflow. So after each clip is processed, Defaulter sends Shift+Ctl+Alt+Cmd+0 to keyboard Maestro, so I used that to continue my Macro and all working well now.
Thank you again!
- In reply toPete_Watson⬆:Chris Andrews @Chris_Andrews
Hey guys, I am wondering if there is a way to make this continue automatically across all selected clips? When I run it, it works great, but I have to physically click each region to let the macro move forward. Is there something that I am missing on this possibly setting wise?
Thanks for any assist.
Chris
Chad Wahlbrink @Chad2024-09-24 18:01:15.284Z2024-09-24 18:08:19.875Z
Hi @Chris_Andrews!
The workflow outlined earlier in this thread should work for all selected clips in the session. I believe it relied on using the corresponding Keyboard Maestro macros from Quiet Art. See the FAQ section here, specifically "The macros no longer work after Pro Tools upgrade (Mac)":
https://quietart.co.nz/defaulter/However, the workflow is pretty buggy on my current system. Also, since I'm all in on SoundFlow, I prefer to avoid using Keyboard Maestro.
Below is my version of a defaulter workflow. It should work on all selected clips and has a parameter to define a preset to load if desired. Please note that leaving "Fire Macro Keys" OFF is vital for my script to behave as expected.
// IMPORTANT: The "fire macro keys" checkbox should be OFF for this version to run. // Put a Preset Name in the Parentheses to load a named preset // ex: let presetToLoad = '24 LUFS'; let presetToLoad = ''; /////////////////////////////////// if (!sf.ui.proTools.isRunning) throw `Pro Tools is not running`; sf.ui.proTools.appActivateMainWindow(); sf.ui.proTools.mainWindow.invalidate(); // Check Track Width function getTrackWidth(tracks) { var numberOfPanSliders = sf.ui.proTools.selectedTrack.groups.whoseTitle.is('Audio IO').first. sliders.whoseTitle.startsWith('Audio Pan indicator').count; return numberOfPanSliders }; // Check Two Arrays for the Same Contents const haveSameContents = (a, b) => a.length === b.length && [...new Set([...a, ...b])].every( v => a.filter(e => e === v).length === b.filter(e => e === v).length ); // Open and Set Defaulter. function openAndSetDefaulter() { let defaulterWin = sf.ui.proTools.getAudioSuiteWindow('Defaulter') if (!defaulterWin.exists) { const category = (sf.ui.proTools.getMenuItem('AudioSuite', 'Quiet Art Ltd.').exists) ? 'Quiet Art Ltd.' : 'Other'; defaulterWin = sf.ui.proTools.audioSuiteOpenPlugin({ category, name: 'Defaulter' }).window } if (getTrackWidth(sf.ui.proTools.selectedTrack) == 1) { defaulterWin.audioSuiteSetOptions({ processingInputMode: "ClipByClip", processingOutputMode: "CreateIndividualFiles", }) defaulterWin.popupButtons.first.popupMenuSelect({ menuPath: ['mono mode'] }); } else { defaulterWin.audioSuiteSetOptions({ processingInputMode: "EntireSelection", }) defaulterWin.popupButtons.first.popupMenuSelect({ menuPath: ['multi-input mode'] }); } if (presetToLoad) { defaulterWin.audioSuiteSelectPreset({ presetMenuPath: [presetToLoad] }) } } // Process with Defaulter function processWithDefaulter() { const defaulterWin = sf.ui.proTools.getAudioSuiteWindow('Defaulter') defaulterWin.buttons.whoseTitle.is('Analyze').first.elementClick(); let t = 0; // Wait Until Undo History is Unchanged for two cycles while (t < 2) { // Undo History Table let undoHistoryStart = sf.ui.proTools.windows.whoseTitle.is("Undo History").first.tables .whoseTitle.is("Event List").first.children.whoseRole.is("AXRow").allItems.map(x => x.children.whoseRole.is("AXCell").first.children.first.value.value); sf.wait({ intervalMs: 200 }); let undoHistoryFinish = sf.ui.proTools.windows.whoseTitle.is("Undo History").first.tables .whoseTitle.is("Event List").first.children.whoseRole.is("AXRow").allItems.invalidate().map(x => x.children.whoseRole.is("AXCell").first.children.first.value.value); // If the undo history is unchanged, then add to t if (haveSameContents(undoHistoryStart, undoHistoryFinish)) { t++; } } } // Main function main() { // Get state of Undo History let undoHistoryIsOpen = sf.ui.proTools.windows.whoseTitle.is("Undo History").first.exists; try { if (!undoHistoryIsOpen) { // Open Undo History, Even if "Auto-Update" Window Config is on. sf.ui.proTools.getElement("AXMenuBar").children.whoseTitle.startsWith("Window") .first.children.first.children.whoseTitle.is('Undo History').first.elementClick(); } // Clear Current Clip Gain for Selection sf.ui.proTools.menuClick({ menuPath: ['Edit', 'Clear Special', 'Clip Gain'] }) openAndSetDefaulter(); sf.ui.proTools.clipDoForEachClip({ action: processWithDefaulter }); } catch (err) { throw err; } finally { if (!undoHistoryIsOpen) { // Open Undo History, Even if "Auto-Update" Window Config is on. sf.ui.proTools.windows.whoseTitle.is("Undo History").first.windowClose(); } } } main();
Chris Andrews @Chris_Andrews
Chad! This worked like a champ, thanks again for the assist. I think what I am going to do is base a new Defaulter deck on this with a few settings that I will tweak. That will allow people to have a new one that has -27, -24, -23, -18, -16, -12, -10, etc with a few preset creations. This saved me a ton this am with a 75 min long movie prep. Dialog went back to a usable level. ;)
Thanks again and I will let you know when I get the deck out.
C
- In reply toChad⬆:
Chris Andrews @Chris_Andrews
Chad,
So I have this working really well - thanks again. I went through and made a new deck witoh some preset settings.
What I created so far is this.DBFS section
-6,-10,-12, -14, -16, -18, -20LKFS Section
-10, -12, -14, -16, -18, -23, -24, -27Clip Gain On
Clip Gain Off
Mix / Edit Toggle
Folder Open
Folder Close
Delete active TrackThese are things that I use a lot, and thought it would be good to have based on the old Defaulter app not working.
Plan is to have a few screenshots on how the presets should look and have that in the instructions.
The button colors I was thinking HOT to COLD with a simple -23 LKFS and say a cool blue -10LKFS would be Red, etc
Thoughts to anything else?
- In reply toPete_Watson⬆:Chris Andrews @Chris_Andrews
Aweome man! I will try it tonight and see how it works out. I am working a 75min fild at the moment and new to Defaulter, but love it. Always used Stereo moniizer, but this is much more macro accruate to small clips, etc.
Thanks for the reply.
- In reply toPete_Watson⬆:Chris Andrews @Chris_Andrews
All, I went ahead and made a new working Package with a bunch of starter options. Thank you again CHAD for the help on this. In the store you will see it as "Defaulter Tools" under NEW and then under Chris Andrews (me) as well.
If you setup the presets like I have on the list, it should work flawlessly. Let me know
C