No internet connection
  1. Home
  2. How to

Beat detective edit smoothing

By Dave Rhodes @Dave_Rhodes
    2022-10-20 19:42:49.685Z

    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.

    Solved in post #8, click to view
    • 16 replies

    There are 16 replies. Estimated reading time: 14 minutes

    1. Ryan DeRemer @Ryan_DeRemer
        2022-10-20 20:37:59.958Z

        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.

        1. DDave Rhodes @Dave_Rhodes
            2022-10-20 20:44:46.503Z

            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?

            1. Ryan DeRemer @Ryan_DeRemer
                2022-10-20 20:53:44.963Z

                Makes sense. I'll check it out when I get a minute.

            2. In reply toDave_Rhodes⬆:
              Ryan DeRemer @Ryan_DeRemer
                2022-10-20 23:17:49.330Z

                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 });
                
                1. DDave Rhodes @Dave_Rhodes
                    2022-10-20 23:34:19.518Z

                    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?

                    1. Ryan DeRemer @Ryan_DeRemer
                        2022-10-20 23:37:17.255Z

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

                        1. In reply toDave_Rhodes⬆:
                          Ryan DeRemer @Ryan_DeRemer
                            2022-10-20 23:39:00.057Z

                            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 });
                            
                            Reply1 LikeSolution
                            1. In reply toDave_Rhodes⬆:
                              Ryan DeRemer @Ryan_DeRemer
                                2022-10-20 23:40:37.578Z

                                I've labelled what each call does in a comment above each one.

                                1. DDave Rhodes @Dave_Rhodes
                                    2022-10-20 23:43:56.990Z

                                    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!

                                    1. Ryan DeRemer @Ryan_DeRemer
                                        2022-10-20 23:44:33.199Z

                                        What's the bug?

                                        1. DDave Rhodes @Dave_Rhodes
                                            2022-10-20 23:45:55.739Z

                                            The fill part of 'fill and crossfade' seems to have stopped working. Just trying an older version of PT. Never come across this before.

                                            1. Ryan DeRemer @Ryan_DeRemer
                                                2022-10-20 23:51:26.839Z

                                                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.

                                                1. DDave Rhodes @Dave_Rhodes
                                                    2022-10-20 23:59:46.193Z

                                                    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
                                                      2022-10-20 23:52:13.450Z

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

                                                      1. Ryan DeRemer @Ryan_DeRemer
                                                          2022-10-20 23:58:31.893Z

                                                          Glad to hear it! 😃

                                                          1. In reply toDave_Rhodes⬆:
                                                            SSean McDonald @Sean_McDonald5
                                                              2023-06-18 05:18:17.114Z

                                                              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