No internet connection
  1. Home
  2. How to

how to wait for RX7 Audio Editor to open before proceeding.

By Dustin Harris @Dustin_Harris
    2019-10-21 18:09:10.614Z

    H! I'm working on a script that needs to wait for RX7 Audio editor to be fully open to continue. The way I'm trying to do this is via the availability​ of the composite button (conveniently​ the next step in the script I'm writing) but I must have something wrong with the syntax. I'm currently trying this code below, but I get the error:
    Object reference not set to an instance of an object
    Thoughts?

        sf.engine.runInBackground(function () {
            while (true) {
                sf.engine.checkForCancellation();
                sf.wait({ executionMode: 'Background', intervalMs: 100, onError: 'Continue' });
    
                if (sf.ui.izotope.mainWindow.getFirstWithDescription('RX7 Main Window').getFirstWithDescription("Composite View").exists)
                    break;
            }
        });
    

    Thanks!
    Dustin

    • 20 replies

    There are 20 replies. Estimated reading time: 16 minutes

    1. Hi @Dustin_Harris

      It looks circa right as it is so it might be a bug.
      I have a fix coming in 3.1.1 that might address this though.

      Is there a reason why you're running this in the background?

      1. Dustin Harris @Dustin_Harris
          2019-10-21 18:19:06.190Z

          Hi Cristian!
          No reason other than it was the closest code-snippet I found to what I was trying to do. It's to pause the script while pro tools is sending audio over to RX7 (which can take a while if the files are long and RX7 isn't already open)

          If there is a better way to achieve this, I'm interested in any suggestions :)
          Thanks again,
          Dustin

          1. Cool! You definitely don't need the background mode then.

            Try my suggestions below. Just for clarity, I'll rewrite your above code to be non-background:

            
            while (true) {
                sf.engine.checkForCancellation();
            
                if (sf.ui.izotope.exists && sf.ui.izotope.mainWindow.getFirstWithDescription('RX7 Main Window').getFirstWithDescription("Composite View").exists)
                    break;
            
                sf.wait({ intervalMs: 100 });
            }
            
            
            1. Dustin Harris @Dustin_Harris
                2019-10-21 18:33:42.821Z

                This particular solution continues in the while loop even when the condition appears to be true.
                It might be getting fooled by the appearance of the 'changing audio engine settings' dialogue box that appears on startup?

            2. In reply tochrscheuer:

              You might get slightly better results by doing:

               if (sf.ui.izotope.exists && sf.ui.izotope.mainWindow.getFirstWithDescription('RX7 Main Window').getFirstWithDescription("Composite View").exists)
              
              1. You might also get inspiration here:
                https://forum.soundflow.org/-955#post-12

                function openFileInIzotope(path) {
                        sf.system.exec({
                            commandLine: 'open -a "' + izotopeRx + '" "' + path + '"'
                        });
                        sf.ui.izotope.appWaitForActive();
                        sf.ui.izotope.windows.whoseTitle.isNullOrEmpty.first.elementWaitFor({ waitForNoElement: true });
                    }
                
                1. These 2 lines in particular should do what you need:

                  sf.ui.izotope.appWaitForActive();
                  sf.ui.izotope.windows.whoseTitle.isNullOrEmpty.first.elementWaitFor({ waitForNoElement: true });
                  
                  1. @Dustin_Harris check this one. That works for me.
                    But yes if you get a popup with changing audio engine settings, this one doesn't take care of that.

                    1. Dustin Harris @Dustin_Harris
                        2019-10-21 21:40:37.721Z

                        I tried this, but I get the error "Requested app is not running (AppActivateMainWindowAction)" pointing at the line with the //THIS ONE comment, which I think means it's not waiting for the app to be open (and/or ready) before continuing the script. Thoughts? :)

                        
                        sf.ui.proTools.appActivateMainWindow();
                        
                        var asWin = sf.ui.proTools.getAudioSuiteWindow("RX 7 Connect");
                            if (!asWin.exists){ 
                            log('Please press F13 to open Rx Connect');
                            throw 0;
                        //    var asWin = sf.ui.proTools.audioSuiteOpenPlugin({
                        //        category: 'Noise Reduction',
                        //        name: "RX 7 Connect"
                        //        }).window;
                            
                            }
                        else {}
                        
                        
                        var renderBtn = asWin.getFirstWithTitle("Analyze");
                        renderBtn.elementClick();
                        
                        
                        try {
                        sf.ui.izotope.appActivateMainWindow();
                        }
                        catch(err) {
                            //log('Waiting for Rx Editor To Open')
                            //sf.wait({ intervalMs: 5000 });
                        }
                        
                        //sf.wait({ intervalMs: 750 });
                        
                        sf.ui.izotope.appWaitForActive();
                        sf.ui.izotope.windows.whoseTitle.isNullOrEmpty.first.elementWaitFor({ waitForNoElement: true });
                        
                        sf.ui.izotope.appActivateMainWindow(); //THIS ONE
                        
                        var compositeViewBtn = sf.ui.izotope.mainWindow.getFirstWithDescription('RX7 Main Window').getFirstWithDescription("Composite View");
                        compositeViewBtn.elementClick();
                        

                        Thanks,
                        Dustin.

                        1. Hmm that's odd. This script is just trying to send audio from Connect to iZotope, and perform some actions there?
                          Can you get it to work if iZotope is already running?
                          Is this about making sure that the script also works in those few cases where iZotope wasn't running initially?

                          1. It's very weird that you're getting a requested app is not running after we've already been calling things with izotope. Do you happen to have more than one version of iZotope installed and SF could be confused about which one? This should only matter if they were both running at the same time.

                            1. Dustin Harris @Dustin_Harris
                                2019-10-21 22:11:18.392Z

                                I’ll check my system for other Izotope RX versions... I have all their products so maybe it’s another app interfering?

                                1. In reply tochrscheuer:
                                  Dustin Harris @Dustin_Harris
                                    2019-10-22 00:28:20.229Z

                                    it has occured to me that the error in question could have been thrown after an RX Audio Editor crash. Having rebooted and restarted both programs, I cannot reproduce that error (but the script still doesn't work as intended)
                                    Log attached. Maybe there is some useful info in there!
                                    Dustin

                                    soundflow20191021mainlog.zip (18.4 kB)

                                    1. How does it not work now then (if the original error didn't show)?

                                      I would start by removing this section and debug from then on.
                                      The appWaitForActive action is waiting for iZotope to become active (when Connect is done doing what it does), so this is sort of preempting that.

                                      try {
                                      sf.ui.izotope.appActivateMainWindow();
                                      }
                                      catch(err) {
                                          //log('Waiting for Rx Editor To Open')
                                          //sf.wait({ intervalMs: 5000 });
                                      }
                                      

                                      Also, I think if this continues to not work, I would wait until 3.1.1 comes out with a potential fix for when apps are loading

                                      1. Dustin Harris @Dustin_Harris
                                          2019-10-22 15:09:20.691Z

                                          Heyya! Just in case this is useful, I've made a video of the behavior.
                                          It definitely seems that the script isn't waiting for izotope to be active before continuing, or it's continuing at the very earliest stage of the app initializing.

                                          here's the script:

                                          sf.ui.proTools.appActivateMainWindow();
                                          
                                          var asWin = sf.ui.proTools.getAudioSuiteWindow("RX 7 Connect");
                                              if (!asWin.exists){ 
                                              log('Please press F13 to open Rx Connect');
                                              throw 0;
                                          
                                              }
                                          else {}
                                          
                                          
                                          var renderBtn = asWin.getFirstWithTitle("Analyze");
                                          renderBtn.elementClick();
                                          
                                          
                                          //try {
                                          //sf.ui.izotope.appActivateMainWindow();
                                          //}
                                          //catch(err) {
                                              //log('Waiting for Rx Editor To Open')
                                              //sf.wait({ intervalMs: 5000 });
                                          //}
                                          
                                          //sf.wait({ intervalMs: 750 });
                                          
                                          //sf.ui.izotope.appActivateMainWindow(); //THIS ONE
                                          
                                          sf.ui.izotope.appWaitForActive();
                                          sf.ui.izotope.windows.whoseTitle.isNullOrEmpty.first.elementWaitFor({ waitForNoElement: true });
                                          
                                          //sf.ui.izotope.appActivateMainWindow(); //THIS ONE
                                          
                                          sf.wait({ intervalMs: 750 });
                                          
                                          log('This happens before the composite button click')
                                          
                                          var compositeViewBtn = sf.ui.izotope.mainWindow.getFirstWithDescription('RX7 Main Window').getFirstWithDescription("Composite View");
                                          compositeViewBtn.elementClick();
                                          
                                          log('This happens after the composite button click')
                                          
                                          

                                          and here's a QuickTime​ of what happens. Note the log('This happens before the composite button click') is occurring​ before Izotope becomes the active window.

                                          It's still quite possible that I've messed something up in the code, but I'll let you decide that :)

                                          https://www.dropbox.com/s/c74u8gns7mpepa5/ScriptDebug1.mov?dl=0

                                          Cheers,
                                          Dustin

                                          1. Here's a more fool-proof attempt:

                                            sf.ui.proTools.appActivateMainWindow();
                                            
                                            var asWin = sf.ui.proTools.getAudioSuiteWindow("RX 7 Connect");
                                            if (!asWin.exists) {
                                                log('Please press F13 to open Rx Connect');
                                                throw 0;
                                            }
                                            
                                            var renderBtn = asWin.getFirstWithTitle("Analyze");
                                            renderBtn.elementClick();
                                            
                                            //Wait for iZotope to become responsive
                                            sf.ui.izotope.appWaitForActive();
                                            while (true) {
                                                try {
                                                    sf.ui.izotope.windows.whoseTitle.isNullOrEmpty.first.elementWaitFor({ waitForNoElement: true });
                                                    break;
                                                } catch (err) {
                                                }
                                            }
                                            
                                            //Wait for the shuttle button to appear (indicating that we loaded correctly)
                                            while (true) {
                                                sf.engine.checkForCancellation();
                                                try {
                                                    var shuttleBtn = sf.ui.izotope.mainWindow.children.whoseDescription.endsWith('Main Window').first.children.whoseDescription.is("Shuttle").first;
                                                    shuttleBtn.elementWaitFor({ timeout: 10000 });
                                                    break;
                                                } catch (err) { }
                                                sf.wait({ intervalMs: 200 });
                                            }
                                            
                                            //Now you can click the composite button (note that will only work if more than one clip was selected originally)
                                            
                                            

                                            Note here I'm waiting on the Shuttle (send back) button instead of the Composite one, since if you're only sending one clip, the Composite won't be available.

                                            1. Dustin Harris @Dustin_Harris
                                                2019-10-22 16:52:06.720Z

                                                OOh, this one results in:

                                                an error too long to catch, but here is the associated log bit:

                                                22.10.2019 12:43:49.85 [BackendConnection]: Received msg from backend: { name: '/commands/error',
                                                args:
                                                { command: 'user:ck127r9d00000gz106x00uh9h:ck20q31wl0003rn1053r1xlg7',
                                                commandName: 'SEND TEST',
                                                error:
                                                'SoundFlow.Shortcuts.AXUIElementException: kAXErrorCannotComplete\n at SoundFlow.Shortcuts.AXUIElement.GetSubElements(String) + 0x222\n at SoundFlow.Shortcuts.Ax.AxNodes.AxElementArrayFromAttribute.get_RawItems() + 0x42\n at SoundFlow.Shortcuts.Ax.AxNodes.AxElementArray.get_Length() + 0x28\n at SoundFlow.Shortcuts.Ax.AxNodes.AxElementArrayObjectWrapper..ctor(Engine, AxElementArray) + 0x69\n at SoundFlow.Shortcuts.Ax.AxNodes.AxElementArrayObjectConverter.TryConvert(Engine, Object, JsValue&) + 0x42\n at Jint.Native.JsValue.FromObject(Engine, Object) + 0xac\n at Jint.Runtime.Descriptors.Specialized.PropertyInfoDescriptor.get_CustomValue() + 0x39\n at Jint.Native.Object.ObjectInstance.UnwrapJsValue(PropertyDescriptor, JsValue) + 0x48\n at Jint.Native.Object.ObjectInstance.Get(Key&) + 0x6e\n at Jint.Engine.GetValue(Reference, Boolean) + 0x14a\n at Jint.Runtime.Interpreter.Expressions.JintMemberExpression.EvaluateInternal() + 0x183\n at Jint.Runtime.Interpreter.Expressions.JintMemberExpression.EvaluateInternal() + 0x13b\n at Jint.Runtime.Interpreter.Expressions.JintMemberExpression.EvaluateInternal() + 0x13b\n at Jint.Runtime.Interpreter.Expressions.JintMemberExpression.EvaluateInternal() + 0x13b\n at Jint.Runtime.Interpreter.Expressions.JintCallExpression.EvaluateInternal() + 0x63\n at Jint.Runtime.Interpreter.Expressions.JintExpression.GetValue() + 0x46\n at Jint.Runtime.Interpreter.Statements.JintExpressionStatement.ExecuteInternal() + 0x38\n at Jint.Runtime.Interpreter.JintStatementList.Execute() + 0x279\n at Jint.Runtime.Interpreter.Statements.JintBlockStatement.ExecuteInternal() + 0x2e\n at Jint.Runtime.Interpreter.Statements.JintTryStatement.ExecuteInternal() + 0x98\n at Jint.Runtime.Interpreter.JintStatementList.Execute() + 0x279\n at Jint.Runtime.Interpreter.Statements.JintBlockStatement.ExecuteInternal() + 0x2e\n at Jint.Runtime.Interpreter.Statements.JintWhileStatement.ExecuteInternal() + 0xdf\n at Jint.Runtime.Interpreter.JintStatementList.Execute() + 0x279\n at Jint.Runtime.Interpreter.Statements.JintBlockStatement.ExecuteInternal() + 0x2e\n at Jint.Native.Function.ScriptFunctionInstance.Call(JsValue, JsValue[]) + 0x1c0\n at Jint.Runtime.Interpreter.Expressions.JintCallExpression.EvaluateInternal() + 0x59b\n at Jint.Runtime.Interpreter.Expressions.JintExpression.GetValue() + 0x46\n at Jint.Runtime.Interpreter.Statements.JintExpressionStatement.ExecuteInternal() + 0x38\n at Jint.Runtime.Interpreter.JintStatementList.Execute() + 0x279\n at Jint.Engine.Execute(Program) + 0xf5\n at SoundFlow.Shortcuts.Automation.AutomationEngine.<>c__DisplayClass19_0.b__0() + 0x2e\n at SoundFlow.Shortcuts.Automation.AutomationEngine.d__11.MoveNext() + 0x1be\n\n' } }
                                                22.10.2019 12:43:49.85 [BackendConnection]: Received msg from backend: { name: '/commands/completed', args: { r: 0, e: 10 } }

                                                1. This is the error that will likely be fixed in 3.1.1. Please stay tuned.

                                      2. In reply tochrscheuer:
                                        Dustin Harris @Dustin_Harris
                                          2019-10-21 22:09:22.841Z

                                          You’re exactly right, it works except for when izotope isn’t initially open and the script passes commands before RX is ready for them. I’m just trying to be a tidy programmer :)

                                          1. Nice haha. It's always good to be tidy. But sometimes the 5% corner cases take up 60% of the development time ;)
                                            I will see if I can repro the bug. Can you send me your log file?