Title
Rx Connect Sending Early Before Settings Established (Sonoma 14.6)
What do you expect to happen when you run the script/macro?
Sent a clip to Rx with the designated setting.
Are you seeing an error?
What happens when you run this script?
Pro Tools will pre-emptively send the clip before SoundFlow implements the correct settings. Specifically, when switching from Clip-by-Clip / Individual Files / Mono Input to Entire Selection / Continuous File / Multi Input. PT will submit the first settings, but when re-sending a second time, Rx will properly receive it.
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": "Sent a clip to Rx with the designated setting.", "inputIsError": false, "inputWhatHappens": "Pro Tools will pre-emptively send the clip before SoundFlow implements the correct settings. Specifically, when switching from Clip-by-Clip / Individual Files / Mono Input to Entire Selection / Continuous File / Multi Input. PT will submit the first settings, but when re-sending a second time, Rx will properly receive it.", "inputHowRun": { "key": "-Mpfwh4RkPLb2LPwjePT", "title": "I used a keyboard shortcut within the target app" }, "inputImportance": 5, "inputTitle": "Rx Connect Sending Early Before Settings Established (Sonoma 14.6)" }
Source
if (!sf.ui.proTools.isRunning) throw `Pro Tools is not running`;
const {
rxConnectVersion,
selectionReference,
copyAction,
copyTargetTrackName,
copyTargetTrackNameMatch,
useInPlaylist,
presetPath,
processingOutputMode,
processingInputMode,
inputMode,
previewProcessing,
bypass,
previewVolume,
learn,
wholeFile,
processingHandleLength,
render,
compositeView,
} = event.props;
// Bail out if copy action exists but no track name is specified.
if (copyAction) {
if (copyTargetTrackName === null || copyTargetTrackName === "" || copyTargetTrackName === undefined) {
throw `The "RX Connect: Send to iZotope" preset has no specified "Copt Target Track Name"`;
} else if (copyTargetTrackNameMatch === null || copyTargetTrackNameMatch === "" || copyTargetTrackNameMatch === undefined) {
throw `The "RX Connect: Send to iZotope" preset has no specified "Copt Target Track Name Match"`;
}
}
const rxConnectNames = [
'RX 10 Connect',
'RX 9 Connect',
'RX 8 Connect',
'RX 7 Connect',
'RX 6 Connect',
];
function openRxConnect(version) {
let audioSuiteWindow = sf.ui.proTools.windows.invalidate().whoseTitle.is(`Audio Suite: ${version}`).first;
if (!audioSuiteWindow.exists) {
audioSuiteWindow = sf.ui.proTools.audioSuiteOpenPlugin({
category: 'Noise Reduction',
name: version
}, `Unable to open ${rxConnectVersion}`).window;
}
return audioSuiteWindow;
}
function naturalCompare(a, b) {
const aNum = parseInt(a.match(/\d+/)[0]);
const bNum = parseInt(b.match(/\d+/)[0]);
return aNum - bNum;
}
function getRxConnectWindow() {
let win;
const rxSubPaths = ["iZotope", "iZotope, Inc", "Noise Reduction"];
function getLatest() {
const latestRxVersionName = sf.ui.proTools.getMenuItem("AudioSuite").getMenuItem("Noise Reduction").children.first.children.filter(asName => {
return asName.title.invalidate().value.startsWith("RX") && asName.title.invalidate().value.endsWith("Connect")
}).map(e => e.title.invalidate().value).sort(naturalCompare).reverse()[0];
if (!latestRxVersionName) throw `iZotope RX (6-10) Connect not installed`;
//Open and get the latest RX Connect version's AudioSuite window
return openRxConnect(latestRxVersionName);
}
if (rxConnectVersion === "Currently Open Version") {
let firstOpenRxConnectWindow = sf.ui.proTools.windows.filter(w => {
let title = w.title.invalidate().value;
return title.startsWith("Audio Suite: RX") && title.endsWith("Connect")
})[0];
//Return RX Connect Window
win = firstOpenRxConnectWindow;
if (!win || !win.exists)
win = getLatest();
}
else if (rxConnectVersion === "Latest Available Version") {
win = getLatest();
} else {
//Check for existance of specified RX Connect pluggin
let hasSpecifiedRxConnectVersion = rxSubPaths.some(subPath => {
return sf.ui.proTools.getMenuItem("AudioSuite", subPath, rxConnectVersion).exists
});
//If the RX Conneect version does not exist throw error
if (!hasSpecifiedRxConnectVersion) throw `${rxConnectVersion} not installed`;
//Open Given version AudioSuite Win
win = openRxConnect(rxConnectVersion);
}
return win;
}
function createSelectionCopy() {
const pasteToFirstTrackWithSpace = () => {
sf.ui.proTools.mainWindow.invalidate();
const originalTrack = sf.ui.proTools.selectedTrack;
// Filter the tracks list for backup (copy) tracks
let backupTrackNames = sf.ui.proTools.trackNames.filter(name => name.startsWith(copyTargetTrackName));
for (const trackName of backupTrackNames) {
const track = sf.ui.proTools.trackGetByName({ name: trackName }).track;
track.trackSelect();
sf.keyboard.press({ keys: "left" });
if (!sf.ui.proTools.getMenuItem("Edit", "Trim Clip").isEnabled) {
pasteSelection();
break;
}
if (trackName === backupTrackNames[backupTrackNames.length - 1]) {
originalTrack.trackSelect();
throw "There is no empty space on the backup (copy) track(s)";
}
}
}
const refreshProToolsMenu = () => sf.keyboard.press({ keys: "left" });
const copySelection = () => {
refreshProToolsMenu();
sf.ui.proTools.menuClick({ menuPath: ["Edit", "Copy"] });
}
const pasteSelection = () => {
refreshProToolsMenu();
sf.ui.proTools.menuClick({ menuPath: ["Edit", "Paste"] });
}
const separateSelection = () => {
refreshProToolsMenu();
if (sf.ui.proTools.getMenuItem("Edit", "Trim Clip", "To Selection").isEnabled) {
sf.ui.proTools.menuClick({ menuPath: ["Edit", "Separate Clip", "At Selection"] });
}
}
const muteClips = () => {
refreshProToolsMenu();
const unMuteClipsMenuItem = () => sf.ui.proTools.getMenuItem("Edit", "Unmute Clips");
const muteClipsMenuItem = () => sf.ui.proTools.getMenuItem("Edit", "Mute Clips");
if (unMuteClipsMenuItem().exists) {
unMuteClipsMenuItem().elementClick();
}
muteClipsMenuItem().elementClick();
}
/** This function uses trackGetByName to select the track with a matching name */
function selectTrackByName(name) {
const track = () => sf.ui.proTools.trackGetByName({ name }).track;
if (track().exists) {
track().trackSelect();
} else {
throw `The track named "${name}" does not exist`
}
}
sf.ui.proTools.appActivateMainWindow();
if (copyAction === "ProcessOriginalMutedCopy") {
const originalTrack = sf.ui.proTools.selectedTrack;
copySelection(); // Copy the Selection
if (copyTargetTrackNameMatch === "Equals") {
// Added Temporarily
selectTrackByName(copyTargetTrackName);
} else if (copyTargetTrackNameMatch === "Starts With") {
// Future implementation
//pasteToFirstTrackWithSpace(); // Paste to first available backup (copy) track
}
pasteSelection();
muteClips(); // Mute the selection
originalTrack.trackSelect();
sf.wait({ intervalMs: 20 });
} else if (copyAction === "MuteOriginalProcessCopy") {
copySelection(); // Copy the Selection
separateSelection(); // Separate Selection if part of a full clip
muteClips(); // Mute the selection
if (copyTargetTrackNameMatch === "Equals") {
// Added Temporarily
selectTrackByName(copyTargetTrackName);
} else if (copyTargetTrackNameMatch === "Starts With") {
// Future implementation
//pasteToFirstTrackWithSpace(); // Paste to first available backup (copy) track
}
pasteSelection();
}
}
function setAudioSuiteSettings() {
sf.ui.proTools.appActivateMainWindow();
sf.ui.proTools.mainWindow.invalidate();
const firstAudioSuiteWindow = sf.ui.proTools.firstAudioSuiteWindow;
// Header Elements
const selectionReferencePopUpBtn = firstAudioSuiteWindow.invalidate().getFirstWithTitle("Selection Reference");
const useProcessedOutputInPlaylistBtn = firstAudioSuiteWindow.getFirstWithTitle("Use Processed Output In Playlist");
const presetPopUpBtn = firstAudioSuiteWindow.getFirstWithTitle("Preset");
const processingOutputModePopUpBtn = firstAudioSuiteWindow.getFirstWithTitle("Processing Output Mode");
const processingInputModePopUpBtn = firstAudioSuiteWindow.getFirstWithTitle("Processing Input Mode");
const inputModePopUpBtn = firstAudioSuiteWindow.getFirstWithTitle("input mode");
// Footer Elements
const previewProcessingBtn = firstAudioSuiteWindow.buttons.whoseTitle.is("Preview Processing").first;
const bypassBtn = firstAudioSuiteWindow.buttons.whoseTitle.is("Bypass").first;
const previewVolumeSlider = firstAudioSuiteWindow.sliders.whoseTitle.is("Preview Volume").first;
const learnBtn = firstAudioSuiteWindow.buttons.whoseTitle.is("Analyze").first;
const wholeFileBtn = firstAudioSuiteWindow.buttons.whoseTitle.is("WHOLE FILE").first;
const processingHandleLengthTextField = firstAudioSuiteWindow.textFields.whoseTitle.is("Processing Handle Length in Seconds").first;
const renderBtn = firstAudioSuiteWindow.buttons.whoseTitle.is("Render").first;
// Set Header Settings
// Set Selection Reference ('playlist'|'cliplist')
if (selectionReference !== undefined && selectionReferencePopUpBtn.value.invalidate().value !== selectionReference) {
selectionReferencePopUpBtn.popupMenuSelect({
menuPath: [selectionReference],
});
}
// Set "USE IN PLAYLIST" button (boolean)
let isUsedInPlaylist = useProcessedOutputInPlaylistBtn.value.invalidate().value === "Selected";
if (useInPlaylist !== undefined && isUsedInPlaylist !== useInPlaylist) {
useProcessedOutputInPlaylistBtn.elementClick();
}
// Set AudioSuite Preset
if (presetPath !== undefined && presetPath !== "") {
presetPopUpBtn.popupMenuSelect({
menuPath: presetPath,
});
}
// Set AudioSuite Processing Output Mode ('overwrite files'|'create individual files'|'create continuous file')
if (processingOutputMode !== undefined && processingOutputModePopUpBtn.value.invalidate().value !== processingOutputMode) {
processingOutputModePopUpBtn.popupMenuSelect({
menuPath: [processingOutputMode],
});
//Hack needed to close popup menu.
sf.ui.proTools.appActivateMainWindow();
}
// Set AudioSuite Processing Input Mode ('clip-byclip'|'entire-selection')
if (processingInputMode !== undefined && processingInputModePopUpBtn.value.invalidate().value !== processingInputMode) {
processingInputModePopUpBtn.popupMenuSelect({
menuPath: [processingInputMode],
});
}
// Set AudioSuite "Input Mode" ('mono mode'|'multi-input mode')
if (inputMode !== undefined && inputModePopUpBtn.value.invalidate().value !== inputMode) {
inputModePopUpBtn.popupMenuSelect({
menuPath: [inputMode],
});
}
// Set Footer Settings
// Press "Preview Processing" Button
if (previewProcessing !== undefined && previewProcessingBtn.exists && previewProcessingBtn.value.invalidate().value === "Selected" !== previewProcessing) {
previewProcessingBtn.elementClick();
}
//Set "Bypass" button state
if (bypass !== undefined && bypassBtn.exists && bypassBtn.value.invalidate().value === "Selected" !== bypass) {
bypassBtn.elementClick();
}
//Set "Preview Volume" (Not Tested)
if (previewVolume !== undefined && previewVolumeSlider.exists && previewVolumeSlider.value.invalidate().value !== previewVolume) {
previewVolumeSlider.value.value = previewVolume;
}
//Click "Learn" button
if (learn !== undefined && learnBtn.exists && learnBtn.value.invalidate().value !== learn) {
learnBtn.elementClick();
sf.ui.proTools.waitForNoModals();
}
//Set "WHOLE FILE" button state
if (wholeFile !== undefined && wholeFileBtn.exists && (wholeFileBtn.value.invalidate().value === "Selected" !== wholeFile)) {
wholeFileBtn.elementClick();
}
/**
* @param {object} obj
* @param {AxElement} obj.handleField
* @param {number} obj.value
*/
function setHandleLengthValue({ handleField, value }) {
handleField.elementWaitFor();
const formatedValue = value.toFixed(2).toString().padStart(7).toString();
if (handleField.value.invalidate().value !== formatedValue) {
// Get clipboard text
const oldClipboardText = sf.clipboard.getText().text || "";
try {
sf.clipboard.setText({ text: formatedValue });
handleField.elementClick();
sf.keyboard.press({ keys: "cmd+v", });
let i = 0;
do {
sf.wait({ intervalMs: 100 });
i++
if (i >= 20) { throw `Could not update the number field` }
} while (handleField.value.invalidate().value !== formatedValue);
sf.keyboard.press({ keys: 'return' });
} finally {
// Restore Clipboard text
sf.clipboard.setText({ text: oldClipboardText });
}
}
}
//Set Processing Handle Length
if (processingHandleLength && processingHandleLengthTextField.exists) {
setHandleLengthValue({
handleField: processingHandleLengthTextField,
value: processingHandleLength,
});
}
//Click Render
if (render) {
renderBtn.elementClick();
firstAudioSuiteWindow.elementWaitFor({ waitForNoElement: true });
sf.ui.proTools.waitForNoModals();
}
}
/**
* @param {object} obj
* @param {'Enable'|'Disable'|'Toggle'} obj.targetValue
*/
function setCompositeView({ targetValue }) {
const izotope = sf.ui.izotope;
izotope.invalidate();
izotope.appActivateMainWindow();
const compositViewBtn = izotope.mainWindow.buttons.whoseDescription.is("Composite View").first;
const compositeTab = izotope.mainWindow.getFirstWithDescription("Composite Tab");
const clickCompositeBtn = () => compositViewBtn.elementClick({ onError: "Continue" });
switch (targetValue) {
case "Enable":
if (!compositeTab.exists) clickCompositeBtn();
break;
case "Disable":
if (compositeTab.exists) clickCompositeBtn();
break;
case "Toggle":
clickCompositeBtn();
break;
}
}
//Wait for iZotope to be in focus.
function activateAndWaitForiZotope() {
let tries = 0;
while (!sf.ui.frontmostApp.title.value || !sf.ui.frontmostApp.title.value.includes("iZotope") && tries < 20) {
sf.wait({ intervalMs: 200 });
tries++;
}
if (tries === 40) throw `Could not activate iZotope RX`;
}
function main() {
const win = getRxConnectWindow();
// Make Unprocessed Copy
if (copyAction) {
createSelectionCopy();
}
setAudioSuiteSettings();
win.getFirstWithTitle("Analyze").elementClick();
activateAndWaitForiZotope();
//Set to Composite View option
if (compositeView !== undefined && compositeView) {
setCompositeView({ targetValue: compositeView });
}
}
main();
Links
User UID: TnhuNKPrVzSFfAusX111YfbM4T82
Feedback Key: sffeedback:TnhuNKPrVzSFfAusX111YfbM4T82:-O3cgUTZy0s6uXLpWci9
Feedback ZIP: QMPvYoKtlXvH6ox4bN0rzcH59DoylyhisKJ6+elJUh0rRySH7Xotp/oXX2qFndfflAEE6V54HN/Ct2kcMBg/FT3kWsJ2lJzlWkSOAVyThD1xU6iU77eDdfW4uiJ75ktHBt3pI1PIRhRqOW1BK7QrOI7r7AMeInfW2+VKo9r/OXIx8PC8GN9Rt3PmaZ3qKLf0bDFZmL93tw3tmR1o6OFZDj+062ILWIAkS/e3Gv8OvPvFtUQ6E3PkGbXE2O9NSYIHK2S5pZt8zF9ySYh+r15mrqcAnUMUSG8hyBKTPnvYPDPAfHucu1GzMlIEa+cZcRsTVIoq0mOuBw51psP/3jDVQLCXRT392ShpR2LJJ82oLq8=
- Dustin Harris @Dustin_Harris
this is a very quick and dirty fix attempt, but try replacing the above lines 280 through 292 inclusive with this and see if it solves the issue? (back up your original script first :) )
// Set AudioSuite Processing Input Mode ('clip-byclip'|'entire-selection') if (processingInputMode !== undefined && processingInputModePopUpBtn.value.invalidate().value !== processingInputMode) { processingInputModePopUpBtn.popupMenuSelect({ menuPath: [processingInputMode], }); while (processingInputModePopUpBtn.value.invalidate().value !== processingInputMode) sf.wait({ intervalMs: 100 }) } // Set AudioSuite "Input Mode" ('mono mode'|'multi-input mode') if (inputMode !== undefined && inputModePopUpBtn.value.invalidate().value !== inputMode) { inputModePopUpBtn.popupMenuSelect({ menuPath: [inputMode], }); while (inputModePopUpBtn.value.invalidate().value !== inputMode) sf.wait({ intervalMs: 100 }) }
- BIn reply toBen_Rauscher⬆:Ben Rauscher @Ben_Rauscher
Thank you Dustin; this is working properly again. I made an editable copy of the command from the iZotope package, and replaced the code as directed.