AAX IDs / legacy version not replaced


I have rewritten a plugin that was formerly only available for tax / ProTools. It was written with vstGUI and had the Manufacturer ID, Product ID, and channel IDs also for AudioSuite and TI DSP. DSP is not implemented in the new version yet. If I understand this correctly in the Projucer settings I can set Manufacturer ID and must set the Plugin Code as Product ID. My first question is what exactly is the Plugin AAX Identifier? Am I getting something wrong here?

I read that for the ChannelSet IDs I have to manually overwrite getAAXPluginIDForMainBusConfig() function which I did. So for Mono and Stereo the legacy IDs are returned, for the bus configurations IDs get assigned as they were before with Juce. I set the version number higher in Juce Settings but still ProTools shows them as two different plugins.

Can anybody help me out here. I am not a programmer and managed to get everything else working including signing and notarizing with pace. So this becomes a pita. Also one last question for now. I have rewritten the getAAXPluginIDForMainBusConfig() in audio processor module. Since the global path points to the modules and, if I get this correctly, this is used for all projects I have to isolate the project that needs this modification? What is the best way to do this? Just have a separate version of Juce for this project so it doesn’t affect others?

Any help is highly appreciated.

Pro Tools will identify your plugin using the supplied Plugin AAX Identifier, so you must specify it if you’re building AAX.

For returning the ChannelSet IDs you need to follow a slightly different approach, especially since getAAXPluginIDForMainBusConfig() has been deprecated for current versions of JUCE.

You need to create a class in your plugin project that inherits from AAXClientExtensions. Inside this class you should override getPluginIDForMainBusConfig() and return the IDs that your previous plugin returned.

Finally you should override getAAXClientExtensions() in your plugin’s AudioProcessor class and return a pointer to an object of your AAXClientExtensions class.

You shouldn’t modify code that’s in the modules, in part, because that will affect all projects.

Thank you ever so much, I just learned a lot from your response. Make so much more sense with inheriting and returning a pointer to the class with the overwritten function.

The old Product ID was “Phx2”. Do I get that right that this should be the Plugin AAX Identifier then?

I’m not familiar enough with vstGUI to answer that, but you should be able to quickly see if Pro Tools will load your plugin if you open a project where the previous build of your plugin was added to a track.

I am having troubles to find the AAXClientExtensions class in my project. From the docs it should be under juce_audio_processors >> utilities but I can’t see it. Any hint on what I am doing wrong here?

You may be using an old JUCE version. You can download the latest version from Download - JUCE

Thank you very much for your help. I had the newest version of Juce in my Applications folder so it was the newest version of Projucer. However in the project, which was a sample from Pace, there is the old version and the old modules are loaded. I’ve updated to the new Juce version. I could open it in XCode but said I had to use c++17. After reopening this error was gone but now, no matter what I do, even hardcoded the new Juce version in appconfig.h, I get an error saying that the project was last saved using an outdated version of Projucer. I have resaved so many times, deleted and downloaded Juce over and over but this error stays. I am out of ideas. Any hints what I can do?

I am thinking about staying with the older version and use what I have already written. Can you tell me what the getAAXClientExtensions() for the old version is.

Way to much update stuff going on in the software world. Had already enough upgrading this to Mac Sonoma and Xcode 15. How do you guys handle this, when do you stop upgrading and just finish the project?

Thanks for your help!

Hopefully I’m not barking up the wrong tree here but you might find that the module paths in the project are set to use the version of JUCE that shipped with the example project from PACE. If you want to try and change this you can do so. Just follow the steps below…

If you want to use the version of JUCE located in your “global path”*

  1. Open the project in the Projucer
  2. Select the modules tab in the side panel on the left
  3. Select the cog at the bottom of side panel
  4. On the right scroll to the bottom and select “Enable/disable global path for modules…”
  5. Select “Set all modules to use global paths” (this assumes there are no third party modules)

If you want to use a version of JUCE that is NOT located in your “global path”

  1. Open the project int he Projucer
  2. Select the modules tab in the side panel on the left
  3. Select one of the modules from the list (it doesn’t matter which one, but you’ll need to remember which one it was)
  4. Change the path(s) for the different exporters
  5. Check that “use global path for this module” is unchecked
  6. Select the cog at the bottom of the modules tab in side panel
  7. In the right hand pane (not the side panel) select the same module as you did in step 2
  8. On the right scroll to the bottom and select “Set path for all modules…”
  9. Select “Copy the paths from the module “juce_some_module” to all other modules”

I forgot to add if you’re not familiar with the “global path” this is a setting in the Projucer that you can setup so that all projects can easily point to a single version of JUCE if you prefer. To set it…

  1. Select “Projucer” in the main application menu at the top
  2. Select “Global Paths…”
  3. Set your paths

As you’ll see this allows you to set up the path to your JUCE modules but also paths to all the relevant plugin SDKs.

I hope this helps.

Thank you very much. I knew about the global path but overlooked the individual settings. Still got some dependencies are missing errors.

In the meantime the deprecated method with overriding getAAXPluginIDForMainBusConfig() worked. Pro Tools recognizes the old and the new version of the plugin as the same plugin. However it still loads the old one. By right clicking on the aaxplugin file and clicking get info it shows that the new plugin is version 6.0.0 while the old one is 5. But ProTools doesn’t care. As soon as I delete the old aaxplugin file, the new one is loaded. Am I wrong that ProTools know which file to load by the version number?

I got another hint from pace support. As soon as I got something that works I’ll try to update to the new JUCE and the up to date method for legacy IDs.

Thanks for your support!


You can’t have two plugins with the same triad simultaneously. Also once you change the triad then previous presets won’t load unless the triad matches the plugin.


Rail, thank you for answering. That was my problem. I had Manufacturing and Product IDs matched but struggled to get the plugin ID for native and audiosuite matched. My problem was that it should come up as the same plugin but it didnt.
It is now recognized by ProTools as the same plugin, however it still loads the old version (version number 5) instead of the new one(version number 6.0.0). I thought that the higher version gets loaded but still, the older version is what shows up when a proTools session is loaded. Any hints are highly appreciated.

If the new version should replace the old version, then shouldn’t you remove the old version from the Plug-Ins folder when installing the new version?

1 Like

I feel like a fish trying to climb a tree here. Thanks for beeing patient with me. Coming from analog hardware and microcontrollers, all of this is new to me.

I’ll try to implement removing the old file in my installer.

I remember that someone told me ProTools decides based on the version number which plugin to load. Assuming they have the same IDs. Is this wrong.

For replacing old versions that have a different triad, but being able to load the old session data, there are functions getAAXPluginNativeDeprecatedIDs() and getAAXPluginDSPDeprecatedIDs() for the “native” (non-DSP-AAX plugin) and the AAX DSP versions that you can use to specify the old triad information that your new plugin should be able to load.

However, at least in Juce 7.0.5, these are not implemented in the AAX wrapper. We added them to our Juce SDK like this:

struct SPlugInIdentifierTriad {
    uint32_t            mManufacturerID;    ///< The Plug-In's manufacturer ID
    uint32_t            mProductID;         ///< The Plug-In's product (Effect) ID
    uint32_t            mPlugInID;          ///< The ID of a specific type in the product (Effect)
virtual void getAAXPluginNativeDeprecatedIDs (const AudioChannelSet& mainInputLayout,
                                              const AudioChannelSet& mainOutputLayout,
                                              std::vector<SPlugInIdentifierTriad>& oTriads) const{}
virtual void getAAXPluginDSPDeprecatedIDs (const AudioChannelSet& mainInputLayout,
                                          const AudioChannelSet& mainOutputLayout,
                                           std::vector<SPlugInIdentifierTriad>& oTriads) const{}