mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-02-07 04:10:08 +00:00
Added higher-order ambisonics support to JUCE
This commit is contained in:
parent
1c7185ed25
commit
30269baed1
8 changed files with 424 additions and 92 deletions
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue