| @@ -23,7 +23,12 @@ | |||
| namespace juce | |||
| { | |||
| AudioChannelSet::AudioChannelSet (uint32 c) : channels (c) {} | |||
| AudioChannelSet::AudioChannelSet (uint32 c) : channels (static_cast<int64> (c)) | |||
| { | |||
| } | |||
| AudioChannelSet::AudioChannelSet (const Array<ChannelType>& c) | |||
| { | |||
| for (auto channel : c) | |||
| @@ -106,15 +111,18 @@ String AudioChannelSet::getAbbreviatedChannelTypeName (AudioChannelSet::ChannelT | |||
| case LFE2: return "Lfe2"; | |||
| case leftSurroundSide: return "Lss"; | |||
| case rightSurroundSide: return "Rss"; | |||
| case ambisonicW: return "W"; | |||
| case ambisonicX: return "X"; | |||
| case ambisonicY: return "Y"; | |||
| case ambisonicZ: return "Z"; | |||
| case ambisonicACN0: return "ACN0"; | |||
| case ambisonicACN1: return "ACN1"; | |||
| case ambisonicACN2: return "ACN2"; | |||
| case ambisonicACN3: return "ACN3"; | |||
| case topSideLeft: return "Tsl"; | |||
| case topSideRight: return "Tsr"; | |||
| default: break; | |||
| } | |||
| if (type >= ambisonicACN4 && type <= ambisonicACN35) | |||
| return "ACN" + String (type - ambisonicACN4 + 4); | |||
| return {}; | |||
| } | |||
| @@ -215,7 +223,26 @@ String AudioChannelSet::getDescription() const | |||
| if (*this == pentagonal()) return "Pentagonal"; | |||
| if (*this == hexagonal()) return "Hexagonal"; | |||
| if (*this == octagonal()) return "Octagonal"; | |||
| if (*this == ambisonic()) return "Ambisonic"; | |||
| // ambisonics | |||
| { | |||
| auto order = getAmbisonicOrder(); | |||
| if (order >= 0) | |||
| { | |||
| String suffix; | |||
| switch (order) | |||
| { | |||
| case 1: suffix = "st"; break; | |||
| case 2: suffix = "nd"; break; | |||
| case 3: suffix = "rd"; break; | |||
| default: suffix = "th"; break; | |||
| } | |||
| return String (order) + suffix + " Order Ambisonics"; | |||
| } | |||
| } | |||
| return "Unknown"; | |||
| } | |||
| @@ -223,7 +250,7 @@ String AudioChannelSet::getDescription() const | |||
| bool AudioChannelSet::isDiscreteLayout() const noexcept | |||
| { | |||
| for (auto& speaker : getChannelTypes()) | |||
| if (speaker <= topSideRight) | |||
| if (speaker <= ambisonicACN35) | |||
| return false; | |||
| return true; | |||
| @@ -299,7 +326,6 @@ AudioChannelSet AudioChannelSet::create7point0() { return AudioChannelSet | |||
| AudioChannelSet AudioChannelSet::create7point0SDDS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftCentre) | (1u << rightCentre)); } | |||
| AudioChannelSet AudioChannelSet::create7point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurroundSide) | (1u << rightSurroundSide) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); } | |||
| AudioChannelSet AudioChannelSet::create7point1SDDS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftCentre) | (1u << rightCentre)); } | |||
| AudioChannelSet AudioChannelSet::ambisonic() { return AudioChannelSet ((1u << ambisonicW) | (1u << ambisonicX) | (1u << ambisonicY) | (1u << ambisonicZ)); } | |||
| AudioChannelSet AudioChannelSet::quadraphonic() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << leftSurround) | (1u << rightSurround)); } | |||
| AudioChannelSet AudioChannelSet::pentagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); } | |||
| AudioChannelSet AudioChannelSet::hexagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << centreSurround) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); } | |||
| @@ -307,6 +333,30 @@ AudioChannelSet AudioChannelSet::octagonal() { return AudioChannelSet | |||
| AudioChannelSet AudioChannelSet::create7point0point2() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurroundSide) | (1u << rightSurroundSide) | (1u << leftSurroundRear) | (1u << rightSurroundRear) | (1u << topSideLeft) | (1u << topSideRight)); } | |||
| AudioChannelSet AudioChannelSet::create7point1point2() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurroundSide) | (1u << rightSurroundSide) | (1u << leftSurroundRear) | (1u << rightSurroundRear) | (1u << topSideLeft) | (1u << topSideRight)); } | |||
| AudioChannelSet AudioChannelSet::ambisonic (int order) | |||
| { | |||
| jassert (isPositiveAndBelow (order, 6)); | |||
| if (order == 0) | |||
| return AudioChannelSet ((uint32) (1 << ambisonicACN0)); | |||
| AudioChannelSet set ((1u << ambisonicACN0) | (1u << ambisonicACN1) | (1u << ambisonicACN2) | (1u << ambisonicACN3)); | |||
| auto numAmbisonicChannels = (order + 1) * (order + 1); | |||
| set.channels.setRange (ambisonicACN4, numAmbisonicChannels - 4, true); | |||
| return set; | |||
| } | |||
| int AudioChannelSet::getAmbisonicOrder() const | |||
| { | |||
| auto ambisonicOrder = getAmbisonicOrderForNumChannels (size()); | |||
| if (ambisonicOrder >= 0) | |||
| return (*this == ambisonic (ambisonicOrder) ? ambisonicOrder : -1); | |||
| return -1; | |||
| } | |||
| AudioChannelSet AudioChannelSet::discreteChannels (int numChannels) | |||
| { | |||
| @@ -368,7 +418,6 @@ Array<AudioChannelSet> AudioChannelSet::channelSetsWithNumberOfChannels (int num | |||
| { | |||
| retval.add (AudioChannelSet::quadraphonic()); | |||
| retval.add (AudioChannelSet::createLCRS()); | |||
| retval.add (AudioChannelSet::ambisonic()); | |||
| } | |||
| else if (numChannels == 5) | |||
| { | |||
| @@ -395,6 +444,10 @@ Array<AudioChannelSet> AudioChannelSet::channelSetsWithNumberOfChannels (int num | |||
| retval.add (AudioChannelSet::create7point1SDDS()); | |||
| retval.add (AudioChannelSet::octagonal()); | |||
| } | |||
| auto order = getAmbisonicOrderForNumChannels (numChannels); | |||
| if (order >= 0) | |||
| retval.add (AudioChannelSet::ambisonic (order)); | |||
| } | |||
| return retval; | |||
| @@ -428,4 +481,106 @@ int32 AudioChannelSet::getWaveChannelMask() const noexcept | |||
| return (channels.toInteger() >> 1); | |||
| } | |||
| //============================================================================== | |||
| int JUCE_CALLTYPE AudioChannelSet::getAmbisonicOrderForNumChannels (int numChannels) | |||
| { | |||
| auto sqrtMinusOne = std::sqrt (static_cast<float> (numChannels)) - 1.0f; | |||
| auto ambisonicOrder = jmax (0, static_cast<int> (std::floor (sqrtMinusOne))); | |||
| if (ambisonicOrder > 5) | |||
| return -1; | |||
| return (static_cast<float> (ambisonicOrder) == sqrtMinusOne ? ambisonicOrder : -1); | |||
| } | |||
| //============================================================================== | |||
| #if JUCE_UNIT_TESTS | |||
| class AudioChannelSetUnitTest : public UnitTest | |||
| { | |||
| public: | |||
| AudioChannelSetUnitTest() : UnitTest ("AudioChannelSetUnitTest", "Audio") {} | |||
| void runTest() override | |||
| { | |||
| auto max = AudioChannelSet::maxChannelsOfNamedLayout; | |||
| beginTest ("maxChannelsOfNamedLayout is non-discrete"); | |||
| expect (AudioChannelSet::channelSetsWithNumberOfChannels (max).size() >= 2); | |||
| beginTest ("channelSetsWithNumberOfChannels returns correct speaker count"); | |||
| { | |||
| for (auto ch = 1; ch <= max; ++ch) | |||
| { | |||
| auto channelSets = AudioChannelSet::channelSetsWithNumberOfChannels (ch); | |||
| for (auto set : channelSets) | |||
| expect (set.size() == ch); | |||
| } | |||
| } | |||
| beginTest ("Ambisonics"); | |||
| { | |||
| uint64 mask = 0; | |||
| mask |= (1ull << AudioChannelSet::ambisonicACN0); | |||
| checkAmbisonic (mask, 0, "0th Order Ambisonics"); | |||
| mask |= (1ull << AudioChannelSet::ambisonicACN1) | (1ull << AudioChannelSet::ambisonicACN2) | (1ull << AudioChannelSet::ambisonicACN3); | |||
| checkAmbisonic (mask, 1, "1st Order Ambisonics"); | |||
| mask |= (1ull << AudioChannelSet::ambisonicACN4) | (1ull << AudioChannelSet::ambisonicACN5) | (1ull << AudioChannelSet::ambisonicACN6) | |||
| | (1ull << AudioChannelSet::ambisonicACN7) | (1ull << AudioChannelSet::ambisonicACN8); | |||
| checkAmbisonic (mask, 2, "2nd Order Ambisonics"); | |||
| mask |= (1ull << AudioChannelSet::ambisonicACN9) | (1ull << AudioChannelSet::ambisonicACN10) | (1ull << AudioChannelSet::ambisonicACN11) | |||
| | (1ull << AudioChannelSet::ambisonicACN12) | (1ull << AudioChannelSet::ambisonicACN13) | (1ull << AudioChannelSet::ambisonicACN14) | |||
| | (1ull << AudioChannelSet::ambisonicACN15); | |||
| checkAmbisonic (mask, 3, "3rd Order Ambisonics"); | |||
| mask |= (1ull << AudioChannelSet::ambisonicACN16) | (1ull << AudioChannelSet::ambisonicACN17) | (1ull << AudioChannelSet::ambisonicACN18) | |||
| | (1ull << AudioChannelSet::ambisonicACN19) | (1ull << AudioChannelSet::ambisonicACN20) | (1ull << AudioChannelSet::ambisonicACN21) | |||
| | (1ull << AudioChannelSet::ambisonicACN22) | (1ull << AudioChannelSet::ambisonicACN23) | (1ull << AudioChannelSet::ambisonicACN24); | |||
| checkAmbisonic (mask, 4, "4th Order Ambisonics"); | |||
| mask |= (1ull << AudioChannelSet::ambisonicACN25) | (1ull << AudioChannelSet::ambisonicACN26) | (1ull << AudioChannelSet::ambisonicACN27) | |||
| | (1ull << AudioChannelSet::ambisonicACN28) | (1ull << AudioChannelSet::ambisonicACN29) | (1ull << AudioChannelSet::ambisonicACN30) | |||
| | (1ull << AudioChannelSet::ambisonicACN31) | (1ull << AudioChannelSet::ambisonicACN32) | (1ull << AudioChannelSet::ambisonicACN33) | |||
| | (1ull << AudioChannelSet::ambisonicACN34) | (1ull << AudioChannelSet::ambisonicACN35); | |||
| checkAmbisonic (mask, 5, "5th Order Ambisonics"); | |||
| } | |||
| } | |||
| private: | |||
| void checkAmbisonic (uint64 mask, int order, const char* layoutName) | |||
| { | |||
| auto expected = AudioChannelSet::ambisonic (order); | |||
| auto numChannels = expected.size(); | |||
| expect (numChannels == BigInteger ((int64) mask).countNumberOfSetBits()); | |||
| expect (channelSetFromMask (mask) == expected); | |||
| expect (order == expected.getAmbisonicOrder()); | |||
| expect (expected.getDescription() == layoutName); | |||
| auto layouts = AudioChannelSet::channelSetsWithNumberOfChannels (numChannels); | |||
| expect (layouts.contains (expected)); | |||
| for (auto layout : layouts) | |||
| expect (layout.getAmbisonicOrder() == (layout == expected ? order : -1)); | |||
| } | |||
| static AudioChannelSet channelSetFromMask (uint64 mask) | |||
| { | |||
| Array<AudioChannelSet::ChannelType> channels; | |||
| for (int bit = 0; bit <= 62; ++bit) | |||
| if ((mask & (1ull << bit)) != 0) | |||
| channels.add (static_cast<AudioChannelSet::ChannelType> (bit)); | |||
| return AudioChannelSet::channelSetWithChannels (channels); | |||
| } | |||
| }; | |||
| static AudioChannelSetUnitTest audioChannelSetUnitTest; | |||
| #endif | |||
| } // namespace juce | |||
| @@ -208,13 +208,6 @@ public: | |||
| //============================================================================== | |||
| /** Creates a set for ambisonic surround setups (ambisonicW, ambisonicX, ambisonicY, ambisonicZ). | |||
| Is equivalent to: kBFormat (VST), n/a (AAX), kAudioChannelLayoutTag_Ambisonic_B_Format (CoreAudio) | |||
| */ | |||
| static AudioChannelSet JUCE_CALLTYPE ambisonic(); | |||
| /** Creates a set for quadraphonic surround setup (left, right, leftSurround, rightSurround) | |||
| Is equivalent to: k40Music (VST), AAX_eStemFormat_Quad (AAX), kAudioChannelLayoutTag_Quadraphonic (CoreAudio) | |||
| @@ -246,6 +239,18 @@ public: | |||
| */ | |||
| static AudioChannelSet JUCE_CALLTYPE octagonal(); | |||
| //============================================================================== | |||
| /** Creates a set for ambisonic surround setups (ambisonicW, ambisonicX, ambisonicY, ambisonicZ). | |||
| Is equivalent to: kAmbiXXXOrderACN (VST), AAX_eStemFormat_Ambi_XXX_ACN (AAX), kAudioChannelLayoutTag_HOA_ACN_SN3D (CoreAudio) | |||
| */ | |||
| static AudioChannelSet JUCE_CALLTYPE ambisonic (int order = 1); | |||
| /** Returns the order of the ambisonic layout represented by this AudioChannelSet. If the | |||
| AudioChannelSet is not an ambisonic layout, then this method will return -1. | |||
| */ | |||
| int getAmbisonicOrder() const; | |||
| //============================================================================== | |||
| /** Creates a set of untyped discrete channels. */ | |||
| static AudioChannelSet JUCE_CALLTYPE discreteChannels (int numChannels); | |||
| @@ -269,10 +274,12 @@ public: | |||
| { | |||
| unknown = 0, | |||
| //============================================================================== | |||
| left = 1, // L | |||
| right = 2, // R | |||
| centre = 3, // C (sometimes M for mono) | |||
| //============================================================================== | |||
| LFE = 4, | |||
| leftSurround = 5, // Ls | |||
| rightSurround = 6, // Rs | |||
| @@ -295,17 +302,67 @@ public: | |||
| wideLeft = 22, | |||
| wideRight = 23, | |||
| ambisonicW = 24, | |||
| ambisonicX = 25, | |||
| ambisonicY = 26, | |||
| ambisonicZ = 27, | |||
| //============================================================================== | |||
| // Used by Dolby Atmos 7.0.2 and 7.1.2 | |||
| topSideLeft = 28, // Lts (AAX), Tsl (VST) | |||
| topSideRight = 29, // Rts (AAX), Tsr (VST) | |||
| //============================================================================== | |||
| // Ambisonic ACN formats - all channels are SN3D normalised | |||
| // zero-th and first-order ambisonic ACN | |||
| ambisonicACN0 = 24, | |||
| ambisonicACN1 = 25, | |||
| ambisonicACN2 = 26, | |||
| ambisonicACN3 = 27, | |||
| // second-order ambisonic | |||
| ambisonicACN4 = 30, | |||
| ambisonicACN5 = 31, | |||
| ambisonicACN6 = 32, | |||
| ambisonicACN7 = 33, | |||
| ambisonicACN8 = 34, | |||
| // third-order ambisonic | |||
| ambisonicACN9 = 35, | |||
| ambisonicACN10 = 36, | |||
| ambisonicACN11 = 37, | |||
| ambisonicACN12 = 38, | |||
| ambisonicACN13 = 39, | |||
| ambisonicACN14 = 40, | |||
| ambisonicACN15 = 41, | |||
| // fourth-order ambisonic | |||
| ambisonicACN16 = 42, | |||
| ambisonicACN17 = 43, | |||
| ambisonicACN18 = 44, | |||
| ambisonicACN19 = 45, | |||
| ambisonicACN20 = 46, | |||
| ambisonicACN21 = 47, | |||
| ambisonicACN22 = 48, | |||
| ambisonicACN23 = 49, | |||
| ambisonicACN24 = 50, | |||
| // fifth-order ambisonic | |||
| ambisonicACN25 = 51, | |||
| ambisonicACN26 = 52, | |||
| ambisonicACN27 = 53, | |||
| ambisonicACN28 = 54, | |||
| ambisonicACN29 = 55, | |||
| ambisonicACN30 = 56, | |||
| ambisonicACN31 = 57, | |||
| ambisonicACN32 = 58, | |||
| ambisonicACN33 = 59, | |||
| ambisonicACN34 = 60, | |||
| ambisonicACN35 = 61, | |||
| //============================================================================== | |||
| ambisonicW = ambisonicACN0, | |||
| ambisonicX = ambisonicACN3, | |||
| ambisonicY = ambisonicACN1, | |||
| ambisonicZ = ambisonicACN2, | |||
| //============================================================================== | |||
| discreteChannel0 = 64 /**< Non-typed individual channels are indexed upwards from this value. */ | |||
| }; | |||
| @@ -321,7 +378,7 @@ public: | |||
| //============================================================================== | |||
| enum | |||
| { | |||
| maxChannelsOfNamedLayout = 10 | |||
| maxChannelsOfNamedLayout = 36 | |||
| }; | |||
| /** Adds a channel to the set. */ | |||
| @@ -403,6 +460,9 @@ private: | |||
| //============================================================================== | |||
| explicit AudioChannelSet (uint32); | |||
| explicit AudioChannelSet (const Array<ChannelType>&); | |||
| //============================================================================== | |||
| static int JUCE_CALLTYPE getAmbisonicOrderForNumChannels (int); | |||
| }; | |||
| } // namespace juce | |||
| @@ -52,6 +52,9 @@ struct CoreAudioLayouts | |||
| */ | |||
| static AudioChannelLayoutTag toCoreAudio (const AudioChannelSet& set) | |||
| { | |||
| if (set.getAmbisonicOrder() >= 0) | |||
| return kAudioChannelLayoutTag_HOA_ACN_SN3D | static_cast<unsigned> (set.size()); | |||
| for (auto* tbl = SpeakerLayoutTable::get(); tbl->tag != 0; ++tbl) | |||
| { | |||
| AudioChannelSet caSet; | |||
| @@ -125,6 +128,15 @@ struct CoreAudioLayouts | |||
| } | |||
| auto numChannels = tag & 0xffff; | |||
| if (tag >= kAudioChannelLayoutTag_HOA_ACN_SN3D && tag <= (kAudioChannelLayoutTag_HOA_ACN_SN3D | 0xffff)) | |||
| { | |||
| auto sqrtMinusOne = std::sqrt (static_cast<float> (numChannels)) - 1.0f; | |||
| auto ambisonicOrder = jmax (0, static_cast<int> (std::floor (sqrtMinusOne))); | |||
| if (static_cast<float> (ambisonicOrder) == sqrtMinusOne) | |||
| return AudioChannelSet::ambisonic (ambisonicOrder).getChannelTypes(); | |||
| } | |||
| for (UInt32 i = 0; i < numChannels; ++i) | |||
| speakers.add (static_cast<AudioChannelSet::ChannelType> (AudioChannelSet::discreteChannel0 + i)); | |||
| @@ -146,6 +158,9 @@ private: | |||
| for (auto* tbl = SpeakerLayoutTable::get(); tbl->tag != 0; ++tbl) | |||
| tags.addIfNotAlreadyThere (tbl->tag); | |||
| for (unsigned order = 0; order <= 5; ++order) | |||
| tags.addIfNotAlreadyThere (kAudioChannelLayoutTag_HOA_ACN_SN3D | ((order + 1) * (order + 1))); | |||
| return tags; | |||
| } | |||
| @@ -605,6 +605,17 @@ class CoreAudioLayoutsUnitTest : public UnitTest | |||
| public: | |||
| CoreAudioLayoutsUnitTest() : UnitTest ("Core Audio Layout <-> JUCE channel layout conversion", "Audio") {} | |||
| // some ambisonic tags which are not explicitely defined | |||
| enum | |||
| { | |||
| kAudioChannelLayoutTag_HOA_ACN_SN3D_0Order = kAudioChannelLayoutTag_HOA_ACN_SN3D | 1, | |||
| kAudioChannelLayoutTag_HOA_ACN_SN3D_1Order = kAudioChannelLayoutTag_HOA_ACN_SN3D | 4, | |||
| kAudioChannelLayoutTag_HOA_ACN_SN3D_2Order = kAudioChannelLayoutTag_HOA_ACN_SN3D | 9, | |||
| kAudioChannelLayoutTag_HOA_ACN_SN3D_3Order = kAudioChannelLayoutTag_HOA_ACN_SN3D | 16, | |||
| kAudioChannelLayoutTag_HOA_ACN_SN3D_4Order = kAudioChannelLayoutTag_HOA_ACN_SN3D | 25, | |||
| kAudioChannelLayoutTag_HOA_ACN_SN3D_5Order = kAudioChannelLayoutTag_HOA_ACN_SN3D | 36 | |||
| }; | |||
| void runTest() override | |||
| { | |||
| auto& knownTags = getAllKnownLayoutTags(); | |||
| @@ -703,7 +714,7 @@ private: | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MidSide), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_XY), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_Binaural), | |||
| DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_Ambisonic_B_Format, AudioChannelSet::ambisonic()), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_Ambisonic_B_Format), | |||
| DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_Quadraphonic, AudioChannelSet::quadraphonic()), | |||
| DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_Pentagonal, AudioChannelSet::pentagonal()), | |||
| DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_Hexagonal, AudioChannelSet::hexagonal()), | |||
| @@ -818,7 +829,14 @@ private: | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_8_0_B), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_8_1_A), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_8_1_B), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_6_1_D) | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_6_1_D), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_6_1_D), | |||
| DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_HOA_ACN_SN3D_0Order, AudioChannelSet::ambisonic (0)), | |||
| DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_HOA_ACN_SN3D_1Order, AudioChannelSet::ambisonic (1)), | |||
| DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_HOA_ACN_SN3D_2Order, AudioChannelSet::ambisonic (2)), | |||
| DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_HOA_ACN_SN3D_3Order, AudioChannelSet::ambisonic (3)), | |||
| DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_HOA_ACN_SN3D_4Order, AudioChannelSet::ambisonic (4)), | |||
| DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_HOA_ACN_SN3D_5Order, AudioChannelSet::ambisonic (5)) | |||
| }; | |||
| static Array<CoreAudioChannelLayoutTag> knownTags (tags, sizeof (tags) / sizeof (CoreAudioChannelLayoutTag)); | |||
| @@ -144,6 +144,19 @@ namespace AAXClasses | |||
| AudioChannelSet::ChannelType speakerOrder[10]; | |||
| }; | |||
| static AAX_EStemFormat stemFormatForAmbisonicOrder (int order) | |||
| { | |||
| switch (order) | |||
| { | |||
| case 1: return AAX_eStemFormat_Ambi_1_ACN; | |||
| case 2: return AAX_eStemFormat_Ambi_2_ACN; | |||
| case 3: return AAX_eStemFormat_Ambi_3_ACN; | |||
| default: break; | |||
| } | |||
| return AAX_eStemFormat_INT32_MAX; | |||
| } | |||
| static AAXChannelStreamOrder aaxChannelOrder[] = | |||
| { | |||
| { AAX_eStemFormat_Mono, { AudioChannelSet::centre, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown } }, | |||
| @@ -180,7 +193,10 @@ namespace AAXClasses | |||
| AAX_eStemFormat_7_0_DTS, | |||
| AAX_eStemFormat_7_1_DTS, | |||
| AAX_eStemFormat_7_0_2, | |||
| AAX_eStemFormat_7_1_2 | |||
| AAX_eStemFormat_7_1_2, | |||
| AAX_eStemFormat_Ambi_1_ACN, | |||
| AAX_eStemFormat_Ambi_2_ACN, | |||
| AAX_eStemFormat_Ambi_3_ACN | |||
| }; | |||
| static AAX_EStemFormat getFormatForAudioChannelSet (const AudioChannelSet& set, bool ignoreLayout) noexcept | |||
| @@ -188,7 +204,9 @@ namespace AAXClasses | |||
| // if the plug-in ignores layout, it is ok to convert between formats only by their numchannnels | |||
| if (ignoreLayout) | |||
| { | |||
| switch (set.size()) | |||
| auto numChannels = set.size(); | |||
| switch (numChannels) | |||
| { | |||
| case 0: return AAX_eStemFormat_None; | |||
| case 1: return AAX_eStemFormat_Mono; | |||
| @@ -201,8 +219,17 @@ namespace AAXClasses | |||
| case 8: return AAX_eStemFormat_7_1_DTS; | |||
| case 9: return AAX_eStemFormat_7_0_2; | |||
| case 10: return AAX_eStemFormat_7_1_2; | |||
| default: return AAX_eStemFormat_INT32_MAX; | |||
| default: break; | |||
| } | |||
| // check for ambisonics support | |||
| auto sqrtMinusOne = std::sqrt (static_cast<float> (numChannels)) - 1.0f; | |||
| auto ambisonicOrder = jmax (0, static_cast<int> (std::floor (sqrtMinusOne))); | |||
| if (static_cast<float> (ambisonicOrder) == sqrtMinusOne) | |||
| return stemFormatForAmbisonicOrder (ambisonicOrder); | |||
| return AAX_eStemFormat_INT32_MAX; | |||
| } | |||
| if (set == AudioChannelSet::disabled()) return AAX_eStemFormat_None; | |||
| @@ -222,6 +249,10 @@ namespace AAXClasses | |||
| if (set == AudioChannelSet::create7point0point2()) return AAX_eStemFormat_7_0_2; | |||
| if (set == AudioChannelSet::create7point1point2()) return AAX_eStemFormat_7_1_2; | |||
| auto order = set.getAmbisonicOrder(); | |||
| if (order >= 0) | |||
| return stemFormatForAmbisonicOrder (order); | |||
| return AAX_eStemFormat_INT32_MAX; | |||
| } | |||
| @@ -231,23 +262,26 @@ namespace AAXClasses | |||
| { | |||
| switch (format) | |||
| { | |||
| case AAX_eStemFormat_None: return AudioChannelSet::disabled(); | |||
| case AAX_eStemFormat_Mono: return AudioChannelSet::mono(); | |||
| case AAX_eStemFormat_Stereo: return AudioChannelSet::stereo(); | |||
| case AAX_eStemFormat_LCR: return AudioChannelSet::createLCR(); | |||
| case AAX_eStemFormat_LCRS: return AudioChannelSet::createLCRS(); | |||
| case AAX_eStemFormat_Quad: return AudioChannelSet::quadraphonic(); | |||
| case AAX_eStemFormat_5_0: return AudioChannelSet::create5point0(); | |||
| case AAX_eStemFormat_5_1: return AudioChannelSet::create5point1(); | |||
| case AAX_eStemFormat_6_0: return AudioChannelSet::create6point0(); | |||
| case AAX_eStemFormat_6_1: return AudioChannelSet::create6point1(); | |||
| case AAX_eStemFormat_7_0_SDDS: return AudioChannelSet::create7point0SDDS(); | |||
| case AAX_eStemFormat_7_0_DTS: return AudioChannelSet::create7point0(); | |||
| case AAX_eStemFormat_7_1_SDDS: return AudioChannelSet::create7point1SDDS(); | |||
| case AAX_eStemFormat_7_1_DTS: return AudioChannelSet::create7point1(); | |||
| case AAX_eStemFormat_7_0_2: return AudioChannelSet::create7point0point2(); | |||
| case AAX_eStemFormat_7_1_2: return AudioChannelSet::create7point1point2(); | |||
| default: return AudioChannelSet::disabled(); | |||
| case AAX_eStemFormat_None: return AudioChannelSet::disabled(); | |||
| case AAX_eStemFormat_Mono: return AudioChannelSet::mono(); | |||
| case AAX_eStemFormat_Stereo: return AudioChannelSet::stereo(); | |||
| case AAX_eStemFormat_LCR: return AudioChannelSet::createLCR(); | |||
| case AAX_eStemFormat_LCRS: return AudioChannelSet::createLCRS(); | |||
| case AAX_eStemFormat_Quad: return AudioChannelSet::quadraphonic(); | |||
| case AAX_eStemFormat_5_0: return AudioChannelSet::create5point0(); | |||
| case AAX_eStemFormat_5_1: return AudioChannelSet::create5point1(); | |||
| case AAX_eStemFormat_6_0: return AudioChannelSet::create6point0(); | |||
| case AAX_eStemFormat_6_1: return AudioChannelSet::create6point1(); | |||
| case AAX_eStemFormat_7_0_SDDS: return AudioChannelSet::create7point0SDDS(); | |||
| case AAX_eStemFormat_7_0_DTS: return AudioChannelSet::create7point0(); | |||
| case AAX_eStemFormat_7_1_SDDS: return AudioChannelSet::create7point1SDDS(); | |||
| case AAX_eStemFormat_7_1_DTS: return AudioChannelSet::create7point1(); | |||
| case AAX_eStemFormat_7_0_2: return AudioChannelSet::create7point0point2(); | |||
| case AAX_eStemFormat_7_1_2: return AudioChannelSet::create7point1point2(); | |||
| case AAX_eStemFormat_Ambi_1_ACN: return AudioChannelSet::ambisonic (1); | |||
| case AAX_eStemFormat_Ambi_2_ACN: return AudioChannelSet::ambisonic (2); | |||
| case AAX_eStemFormat_Ambi_3_ACN: return AudioChannelSet::ambisonic (3); | |||
| default: return AudioChannelSet::disabled(); | |||
| } | |||
| } | |||
| @@ -283,9 +317,13 @@ namespace AAXClasses | |||
| static int juceChannelIndexToAax (int juceIndex, const AudioChannelSet& channelSet) | |||
| { | |||
| auto isAmbisonic = (channelSet.getAmbisonicOrder() >= 0); | |||
| auto currentLayout = getFormatForAudioChannelSet (channelSet, false); | |||
| int layoutIndex; | |||
| if (isAmbisonic && currentLayout != AAX_eStemFormat_INT32_MAX) | |||
| return juceIndex; | |||
| for (layoutIndex = 0; aaxChannelOrder[layoutIndex].aaxStemFormat != currentLayout; ++layoutIndex) | |||
| if (aaxChannelOrder[layoutIndex].aaxStemFormat == 0) return juceIndex; | |||
| @@ -1915,6 +1953,12 @@ namespace AAXClasses | |||
| { | |||
| ScopedPointer<const AAX_IPropertyMap> props (featureInfo->AcquireProperties()); | |||
| // Due to a bug in ProTools 12.8, ProTools thinks that AAX_eStemFormat_Ambi_1_ACN is not supported | |||
| // To workaround this bug, check if ProTools supports AAX_eStemFormat_Ambi_2_ACN, and, if yes, | |||
| // we can safely assume that it will also support AAX_eStemFormat_Ambi_1_ACN | |||
| if (stemFormat == AAX_eStemFormat_Ambi_1_ACN) | |||
| stemFormat = AAX_eStemFormat_Ambi_2_ACN; | |||
| if (props != nullptr && props->GetProperty ((AAX_EProperty) stemFormat, (AAX_CPropertyValue*) &supportLevel) != 0) | |||
| return (supportLevel == AAX_eSupportLevel_Supported); | |||
| } | |||
| @@ -1168,8 +1168,6 @@ public: | |||
| err = MusicDeviceBase::ChangeStreamFormat (scope, element, old, format); | |||
| DBG (set.getDescription()); | |||
| if (err == noErr) | |||
| currentTag = CoreAudioLayouts::toCoreAudio (set); | |||
| @@ -133,6 +133,9 @@ static inline Steinberg::Vst::SpeakerArrangement getArrangementForNumChannels (i | |||
| case 12: return k111; | |||
| case 13: return k130; | |||
| case 14: return k131; | |||
| #if VST_VERSION >= 0x030608 | |||
| case 16: return kAmbi3rdOrderACN; | |||
| #endif | |||
| case 24: return (Steinberg::Vst::SpeakerArrangement) 1929904127; // k222 | |||
| default: break; | |||
| } | |||
| @@ -160,9 +163,9 @@ static inline Steinberg::Vst::Speaker getSpeakerType (const AudioChannelSet& set | |||
| case AudioChannelSet::leftCentre: return kSpeakerLc; | |||
| case AudioChannelSet::rightCentre: return kSpeakerRc; | |||
| case AudioChannelSet::centreSurround: return kSpeakerCs; | |||
| case AudioChannelSet::leftSurroundSide: return (1 << 26); /* kSpeakerLcs */ | |||
| case AudioChannelSet::rightSurroundSide: return (1 << 27); /* kSpeakerRcs */ | |||
| case AudioChannelSet::topMiddle: return (1 << 11); /* kSpeakerTm */ | |||
| case AudioChannelSet::leftSurroundSide: return (1ull << 26); /* kSpeakerLcs */ | |||
| case AudioChannelSet::rightSurroundSide: return (1ull << 27); /* kSpeakerRcs */ | |||
| case AudioChannelSet::topMiddle: return (1ull << 11); /* kSpeakerTm */ | |||
| case AudioChannelSet::topFrontLeft: return kSpeakerTfl; | |||
| case AudioChannelSet::topFrontCentre: return kSpeakerTfc; | |||
| case AudioChannelSet::topFrontRight: return kSpeakerTfr; | |||
| @@ -174,12 +177,24 @@ static inline Steinberg::Vst::Speaker getSpeakerType (const AudioChannelSet& set | |||
| case AudioChannelSet::rightSurroundRear: return kSpeakerSr; | |||
| case AudioChannelSet::wideLeft: return kSpeakerPl; | |||
| case AudioChannelSet::wideRight: return kSpeakerPr; | |||
| case AudioChannelSet::ambisonicW: return (1 << 20); /* kSpeakerW */ | |||
| case AudioChannelSet::ambisonicX: return (1 << 21); /* kSpeakerX */ | |||
| case AudioChannelSet::ambisonicY: return (1 << 22); /* kSpeakerY */ | |||
| case AudioChannelSet::ambisonicZ: return (1 << 23); /* kSpeakerZ */ | |||
| case AudioChannelSet::topSideLeft: return (1 << 24); /* kSpeakerTsl */ | |||
| case AudioChannelSet::topSideRight: return (1 << 25); /* kSpeakerTsr */ | |||
| case AudioChannelSet::ambisonicACN0: return (1ull << 20); /* kSpeakerACN0 */ | |||
| case AudioChannelSet::ambisonicACN1: return (1ull << 21); /* kSpeakerACN1 */ | |||
| case AudioChannelSet::ambisonicACN2: return (1ull << 22); /* kSpeakerACN2 */ | |||
| case AudioChannelSet::ambisonicACN3: return (1ull << 23); /* kSpeakerACN3 */ | |||
| case AudioChannelSet::ambisonicACN4: return (1ull << 38); /* kSpeakerACN4 */ | |||
| case AudioChannelSet::ambisonicACN5: return (1ull << 39); /* kSpeakerACN5 */ | |||
| case AudioChannelSet::ambisonicACN6: return (1ull << 40); /* kSpeakerACN6 */ | |||
| case AudioChannelSet::ambisonicACN7: return (1ull << 41); /* kSpeakerACN7 */ | |||
| case AudioChannelSet::ambisonicACN8: return (1ull << 42); /* kSpeakerACN8 */ | |||
| case AudioChannelSet::ambisonicACN9: return (1ull << 43); /* kSpeakerACN9 */ | |||
| case AudioChannelSet::ambisonicACN10: return (1ull << 44); /* kSpeakerACN10 */ | |||
| case AudioChannelSet::ambisonicACN11: return (1ull << 45); /* kSpeakerACN11 */ | |||
| case AudioChannelSet::ambisonicACN12: return (1ull << 46); /* kSpeakerACN12 */ | |||
| case AudioChannelSet::ambisonicACN13: return (1ull << 47); /* kSpeakerACN13 */ | |||
| case AudioChannelSet::ambisonicACN14: return (1ull << 48); /* kSpeakerACN14 */ | |||
| case AudioChannelSet::ambisonicACN15: return (1ull << 49); /* kSpeakerACN15 */ | |||
| case AudioChannelSet::topSideLeft: return (1ull << 24); /* kSpeakerTsl */ | |||
| case AudioChannelSet::topSideRight: return (1ull << 25); /* kSpeakerTsr */ | |||
| case AudioChannelSet::discreteChannel0: return kSpeakerM; | |||
| default: | |||
| @@ -189,9 +204,9 @@ static inline Steinberg::Vst::Speaker getSpeakerType (const AudioChannelSet& set | |||
| switch (static_cast<int> (type)) | |||
| { | |||
| case (int) AudioChannelSet::discreteChannel0 + 3: return (1 << 28); /* kSpeakerBfl */ | |||
| case (int) AudioChannelSet::discreteChannel0 + 4: return (1 << 29); /* kSpeakerBfc */ | |||
| case (int) AudioChannelSet::discreteChannel0 + 5: return (1 << 30); /* kSpeakerBfr */ | |||
| case (int) AudioChannelSet::discreteChannel0 + 3: return (1ull << 28); /* kSpeakerBfl */ | |||
| case (int) AudioChannelSet::discreteChannel0 + 4: return (1ull << 29); /* kSpeakerBfc */ | |||
| case (int) AudioChannelSet::discreteChannel0 + 5: return (1ull << 30); /* kSpeakerBfr */ | |||
| default: | |||
| break; | |||
| } | |||
| @@ -217,7 +232,7 @@ static inline AudioChannelSet::ChannelType getChannelType (Steinberg::Vst::Speak | |||
| case kSpeakerCs: return AudioChannelSet::centreSurround; | |||
| case kSpeakerSl: return AudioChannelSet::leftSurroundRear; | |||
| case kSpeakerSr: return AudioChannelSet::rightSurroundRear; | |||
| case (1 << 11): return AudioChannelSet::topMiddle; /* kSpeakerTm */ | |||
| case (1ull << 11): return AudioChannelSet::topMiddle; /* kSpeakerTm */ | |||
| case kSpeakerTfl: return AudioChannelSet::topFrontLeft; | |||
| case kSpeakerTfc: return AudioChannelSet::topFrontCentre; | |||
| case kSpeakerTfr: return AudioChannelSet::topFrontRight; | |||
| @@ -225,18 +240,30 @@ static inline AudioChannelSet::ChannelType getChannelType (Steinberg::Vst::Speak | |||
| case kSpeakerTrc: return AudioChannelSet::topRearCentre; | |||
| case kSpeakerTrr: return AudioChannelSet::topRearRight; | |||
| case kSpeakerLfe2: return AudioChannelSet::LFE2; | |||
| case (1 << 19): return ((arr & kSpeakerC) != 0 ? AudioChannelSet::discreteChannel0 : AudioChannelSet::centre); | |||
| case (1 << 20): return AudioChannelSet::ambisonicW; /* kSpeakerW */ | |||
| case (1 << 21): return AudioChannelSet::ambisonicX; /* kSpeakerX */ | |||
| case (1 << 22): return AudioChannelSet::ambisonicY; /* kSpeakerY */ | |||
| case (1 << 23): return AudioChannelSet::ambisonicZ; /* kSpeakerZ */ | |||
| case (1 << 24): return AudioChannelSet::topSideLeft; /* kSpeakerTsl */ | |||
| case (1 << 25): return AudioChannelSet::topSideRight; /* kSpeakerTsr */ | |||
| case (1 << 26): return AudioChannelSet::leftSurroundSide; /* kSpeakerLcs */ | |||
| case (1 << 27): return AudioChannelSet::rightSurroundSide; /* kSpeakerRcs */ | |||
| case (1 << 28): return static_cast<AudioChannelSet::ChannelType> ((int)AudioChannelSet::discreteChannel0 + 3); /* kSpeakerBfl */ | |||
| case (1 << 29): return static_cast<AudioChannelSet::ChannelType> ((int)AudioChannelSet::discreteChannel0 + 4); /* kSpeakerBfc */ | |||
| case (1 << 30): return static_cast<AudioChannelSet::ChannelType> ((int)AudioChannelSet::discreteChannel0 + 5); /* kSpeakerBfr */ | |||
| case (1ull << 19): return ((arr & kSpeakerC) != 0 ? AudioChannelSet::discreteChannel0 : AudioChannelSet::centre); | |||
| case (1ull << 20): return AudioChannelSet::ambisonicACN0; /* kSpeakerACN0 */ | |||
| case (1ull << 21): return AudioChannelSet::ambisonicACN1; /* kSpeakerACN1 */ | |||
| case (1ull << 22): return AudioChannelSet::ambisonicACN2; /* kSpeakerACN2 */ | |||
| case (1ull << 23): return AudioChannelSet::ambisonicACN3; /* kSpeakerACN3 */ | |||
| case (1ull << 38): return AudioChannelSet::ambisonicACN4; /* kSpeakerACN4 */ | |||
| case (1ull << 39): return AudioChannelSet::ambisonicACN5; /* kSpeakerACN5 */ | |||
| case (1ull << 40): return AudioChannelSet::ambisonicACN6; /* kSpeakerACN6 */ | |||
| case (1ull << 41): return AudioChannelSet::ambisonicACN7; /* kSpeakerACN7 */ | |||
| case (1ull << 42): return AudioChannelSet::ambisonicACN8; /* kSpeakerACN8 */ | |||
| case (1ull << 43): return AudioChannelSet::ambisonicACN9; /* kSpeakerACN9 */ | |||
| case (1ull << 44): return AudioChannelSet::ambisonicACN10; /* kSpeakerACN10 */ | |||
| case (1ull << 45): return AudioChannelSet::ambisonicACN11; /* kSpeakerACN11 */ | |||
| case (1ull << 46): return AudioChannelSet::ambisonicACN12; /* kSpeakerACN12 */ | |||
| case (1ull << 47): return AudioChannelSet::ambisonicACN13; /* kSpeakerACN13 */ | |||
| case (1ull << 48): return AudioChannelSet::ambisonicACN14; /* kSpeakerACN14 */ | |||
| case (1ull << 49): return AudioChannelSet::ambisonicACN15; /* kSpeakerACN15 */ | |||
| case (1ull << 24): return AudioChannelSet::topSideLeft; /* kSpeakerTsl */ | |||
| case (1ull << 25): return AudioChannelSet::topSideRight; /* kSpeakerTsr */ | |||
| case (1ull << 26): return AudioChannelSet::leftSurroundSide; /* kSpeakerLcs */ | |||
| case (1ull << 27): return AudioChannelSet::rightSurroundSide; /* kSpeakerRcs */ | |||
| case (1ull << 28): return static_cast<AudioChannelSet::ChannelType> ((int)AudioChannelSet::discreteChannel0 + 3); /* kSpeakerBfl */ | |||
| case (1ull << 29): return static_cast<AudioChannelSet::ChannelType> ((int)AudioChannelSet::discreteChannel0 + 4); /* kSpeakerBfc */ | |||
| case (1ull << 30): return static_cast<AudioChannelSet::ChannelType> ((int)AudioChannelSet::discreteChannel0 + 5); /* kSpeakerBfr */ | |||
| case kSpeakerPl: return AudioChannelSet::wideLeft; | |||
| case kSpeakerPr: return AudioChannelSet::wideRight; | |||
| default: break; | |||
| @@ -274,6 +301,12 @@ static inline Steinberg::Vst::SpeakerArrangement getVst3SpeakerArrangement (cons | |||
| else if (channels == AudioChannelSet::quadraphonic()) return k40Music; | |||
| else if (channels == AudioChannelSet::create7point0point2()) return k71_2 & ~(Steinberg::Vst::kSpeakerLfe); | |||
| else if (channels == AudioChannelSet::create7point1point2()) return k71_2; | |||
| else if (channels == AudioChannelSet::ambisonic (0)) return (1ull << 20); | |||
| else if (channels == AudioChannelSet::ambisonic (1)) return (1ull << 20) | (1ull << 21) | (1ull << 22) | (1ull << 23); | |||
| #if VST_VERSION >= 0x030608 | |||
| else if (channels == AudioChannelSet::ambisonic (2)) return kAmbi2cdOrderACN; | |||
| else if (channels == AudioChannelSet::ambisonic (3)) return kAmbi3rdOrderACN; | |||
| #endif | |||
| Steinberg::Vst::SpeakerArrangement result = 0; | |||
| @@ -289,26 +322,32 @@ static inline AudioChannelSet getChannelSetForSpeakerArrangement (Steinberg::Vst | |||
| { | |||
| using namespace Steinberg::Vst::SpeakerArr; | |||
| if (arr == kEmpty) return AudioChannelSet::disabled(); | |||
| else if (arr == kMono) return AudioChannelSet::mono(); | |||
| else if (arr == kStereo) return AudioChannelSet::stereo(); | |||
| else if (arr == k30Cine) return AudioChannelSet::createLCR(); | |||
| else if (arr == k30Music) return AudioChannelSet::createLRS(); | |||
| else if (arr == k40Cine) return AudioChannelSet::createLCRS(); | |||
| else if (arr == k50) return AudioChannelSet::create5point0(); | |||
| else if (arr == k51) return AudioChannelSet::create5point1(); | |||
| else if (arr == k60Cine) return AudioChannelSet::create6point0(); | |||
| else if (arr == k61Cine) return AudioChannelSet::create6point1(); | |||
| else if (arr == k60Music) return AudioChannelSet::create6point0Music(); | |||
| else if (arr == k61Music) return AudioChannelSet::create6point1Music(); | |||
| else if (arr == k70Music) return AudioChannelSet::create7point0(); | |||
| else if (arr == k70Cine) return AudioChannelSet::create7point0SDDS(); | |||
| else if (arr == k71CineSideFill) return AudioChannelSet::create7point1(); | |||
| else if (arr == k71Cine) return AudioChannelSet::create7point1SDDS(); | |||
| else if (arr == kAmbi1stOrderACN) return AudioChannelSet::ambisonic(); | |||
| else if (arr == k40Music) return AudioChannelSet::quadraphonic(); | |||
| else if (arr == k71_2) return AudioChannelSet::create7point1point2(); | |||
| else if (arr == (k71_2 & ~(Steinberg::Vst::kSpeakerLfe))) return AudioChannelSet::create7point0point2(); | |||
| if (arr == kEmpty) return AudioChannelSet::disabled(); | |||
| else if (arr == kMono) return AudioChannelSet::mono(); | |||
| else if (arr == kStereo) return AudioChannelSet::stereo(); | |||
| else if (arr == k30Cine) return AudioChannelSet::createLCR(); | |||
| else if (arr == k30Music) return AudioChannelSet::createLRS(); | |||
| else if (arr == k40Cine) return AudioChannelSet::createLCRS(); | |||
| else if (arr == k50) return AudioChannelSet::create5point0(); | |||
| else if (arr == k51) return AudioChannelSet::create5point1(); | |||
| else if (arr == k60Cine) return AudioChannelSet::create6point0(); | |||
| else if (arr == k61Cine) return AudioChannelSet::create6point1(); | |||
| else if (arr == k60Music) return AudioChannelSet::create6point0Music(); | |||
| else if (arr == k61Music) return AudioChannelSet::create6point1Music(); | |||
| else if (arr == k70Music) return AudioChannelSet::create7point0(); | |||
| else if (arr == k70Cine) return AudioChannelSet::create7point0SDDS(); | |||
| else if (arr == k71CineSideFill) return AudioChannelSet::create7point1(); | |||
| else if (arr == k71Cine) return AudioChannelSet::create7point1SDDS(); | |||
| else if (arr == kAmbi1stOrderACN) return AudioChannelSet::ambisonic(); | |||
| else if (arr == k40Music) return AudioChannelSet::quadraphonic(); | |||
| else if (arr == k71_2) return AudioChannelSet::create7point1point2(); | |||
| else if (arr == (k71_2 & ~(Steinberg::Vst::kSpeakerLfe))) return AudioChannelSet::create7point0point2(); | |||
| else if (arr == (1 << 20)) return AudioChannelSet::ambisonic (0); | |||
| else if (arr == ((1 << 20) | (1 << 21) | (1 << 22) | (1 << 23))) return AudioChannelSet::ambisonic (1); | |||
| #if VST_VERSION >= 0x030608 | |||
| else if (arr == kAmbi2cdOrderACN) return AudioChannelSet::ambisonic (2); | |||
| else if (arr == kAmbi3rdOrderACN) return AudioChannelSet::ambisonic (3); | |||
| #endif | |||
| AudioChannelSet result; | |||
| @@ -1365,6 +1365,9 @@ int32 AudioProcessor::getAAXPluginIDForMainBusConfig (const AudioChannelSet& mai | |||
| else if (set == AudioChannelSet::create7point1SDDS()) aaxFormatIndex = 13; | |||
| else if (set == AudioChannelSet::create7point0point2()) aaxFormatIndex = 14; | |||
| else if (set == AudioChannelSet::create7point1point2()) aaxFormatIndex = 15; | |||
| else if (set == AudioChannelSet::ambisonic (1)) aaxFormatIndex = 16; | |||
| else if (set == AudioChannelSet::ambisonic (2)) aaxFormatIndex = 17; | |||
| else if (set == AudioChannelSet::ambisonic (3)) aaxFormatIndex = 18; | |||
| else | |||
| { | |||
| // AAX does not support this format and the wrapper should not have | |||