Transition from 4.1.0 to 4.3.1 and AAX I/O issue

If you know the place in the code, you do a git blame on the file. It will show for each line, when it got modified the last time. So you can simply click on the commit. I think it’s here:

which leads to commit:

Search the page with CMD-F for AAX and load the diff, because it is a big commit git will not load all file diffs. But you can click there on “Load diff” and see I think around L135

I don’t know, if that’s the exact place you are looking for, but maybe it helps searching…

Shouldn’t RTAS and AAX ids be compatible with each other?? Meaning RTAS wrapper should also call getAAXPluginIDForMainBusConfig?

Something like this: https://github.com/soundradix/JUCE/commit/9a9cc127098343b5f77542108ca2a4135ba1152b

Thank you! I’ve added this to develop.

Uff so complicated, so fixing this depends on which juce and aax-sdk were used before upgrading?
Also which kind of pre/post/revised/legacy multibus-system was used.
There should be example getAAXPluginIDForMainBusConfig() for any possible configuration

-> JucePlugin_PreferredChannelConfigurations (old)
-> setPreferredBusArrangement
-> isBusesLayoutSupported

1 Like

For the sake of others, here’s what we used to fix Sandman Pro. Our layout config was written in reverse ({2,2}, {1,2}, {1,1}).

int32 Sandman2AudioProcessor::getAAXPluginIDForMainBusConfig (const AudioChannelSet& mainInputLayout,
                                      const AudioChannelSet& mainOutputLayout,
                                      bool idForAudioSuite) const
{
    int uniqueFormatId = 0;
    
    if (mainOutputLayout == AudioChannelSet::stereo())
    {
        if (mainInputLayout == AudioChannelSet::mono())
        {
            uniqueFormatId = 1;
        }
    }
    else uniqueFormatId = 2;
    
    return (idForAudioSuite ? 0x6a796161  : 0x6a636161 ) + uniqueFormatId;
}
1 Like

Here is mine, for a plugin which supports numChannelsIn == numChannelsOut
and which already used the isBusesLayoutSupported() Callback

  int32 getAAXPluginIDForMainBusConfig (const AudioChannelSet& mainInputLayout,
                                                              const AudioChannelSet& mainOutputLayout,
                                                              bool idForAudioSuite) const override
{
    int uniqueFormatId = 0;
    
    if (mainInputLayout!=mainOutputLayout)
    {
        jassertfalse;
    }
    
    if      (mainInputLayout == AudioChannelSet::disabled())           uniqueFormatId = 0;
    else if (mainInputLayout == AudioChannelSet::mono())               uniqueFormatId = 0;
    else if (mainInputLayout == AudioChannelSet::stereo())             uniqueFormatId = 1;
    else if (mainInputLayout == AudioChannelSet::createLCR())          uniqueFormatId = 2;
    else if (mainInputLayout == AudioChannelSet::createLCRS())         uniqueFormatId = 3;
    else if (mainInputLayout == AudioChannelSet::quadraphonic())       uniqueFormatId = 4;
    else if (mainInputLayout == AudioChannelSet::create5point0())      uniqueFormatId = 5;
    else if (mainInputLayout == AudioChannelSet::create5point1())      uniqueFormatId = 6;
    else if (mainInputLayout == AudioChannelSet::create6point0())      uniqueFormatId = 7;
    else if (mainInputLayout == AudioChannelSet::create6point1())      uniqueFormatId = 8;
    else if (mainInputLayout == AudioChannelSet::create7point0())      uniqueFormatId = 11;
    else if (mainInputLayout == AudioChannelSet::create7point1())      uniqueFormatId = 12;
    else if (mainInputLayout == AudioChannelSet::create7point0SDDS())  uniqueFormatId = 9;
    else if (mainInputLayout == AudioChannelSet::create7point1SDDS())  uniqueFormatId = 10;
    else
    {
        // AAX does not support this format and the wrapper should not have
        // called this method with this layout
        jassertfalse;
    }
    
    return (idForAudioSuite ? 0x6a796161 /* 'jyaa' */ : 0x6a636161 /* 'jcaa' */) + uniqueFormatId;
}
1 Like

I’ve found a property in the AAX SDK that is meant to be used exactly for this case: AAX_eProperty_PlugInID_Deprecated. There is even a list version: AAX_eProperty_Deprecated_Native_Plugin_List. I suggest the cleanest way to go forward would be to replace getAAXPluginIDForMainBusConfig(…) with something like getDeprecatedAAXPluginIDs(…) which would return an array of int32s. By default, it should contain the two (or is it three) IDs that would have been used in JUCE pre-4.1 and between 4.1 and 4.3. This should sort out any compatibility issues with plugins built using those older JUCE versions.

PS: I’ve tested this with one of my plugins built with JUCE 3.5/5.0 and it works like a charme. All it takes is properties->AddProperty(AAX_eProperty_PlugInID_Deprecated, depID) in juce_AAX_Wrapper.cpp when adding the current plugin ID. This is the single deprecated ID version, obviously.

3 Likes

One thing to be aware of when using deprecated types is that the saved session will not itself be backwards compatible with your older plug-ins; once a user has updated a session to the new version of your plug-ins the old versions will no longer be recognized (e.g. if the session is sent to another user on a different system with the old versions installed.) The only way to maintain full compatibility is to keep the IDs exactly the same between versions.

5 Likes

You can query the ID values and other properties registered by an existing AAX plug-in using the DSH tool from Avid. Follow these steps in the tool:

  1. dsh> load_dish aaxh
  2. dsh> loadpi “/path/to/MyPlugIn.aaxplugin”
  3. dsh> listeffects
  4. dsh> getdescription [0, 0]
    (use the desired plug-in and effect ID values from the “listeffects” printout - usually [0, 0])

In the resulting description print-out, look for the values registered for AAX_eProperty_ManufacturerID, AAX_eProperty_ProductID, and AAX_eProperty_PlugInID_Native. Pro Tools and Media Composer use the set of these three values to uniquely identify a particular variant of an effect.

10 Likes

Hi Rob,

I just wanted to welcome you to the JUCE forum and thank you for coming by to answer questions! :+1:

Best,

Rail

5 Likes

Wow, that Rob Majors!

Welcome, it’s nice to have you on board. :beers:

Rob, if you’re still around: it seems that changes in the AAX_eProperty_ManufacturerID cannot be remedied by this? So only if the PluginID has changed, we can associated a deprecated ID with the new plugin, but not if, say, the capitalization in the ManufacturerID has changed?

In case anyone else finds this useful:

The following is what I had to do to make Pro Tools 10 projects using an old RTAS version of my JUCE-based plugin load in Pro Tools 2018 using a recent AAX 64-bit version of the plugin. This plugin is has the old bus / audio channel combinations specification in the Projucer, namely: {1,1}, {1, 2}, {2, 2}.

int32 MyPluginAudioProcessor::getAAXPluginIDForMainBusConfig(const AudioChannelSet& mainInputLayout, const AudioChannelSet& mainOutputLayout, bool idForAudioSuite) const
{
    // Back when we released the RTAS version, JUCE generated plugin IDs (starting from 'jcaa') incrementing in the order 
    // of the specified supported channel configurations.
    // But, for newer JUCE versions, plugin IDs are generated in another way (see the default implementation of this method).
    // So, in order to make Pro Tools still see the newer releases as the same plugin as before, we need to keep using the same IDs.
    // In the RTAS version, we had the following (and that's what we'll be forcing here in the code):
    // - for mono-mono:         'jcaa'
    // - for mono-stereo:       'jcab'
    // - for stereo-stereo:     'jcac'
    int uniqueFormatId = 0;

    if (mainInputLayout == AudioChannelSet::mono())
    {
        if (mainOutputLayout == AudioChannelSet::mono())
            uniqueFormatId = 0;
        else if (mainOutputLayout == AudioChannelSet::stereo())
            uniqueFormatId = 1;
        else
            jassertfalse;
    }
    else if (mainInputLayout == AudioChannelSet::stereo())
    {
        if (mainOutputLayout == AudioChannelSet::stereo())
            uniqueFormatId = 2;
        else
            jassertfalse;
    }
    else
    {
        jassertfalse;
    }

    return (idForAudioSuite ? 0x6a796161 /* 'jyaa' */ : 0x6a636161 /* 'jcaa' */) + uniqueFormatId;
}

Note: The old RTAS version didn’t show up under the AudioSuite menu, but the new AAX version does (which is a good thing in my case). You can disable this if you want to with the pre-processor flag JucePlugin_AAXDisableAudioSuite (more info: Was AudioSuite support quietly added to Juce?)

With thanks to @ttg for pointing me in this direction!

1 Like

Sorry for resurrecting this old thread, but its very relevant for me, because i updating my oldest plugins to current technology.

Similar to examples above, my plugins using the offset 0 ( added to jcaa/jyaa ) for the mono configuration.

The problem is that (any) example code above also return the same code for any channel-conf which is not supported and for AudioChannelSet::disabled()

The result is that ambiguity the mono-instances of a plugin can’t be reconstructed in latest protools.

So what is the right return value when channel configuration is not supported if jcaa/jyaa + 0 can’t be used?

@rmajors i used the dsh to extract the old stem formats