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.
- Christian Scheuer @chrscheuer2019-06-22 17:48:34.124Z
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.3var 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;
- OOscar Fogelstrom @Oscar_Fogelstrom
Awesome! Just waiting for SF3 and the Logic Folder in the store then!
- In reply tochrscheuer⬆:OOscar Fogelstrom @Oscar_Fogelstrom
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 enoughChristian Scheuer @chrscheuer2019-06-22 18:20:15.795Z
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.
- OOscar Fogelstrom @Oscar_Fogelstrom
Perfect! Let me check
- In reply tochrscheuer⬆:OOscar Fogelstrom @Oscar_Fogelstrom
Hello! This seems to be broken for me now. Any chance of checking what could be the problem?
Thanks//O
- In reply tochrscheuer⬆:AAlex Oldroyd @Alex_Oldroyd8
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
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!- AAlex Oldroyd @Alex_Oldroyd8
Thank you, @Kitch !
Kitch Membery @Kitch2022-02-03 08:12:38.860Z
My pleasure mate!
- AAlex Oldroyd @Alex_Oldroyd8
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", }); };
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!
- AAlex Oldroyd @Alex_Oldroyd8
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
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 thetargetValue
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.
- AAlex Oldroyd @Alex_Oldroyd8
Thanks for this, @Kitch. Really helpful
- 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Ï
- JIn reply toOscar_Fogelstrom⬆:Johan Nordin @Johan_Nordin
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
Christian Scheuer @chrscheuer2022-01-28 14:39:41.695Z
Let me cc @Kitch here as he'll probably know more about this :)
- 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 :-)
- JJohan Nordin @Johan_Nordin
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
Kitch Membery @Kitch2022-01-29 09:42:31.193Z
- JJohan Nordin @Johan_Nordin
Yes :)
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!
- JJohan Nordin @Johan_Nordin
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)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 :-)
- JJohan Nordin @Johan_Nordin
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)Kitch Membery @Kitch2022-02-01 20:26:22.555Z
Hmm, Can you take a screenshot for me. Hopefully I can replicate the failure.
- JJohan Nordin @Johan_Nordin
Here you go.
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?
- JJohan Nordin @Johan_Nordin
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!
- OOscar Fogelstrom @Oscar_Fogelstrom
it works for me.
Logic 10.7.2
OSX 11.6.2Kitch Membery @Kitch2022-02-03 10:31:06.537Z
Thanks @Oscar_Fogelstrom. :-)
- In reply toKitch⬆:AAlex Oldroyd @Alex_Oldroyd8
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...
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. :-)
- JJohan Nordin @Johan_Nordin
So strange. I tried it on my parters setup, and on her computer running the latest Logic it works perfectly fine.
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!
- JJohan Nordin @Johan_Nordin
Great, thank you so much! :)
- In reply toKitch⬆:OOscar Fogelstrom @Oscar_Fogelstrom
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
Kitch Membery @Kitch2022-02-08 18:05:50.233Z
Thanks for checking @Oscar_Fogelstrom :-)
- In reply toKitch⬆:AAlex Oldroyd @Alex_Oldroyd8
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 :)
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,
- 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!
- JJohan Nordin @Johan_Nordin
Works like a charm! Big thanks @Kitch :)