Extending Juce support for Atmos beyond 7.1.2 channel set (including in Logic Pro via new layout tags)

that is weird indeed.

we have tested our channel re-order on both intel and M1 and there it both works.

happy to test your plugin - would you be able to share it so we can run it and report back?

I’ve been testing with the following patches applied. To check the different layouts I’ve commenting/uncommenting the 7.1.4 layouts in the SpeakerLayoutTable so that only one is active at a time.

Apply the patches, comment out one of the 7_1_4 layouts in the speaker table, then build with:

cmake --build cmake-build-debug --target AudioPluginExample_AU

0001-WIP-Add-additional-Logic-layouts.patch (2.0 KB)
0001-WIP-Testing-project.patch (15.5 KB)

I just re-tested the build with only the 7_1_4_B layout active. On the Arm machine, this seems to work correctly both native/rosetta. However, on the x86 machine I now can’t load the plugin at all (tried both copying the UB build from the Arm machine, and doing a fresh build on the Intel machine, with a full plugin reset each time). The plugin passes validation, but fails when I try to load it with the “contact the manufacturer for an updated version…” error.

If I switch the comments around so that only the A layout is active, rebuild the plugin on the x86 machine, and then do a full plugin reset, then I’m finally able to load the plugin, and the channels appear to be ordered correctly.

1 Like

applying your patches the resulting audioPlugin looked like this:

am I missing something?

Looks like you might have built or opened the AudioPluginDemo rather than AudioPluginExample.

ok thanks - i’ll give that a go

Hi, just wondering whether you managed to take a look at this in the end. No worries if not, but I’d be interested to know whether you see the same results that I do.

With this patch my AU plugin get in to isBusesLayoutSupported with layouts 7.1.4 Surround twice. but only 7.1.4 Surround on the output.

layouts.getMainInputChannelSet() = Stereo - numChannels: 2
layouts.getMainOutputChannelSet() = 7.1.4 Surround - numChannels: 12

My plugin does not load in Logic.
I think the problem for me is that I need to return true when it is 7.1.4 on both input and output in isBusesLayoutSupported().

When switching to JUCE development branch (commit a5b76d39891d53c336310447e0aae9769fb09147 )
I get 7.1.4 in isBusesLayoutSupported on both input and output when trying to load the plugin in Logic.

But plugin wont load…
Failed to load Audio Unit “plugin”, please contact the manufacturer for an updated version or further assistance.

Annoyingly, the AU scanning process and Logic’s channel-scanning process are both quite temperamental. I saw the “please contact the manufacturer” warning a few times when testing, but it seemed dependent on the surround layouts that were enabled, along with the platform, Intel vs Arm.

In particular, I was seeing that warning when the 7_1_4_B layout was active on x86_64, but not when the A layout was active (after doing a full plugin reset). Unfortunately, the A layout seemed to cause channel ordering issues on Arm.

In case anyone wants to try reproducing my test results above, here is an example project that might help for testing (same as the test project patch above, but for the Projucer instead of CMake).

LogicSurroundTest.zip (28.1 KB)


Thanks for the test plugin @reuk

I ran this plugin within Logic on an M1 machine and the signal showed up on the correct channels in the level meter.

However, I did notice that the channel order you used was - L, R, C, LFE, Lss, Rss, Tfl, Tfr, Trl, Trr, Lsr, Rsr

This doesn’t seem to correspond to the audio channel set in juce_AudioChannelSet.h

AudioChannelSet AudioChannelSet::create7point1point4() { return AudioChannelSet ({ left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, topFrontLeft, topFrontRight, topRearLeft, topRearRight }); }

After this, I ran @skazassoglou’s test.

Checked out on JUCE development branch (commit ed1bc944fdc904164ae84305cc917d0fc7d84c4f), I created a plugin using AudioChannelSet::create7point1point4() and modified the isBusesLayoutSupported accordingly.

Using 12 mono tracks (spoken words left, right, etc) panned to the 12 speakers, I verified that the plugin passed these through to the expected channels, using Logic’s level meter (7.1.4).

Then I routed the incoming channels, one by one to the first output (as described by Stefan).

The results of this test are shown below

0 Left
1 Right
2 Centre
4 Lss
5 Rss
6 Tfl
7 Tfr
8 Trl
9 Trr
10 Lsr
11 Rsr

This shows the order of the buffer is the same as shown in your test plugin.

Shouldn’t the order of the buffer correspond with the AudioChannelSet?

If not, how would it be possible to create a plugin that works in all DAW’s, without reordering the internal buffer channels?

I’m dealing with similar issues here with the AU version of my multi-channel/multi-format JUCE plug-in. The first odd thing I notice is that Logic re-orders the buffer indices before they hit the JUCE audio callback. For example, loading a 5.1 wav in Logic, I would expect the channels to be in sequential order at buffer channel indices 0 to 5 in the callback, but Logic or the JUCE AU wrapper is already re-ordering this. So, if I have a 5.1 wav file that does not have the channels in the same ordering Logic uses, then I first have to remap the input channels so I can get 0 to 5 in sequential order . The same occurs at the output - if I write to channel index 0 of the JUCE callback buffer, it comes out on channel index 1 of a Logic 5.1 track or channel index 2 of a 7.1.2 track.

This makes matching the ordering of metering in my plug-in to the channel order of the metering in Logic’s surround channels very cumbersome, with manual remapping required. What’s more is that Logic uses a different ordering of Atmos channels than Pro Tools, Nuendo, etc.

So, could we have some kind of option to allow JUCE plug-in buffers to match the sequential 0-N indicies of the Logic meters? Otherwise, it seems like we need the ability to query the channel name of a given buffer index, per format (5.1, 7.1.2, etc) in Logic, so I know how to remap my meters to match the order in Logic.

In a JUCE plugin, you can use the AudioChannelSet class to determine the meaning of each channel. You can use AudioProcessor::getOffsetInBusBufferForAbsoluteChannelIndex to find the bus and bus-channel corresponding to a specific absolute input/output channel. From there, you can use AudioProcessor::getBus to return the bus at that index, then Bus::getCurrentLayout to find the channel layout applied to that bus. Finally, you can use AudioChannelSet::getTypeOfChannel to find the type (left, right, center, LFE etc.) of a specific channel on the bus. This is the sort of technique you should probably be using to label and order your meters.

The above procedure should be portable across all plugin formats and hosts. However, it does require that the host correctly advertises its channel layouts. As discussed in this thread, newer versions of Logic don’t seem to accurately report their channel layouts, which makes it difficult for JUCE to remap the channels correctly into the “JUCE channel order”.

The way this is supposed to work is that the plugin can advertise support for specific layouts, and the host can also request to use specific layouts. Both sides should agree on a layout before processing begins. The purpose of the constants mentioned above (kAudioChannelLayoutTag_Logic_Atmos_7_1_4_A etc.) is to describe the layout of channels on the bus. In the case of the 7.1.4 A and B layouts, these have different channel orderings. Because there are (at least) two different possible 7.1.4 layouts, it’s very important that the host and the client both agree on which layout they are going to use!

The problem that I was seeing in testing is that Logic picks a certain layout, but it doesn’t seem to communicate this layout to the plugin, or respect the plugin’s requests to use a specific layout. In addition, the chosen layout seemed to depend on the architecture of the host.

Thank you for the response - I can verify as well that AudioChannelSet::getTypeOfChannel does not return the correct channels for Logic 10.7.2 on an Intel mac currently. Hopefully this is addressed by Apple soon.

1 Like

An update:

We still haven’t added support for the new Atmos layouts in macOS 12 for hosts or plugins due to the remaining Logic issues.

However, we have now updated the Audio Unit hosting code to support the other Atmos layouts correctly. Previously, the AudioPluginHost would not arrange the ingoing and outgoing channels correctly. The following change ensures that the host channels are supplied in the order expected by the plugin:

We’ve also updated the AudioPluginHost I/O configuration window to allow selecting these new Atmos layouts, which may be useful for testing.


Thanks! My plugin now works 7.1.4 when using the latest development branch :+1:

Thanks @reuk nice to see some updates here. Has JUCE reported this issue to Apple? We really need AudioChannelSet::getTypeOfChannel to work for Logic to match channel ordering without manually overriding buffers indices for each surround format. Just to confirm a simple example: getBus(false, 0)->getCurrentLayout().getTypeOfChannel(0) returns L (left) for a Stereo->5.1 track in Logic whereas it should return Ls (left side) to match Logic’s channel ordering: Ls, L, C, R, Rs, LFE. I realize this is not a JUCE issue, but please keep us posted if this has been reported to Apple and becomes resolved.

The issue discussed above was that the channel order passed by Logic to the plugin didn’t match the channel order it declared in its kAudioChannelLayoutTag for certain Atmos layouts. We reported this issue to Apple and have not heard back.

I think that the behaviour you’re describing is the intended behaviour of the JUCE channel remapping.

The JUCE channel order should not be expected to match the order of inputs provided to the plugin. Although Logic uses the order LS L C R RS LFE by convention for display purposes, in Logic 10.6.3 I see that Logic provides channels a test 5.1 plugin in the order specified by the kAudioChannelLayoutTag_MPEG_5_1_A layout, specifically L R C LFE LS RS. This isn’t set in stone - Logic could also choose to use kAudioChannelLayoutTag_MPEG_5_1_B, and the channel order would be L R LS RS C LFE instead.

To be as clear as possible: the channel order that Logic displays in its UI does not necessarily correspond to the channel order that it passes to hosted plugins.

Perhaps you could approach the problem in a different way. For example, if you know that you want to process the left surround channel, you could use getCurrentLayout.getChannelIndexForType (AudioChannelSet::ChannelType::leftSurround) to find out the channel index for this channel type, and then read from that channel index.

As we are into this topic, i checked Nuendo and found that several Layouts are not really supported. Description is unknown, though speakers seem to somehow fit (not really tested that in detail).

const CString kString90_4 = 9.0.4;
const CString kString91_4 = 9.1.4;
const CString kString90_6 = 9.0.6;
const CString kString91_6 = 9.1.6;
const CString kString100 = 10.0 Auro-3D;
const CString kString101 = 10.1 Auro-3D;
const CString kString110 = 11.0 Auro-3D;
const CString kString111 = 11.1 Auro-3D;
const CString kString130 = 13.0 Auro-3D;
const CString kString131 = 13.1 Auro-3D;
const CString kString81MPEG = 8.1 MPEG;
const CString kString140 = 14.0;
const CString kString222 = 22.2;
const CString kString220 = 22.0;