Enable a plugin to upmix in Logic Pro

When using Apple’s Delay Designer on a stereo track which has a surround output, we get the option to select the option to upmix from stereo to surround:

Screenshot 2024-07-11 at 13.16.39

I would like to achieve the same with my plugin, but I can’t get this to work. My plugin overrides isBusesLayoutSupported() and returns true on the supported combinations.

When running through auval the correct channel capabilities are reported:

Reported Channel Capabilities (explicit):
      [1, 1]  [1, 2]  [1, 6]  [1, 10]  [1, 12]  [2, 2]  [2, 6]  [2, 10]  [2, 12]

Input/Output Channel Handling:
1-1   1-2   1-4   1-5   1-6   1-7   1-8   2-2   2-4   2-5   2-6   2-7   2-8   4-4   4-5   5-5   6-6   7-7   8-8
X     X                 X                 X                 X

# # AudioChannelLayouts (5), Input Scope:
ChannelLayout is Writable: T
The Unit publishes the following Channel Layouts:
  0x640001, 0x650002, 0x660002, 0x670002, 0x6A0002,

Is Audio Channel Layout Available:
Mono    Stereo  Binau.  AU_4    Ambi.   AU_5    AU_5_0  AU_6    AU_6_0  AU_7_0  AU_7_0F AU_8    AU_5_1  AU_6_1  AU_7_1  AU_7_1F
X       X       X

# # AudioChannelLayouts (11), Output Scope:
ChannelLayout is Writable: T
The Unit publishes the following Channel Layouts:
  0x640001, 0x650002, 0x660002, 0x670002, 0x6A0002, 0x790006, 0x7A0006, 0x7B0006, 0x7C0006, 0xC0000C, 0xC4000A,

Is Audio Channel Layout Available:
Mono    Stereo  Binau.  AU_4    Ambi.   AU_5    AU_5_0  AU_6    AU_6_0  AU_7_0  AU_7_0F AU_8    AU_5_1  AU_6_1  AU_7_1  AU_7_1F
X       X       X                                                                               X

Based on this auval report I would expect Logic to be able to instantiate the plugin as stereo → 5.1, but it doesn’t.

What am I missing?

Quite possible that Logic’s aggressive caching of plugin channel capablities is biting you. Recently a colleague had a similar issue that was only possible to fix by changing the PLUGIN_CODE so that Logic would actually respect the new channel capabilities being reported to auval.

Thanks! That solved part of the problem!

The other part is that this plugin also supports 1:1 surround channel layouts, enabling passthrough of surround tracks.

When I disable this 1:1 surround pass through the plugin allows to be instantiated as stereo => surround, but when the 1:1 surround pass through is enabled is doesn’t allow to be instantiated as stereo => surround.

Any more suggestions?

I was able to fix this by testing for the amount of channels of the ChannelSets instead of comparing the supported ChannelSets themselves.

So instead of doing:

if (in == juce::AudioChannelSet::mono() || in == juce::AudioChannelSet::stereo())
{
    if (out == juce::AudioChannelSet::mono() || out == juce::AudioChannelSet::stereo() ||
        out == juce::AudioChannelSet::create5point1() || out == juce::AudioChannelSet::create7point1point2() ||
        out == juce::AudioChannelSet::create7point1point4())
    {
        return true;
    }
}

I’m now doing:

if (in.size() == 1 || in.size() == 2)
{
    if (out.size() == 1 || out.size() == 2 || out.size() == 6 || out.size() == 10 || out.size() == 12)
        return true;
}
3 Likes

Unfortunately this broke the AAX versions which was now reporting invalid (unsupported) channel configurations.

Then I tried to wrap the channel count based logic into a special case for logic like this:

if (pluginHostType.isLogic())
{
    // A hack for Logic Pro which seems to probe the plugin without specific channel sets.
    if (in.size() == 1 || in.size() == 2)
    {
        if (out.size() == 1 || out.size() == 2 || out.size() == 6 || out.size() == 10 || out.size() == 12)
        {
            return true;
        }
    }
}

But now Logic doesn’t consider the plugin capabel of doing upmixing (mono to stereo, or mono/stereo to surround).

The behaviour of Logic seems to be very inconsistent, changing the plugin id helped a t bit, but also not consistently. I haven’t found a pattern in it’s behaviour yet.

Is there anyone with insight into what might be going on? Or have any tips?

I found that when running in auval the channel configurations were reported incorrectly:

FORMAT TESTS:

Reported Channel Capabilities (explicit):
      [-1, -1]

Input/Output Channel Handling:
1-1   1-2   1-4   1-5   1-6   1-7   1-8   2-2   2-4   2-5   2-6   2-7   2-8   4-4   4-5   5-5   6-6   7-7   8-8
X                                         X                                   X           X     X     X     X

After changing the custom Logic logic (pun intended) to this:

const auto pluginHostType = juce::PluginHostType();
if (pluginHostType.isLogic() || pluginHostType.isAUVal() || pluginHostType.getHostPath().containsIgnoreCase ("auval"))
{
    // A special case for Logic Pro which seems to probe the plugin without specific channel sets.
    if (in.size() == 1 || in.size() == 2)
    {
        if (out.size() == 1 || out.size() == 2 || out.size() == 6 || out.size() == 10 || out.size() == 12)
        {
            LOGINFO (
                "Using workaround of channelcounts for Logic Pro (ins={}, outs={})",
                in.size(),
                out.size());
            return true;
        }
    }
}

auval now reports the correct channel configs:

FORMAT TESTS:

Reported Channel Capabilities (explicit):
      [1, 1]  [1, 2]  [1, 6]  [1, 10]  [1, 12]  [2, 2]  [2, 6]  [2, 10]  [2, 12]  [3, 3]  [4, 4]  [5, 5]
      [6, 6]  [7, 7]  [8, 8]  [9, 9]  [10, 10]  [11, 11]  [12, 12]  [13, 13]  [14, 14]  [15, 15]  [16, 16]

Input/Output Channel Handling:
1-1   1-2   1-4   1-5   1-6   1-7   1-8   2-2   2-4   2-5   2-6   2-7   2-8   4-4   4-5   5-5   6-6   7-7   8-8
X     X                 X                 X                 X                 X           X     X     X     X

This tels me that juce::PluginHostType().isAUVal() is not working correctly, because it matches on auvaltool whereas the tool is called auval and is located inside /usr/bin/.

Nevertheless, after verifying the channel configurations with auval, Logic Pro is still not picking up the correct channel configurations.

I found that the Apple Info helper also instantiates the plugin. I’m not sure on exactly when.

After updating the special case for Logic like this:

    const auto pluginHostType = juce::PluginHostType();
if (pluginHostType.isLogic() || pluginHostType.isAppleInfoHelper() || pluginHostType.isAUVal() ||
    pluginHostType.getHostPath().containsIgnoreCase ("auval"))
{
    // A special case for Logic Pro which seems to probe the plugin without specific channel sets.
    if (in.size() == 1 || in.size() == 2)
    {
        if (out.size() == 1 || out.size() == 2 || out.size() == 6 || out.size() == 10 || out.size() == 12)
        {
            return true;
        }
    }
}

The plugin is correctly loaded on a fresh installation of macOS and Logic. However, on my development machine I can’t get it to work. I think this is because of the aggressive caching as mentioned above, but I want to try prevent to change the plugin code because that’s break existing projects when updating the plugin.