Is there a macro for beat detective edit smoothing?
I just want it to open beat detective, select edit smoothing then press smooth button.
If there isn't a premade macro I can use, can someone explain how to make one please. I have a basic understanding of how to use macros and assign them to a deck but scripting is beyond me. Thanks.
- Ryan DeRemer @Ryan_DeRemer
Hey Dave, are you wanting to actually run the full beat detective process, or are you doing that part manually and just wan t a command for edit smoothing? The latter shouldn't be terribly difficult, though I got into the scripting early and haven't done much with macros, so I'm not sure how that might work. Happy to write something up for you if you can lay out a step-by-step process on what you would do, which will be replaced by automation.
- DDave Rhodes @Dave_Rhodes
I just want to run the smoothing part. I use it for all sorts of things, not just drum editing.
That would be amazing! OK, here's the process....
I manually select a range of clips, then I want a macro (or script) to open beat detective, select edit smoothing, press smooth button, close beat detective window.
I dont need it to set the the parameters of beat detective because they are already set. I may change them from time to time but don't need to do that on each operation.
The only other thing that might be useful is if the script deleted all current fades in the selection before running beat detective.
Does that make sense?
Ryan DeRemer @Ryan_DeRemer
Makes sense. I'll check it out when I get a minute.
- In reply toDave_Rhodes⬆:Ryan DeRemer @Ryan_DeRemer
Hey Dave, give this a try. it does have some additional settings, but they all have default values that you can set. To run it, there are a couple function calls at the bottom that are commented out, just delete the 2 slashes (/) before the
smoothEditsBeatDetective()
. both calls function slightly differently, but it's easy to just change some values to what you want. Let me know if you have any questions!/** * @param {{ smoothingType: 'Fill Gaps'|'Fill And Crossfade', crossfadeLength: number, closeWindowOnComplete?: boolean, deleteCurrentFades?: boolean }} [args] */ function smoothEditsBeatDetective({ smoothingType, crossfadeLength, closeWindowOnComplete = false, deleteCurrentFades = true } = { smoothingType: 'Fill And Crossfade', crossfadeLength: 10, closeWindowOnComplete: true, deleteCurrentFades: true }) { sf.ui.proTools.appActivateMainWindow(); if (deleteCurrentFades && sf.ui.proTools.getMenuItem('Edit', 'Fades', 'Delete').isEnabled) sf.ui.proTools.menuClick({ menuPath: ['Edit', 'Fades', 'Delete'] }) const beatDetectiveWin = sf.ui.proTools.windows.getByTitle('Beat Detective'); if (!beatDetectiveWin.exists) { try { sf.ui.proTools.menuClick({ menuPath: ['Event', 'Beat Detective'] }); } catch (err) { sf.keyboard.press({ keys: 'left', repetitions: 2 }); sf.ui.proTools.menuClick({ menuPath: ['Event', 'Beat Detective'] }); } beatDetectiveWin.elementWaitFor({ waitType: 'Appear' }); } else { beatDetectiveWin.windowFocusClick(); } const editSmoothingButton = beatDetectiveWin.groups.getByTitle('Operation').radioButtons.getByTitle('Edit Smoothing'); const smoothingTypeButton = beatDetectiveWin.groups.getByTitle('Smoothing:').radioButtons.getByTitle(smoothingType); const crossfadeLengthField = beatDetectiveWin.groups.getByTitle('Smoothing:').textFields.getByTitle('NumericEntryText'); const smoothButton = beatDetectiveWin.buttons.getByTitle('Smooth'); if (!editSmoothingButton.isCheckBoxChecked) editSmoothingButton.elementClick(); if (!smoothingTypeButton.isCheckBoxChecked) smoothingTypeButton.elementClick(); if (crossfadeLengthField.isEnabled && crossfadeLengthField.value.invalidate().value !== String(crossfadeLength)) { crossfadeLengthField.elementClick(); sf.keyboard.press({ keys: 'backspace' }); sf.keyboard.type({ text: String(crossfadeLength) }); sf.keyboard.press({ keys: 'return' }); } smoothButton.elementClick(); const conDlg = sf.ui.proTools.confirmationDialog; conDlg.elementWaitFor({ waitType: 'Appear', timeout: 300, pollingInterval: 10, onError: 'Continue' }); if (conDlg.exists) { log('Something went wrong. Ensure there are no fades in the current selection, or that [deleteCurrentFades] is set to true, and that there is a current timeline selection') conDlg.buttons.getByTitle('OK').elementClick(); conDlg.elementWaitFor({ waitType: 'Disappear' }); } if (closeWindowOnComplete) beatDetectiveWin.windowClose(); } // runs command using defaults: Smoothing - Fill And Crossfade | Crossfade Length - 10ms | Closes Window On Completion | Deletes Current Fades // smoothEditsBeatDetective(); // runs command based on your preferences. ex: Smoothing - Fill Gaps | Crossfade Length - 10ms | Closes Window On Completion | Deletes Current Fades // smoothEditsBeatDetective({ smoothingType: 'Fill Gaps', crossfadeLength: 15, closeWindowOnComplete: false, deleteCurrentFades: false });
- DDave Rhodes @Dave_Rhodes
Hey Ryan,
I've cut and paste this into a new script but for some reason nothing happens when I press Run Command. I've done this with other scripts I've found on the forums and its worked fine. There is no error message, just nothing as if its not registering me pressing 'Run Command'... any ideas?
Ryan DeRemer @Ryan_DeRemer
You have to delete the slashes in front of one of the function calls at the bottom of the script. Those are what tells the script to run the function.
smoothEditsBeatDetective();
- In reply toDave_Rhodes⬆:
Ryan DeRemer @Ryan_DeRemer
For example:
/** * @param {{ smoothingType: 'Fill Gaps'|'Fill And Crossfade', crossfadeLength: number, closeWindowOnComplete?: boolean, deleteCurrentFades?: boolean }} [args] */ function smoothEditsBeatDetective({ smoothingType, crossfadeLength, closeWindowOnComplete = false, deleteCurrentFades = true } = { smoothingType: 'Fill And Crossfade', crossfadeLength: 10, closeWindowOnComplete: true, deleteCurrentFades: true }) { sf.ui.proTools.appActivateMainWindow(); if (deleteCurrentFades && sf.ui.proTools.getMenuItem('Edit', 'Fades', 'Delete').isEnabled) sf.ui.proTools.menuClick({ menuPath: ['Edit', 'Fades', 'Delete'] }) const beatDetectiveWin = sf.ui.proTools.windows.getByTitle('Beat Detective'); if (!beatDetectiveWin.exists) { try { sf.ui.proTools.menuClick({ menuPath: ['Event', 'Beat Detective'] }); } catch (err) { sf.keyboard.press({ keys: 'left', repetitions: 2 }); sf.ui.proTools.menuClick({ menuPath: ['Event', 'Beat Detective'] }); } beatDetectiveWin.elementWaitFor({ waitType: 'Appear' }); } else { beatDetectiveWin.windowFocusClick(); } const editSmoothingButton = beatDetectiveWin.groups.getByTitle('Operation').radioButtons.getByTitle('Edit Smoothing'); const smoothingTypeButton = beatDetectiveWin.groups.getByTitle('Smoothing:').radioButtons.getByTitle(smoothingType); const crossfadeLengthField = beatDetectiveWin.groups.getByTitle('Smoothing:').textFields.getByTitle('NumericEntryText'); const smoothButton = beatDetectiveWin.buttons.getByTitle('Smooth'); if (!editSmoothingButton.isCheckBoxChecked) editSmoothingButton.elementClick(); if (!smoothingTypeButton.isCheckBoxChecked) smoothingTypeButton.elementClick(); if (crossfadeLengthField.isEnabled && crossfadeLengthField.value.invalidate().value !== String(crossfadeLength)) { crossfadeLengthField.elementClick(); sf.keyboard.press({ keys: 'backspace' }); sf.keyboard.type({ text: String(crossfadeLength) }); sf.keyboard.press({ keys: 'return' }); } smoothButton.elementClick(); const conDlg = sf.ui.proTools.confirmationDialog; conDlg.elementWaitFor({ waitType: 'Appear', timeout: 300, pollingInterval: 10, onError: 'Continue' }); if (conDlg.exists) { log('Something went wrong. Ensure there are no fades in the current selection, or that [deleteCurrentFades] is set to true, and that there is a current timeline selection') conDlg.buttons.getByTitle('OK').elementClick(); conDlg.elementWaitFor({ waitType: 'Disappear' }); } if (closeWindowOnComplete) beatDetectiveWin.windowClose(); } // runs command using defaults: Smoothing - Fill And Crossfade | Crossfade Length - 10ms | Closes Window On Completion | Deletes Current Fades smoothEditsBeatDetective(); // runs command based on your preferences. ex: Smoothing - Fill Gaps | Crossfade Length - 10ms | Closes Window On Completion | Deletes Current Fades // smoothEditsBeatDetective({ smoothingType: 'Fill Gaps', crossfadeLength: 15, closeWindowOnComplete: false, deleteCurrentFades: false });
- In reply toDave_Rhodes⬆:
Ryan DeRemer @Ryan_DeRemer
I've labelled what each call does in a comment above each one.
- DDave Rhodes @Dave_Rhodes
Aaahhh Sorry total Noob! Gotcha. OK I think its working but now I seem to have discovered a new pro tools bug haha... I need to do some testing and get back to you. Thanks!
Ryan DeRemer @Ryan_DeRemer
What's the bug?
- DDave Rhodes @Dave_Rhodes
The fill part of 'fill and crossfade' seems to have stopped working. Just trying an older version of PT. Never come across this before.
Ryan DeRemer @Ryan_DeRemer
Interesting. I don't do a lot of Beat Detective stuff so I'm not sure how that all works under the hood. I've never seen that before either. Post your results here if you don't mind. A lot of the devs are in the Pro Tools beta group so if it is a bug I'd like to investigate it myself and see if I can pass it along.
- DDave Rhodes @Dave_Rhodes
It was just user error. I chopped some holes in a piece of audio then tried to run the script but it didn't fill the gaps. Thats not a real world use for it though because it would be filling the gaps with the same audio i just deleted. I guess I've never done that in real life so I tried using it on a some audio that was edited and moved and it worked perfectly.
If you've not used it before... its an alternative to the bulk fades option but it has the benefit of filling the gap rather than just fading which is actually preferable in a lot of situations, not just on drums. But since there's no keyboard short cut its always been a bit slow.
- In reply toDave_Rhodes⬆:DDave Rhodes @Dave_Rhodes
Ok... So maybe it was user error, anyway.... it works!! I've wanted a keyboard shortcut for this for at least 20 years! I can't believe it haha. Thank you so much!!
Ryan DeRemer @Ryan_DeRemer
Glad to hear it! 😃
- In reply toDave_Rhodes⬆:SSean McDonald @Sean_McDonald5
Hi Dave,
Following along here as Im looking for this same task to be automated in SF.Does the script in fact smooth and crossfade selected track/ tracks?
thanks in advance,
Sean