No internet connection
  1. Home
  2. How to

Script for quick volume automation dip

By Shiheng Xu @Shiheng_Xu8
    2022-11-09 18:45:06.765Z

    hi there, does anyone know how to create a quick 3 point 4db dip like the situation shown in the picture? Maybe the script create two points of automation with 6 frames and dip 4db in the middle? Please help, thank you!

    • 9 replies
    1. samuel henriques @samuel_henriques
        2022-11-12 22:43:16.803Z2022-11-25 13:52:36.893Z

        Hello Shiheng Xu,
        Select from the start to the position you want the dip to be, then run the script. To set the volume change the number in the end of the script in this line dipBydB(-4).
        Here's a video with a demo.
        https://youtu.be/_Xsu2L4q7-g

        Here you go, I hope this is it:

        const writeToCurrent = () => sf.ui.proTools.menuClick({ menuPath: ["Edit", "Automation", "Write to Current"] });
        const doubleEdit = () => sf.ui.proTools.menuClick({ menuPath: ["Edit", "Selection", "Double Edit"] });
        const halveEdit = () => sf.ui.proTools.menuClick({ menuPath: ["Edit", "Selection", "Halve Edit"] });
        const getSelection = () => sf.ui.proTools.selectionGetInSamples();
        const clearAutomation = () => sf.ui.proTools.menuClick({ menuPath: ["Edit", "Clear Special", "All Automation"] });
        const arrowUp = () => sf.keyboard.press({ keys: "up", fast: true });
        
        
        /**
         * @param {"blocks"|"playlists"|"analysis"|"warp"|"waveform"|"volume"|"volume trim"|"mute"|"pan"} view
         */
        function setAutomationView(view) {
            // view popup
            const viewSelector = sf.ui.proTools.selectedTrack.popupButtons.whoseTitle.is('Track View selector').first;
            const viewSelectorValue = viewSelector.value.invalidate().value;
            if (viewSelectorValue !== view) {
                viewSelector.popupMenuSelect({ menuPath: [view] });
            };
            return viewSelectorValue;
        };
        
        
        /**
        * @param {number} volume
        */
        function setFaderVolume(volume) {
            const volumeTextEl = sf.ui.proTools.mainTrackOutputWindow.textFields.first
            const currentVolume = volumeTextEl.value.invalidate().value
            const newVolume = +currentVolume + volume
            sf.ui.proTools.mainTrackOutputWindow.textFields.first.elementSetTextFieldWithAreaValue({ value: newVolume.toString(), useMouseKeyboard: true });
            sf.keyboard.press({ keys: "return" })
        };
        
        
        
        /**
         * @param {number} [volume]
         * @param {'send a'|'send b'|'send c'|'send d'|'send e'|'send f'|'send g'|'send h'|'send i'|'send j'|'main out'} outputViewSelector
         */
        function openOutputWindow(outputViewSelector, volume) {
        
            const outputViewSelectorBtn = sf.ui.proTools.mainTrackOutputWindow.buttons.whoseTitle.is("Output View selector").first;
            const selectedTrackName = sf.ui.proTools.selectedTrackNames[0];
            const outWinTrackNameBtn = sf.ui.proTools.mainTrackOutputWindow.buttons.first;
        
        
            if (!outputViewSelectorBtn.exists) {
                sf.ui.proTools.selectedTrack.trackOutputToggleShow();
                sf.ui.proTools.invalidate()
            }
        
            const outputViewSelectorValue = outputViewSelectorBtn.value.invalidate().value;
            const outWinTrackName = outWinTrackNameBtn.value.invalidate().value;
        
            // Set Output win to selected track
            if (selectedTrackName != outWinTrackName) {
                outWinTrackNameBtn.popupMenuSelect({ menuSelector: items => items.filter(item => item.element.title.value.startsWith(selectedTrackName))[0] })
            };
        
            // Set Output win to outputViewSelector
            if (!outputViewSelectorValue.startsWith(outputViewSelector)) {
                outputViewSelectorBtn.popupMenuSelect({ menuSelector: items => items.filter(item => item.element.title.value.startsWith(outputViewSelector))[0] })
            };
        
            if (volume) {
                setFaderVolume(volume)
            };
        
            sf.ui.proTools.selectedTrack.trackOutputToggleShow();
        };
        
        
        /**
         * @param {number} dB
         */
        function dipBydB(dB) {
        
            const userView = setAutomationView("volume");
        
            const { selectionStart, selectionEnd } = getSelection();
        
            doubleEdit();
        
            writeToCurrent();
        
            halveEdit();
        
            arrowUp();
        
            //Set fader to volume
            openOutputWindow("main out", dB);
        
            writeToCurrent();
        
            sf.ui.proTools.selectionSetInSamples({ selectionStart });
        
            clearAutomation();
        
            // Set original view if not volume
            // @ts-ignore
            setAutomationView(userView)
        
        };
        
        
        dipBydB(-4);
        
        1. Ddanielkassulke @danielkassulke
            2022-11-23 23:20:23.535Z

            Hi @samuel_henriques , once again, this is amazing. This is very very close to something I've been searching for already, which is just a simpler 4-point edit where the selection is uniformly turned down by the same amount within the selection. I tried to tweak it to ignore the halve/double edit selection which I assume is just to create a breakpoint in the automation halfway through, but not it just creates a fadeout. Do you have any suggestions for where to adapt the script?

            1. samuel henriques @samuel_henriques
                2022-11-25 13:52:13.940Z2022-11-25 14:11:12.727Z

                There was a pretty stupid mistake on the first version, where instead of dipping by... it was setting at that value. I fixed it.

                Here's a 4 point version. Frames for fade in/out must be calculated in samples, so frame length depends on session format. It's set as 1920 = 1 frame@48k@25fps. you can change this on line 75.

                const writeToCurrent = () => sf.ui.proTools.menuClick({ menuPath: ["Edit", "Automation", "Write to Current"] });
                const getSelection = () => sf.ui.proTools.selectionGetInSamples();
                const cut = () => sf.ui.proTools.menuClick({ menuPath: ["Edit", "Cut"] });
                
                /**
                 * @param {"blocks"|"playlists"|"analysis"|"warp"|"waveform"|"volume"|"volume trim"|"mute"|"pan"} view
                 */
                function setAutomationView(view) {
                    // view popup
                    const viewSelector = sf.ui.proTools.selectedTrack.popupButtons.whoseTitle.is('Track View selector').first;
                    const viewSelectorValue = viewSelector.value.invalidate().value;
                    if (viewSelectorValue !== view) {
                        viewSelector.popupMenuSelect({ menuPath: [view] });
                    };
                    return viewSelectorValue;
                };
                
                
                /**
                * @param {number} volume
                */
                function setFaderVolume(volume) {
                    const volumeTextEl = sf.ui.proTools.mainTrackOutputWindow.textFields.first
                    const currentVolume = volumeTextEl.value.invalidate().value
                    const newVolume = +currentVolume + volume
                    sf.ui.proTools.mainTrackOutputWindow.textFields.first.elementSetTextFieldWithAreaValue({ value: newVolume.toString(), useMouseKeyboard: true });
                    sf.keyboard.press({ keys: "return" })
                };
                
                
                /**
                 * @param {number} [volume]
                 * @param {'send a'|'send b'|'send c'|'send d'|'send e'|'send f'|'send g'|'send h'|'send i'|'send j'|'main out'} outputViewSelector
                 */
                function openOutputWindow(outputViewSelector, volume) {
                
                    const outputViewSelectorBtn = sf.ui.proTools.mainTrackOutputWindow.buttons.whoseTitle.is("Output View selector").first;
                    const selectedTrackName = sf.ui.proTools.selectedTrackNames[0];
                    const outWinTrackNameBtn = sf.ui.proTools.mainTrackOutputWindow.buttons.first;
                
                
                    if (!outputViewSelectorBtn.exists) {
                        sf.ui.proTools.selectedTrack.trackOutputToggleShow();
                        sf.ui.proTools.invalidate()
                    }
                
                    const outputViewSelectorValue = outputViewSelectorBtn.value.invalidate().value;
                    const outWinTrackName = outWinTrackNameBtn.value.invalidate().value;
                
                    // Set Output win to selected track
                    if (selectedTrackName != outWinTrackName) {
                        outWinTrackNameBtn.popupMenuSelect({ menuSelector: items => items.filter(item => item.element.title.value.startsWith(selectedTrackName))[0] })
                    };
                
                    // Set Output win to outputViewSelector
                    if (!outputViewSelectorValue.startsWith(outputViewSelector)) {
                        outputViewSelectorBtn.popupMenuSelect({ menuSelector: items => items.filter(item => item.element.title.value.startsWith(outputViewSelector))[0] })
                    };
                
                    if (volume) {
                        setFaderVolume(volume)
                    };
                
                    sf.ui.proTools.selectedTrack.trackOutputToggleShow();
                };
                
                
                /**
                 * @param {object} obj
                 * @param {number} obj.dB
                 * @param {number} [obj.fadeLengthFrames]
                 */
                function dipBydB({ dB, fadeLengthFrames = 1 }) {
                
                    const fadeLengthInSamples = (frames) => frames * 1920; //1920 = 1 frame@48k@25fps
                
                    //Set Volume view and get original view for later
                    const userView = setAutomationView("volume");
                
                    //Get user selection
                    const { selectionStart, selectionEnd, selectionLength } = getSelection();
                
                    //If the original selecton is less than the fade length, probably user did't set a selection so return
                    if (selectionLength < fadeLengthInSamples(fadeLengthFrames)) { alert("Please make a selection."); return; }
                
                    try {
                
                        writeToCurrent();
                
                        //Set fader to volume
                        openOutputWindow("main out", dB);
                
                        //Write start end automation break points
                        writeToCurrent();
                
                        //Start fade
                        sf.ui.proTools.selectionSetInSamples({ selectionStart, selectionEnd: +selectionStart + fadeLengthInSamples(fadeLengthFrames) });
                        cut();
                
                        //End fade
                        sf.ui.proTools.selectionSetInSamples({ selectionStart: +selectionEnd - fadeLengthInSamples(fadeLengthFrames), selectionEnd });
                        cut();
                
                    } catch (err) {
                
                    } finally {
                
                        //Set original selection
                        sf.ui.proTools.selectionSetInSamples({ selectionStart, selectionEnd })
                
                        // Set original view if not volume
                        // @ts-ignore
                        setAutomationView(userView)
                    };
                };
                
                
                dipBydB({ dB: -4, fadeLengthFrames: 4 });
                
                1. Ddanielkassulke @danielkassulke
                    2022-11-25 21:21:16.833Z

                    @samuel_henriques you are an absolute treasure! I am so grateful for your time and generosity.

                    1. Curtis Macdonald @Curtis_Macdonald
                        2022-11-27 14:25:26.931Z

                        this is very cool!
                        Q: how can I make a similar dip using clip gain instead of volume automation?

                        1. Probably just tack a 'coalesce volume automation to clip gain' onto the end of the script or as a macro afterwards is the easiest way.

                    2. Anthony Bauman @Anthony_Bauman
                        2023-01-02 19:07:48.501Z

                        What would need changed to set the fade length in Min:Secs instead of Frames?

                        1. samuel henriques @samuel_henriques
                            2023-01-02 21:50:31.843Z

                            Hello Anthony.
                            The script actually sets samples, that's the best way.
                            So you just need to change the conversion from frames/samples to ms/samples

                            in this line:

                             const fadeLengthInSamples = (frames) => frames * 1920; //1920 = 1 frame@48k@25fps
                            

                            change to:

                             const fadeLengthInSamples = (ms) => ms * 48; //48 samples  = 1 Millisecond
                            

                            48 if you are at a 48k. If you need more min:sec precision, we ned to change the script and add more actions.

                            Then at the end, If you want 1/2 sec, for example

                            dipBydB({ dB: -4, fadeLengthFrames: 500 })
                            

                            Let me know if this is it.

                            1. Anthony Bauman @Anthony_Bauman
                                2023-01-06 20:52:11.961Z

                                That worked perfectly, thank you so much!