diff --git a/modules/juce_audio_basics/native/juce_mac_CoreAudioLayouts.h b/modules/juce_audio_basics/native/juce_mac_CoreAudioLayouts.h index d6b95326e5..1bf5cda274 100644 --- a/modules/juce_audio_basics/native/juce_mac_CoreAudioLayouts.h +++ b/modules/juce_audio_basics/native/juce_mac_CoreAudioLayouts.h @@ -36,6 +36,15 @@ struct CoreAudioLayouts return AudioChannelSet::channelSetWithChannels (getCoreAudioLayoutChannels (layout)); } + /** Convert CoreAudio's native AudioChannelLayoutTag to JUCE's AudioChannelSet. + + Note that this method cannot preserve the order of channels. + */ + static AudioChannelSet fromCoreAudio (AudioChannelLayoutTag layoutTag) + { + return AudioChannelSet::channelSetWithChannels (getSpeakerLayoutForCoreAudioTag (layoutTag)); + } + /** Convert JUCE's AudioChannelSet to CoreAudio's AudioChannelLayoutTag. Note that this method cannot preserve the order of channels. @@ -67,7 +76,7 @@ struct CoreAudioLayouts /** Convert CoreAudio's native AudioChannelLayout to an array of JUCE ChannelTypes. */ static Array getCoreAudioLayoutChannels (const AudioChannelLayout& layout) { - switch (layout.mChannelLayoutTag) + switch (layout.mChannelLayoutTag & 0xffff0000) { case kAudioChannelLayoutTag_UseChannelBitmap: return AudioChannelSet::fromWaveChannelMask (static_cast (layout.mChannelBitmap)).getChannelTypes(); @@ -94,30 +103,12 @@ struct CoreAudioLayouts return getSpeakerLayoutForCoreAudioTag (layout.mChannelLayoutTag); } - //============================================================================== - /* Convert between a CoreAudio and JUCE channel indices - and vice versa. */ - // TODO: Fabian remove this -// static int convertChannelIndex (const AudioChannelLayout& caLayout, const AudioChannelSet& juceLayout, int index, bool fromJUCE) -// { -// auto coreAudioChannels = getCoreAudioLayoutChannels (caLayout); -// -// jassert (juceLayout.size() == coreAudioChannels.size()); -// jassert (index >= 0 && index < juceLayout.size()); -// -// return (fromJUCE ? coreAudioChannels.indexOf (juceLayout.getTypeOfChannel (index)) -// : juceLayout.getChannelIndexForType (coreAudioChannels.getReference (index))); -// } - -private: - //============================================================================== - struct LayoutTagSpeakerList - { - AudioChannelLayoutTag tag; - AudioChannelSet::ChannelType channelTypes[16]; - }; - static Array getSpeakerLayoutForCoreAudioTag (AudioChannelLayoutTag tag) { + // You need to specify the full AudioChannelLayout when using + // the UseChannelBitmap and UseChannelDescriptions layout tag + jassert (tag != kAudioChannelLayoutTag_UseChannelBitmap && tag != kAudioChannelLayoutTag_UseChannelDescriptions); + Array speakers; for (auto* tbl = SpeakerLayoutTable::get(); tbl->tag != 0; ++tbl) @@ -139,6 +130,14 @@ private: return speakers; } +private: + //============================================================================== + struct LayoutTagSpeakerList + { + AudioChannelLayoutTag tag; + AudioChannelSet::ChannelType channelTypes[16]; + }; + static Array createKnownCoreAudioTags() { Array tags; diff --git a/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.cpp b/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.cpp index c408f6af11..4808fd85fc 100644 --- a/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.cpp +++ b/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.cpp @@ -619,8 +619,7 @@ public: for (auto tagEntry : knownTags) { - AudioChannelLayout layout { tagEntry.tag }; - auto labels = CoreAudioLayouts::fromCoreAudio (layout); + auto labels = CoreAudioLayouts::fromCoreAudio (tagEntry.tag); expect (! labels.isDiscreteLayout(), String ("Tag \"") + String (tagEntry.name) + "\" is not handled by JUCE"); } @@ -631,8 +630,7 @@ public: for (auto tagEntry : knownTags) { - AudioChannelLayout layout { tagEntry.tag }; - auto labels = CoreAudioLayouts::getCoreAudioLayoutChannels (layout); + auto labels = CoreAudioLayouts::getSpeakerLayoutForCoreAudioTag (tagEntry.tag); expect (labels.size() == (tagEntry.tag & 0xffff), String ("Tag \"") + String (tagEntry.name) + "\" has incorrect channel count"); } @@ -643,8 +641,7 @@ public: for (auto tagEntry : knownTags) { - AudioChannelLayout layout { tagEntry.tag }; - auto labels = CoreAudioLayouts::getCoreAudioLayoutChannels (layout); + auto labels = CoreAudioLayouts::getSpeakerLayoutForCoreAudioTag (tagEntry.tag); labels.sort(); for (int i = 0; i < (labels.size() - 1); ++i) @@ -657,13 +654,9 @@ public: beginTest ("CA speaker list and juce layouts are consistent"); for (auto tagEntry : knownTags) - { - AudioChannelLayout layout { tagEntry.tag }; - - expect (AudioChannelSet::channelSetWithChannels (CoreAudioLayouts::getCoreAudioLayoutChannels (layout)) - == CoreAudioLayouts::fromCoreAudio (layout), + expect (AudioChannelSet::channelSetWithChannels (CoreAudioLayouts::getSpeakerLayoutForCoreAudioTag (tagEntry.tag)) + == CoreAudioLayouts::fromCoreAudio (tagEntry.tag), String ("Tag \"") + String (tagEntry.name) + "\" is not converted consistantly by JUCE"); - } } { @@ -674,9 +667,7 @@ public: if (tagEntry.equivalentChannelSet.isDisabled()) continue; - AudioChannelLayout layout { tagEntry.tag }; - - expect (CoreAudioLayouts::fromCoreAudio (layout) == tagEntry.equivalentChannelSet, + expect (CoreAudioLayouts::fromCoreAudio (tagEntry.tag) == tagEntry.equivalentChannelSet, String ("Documentation for tag \"") + String (tagEntry.name) + "\" is incorrect"); } } diff --git a/modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm b/modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm index 2ddffafefa..d7092aadb7 100644 --- a/modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm +++ b/modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm @@ -1818,12 +1818,7 @@ private: if (numChannels != tagNumChannels) return kAudioUnitErr_FormatNotSupported; - AudioChannelLayout layout; - - zerostruct (layout); - layout.mChannelLayoutTag = currentLayoutTag; - - requestedBuses.add (CoreAudioLayouts::fromCoreAudio (layout)); + requestedBuses.add (CoreAudioLayouts::fromCoreAudio (currentLayoutTag)); } } @@ -1909,7 +1904,7 @@ private: auto& knownTags = CoreAudioLayouts::getKnownCoreAudioTags(); for (auto tag : knownTags) - if (bus->isLayoutSupported (CoreAudioLayouts::fromCoreAudio (AudioChannelLayout {tag}))) + if (bus->isLayoutSupported (CoreAudioLayouts::fromCoreAudio (tag))) tags.addIfNotAlreadyThere (tag); #endif diff --git a/modules/juce_audio_plugin_client/AU/juce_AUv3_Wrapper.mm b/modules/juce_audio_plugin_client/AU/juce_AUv3_Wrapper.mm index f94c1a5bd1..2fe29fa646 100644 --- a/modules/juce_audio_plugin_client/AU/juce_AUv3_Wrapper.mm +++ b/modules/juce_audio_plugin_client/AU/juce_AUv3_Wrapper.mm @@ -629,11 +629,7 @@ public: if (layoutTag != 0) { - AudioChannelLayout caLayout; - - zerostruct (caLayout); - caLayout.mChannelLayoutTag = layoutTag; - AudioChannelSet newLayout = CoreAudioLayouts::fromCoreAudio (caLayout); + AudioChannelSet newLayout = CoreAudioLayouts::fromCoreAudio (layoutTag); if (newLayout.size() != newNumChannels) return false; @@ -714,13 +710,7 @@ public: const AudioChannelLayoutTag layoutTag = (layout != nullptr ? [layout layoutTag] : 0); if (layoutTag != 0) - { - AudioChannelLayout caLayout; - - zerostruct (caLayout); - caLayout.mChannelLayoutTag = layoutTag; - newLayout = CoreAudioLayouts::fromCoreAudio (caLayout); - } + newLayout = CoreAudioLayouts::fromCoreAudio (layoutTag); else newLayout = bus->supportedLayoutWithChannels (static_cast ([format channelCount]));