No internet connection
  1. Home
  2. How to

Logic Pro X: Access the parameters in the inspector via key commands/shortcuts

By Oscar Fogelstrom @Oscar_Fogelstrom
    2019-06-22 15:46:29.667Z

    It would be nice to be able to access the parameters in the [Inspector] via key commands/shortcuts, for example [Gain], [Transpose] etc for the selected region. Pretty much like the change clip gain function in Pro Tools [Cntrl+Shift+Up/Down Arrow] but selectable of course.

    Solved in post #2, click to view
    • 44 replies

    There are 44 replies. Estimated reading time: 26 minutes

    1. Hi @Oscar_Fogelstrom.

      This script decreases the gain by 0,5 dB:
      I have also made a package where I will be putting all Logic related scripts (I just called it Logic, you can find it in the Store tab and install it)
      This requires newest SoundFlow 3 preview (I'll get you a copy) and was tested on Logic Pro X 10.3.3

      
      var logic = sf.ui.app('com.apple.logic10');
      
      function getSlider(name) {
          var mainWin = logic.mainWindow;
          var inspector = mainWin.groups.whoseDescription.is('Inspector').first;
          var inspectorList = inspector.childrenByRole("AXList").first;
          var regionGroup = inspectorList.children.first;
          var regionOutline = regionGroup.childrenByRole("AXScrollArea").first.children.first;
          var itemRow = regionOutline.children.allItems.filter(function (row) {
              var textField = row.textFields.first;
              return textField.exists && textField.value.value == name + ":";
          })[0];
          var slider = itemRow.sliders.first;
          return slider;
      }
      
      var gainSlider = getSlider("Gain");
      gainSlider.value.intValue = gainSlider.value.invalidate().intValue - 5;
      
      ReplySolution
      1. OOscar Fogelstrom @Oscar_Fogelstrom
          2019-06-22 18:00:36.236Z

          Awesome! Just waiting for SF3 and the Logic Folder in the store then!

          1. In reply tochrscheuer:
            OOscar Fogelstrom @Oscar_Fogelstrom
              2019-06-22 18:09:03.566Z

              Ok, this is a bit embarrassing, but apparently the transpose function already existed as a Logic Key Command. I Didn't check, since I was in a "hurry" to get this going...

              BUT the gain certainly did not exist! And it works exactly as intended. Perfect, thanks!
              Maybe you can add a 3db step too? Think that should be enough

              1. No worries - have added some more gain functions in 0.0.4. If you close the SoundFlow window, open it again and then go to the Store and click available updates, you should be able to update.

                1. OOscar Fogelstrom @Oscar_Fogelstrom
                    2019-06-22 18:26:34.612Z

                    Perfect! Let me check

                    1. In reply tochrscheuer:
                      OOscar Fogelstrom @Oscar_Fogelstrom
                        2021-04-10 05:42:11.094Z

                        Hello! This seems to be broken for me now. Any chance of checking what could be the problem?
                        Thanks//O

                    2. In reply tochrscheuer:
                      AAlex Oldroyd @Alex_Oldroyd8
                        2022-01-29 13:49:46.975Z

                        Hey @chrscheuer. This script puts the gain up to +30db before then decreasing by 0.5db... I can't work out what's going wrong... I'm in Logic 10.7.1

                        1. Kitch Membery @Kitch2022-01-31 10:59:01.860Z

                          @Alex_Oldroyd8 & @Oscar_Fogelstrom you champions,

                          I see what's going on here. It looks like the slider element uses the "AXIncrement" and "AXDecrement" to adjust the value. That takes a little extra code like this;

                          /**
                           * @param {string} name
                           */
                          function getSlider(name) {
                              const logic = sf.ui.app('com.apple.logic10');
                              const mainWin = logic.mainWindow;
                              const inspector = mainWin.groups.whoseDescription.is('Inspector').first;
                              const inspectorList = inspector.childrenByRole("AXList").first;
                              const regionGroup = inspectorList.groups.find(e =>
                                  e.childrenByRole("AXStaticText").whoseValue.is("Region:").first.exists
                              );
                              const regionOutline = regionGroup.childrenByRole("AXScrollArea").first.children.first;
                              const itemRow = regionOutline.children.allItems.find(row => {
                                  const textField = row.textFields.first;
                                  return textField.exists && textField.value.value == name + ":";
                              });
                          
                              const slider = itemRow.sliders.first;
                              return slider;
                          }
                          
                          /**
                           * @param {object} obj
                           * @param {string} obj.sliderName
                           * @param {number} obj.amount
                           */
                          function adjustSliderValue({ sliderName, amount }) {
                              const gainSlider = getSlider(sliderName);
                          
                              if (amount >= 0) {
                                  for (let i = 0; i < amount; i++) {
                                      gainSlider.elementClick({ actionName: "AXIncrement" });
                                  }
                              } else {
                                  for (let i = 0; i > amount; i--) {
                                      gainSlider.elementClick({ actionName: "AXDecrement" });
                                  }
                              }
                          }
                          

                          Then use these get the slider moving :-)

                          //Increment Gain 5db
                          adjustSliderValue({
                              sliderName: "Gain",
                              amount: +5
                          });
                          
                          //Decrement Gain 5db
                          adjustSliderValue({
                              sliderName: "Gain",
                              amount: -5
                          });
                          
                          //Reset Gain
                          getSlider("Gain").elementClick({ actionName: "AXPress" });
                          

                          I've also updated the getSlider function to account for the GUI changing UIElement positions.

                          Let me know how it runs for you.
                          Rock on!

                          1. AAlex Oldroyd @Alex_Oldroyd8
                              2022-02-03 08:04:56.044Z

                              Thank you, @Kitch !

                              1. Kitch Membery @Kitch2022-02-03 08:12:38.860Z

                                My pleasure mate!

                                1. AAlex Oldroyd @Alex_Oldroyd8
                                    2022-02-03 18:22:37.307Z

                                    I'm trying to add to this script so that if the region inspector isn't already open, it will open... but for some reason I can't get it to work... This is where I've got to

                                    const inspector = sf.ui.app("com.apple.logic10").mainWindow.groups.whoseDescription.is("Inspector");
                                    
                                    if (!inspector.exists){
                                        sf.ui.app("com.apple.logic10").mainWindow.groups.whoseDescription.is("Inspector").first.children.whoseRole.is("AXList").first.groups.first.children.whoseRole.is("AXDisclosureTriangle").first.checkboxSet({
                                        targetValue: "Enable",
                                    });
                                    };
                                    
                                    1. Kitch Membery @Kitch2022-02-03 19:30:29.906Z

                                      Hi @Alex_Oldroyd8,

                                      I actually wrote a script for this the other day.

                                      /**
                                       * @param {object} obj
                                       * @param {'Library'|'Inspector'|'Quick Help'|'Toolbar'|'Smart Controls'|'Mixer'|'Editors'} obj.viewName
                                       * @param {'Enable'|'Disable'|'Toggle'} [obj.targetValue]
                                       */
                                      function setViews({ viewName, targetValue }) {
                                          const logic = sf.ui.app("com.apple.logic10");
                                          const controlBar = logic.mainWindow.groups.whoseDescription.is("Control Bar").first;
                                          const viewButton = controlBar.checkBoxes.whoseTitle.is(viewName).first;
                                      
                                          viewButton.checkboxSet({ targetValue, });
                                      }
                                      
                                      /**
                                       * @param {object} obj
                                       * @param {'Quick Help'|'Region'|'Groups'|'Track'} obj.inspectorName
                                       * @param {'Enable'|'Disable'|'Toggle'} [obj.targetValue]
                                       */
                                      function ensureInspector({ inspectorName, targetValue = "Toggle" }) {
                                          const logic = sf.ui.app('com.apple.logic10');
                                          const mainWin = logic.mainWindow;
                                          const inspector = mainWin.groups.whoseDescription.is('Inspector').first;
                                          const inspectorList = inspector.childrenByRole("AXList").first;
                                      
                                          const inspectorRow = inspectorList.groups.filter(e =>
                                              e.childrenByRole("AXStaticText").whoseValue.is(inspectorName + ":").first.exists ||
                                              e.childrenByRole("AXStaticText").whoseValue.is(inspectorName).first.exists,
                                          )[0];
                                      
                                          const disclosureTriangle = inspectorRow.childrenByRole("AXDisclosureTriangle").first;
                                      
                                          const isInspectorOpen = disclosureTriangle.value.invalidate().intValue === 1;
                                      
                                          switch (true) {
                                              case targetValue === "Enable" && !isInspectorOpen:
                                                  disclosureTriangle.elementClick();
                                                  break;
                                              case targetValue === "Disable" && isInspectorOpen:
                                                  disclosureTriangle.elementClick();
                                                  break;
                                              case targetValue === "Toggle":
                                                  disclosureTriangle.elementClick();
                                                  break;
                                          }
                                      }
                                      
                                      function main() {
                                          const logic = sf.ui.app("com.apple.logic10");
                                          logic.appActivateMainWindow();
                                      
                                          setViews({
                                              viewName: "Inspector",
                                              targetValue: "Enable",
                                          });
                                      
                                          ensureInspector({
                                              inspectorName: 'Region',
                                              targetValue: 'Enable',
                                          });
                                      }
                                      
                                      main();
                                      

                                      Rock on!

                                      1. AAlex Oldroyd @Alex_Oldroyd8
                                          2022-02-04 11:25:50.507Z

                                          Oh wow this looks amazing. I've noticed you using this sort of code a lot:

                                          /**
                                           * @param {object} obj
                                           * @param {'Library'|'Inspector'|'Quick Help'|'Toolbar'|'Smart Controls'|'Mixer'|'Editors'} obj.viewName
                                           * @param {'Enable'|'Disable'|'Toggle'} [obj.targetValue]
                                           */
                                          

                                          What does it mean? It's all inactive no?

                                          Also - how would you adapt this code to affect the loop browser window or file browser for example?

                                          Thanks again @kitch

                                          1. Kitch Membery @Kitch2022-02-04 18:48:59.415Z

                                            Hi @Alex_Oldroyd8,

                                            Ah yeah, this markup is what is called JSDoc (i think it stands for Javascript Documentation) Most of the time it's not required for the associated function to run. It is however active in that it states what the argument type and value is, so in this example, I'm stating that the first argument/parameter viewName can be any of the following values 'Library'|'Inspector'|'Quick Help'|'Toolbar'|'Smart Controls'|'Mixer'|'Editors' and the targetValue parameter can be any of these values 'Enable'|'Disable'|'Toggle' The first line simply means that the parameters reside inside an object (ie wrapped in curly brackets {}).

                                            You can read more about JSDoc here https://jsdoc.app/

                                            When I have some time I'll put together a script to do the same thing for the List Editors, Note Pads, Loop Browser and Browser.

                                            1. AAlex Oldroyd @Alex_Oldroyd8
                                                2022-02-05 01:38:00.223Z

                                                Thanks for this, @Kitch. Really helpful

                                          2. In reply toAlex_Oldroyd8:
                                            Kitch Membery @Kitch2022-02-03 19:39:18.204Z

                                            Note:

                                            The setViews function can be used to show/hide/toggle the following views as long as they appear in the header of the logic;

                                            • Library
                                            • Inspector
                                            • Quick Help
                                            • Toolbar
                                            • Smart Controls
                                            • Mixer
                                            • Editors

                                            And the ensureInspector function can open/close/toggle the following sections of the Inspector.

                                            • Quick Help
                                            • Region
                                            • Groups
                                            • TrackÏ
                                2. J
                                  Johan Nordin @Johan_Nordin
                                    2022-01-27 20:16:51.580Z2022-01-27 20:41:18.201Z

                                    Hello! I would like to access the fade in and fade out boxes for entering fade values but can’t figure out how to access them with the UI picker tool when they’re not pop-up menus. @chrscheuer do you have any advice?

                                    Johan

                                    1. Let me cc @Kitch here as he'll probably know more about this :)

                                      1. In reply toJohan_Nordin:
                                        Kitch Membery @Kitch2022-01-28 23:00:27.628Z

                                        Hi @Johan_Nordin,

                                        This should do the trick;

                                        Add this function to your script

                                        function getSlider(name) {
                                            const logic = sf.ui.app('com.apple.logic10');
                                            const mainWin = logic.mainWindow;
                                            const inspector = mainWin.groups.whoseDescription.is('Inspector').first;
                                            const inspectorList = inspector.childrenByRole("AXList").first;
                                            const regionGroup = inspectorList.children.first;
                                            const regionOutline = regionGroup.childrenByRole("AXScrollArea").first.children.first;
                                            const itemRow = regionOutline.children.allItems.filter(row => {
                                                const popupButton = row.popupButtons.first;
                                                return popupButton.exists && popupButton.value.value == name;
                                            })[0];
                                            const slider = itemRow.sliders.first;
                                            return slider;
                                        }
                                        

                                        Then you can manipulate the Fade-in & Fade-out values with this code (See code comments).

                                        const fadeInSlider = getSlider("Fade-In");
                                        const fadeOutSlider = getSlider("Fade-Out");
                                        
                                        //Set Fade-In Value
                                        fadeInSlider.value.intValue = 200;
                                        
                                        //Set Fade-Out Value
                                        fadeOutSlider.value.intValue = 200;
                                        
                                        //Increment Fade-In Value
                                        fadeInSlider.value.intValue = fadeInSlider.value.invalidate().intValue + 100;
                                        
                                        //Increment Fade-Out Value
                                        fadeOutSlider.value.intValue = fadeOutSlider.value.invalidate().intValue + 100;
                                        
                                        //Decrement Fade-In Value
                                        fadeInSlider.value.intValue = fadeInSlider.value.invalidate().intValue - 100;
                                        
                                        //Decrement Fade-Out Value
                                        fadeOutSlider.value.intValue = fadeOutSlider.value.invalidate().intValue - 100;
                                        

                                        I hope that helps :-)

                                        1. JJohan Nordin @Johan_Nordin
                                            2022-01-29 09:30:09.004Z

                                            Thanks @kitch. Don't know if I need something before your code, but Im getting this error message:

                                            29.01.2022 10:28:54.38 [Backend]: !! Command Error: Fade [user:ckoppxsq90012ua10r2wmsfcd:ckyzmh3fn0000r4104h42f03p]:
                                            TypeError: Cannot read property 'sliders' of undefined
                                            (Fade line 12)

                                            Best, Johan

                                            1. Kitch Membery @Kitch2022-01-29 09:42:31.193Z

                                              Hi @Johan_Nordin,

                                              Just to check... Is the region details panel visible?

                                              1. JJohan Nordin @Johan_Nordin
                                                  2022-01-29 10:22:26.660Z

                                                  Yes :)

                                                  1. Kitch Membery @Kitch2022-01-29 10:32:51.616Z

                                                    Hmm,

                                                    And say for instance you wanted to set the "Fade-In" value to 300 Your script should like like this.

                                                    function getSlider(name) {
                                                        const logic = sf.ui.app('com.apple.logic10');
                                                        const mainWin = logic.mainWindow;
                                                        const inspector = mainWin.groups.whoseDescription.is('Inspector').first;
                                                        const inspectorList = inspector.childrenByRole("AXList").first;
                                                        const regionGroup = inspectorList.children.first;
                                                        const regionOutline = regionGroup.childrenByRole("AXScrollArea").first.children.first;
                                                        const itemRow = regionOutline.children.allItems.filter(row => {
                                                            const popupButton = row.popupButtons.first;
                                                            return popupButton.exists && popupButton.value.value == name;
                                                        })[0];
                                                        const slider = itemRow.sliders.first;
                                                        return slider;
                                                    }
                                                    
                                                    const fadeInSlider = getSlider("Fade-In");
                                                    
                                                    //Set Fade-In Value
                                                    fadeInSlider.value.intValue = 300;
                                                    

                                                    Can you try that and see if it works?

                                                    Fingers crossed!

                                                    1. JJohan Nordin @Johan_Nordin
                                                        2022-01-30 21:08:54.400Z

                                                        Nop, sorry. :(

                                                        30.01.2022 22:08:07.44 [Backend]: !! Command Error: Fade [user:ckoppxsq90012ua10r2wmsfcd:ckyzmh3fn0000r4104h42f03p]:
                                                        TypeError: Cannot read property 'sliders' of undefined
                                                        (Fade line 12)

                                                        1. Kitch Membery @Kitch2022-01-30 22:31:01.140Z2022-01-31 02:31:48.442Z

                                                          I just noticed that the UI Element position of the "Region:" inspector changes. Hopefully this will work; :-)

                                                          function getRegionInspectorSlider(name) {
                                                              const logic = sf.ui.app('com.apple.logic10');
                                                              logic.appActivateMainWindow();
                                                              const mainWin = logic.mainWindow;
                                                              const inspector = mainWin.getFirstWithDescription('Inspector');
                                                              const inspectorList = inspector.childrenByRole("AXList").first;
                                                              const regionGroup = inspectorList.groups.find(e =>
                                                                  e.childrenByRole("AXStaticText").whoseValue.is("Region:").first.exists
                                                              );
                                                              const regionOutline = regionGroup.childrenByRole("AXScrollArea").first.children.first;
                                                              const itemRow = regionOutline.children.allItems.find(row => {
                                                                  const popupButton = row.popupButtons.first;
                                                                  return popupButton.exists && popupButton.value.value == name;
                                                              });
                                                          
                                                              const slider = itemRow.sliders.first;
                                                              return slider;
                                                          }
                                                          
                                                          const fadeInSlider = getRegionInspectorSlider("Fade-In");
                                                          const fadeOutSlider = getRegionInspectorSlider("Fade-Out");
                                                          
                                                          //Set Fade-In Value
                                                          fadeInSlider.value.intValue = 400;
                                                          
                                                          //Set Fade-Out Value
                                                          fadeOutSlider.value.intValue = 400;
                                                          
                                                          //Increment Fade-In Value
                                                          //fadeInSlider.value.intValue = fadeInSlider.value.invalidate().intValue + 100;
                                                          
                                                          //Increment Fade-Out Value
                                                          //fadeOutSlider.value.intValue = fadeOutSlider.value.invalidate().intValue + 100;
                                                          
                                                          //Decrement Fade-In Value
                                                          //fadeInSlider.value.intValue = fadeInSlider.value.invalidate().intValue - 100;
                                                          
                                                          //Decrement Fade-Out Value
                                                          //fadeOutSlider.value.intValue = fadeOutSlider.value.invalidate().intValue - 100;
                                                          

                                                          UPDATED (now Activates Logics main window if it is not frontmost)

                                                          Let me know :-)

                                                          1. JJohan Nordin @Johan_Nordin
                                                              2022-02-01 20:14:47.202Z

                                                              No sorry :(

                                                              01.02.2022 21:14:10.73 [Backend]: JavaScript error with InnerException: null
                                                              !! Command Error: Fade [user:ckoppxsq90012ua10r2wmsfcd:ckyzmh3fn0000r4104h42f03p]:
                                                              TypeError: Cannot read property 'sliders' of undefined
                                                              (Fade line 16)

                                                              1. Kitch Membery @Kitch2022-02-01 20:26:22.555Z

                                                                Hmm, Can you take a screenshot for me. Hopefully I can replicate the failure.

                                                                1. JJohan Nordin @Johan_Nordin
                                                                    2022-02-02 15:17:44.036Z

                                                                    Here you go.

                                                                    1. Kitch Membery @Kitch2022-02-02 23:17:37.883Z

                                                                      Hi @Johan_Nordin,

                                                                      Thank you for that. I have set up a session just like you have in the screen shot and cannot make it fail.

                                                                      What version of logic pro are you using, maybe that's the issue?

                                                                      1. JJohan Nordin @Johan_Nordin
                                                                          2022-02-08 07:38:29.175Z

                                                                          Hello! Sorry for my late reply.

                                                                          Im running Logic Pro 10.6.2.

                                                                  • In reply toKitch:
                                                                    Kitch Membery @Kitch2022-02-03 08:17:58.597Z

                                                                    @Alex_Oldroyd8, does the above script work for you? I'm trying to work out if there is any edge case that is stopping it working for @Johan_Nordin.

                                                                    See the inspector setup in Johan's post

                                                                    Rock on!

                                                                    1. OOscar Fogelstrom @Oscar_Fogelstrom
                                                                        2022-02-03 10:29:57.725Z

                                                                        it works for me.
                                                                        Logic 10.7.2
                                                                        OSX 11.6.2

                                                                      • In reply toKitch:
                                                                        AAlex Oldroyd @Alex_Oldroyd8
                                                                          2022-02-03 11:55:07.431Z

                                                                          Yep. Works great for me! I've imitated Johan's setup as best I can. I notice he doesn't have a 'groups' tab in the inspector...

                                                                          1. Kitch Membery @Kitch2022-02-03 19:01:31.657Z

                                                                            Thanks, @Alex_Oldroyd8,

                                                                            Great it works for you also. I believe have accounted for the "groups" tab visibility in the scrips so that shouldn't be the issue, but thanks for pointing that out. :-)

                                                                            1. JJohan Nordin @Johan_Nordin
                                                                                2022-02-08 07:40:13.980Z

                                                                                So strange. I tried it on my parters setup, and on her computer running the latest Logic it works perfectly fine.

                                                                                1. Kitch Membery @Kitch2022-02-08 07:48:50.725Z

                                                                                  Hi @Johan_Nordin,

                                                                                  Ahh yeah, the Logic Pro GUI might have changed since 10.6.2.

                                                                                  I'll have to see if I have a 10.6.2 LPX installer lying around and see if I can figure it out on the weekend.

                                                                                  Rock on!

                                                                                  1. JJohan Nordin @Johan_Nordin
                                                                                      2022-02-08 10:52:26.754Z

                                                                                      Great, thank you so much! :)

                                                                                      1. In reply toKitch:
                                                                                        OOscar Fogelstrom @Oscar_Fogelstrom
                                                                                          2022-02-08 11:05:28.450Z

                                                                                          FYI: Had to switch back to Logic 10.6.3 for various reasons. I can confirm that it does not work on 10.6.3

                                                                                          1. Kitch Membery @Kitch2022-02-08 18:05:50.233Z

                                                                                            Thanks for checking @Oscar_Fogelstrom :-)

                                                                                      2. In reply toKitch:
                                                                                        AAlex Oldroyd @Alex_Oldroyd8
                                                                                          2022-02-22 19:01:44.386Z

                                                                                          strangely, i can't change the gain amount to anything less than 1db... if i change in to 0.5db in the script, it still changes 1db in the region inspector.... not the end of the world :)

                                                                                          1. Kitch Membery @Kitch2022-02-22 19:22:18.868Z

                                                                                            Nice catch... I'll have to take a look at that and see if there is a way,

                                                                                  2. In reply toJohan_Nordin:
                                                                                    Kitch Membery @Kitch2022-02-20 00:16:03.383Z

                                                                                    Hi @Jorhan_Nordin,

                                                                                    Sorry for the delay... I got it working on LPX 10.6.2. Hopefully, it works for you. :-)

                                                                                    const logic = sf.ui.app('com.apple.logic10');
                                                                                    const mainWin = logic.mainWindow;
                                                                                    const inspector = mainWin.getFirstWithDescription('Inspector');
                                                                                    const inspectorList = inspector.children.whoseRole.is("AXList").first;
                                                                                    const inspectorOutline = inspectorList.groups.first.scrollAreas.first.childrenByRole("AXOutline").first
                                                                                    const rows = inspectorOutline.childrenByRole("AXRow").map(c => c)
                                                                                    const fadeSliders = rows.filter(row => row.children.allItems[1].frame.y === 325 || row.children.allItems[1].frame.y === 363,);
                                                                                    
                                                                                    const fadeInSlider = fadeSliders[0].sliders.first
                                                                                    const fadeOutSlider = fadeSliders[1].sliders.first
                                                                                    
                                                                                    //Set Fade-In Value
                                                                                    fadeInSlider.value.intValue = 400;
                                                                                    
                                                                                    //Set Fade-Out Value
                                                                                    fadeOutSlider.value.intValue = 400;
                                                                                    
                                                                                    //Increment Fade-In Value
                                                                                    //fadeInSlider.value.intValue = fadeInSlider.value.invalidate().intValue + 100;
                                                                                    
                                                                                    //Increment Fade-Out Value
                                                                                    //fadeOutSlider.value.intValue = fadeOutSlider.value.invalidate().intValue + 100;
                                                                                    
                                                                                    //Decrement Fade-In Value
                                                                                    //fadeInSlider.value.intValue = fadeInSlider.value.invalidate().intValue - 100;
                                                                                    
                                                                                    //Decrement Fade-Out Value
                                                                                    //fadeOutSlider.value.intValue = fadeOutSlider.value.invalidate().intValue - 100;
                                                                                    

                                                                                    Rock on!

                                                                                    1. JJohan Nordin @Johan_Nordin
                                                                                        2022-02-22 08:09:58.123Z

                                                                                        Works like a charm! Big thanks @Kitch :)