How to send file to iZotope, process it and get it back again (fix old script)
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
- Christian Scheuer @chrscheuer2023-03-25 02:07:46.121Z
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+- Jjk79 @jk79
Can someone help me figure out how to use Dialog Editing iZotope package to do what this script does?
Christian Scheuer @chrscheuer2023-03-25 10:35:56.415Z
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 :)
Christian Scheuer @chrscheuer2023-03-25 10:42:42.902Z
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)
- Jjk79 @jk79
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