No internet connection
  1. Home
  2. How to

How to send file to iZotope, process it and get it back again (fix old script)

By jk79 @jk79
    2023-03-24 19:36:20.715Z

    Title

    Error running script after updating Izotope RX and Pro Tools

    What do you expect to happen when you run the script/macro?

    Send audio from Pro Tools to Izotope RX and back

    Are you seeing an error?

    Tope write corner

    What happens when you run this script?

    Error when running scipt after updating RX and Pro Tools

    How were you running this script?

    I used a keyboard shortcut within the target app

    How important is this issue to you?

    5

    Details

    {
        "inputExpected": "Send audio from Pro Tools to Izotope RX and back",
        "inputIsError": true,
        "inputError": "Tope write corner",
        "inputWhatHappens": "Error when running scipt after updating RX and Pro Tools",
        "inputHowRun": {
            "key": "-Mpfwh4RkPLb2LPwjePT",
            "title": "I used a keyboard shortcut within the target app"
        },
        "inputImportance": 5,
        "inputTitle": "Error running script after updating Izotope RX and Pro Tools"
    }

    Source

    function sendToIzotope() {
        var win = sf.ui.proTools.getAudioSuiteWindow('RX 10 Connect');
        if (!win || !win.exists)
            win = sf.ui.proTools.getAudioSuiteWindow('RX 10 Connect');
        if (!win || !win.exists) {
            if (sf.ui.proTools.getMenuItem('AudioSuite', 'Noise Reduction', 'RX 10 Connect').exists) {
                win = sf.ui.proTools.audioSuiteOpenPlugin({
                    category: 'Noise Reduction',
                    name: 'RX 10 Connect'
                }).window;
            } else if (sf.ui.proTools.getMenuItem('AudioSuite', 'Noise Reduction', 'RX 10 Connect').exists) {
                win = sf.ui.proTools.audioSuiteOpenPlugin({
                    category: 'Noise Reduction',
                    name: 'RX 10 Connect'
                }).window;
            } else
                throw "RX 10 Connect not installed, or you are not sorting modules by Category";
        }
    
        win.audioSuiteSetOptions({ processingInputMode: 'ClipByClip', processingOutputMode: 'CreateIndividualFiles' });
        win.getFirstWithTitle("Analyze").elementClick();
    }
    
    function sendToIzotopeAndWaitForFileToBeReady() {
        function getPath() {
            var docs = sf.ui.izotope.windows.filter(w => w.getString("AXDocument") != null);
            return docs.length > 0 ? decodeURIComponent(docs[0].getString("AXDocument")).replace(/^file:\/\//, "") : null;
        }
    
        //Make sure to clean any existing files for RX connect
        var path = getPath();
        if (path && sf.file.exists({ path: path }).exists) {
            sf.file.delete({ path: path });
        }
    
        sf.ui.proTools.appActivateMainWindow();
        sendToIzotope();
        sf.ui.izotope.appActivateMainWindow();
    
        //Wait for file to exist and be ready in the document
        path = getPath();
        while (!path || !sf.file.exists({ path: path }).exists) {
            sf.wait({ intervalMs: 100 });
            path = getPath();
        }
    }
    
    function waitForIzotopeProcessing() {
        const isProcessing = () => {
            try {
                return sf.ui.izotope.floatingWindows.whoseTitle.startsWith("Pro Tools ").exists ||
                    sf.ui.izotope.floatingWindows.whoseTitle.startsWith("Composite").exists;
            } catch (err) {
                //We should get here if iZotope didn't respond in time
                return true;
            }
        }
    
        sf.wait({ intervalMs: 1000 });
    
        while (isProcessing()) {
            sf.wait({ intervalMs: 500 });
        }
    }
    
    function renderAndSpot() {
        var shuttleBtn = sf.ui.izotope.mainWindow.children.whoseDescription.endsWith('Main Window').first.children.whoseDescription.is("Shuttle").first;
        shuttleBtn.elementClick({}, "Could not click Send Back button");
    
        sf.wait({ intervalMs: 500 });
    
        sf.ui.proTools.appActivateMainWindow({}, "Could not activate Pro Tools");
    
        var win = sf.ui.proTools.floatingWindows.filter(function (w) { var t = w.title.value; return t.indexOf("Audio Suite: RX") == 0 && t.indexOf("Connect") >= 0 })[0];
        if (!win || !win.exists) throw "Could not find iZotope RX Connect AudioSuite window";
    
        win.buttons.whoseTitle.is("Render").first.elementClick({}, "Could not click Render");
    }
    
    /**
     * @param {AxElement} moduleWin
     */
    function selectPluginPreset(moduleWin, name) {
        var btn = moduleWin.groups.whoseDescription.startsWith('EffectPanel').first.groups.whoseDescription.startsWith('EffectPanel').first.groups.whoseDescription.contains('Header Background').first.popupButtons.whoseTitle.contains('Preset').first;
        if (btn.value.invalidate().value == name) return;
        btn.elementClick();
        sf.keyboard.press({ keys: 'enter' });
        while (true) {
            sf.engine.checkForCancellation();
            if (btn.value.invalidate().value == name) break;
            sf.keyboard.press({ keys: 'down' });
        }
    }
    
    /**
     * @param {AxElement} moduleWin
     */
    function refreshPluginPreset(moduleWin) {
        var btn = moduleWin.groups.whoseDescription.startsWith('EffectPanel').first.groups.whoseDescription.startsWith('EffectPanel').first.groups.whoseDescription.contains('Header Background').first.popupButtons.whoseTitle.contains('Preset').first;
        btn.elementClick();
        sf.keyboard.press({ keys: 'return' });
    }
    
    function doProcess(modules) {
    
        sendToIzotopeAndWaitForFileToBeReady();
    
        //Make sure to click composite view button
        const compositeViewBtn = sf.ui.izotope.mainWindow.children.whoseDescription.endsWith('Main Window').first.getFirstWithDescription("Composite View");
        if (compositeViewBtn.exists) {
            compositeViewBtn.elementClick({}, 'Could not click composite view button');
        }
    
        //Process modules
        modules.map(({ moduleName, presetName }) => {
    
            //Make sure module is open
            var moduleWin = sf.ui.izotope.floatingWindows.whoseTitle.is(moduleName).first;
            if (!moduleWin.exists) {
                sf.ui.izotope.getMenuItem('Modules', moduleName + '...').elementClick();
                moduleWin.elementWaitFor({}, `Could not open module '${moduleName}'`);
            }
    
            //Try to select the correct preset
            refreshPluginPreset(moduleWin);
            selectPluginPreset(moduleWin, presetName);
    
            //Click Process
            var btn = moduleWin.getFirstOf('AXGroup').getFirstOf('AXGroup').getElements('AXChildren')[1].getFirstOf('AXButton');
            if (!btn.exists)
                throw 'Could not find Process button in module';
    
            //Sometimes iZotope is busy from the previous operation, so keep trying to click process until we succeed :)
            while (true) {
                var clickResult = btn.elementClick({ onError: 'Continue' });
                if (clickResult.success) break;
    
                sf.wait({ intervalMs: 1000 });
            }
    
            waitForIzotopeProcessing();
        });
    
        //Done processing, send back
        renderAndSpot();
    }
    
    
    /* MAIN */
    
    function main() {
        doProcess([
            {
                moduleName: 'Leveler',
                presetName: '00 JK DX',
            },
        ]);
    }
    
    main();
    
    
    
    
    
    
    
    

    Links

    User UID: 7UT9gXitUkgi9UEG2k1BdDw7rwd2

    Feedback Key: sffeedback:7UT9gXitUkgi9UEG2k1BdDw7rwd2:-NRK6nZwlGJ6iCWGcXqX

    Feedback ZIP

    • 5 replies
    1. Hi Joe,

      Thanks for reporting here. As I mentioned on your comment on Facebook as well, the 10.2 version of iZotope RX introduced a lot of changes to UI elements. I'd recommend doing a quick search on the forum for more news on this, as this has already been covered in quite a few threads.

      In short, because the layouts of UI elements were changed in RX 10, you'd have to remake the parts of your script that rely on those UI elements.
      If you generally use standard iZotope workflows, the Dialog Editing iZotope package is a good place to start, since it already supports the UI element layout changes that were made in RX 10+

      1. Jjk79 @jk79
          2023-03-25 04:47:17.800Z

          Can someone help me figure out how to use Dialog Editing iZotope package to do what this script does?

          1. Let me move this to the How to section, where I think it may get more attention. Also please note that we'll have some product news in this space very soon, that I can't talk publicly about yet :)

            1. To anybody helping out with this, the error is in line 100 and is because the code to fetch the preset popup button needs to be updated for RX 10:

              !! Command Error: RX 10 LEVEL CONSIST [user:ckk73iyut0000mf10dxhxdkfv:cl7s02wl80008o310a3n6gxv3]:
              ClickButtonAction requires UIElement (RX 10 LEVEL CONSIST: Line 100)
              
              1. Jjk79 @jk79
                  2023-04-10 17:46:50.625Z

                  Hi Christian, I believe you created this script for me originally, any chance you can help me getting it working with the new version of RX10? Thanks