Midi effects only show up on Mono tracks in Pro Tools

Pro Tools now supports Midi effect plugins as of update 2024.3. However, they only show up on Mono instrument track, which makes little sense as midi channels shouldn’t care about the number of audio channels. I’ve tracked down the problem to this segment:

static void createDescriptor (AAX_IComponentDescriptor& desc,
                              const AudioProcessor::BusesLayout& fullLayout,
                              AudioProcessor& processor,
                              Array<int32>& pluginIds,
                              const int numMeters)
{
    [[maybe_unused]] auto aaxInputFormat  = getFormatForAudioChannelSet (fullLayout.getMainInputChannelSet(),  false);
    [[maybe_unused]] auto aaxOutputFormat = getFormatForAudioChannelSet (fullLayout.getMainOutputChannelSet(), false);

   #if JucePlugin_IsSynth
    if (aaxInputFormat == AAX_eStemFormat_None)
        aaxInputFormat = aaxOutputFormat;
   #endif

    if (processor.isMidiEffect())
    // this line is the culprit
        aaxInputFormat = aaxOutputFormat = AAX_eStemFormat_Mono;

It’s possible to change it to AAX_eStemFormat_Stereo and then have the plug-in show up on stereo tracks, but then it won’t show on any other channel combinations.

I also tried adding the stereo format after, but it just overwrote the mono:

    properties->AddProperty (AAX_eProperty_InputStemFormat,     static_cast<AAX_CPropertyValue> (aaxInputFormat));
    properties->AddProperty (AAX_eProperty_OutputStemFormat,    static_cast<AAX_CPropertyValue> (aaxOutputFormat));

    if (processor.isMidiEffect()){ 
        properties->AddProperty(AAX_eProperty_InputStemFormat, static_cast<AAX_CPropertyValue> (AAX_eStemFormat_Stereo));
        properties->AddProperty(AAX_eProperty_OutputStemFormat, static_cast<AAX_CPropertyValue> (AAX_eStemFormat_Stereo));
    }

Are there any solutions? Should it create multiple descriptors in a loop, for both mono, stereo, and any conceivable channel format?

I’ve found a solution.

Removing the following entirely:

  #if JucePlugin_IsSynth
    if (aaxInputFormat == AAX_eStemFormat_None)
        aaxInputFormat = aaxOutputFormat;
   #endif

Modifying juce_audio_plugin_client_AAX to have the following:

        if (plugin->isMidiEffect())
        {
            // MIDI effect plug-ins do not support any audio channels
            jassert (numInputBuses == 0 && numOutputBuses == 0);

            if (auto* desc = descriptor.NewComponentDescriptor())
            {
                AudioProcessor::BusesLayout fakeLayout;
				fakeLayout.inputBuses.add(AudioChannelSet::mono());
				fakeLayout.outputBuses.add(AudioChannelSet::mono());

                createDescriptor(*desc, fakeLayout, *plugin, pluginIds, numMeters);
                check (descriptor.AddComponent (desc));
            }

            if (auto* desc = descriptor.NewComponentDescriptor())
            {
                AudioProcessor::BusesLayout fakeLayout;
                fakeLayout.inputBuses.add(AudioChannelSet::stereo());
                fakeLayout.outputBuses.add(AudioChannelSet::stereo());

                createDescriptor(*desc, fakeLayout, *plugin, pluginIds, numMeters);
                check(descriptor.AddComponent(desc));
            }

        }

In theory this could be extended for every conceivable channel configuration as well.

1 Like

Hi, thanks for this info, I was struggling for days trying to figure out why I could only instantiate on mono instrument tracks.

Adjusting L2418 of juce_audio_plugin_client_AAX.cpp to stereo has the added side-effect of noise coming out of the speakers!

Small correction for your solution though:

        if (processor.isMidiEffect())
            aaxInputFormat = aaxOutputFormat = AAX_eStemFormat_Mono;

is the part that needs removing, and then your additions. It’s possible to leave the other part you said to remove in place.

Now everything works perfectly!

Could the JUCE team weigh in on this. It’s clearly an issue at the moment only being able to instantiate AAX MIDI FX plugins on mono instrument tracks.

1 Like

Slightly more succint and easier to extend for your addition:

replace L2589 - L2593 of juce_audio_plugin_client_AAX.cpp with

auto bussTypes = std::vector<juce::AudioChannelSet> {
    AudioChannelSet::mono(),
    AudioChannelSet::stereo()
};
for (auto& bussType : bussTypes)
    if (auto* desc = descriptor.NewComponentDescriptor())
    {
        AudioProcessor::BusesLayout fakeLayout;
        fakeLayout.inputBuses.add(bussType);
        fakeLayout.outputBuses.add(bussType);

        createDescriptor(*desc, fakeLayout, *plugin, pluginIds, numMeters);
        check (descriptor.AddComponent (desc));
    }
1 Like

That’s my bad, I copy pasted the wrong part. The excerpt you put is the correct one to remove of course!

It would be nice to have those changes integrated into the mainline JUCE asap, I’m sure we’re not the only ones making AAX midi effect plugins.

1 Like

Any JUCE team member care to say if this (imo) bug is going to be addressed? (Or not… :sob:)

I think I’ll just make a PR on the JUCE github repo, that’s probably the best way to get this fixed.

There’s a fix on the way, will hopefully land next week.

1 Like

Thanks for your patience. The fix is now available on the develop branch:

1 Like