Rudimentary question about popupMenuFetchAllItems and how to utilize in plugin menu
Hi,
This is a rudimentary question - I see the use of popupMenuFetchAllItems()
(and various extensions of it) quite a lot in the forum and scripts and I know I can see how it would be useful to me, but I am having trouble wrapping my head around it. I was wondering if someone could kindly provide some information on how to use it so I can get a better handle on it, but also help with it in this example.
In my specific case today, I'm hoping to
- Get the full plug-in name of the current insert
- use popupMenuFetchAllItems to index all plugins
- Then amend the original plugin name (from #1) using regex or slicing etc
- Then search the index of the popupMenuFetchAllItems from earlier to load another plugin with the amended name.
Basically similar to what Chris Shaw did with his copy plugin to audiosuite function, but kept within the live, active plug-in world (not audiosuite).
Any help would be appreciated!
- Kitch Membery @Kitch2022-11-15 07:06:18.454Z
Legend, I believe I created a script for you in our the last thread we had going that did something very similar. Did that not work? Or are you just trying to get an understanding of how its done?
If you are free on Wednesday 11am PT come join us at the SoundFlow Hangout, I can possibly give you a more detailed rundown on how to do this.
I also plan on answering here, but it may take me a day or two to get to it. :-)
- In reply toTristan⬆:Kitch Membery @Kitch2022-11-15 07:54:22.919Z
You can get the full plug-in name of the current insert (the frontmost plugin) like this
const fullPluginName = sf.ui.proTools.pluginWindow.title.invalidate().value; log(fullPluginName);
To fetch all the plug-in menu items from the front most plugin you can use this.
sf.ui.proTools.appActivateMainWindow(); const pluginMenuItems = sf.ui.proTools.pluginWindow.invalidate().popupButtons.whoseTitle.startsWith("Plug-In Selector").first.popupMenuFetchAllItems({ dismissMenu: true }).menuItems; log(pluginMenuItems);
This will create an array of Menu Items containing important information about the Menu Item including the Path and UI Element.
For step three in your post... how do you want to alter the full plugin name?
For the forth step, you'll need to use either the Filter or Find method. Here is an example of using the find method to match the menu item from the
popupMenuFetchAllItems().menuItems
.sf.ui.proTools.appActivateMainWindow(); const pluginMenuItems = sf.ui.proTools.pluginWindow.invalidate().popupButtons.whoseTitle.startsWith("Plug-In Selector").first.popupMenuFetchAllItems({ dismissMenu: true }).menuItems; const targetPath = [ "plug-in", "EQ", "EQ3 1-Band (mono)" ]; const matchingMenuItem = pluginMenuItems.find(menuItem => JSON.stringify(menuItem.path) === JSON.stringify(targetPath)); log(matchingMenuItem); log(matchingMenuItem.path);
Some of this is quite complex but I'm happy to provide more info if you need it.
Rock on, Champion!
- TTristan Hoogland @Tristan
Thanks Kitch!
Firstly thanks so much as always. Yep definitely saw it in function in the other script (thanks!), just eager to increase the understanding a bit more so I can better implement it elsewhere. This is a little easier to digest so that helps, and for the most part I understand the concept of storing it in an array, I'm just having trouble naturally grasping how to then search the array and thus select another plugin.
An example would be looking to amend the plugin name(s) as follows:
iZotope, Inc. -> RX-8 Mouth De-click
to:
iZotope -> RX-9 Mouth De-clickiZotope, Inc. -> RX-8 De-ess
to:
iZotope -> RX-9 Mouth De-ess
etcWhat's great about this example is that I need to overcome two challenges:
- Determine if it's a multichannel plug-in or a multi-mono in stereo, or a single instance (mono)
- Be able to amend the iZotope, Inc. to iZotope
While I know I could just specify the iZotope, Inc. to iZotope path easily, I actually have a few other things i'm working on where I'd love if the original plugin could be stored as a variable so I can utilize it in other plugin manufacturers.
Let me know what you think king kitch!
Kitch Membery @Kitch2022-11-15 19:29:34.656Z
I'm more of a jester than a King ;-)
There is a bit to digest here and it would be great to discuss this stuff in the Weekly Hangout if you are free as I can preemptively guess what your next questions will be.
But to do what you are after check out the following script.
//This is the original path to the plugin. const menuPath = ["plugin", "iZotope, Inc.", "RX-8 Mouth De-click"]; //From the first section of the menu path work out if the plugin is multichannel const isMultichannel = menuPath[0] === "plugin" || menuPath[0] === ("multichannel plug-in"); //From the first section of the menu path work out if the plugin is multichannel const isMultiMono = menuPath[0] === ("multi-mono plug-in"); //This accesses the second (or 1th since Javascript index numbering starts at 0) item in the array //converting "iZotope, Inc." to "iZotope" menuPath[1] = menuPath[1].replace(", Inc.", ""); //This accesses the second (or 2th since Javascript index numbering starts at 0) item in the array //converting "RX-8 Mouth De-click" to "RX-9 Mouth De-click" menuPath[1] = menuPath[1].replace("8", "9"); log("Multichannel plugin: "+ isMultichannel); log("Multi-Mono plugin: "+ isMultiMono); log(menuPath);
- TTristan Hoogland @Tristan
Thanks Kitch! Still a king in my eyes.
Oh i totally forgot to say - yes i'll jump in on the hangout tomorrow! I'll have a look at this and show you what I've got so far tomorrow. Appreciate your sage wisdom as always
- In reply toKitch⬆:TTristan Hoogland @Tristan
Hey Kitch,
I'm having a bit of trouble getting the script to recognize when it's a multi-channel plugin. It works great in both "stereo" and "mono" track-width instances though. I can already tell it's something simple and assuming it has something to do with the constant not being determined if it's true or false, and just chooses the path that appears first (which multichannel appears first).
Here's the portion of the script in how I'm using it:
const currentPluginName = pluginMenuItems.find(mi => mi.element.isMenuChecked).path; //From the first section of the menu path work out if the plugin is multichannel const isMultichannel = currentPluginName[0] === "plugin" || currentPluginName[0] === ("multichannel plug-in"); //From the first section of the menu path work out if the plugin is multichannel const isMultiMono = currentPluginName[0] === ("multi-mono plug-in"); const path1 = currentPluginName[0] //category path const path2 = currentPluginName[1] //actual plugin const uadName = currentPluginName[2] //stereo or mono instance const stripStereoMono = uadName.split(" ("); //result should be "stereo)" or "mono)" const stereoMono = " (" + stripStereoMono[1]; //strip "UAD" "UA" Tags const uadxName = uadName.replace(/(UAD UA\s)|(UAD\s)/g, "UADx ").split(" (").slice(0, -1).join("") + " Compressor" + stereoMono; sf.ui.proTools.appActivateMainWindow();
Thanks!
Kitch Membery @Kitch2022-11-18 01:55:17.001Z
Ahh, yeah I see. I like what you did there!
I mentioned in the hangout, a way to do this with a lookup table (but for this example, I decided it was better to create an array of objects and filter them with the find method. That way you can get the plugin names, preset button positions, and paste button positions as you've specified.
Here is how you'd do it.
const uadXpluginLookupArray = [ { uadPluginName: "UAD UA 1176LN Rev E", uadPresetsButtonPosition: { x: 20, y: 300 }, uadXPluginName: "UADx UA 1176LN Rev E Compressor", uadXPasteButtonPosition: { x: 20, y: 300 }, }, { uadPluginName: "UAD UA 1176LN Rev A", uadPresetsButtonPosition: { x: 10, y: 200 }, uadXPluginName: "UADx UA 1176LN Rev A Compressor", uadXPasteButtonPosition: { x: 10, y: 200 }, }, ]; //If this is the original path to the plugin. const menuPath = ["plugin", "UAD", "UAD UA 1176LN Rev E (Stereo)"]; //Get the width to add to the end of the plugin name. const pluginWidth = menuPath[2].match(/\(([^)]+)\)/)[0]; //Find the matching object in the const matchingPluginObject = uadXpluginLookupArray.find(plugin => { return plugin.uadPluginName === menuPath[2].split(" (")[0]; }); //Create the UADx pluing name const targetPluginName = `${matchingPluginObject.uadXPluginName} ${pluginWidth}`; //This is the path to the UADx plugin const uadXPluginPath = [ menuPath[0], menuPath[1], targetPluginName ]; log(uadXPluginPath); // Logs the Plugin Path log(matchingPluginObject.uadPluginName); //Logs the UAD plugin name log(matchingPluginObject.uadPresetsButtonPosition); //Logs the UAD plugin preset button position log(matchingPluginObject.uadXPluginName); //Logs the UADx plugin name log(matchingPluginObject.uadXPasteButtonPosition); //Logs the UADx plugin preset button position
It may need a bit more of an explanation but I'm about to head into a Zoom meeting so if you have any questions let me know.
Rock on!
- TTristan Hoogland @Tristan
You went beyond here, mate! Thank you as always.
Perfect timing, too as I've just gone through the painful mouse-click coordinates for all the plugins. I'll implement everything here, have a play with it all and get back to you with where I'm at!
- In reply toKitch⬆:TTristan Hoogland @Tristan
Hey Kitch, one thing the array doesn’t take into account is the initial “copy settings” in the UAD plug is actually in a drop down menu.
So the actions need to be (in the example of 1176)
1 - Firstly, can we use the plug-in screen as a reference for the cursor? (That’s how I’m currently doing it)
2 - mouse position to x91, y357
3 - mouse click (drop down menu appears)
4 - move mouse down 51 on y axis to hover “copy settings”
5 - click copy settings.Fortunately the move down distance is the same for all instances of the UAD plug
The paste coordinates are in the one place though - so nothing to worry about there!
Kitch Membery @Kitch2022-11-18 18:06:32.222Z
Yeah that's all doable... I'll take a look at it when I get a chance.