32AudioChannelSet::AudioChannelSet (
const std::initializer_list<ChannelType>& c)
34 for (
auto channel : c)
38bool AudioChannelSet::operator== (
const AudioChannelSet& other)
const noexcept {
return channels == other.channels; }
39bool AudioChannelSet::operator!= (
const AudioChannelSet& other)
const noexcept {
return channels != other.channels; }
40bool AudioChannelSet::operator< (
const AudioChannelSet& other)
const noexcept {
return channels < other.channels; }
49 case left:
return NEEDS_TRANS (
"Left");
50 case right:
return NEEDS_TRANS (
"Right");
51 case centre:
return NEEDS_TRANS (
"Centre");
52 case LFE:
return NEEDS_TRANS (
"LFE");
55 case leftCentre:
return NEEDS_TRANS (
"Left Centre");
56 case rightCentre:
return NEEDS_TRANS (
"Right Centre");
60 case topMiddle:
return NEEDS_TRANS (
"Top Middle");
61 case topFrontLeft:
return NEEDS_TRANS (
"Top Front Left");
64 case topRearLeft:
return NEEDS_TRANS (
"Top Rear Left");
66 case topRearRight:
return NEEDS_TRANS (
"Top Rear Right");
67 case wideLeft:
return NEEDS_TRANS (
"Wide Left");
68 case wideRight:
return NEEDS_TRANS (
"Wide Right");
69 case LFE2:
return NEEDS_TRANS (
"LFE 2");
72 case ambisonicW:
return NEEDS_TRANS (
"Ambisonic W");
73 case ambisonicX:
return NEEDS_TRANS (
"Ambisonic X");
74 case ambisonicY:
return NEEDS_TRANS (
"Ambisonic Y");
75 case ambisonicZ:
return NEEDS_TRANS (
"Ambisonic Z");
76 case topSideLeft:
return NEEDS_TRANS (
"Top Side Left");
77 case topSideRight:
return NEEDS_TRANS (
"Top Side Right");
163 case left:
return "L";
164 case right:
return "R";
166 case LFE:
return "Lfe";
183 case LFE2:
return "Lfe2";
272 if (abbr.
length() > 0 && (abbr[0] >=
'0' && abbr[0] <=
'9'))
276 if (abbr ==
"L")
return left;
277 if (abbr ==
"R")
return right;
278 if (abbr ==
"C")
return centre;
279 if (abbr ==
"Lfe")
return LFE;
296 if (abbr ==
"Lfe2")
return LFE2;
388 if (name.isNotEmpty())
389 speakerTypes.
add (name);
413 if (*
this ==
disabled())
return "Disabled";
414 if (*
this ==
mono())
return "Mono";
415 if (*
this ==
stereo())
return "Stereo";
447 if (*
this ==
pentagonal())
return "Pentagonal";
448 if (*
this ==
hexagonal())
return "Hexagonal";
449 if (*
this ==
octagonal())
return "Octagonal";
461 case 1: suffix =
"st";
break;
462 case 2: suffix =
"nd";
break;
463 case 3: suffix =
"rd";
break;
464 default: suffix =
"th";
break;
467 return String (order) + suffix +
" Order Ambisonics";
478 return std::none_of (std::begin (channelTypes),
479 std::end (channelTypes),
485 return channels.countNumberOfSetBits();
490 int bit = channels.findNextSetBit (0);
492 for (
int i = 0; i < index && bit >= 0; ++i)
493 bit = channels.findNextSetBit (bit + 1);
502 for (
int bit = channels.findNextSetBit (0); bit >= 0; bit = channels.findNextSetBit (bit + 1))
517 for (
int bit = channels.findNextSetBit (0); bit >= 0; bit = channels.findNextSetBit (bit + 1))
525 const int bit =
static_cast<int> (newChannel);
526 jassert (bit >= 0 && bit < 1024);
527 channels.setBit (bit);
532 const int bit =
static_cast<int> (newChannel);
533 jassert (bit >= 0 && bit < 1024);
534 channels.clearBit (bit);
563AudioChannelSet AudioChannelSet::create7point0point4() {
return AudioChannelSet ({
left,
right,
centre,
leftSurroundSide,
rightSurroundSide,
leftSurroundRear,
rightSurroundRear,
topFrontLeft,
topFrontRight,
topRearLeft,
topRearRight }); }
564AudioChannelSet AudioChannelSet::create7point1point4() {
return AudioChannelSet ({
left,
right,
centre,
LFE,
leftSurroundSide,
rightSurroundSide,
leftSurroundRear,
rightSurroundRear,
topFrontLeft,
topFrontRight,
topRearLeft,
topRearRight }); }
565AudioChannelSet AudioChannelSet::create7point0point6() {
return AudioChannelSet ({
left,
right,
centre,
leftSurroundSide,
rightSurroundSide,
leftSurroundRear,
rightSurroundRear,
topFrontLeft,
topFrontRight,
topSideLeft,
topSideRight,
topRearLeft,
topRearRight }); }
566AudioChannelSet AudioChannelSet::create7point1point6() {
return AudioChannelSet ({
left,
right,
centre,
LFE,
leftSurroundSide,
rightSurroundSide,
leftSurroundRear,
rightSurroundRear,
topFrontLeft,
topFrontRight,
topSideLeft,
topSideRight,
topRearLeft,
topRearRight }); }
567AudioChannelSet AudioChannelSet::create9point0point4() {
return AudioChannelSet ({
left,
right,
centre,
leftSurroundSide,
rightSurroundSide,
leftSurroundRear,
rightSurroundRear,
wideLeft,
wideRight,
topFrontLeft,
topFrontRight,
topRearLeft,
topRearRight }); }
568AudioChannelSet AudioChannelSet::create9point1point4() {
return AudioChannelSet ({
left,
right,
centre,
LFE,
leftSurroundSide,
rightSurroundSide,
leftSurroundRear,
rightSurroundRear,
wideLeft,
wideRight,
topFrontLeft,
topFrontRight,
topRearLeft,
topRearRight }); }
569AudioChannelSet AudioChannelSet::create9point0point6() {
return AudioChannelSet ({
left,
right,
centre,
leftSurroundSide,
rightSurroundSide,
leftSurroundRear,
rightSurroundRear,
wideLeft,
wideRight,
topFrontLeft,
topFrontRight,
topSideLeft,
topSideRight,
topRearLeft,
topRearRight }); }
570AudioChannelSet AudioChannelSet::create9point1point6() {
return AudioChannelSet ({
left,
right,
centre,
LFE,
leftSurroundSide,
rightSurroundSide,
leftSurroundRear,
rightSurroundRear,
wideLeft,
wideRight,
topFrontLeft,
topFrontRight,
topSideLeft,
topSideRight,
topRearLeft,
topRearRight }); }
574 jassert (isPositiveAndBelow (order, 8));
582 const auto setBits = [&set] (
auto range,
auto maxNumToSet)
584 const auto numToSet = std::min (maxNumToSet, range.second - range.first + 1);
585 set.channels.
setRange (range.first, numToSet,
true);
589 const auto numAmbisonicChannels = square (order + 1);
591 for (
int rangeIdx = 0, bitsSet = 0; bitsSet < numAmbisonicChannels; ++rangeIdx)
593 bitsSet += setBits (continuousRanges[rangeIdx], numAmbisonicChannels - bitsSet);
603 if (ambisonicOrder >= 0)
604 return (*
this ==
ambisonic (ambisonicOrder) ? ambisonicOrder : -1);
648 if (numChannels != 0)
714 for (
auto ch : channelArray)
716 jassert (! set.channels[
static_cast<int> (ch)]);
727 return AudioChannelSet (
static_cast<uint32
> ((dwChannelMask & ((1 << 18) - 1)) << 1));
735 return (channels.toInteger() >> 1);
741 for (
auto i = 0; i <= maxOrderToCheck; ++i)
742 if (numChannels == square (i + 1))
753class AudioChannelSetUnitTest final :
public UnitTest
756 AudioChannelSetUnitTest()
757 :
UnitTest (
"AudioChannelSetUnitTest", UnitTestCategories::audio)
762 auto max = AudioChannelSet::maxChannelsOfNamedLayout;
764 beginTest (
"maxChannelsOfNamedLayout is non-discrete");
765 expect (AudioChannelSet::channelSetsWithNumberOfChannels (max).size() >= 2);
767 beginTest (
"channelSetsWithNumberOfChannels returns correct speaker count");
769 for (
auto ch = 1; ch <= max; ++ch)
773 for (
auto set : channelSets)
774 expect (set.size() == ch);
782 mask |= (1ull << AudioChannelSet::ambisonicACN0);
783 checkAmbisonic (mask, 0,
"0th Order Ambisonics");
785 mask |= (1ull << AudioChannelSet::ambisonicACN1) | (1ull << AudioChannelSet::ambisonicACN2) | (1ull << AudioChannelSet::ambisonicACN3);
786 checkAmbisonic (mask, 1,
"1st Order Ambisonics");
788 mask |= (1ull << AudioChannelSet::ambisonicACN4) | (1ull << AudioChannelSet::ambisonicACN5) | (1ull << AudioChannelSet::ambisonicACN6)
789 | (1ull << AudioChannelSet::ambisonicACN7) | (1ull << AudioChannelSet::ambisonicACN8);
790 checkAmbisonic (mask, 2,
"2nd Order Ambisonics");
792 mask |= (1ull << AudioChannelSet::ambisonicACN9) | (1ull << AudioChannelSet::ambisonicACN10) | (1ull << AudioChannelSet::ambisonicACN11)
793 | (1ull << AudioChannelSet::ambisonicACN12) | (1ull << AudioChannelSet::ambisonicACN13) | (1ull << AudioChannelSet::ambisonicACN14)
794 | (1ull << AudioChannelSet::ambisonicACN15);
795 checkAmbisonic (mask, 3,
"3rd Order Ambisonics");
797 mask |= (1ull << AudioChannelSet::ambisonicACN16) | (1ull << AudioChannelSet::ambisonicACN17) | (1ull << AudioChannelSet::ambisonicACN18)
798 | (1ull << AudioChannelSet::ambisonicACN19) | (1ull << AudioChannelSet::ambisonicACN20) | (1ull << AudioChannelSet::ambisonicACN21)
799 | (1ull << AudioChannelSet::ambisonicACN22) | (1ull << AudioChannelSet::ambisonicACN23) | (1ull << AudioChannelSet::ambisonicACN24);
800 checkAmbisonic (mask, 4,
"4th Order Ambisonics");
802 mask |= (1ull << AudioChannelSet::ambisonicACN25) | (1ull << AudioChannelSet::ambisonicACN26) | (1ull << AudioChannelSet::ambisonicACN27)
803 | (1ull << AudioChannelSet::ambisonicACN28) | (1ull << AudioChannelSet::ambisonicACN29) | (1ull << AudioChannelSet::ambisonicACN30)
804 | (1ull << AudioChannelSet::ambisonicACN31) | (1ull << AudioChannelSet::ambisonicACN32) | (1ull << AudioChannelSet::ambisonicACN33)
805 | (1ull << AudioChannelSet::ambisonicACN34) | (1ull << AudioChannelSet::ambisonicACN35);
806 checkAmbisonic (mask, 5,
"5th Order Ambisonics");
811 void checkAmbisonic (uint64 mask,
int order,
const char* layoutName)
814 auto numChannels = expected.size();
816 expect (numChannels == BigInteger ((int64) mask).countNumberOfSetBits());
817 expect (channelSetFromMask (mask) == expected);
819 expect (order == expected.getAmbisonicOrder());
820 expect (expected.getDescription() == layoutName);
823 expect (layouts.contains (expected));
825 for (
auto layout : layouts)
826 expect (layout.getAmbisonicOrder() == (layout == expected ? order : -1));
829 static AudioChannelSet channelSetFromMask (uint64 mask)
831 Array<AudioChannelSet::ChannelType> channels;
832 for (
int bit = 0; bit <= 62; ++bit)
833 if ((mask & (1ull << bit)) != 0)
834 channels.add (
static_cast<AudioChannelSet::ChannelType
> (bit));
840static AudioChannelSetUnitTest audioChannelSetUnitTest;
void addArray(const Type *elementsToAdd, int numElementsToAdd)
void add(const ElementType &newElement)
int getAmbisonicOrder() const
static AudioChannelSet JUCE_CALLTYPE create7point1()
static AudioChannelSet JUCE_CALLTYPE namedChannelSet(int numChannels)
static AudioChannelSet JUCE_CALLTYPE quadraphonic()
static AudioChannelSet JUCE_CALLTYPE create5point0point2()
static AudioChannelSet JUCE_CALLTYPE create5point0()
static ChannelType JUCE_CALLTYPE getChannelTypeFromAbbreviation(const String &abbreviation)
static AudioChannelSet JUCE_CALLTYPE create9point0point4()
int size() const noexcept
static AudioChannelSet JUCE_CALLTYPE create6point0()
bool isDiscreteLayout() const noexcept
AudioChannelSet()=default
static AudioChannelSet JUCE_CALLTYPE create6point1Music()
static AudioChannelSet JUCE_CALLTYPE create5point0point4()
void removeChannel(ChannelType newChannelType)
static AudioChannelSet JUCE_CALLTYPE create5point1point4()
static AudioChannelSet JUCE_CALLTYPE disabled()
static AudioChannelSet JUCE_CALLTYPE hexagonal()
static AudioChannelSet fromAbbreviatedString(const String &set)
static AudioChannelSet JUCE_CALLTYPE mono()
static AudioChannelSet JUCE_CALLTYPE create7point0point4()
static AudioChannelSet JUCE_CALLTYPE createLRS()
static Array< AudioChannelSet > JUCE_CALLTYPE channelSetsWithNumberOfChannels(int numChannels)
static AudioChannelSet JUCE_CALLTYPE stereo()
static AudioChannelSet JUCE_CALLTYPE octagonal()
static AudioChannelSet JUCE_CALLTYPE create6point1()
static AudioChannelSet JUCE_CALLTYPE create9point1point4()
static AudioChannelSet JUCE_CALLTYPE create9point0point6()
void addChannel(ChannelType newChannelType)
static AudioChannelSet JUCE_CALLTYPE create5point1()
static AudioChannelSet JUCE_CALLTYPE create7point0SDDS()
static AudioChannelSet JUCE_CALLTYPE create5point1point2()
static int getAmbisonicOrderForNumChannels(int numChannels, int maxOrderToCheck=7)
ChannelType getTypeOfChannel(int channelIndex) const noexcept
static AudioChannelSet JUCE_CALLTYPE create9point1point6()
static AudioChannelSet JUCE_CALLTYPE create6point0Music()
static String JUCE_CALLTYPE getChannelTypeName(ChannelType)
static AudioChannelSet JUCE_CALLTYPE create7point0point2()
static AudioChannelSet JUCE_CALLTYPE create7point1SDDS()
String getSpeakerArrangementAsString() const
static AudioChannelSet JUCE_CALLTYPE create7point0()
static AudioChannelSet JUCE_CALLTYPE channelSetWithChannels(const Array< ChannelType > &)
static AudioChannelSet JUCE_CALLTYPE ambisonic(int order=1)
static AudioChannelSet JUCE_CALLTYPE createLCRS()
static AudioChannelSet JUCE_CALLTYPE create7point1point2()
static AudioChannelSet JUCE_CALLTYPE canonicalChannelSet(int numChannels)
static AudioChannelSet JUCE_CALLTYPE discreteChannels(int numChannels)
static AudioChannelSet JUCE_CALLTYPE create7point0point6()
static AudioChannelSet JUCE_CALLTYPE create7point1point6()
static AudioChannelSet JUCE_CALLTYPE createLCR()
static AudioChannelSet JUCE_CALLTYPE fromWaveChannelMask(int32 dwChannelMask)
String getDescription() const
static AudioChannelSet JUCE_CALLTYPE pentagonal()
int getChannelIndexForType(ChannelType type) const noexcept
static String JUCE_CALLTYPE getAbbreviatedChannelTypeName(ChannelType)
int32 getWaveChannelMask() const noexcept
static AudioChannelSet JUCE_CALLTYPE create7point1point4()
Array< ChannelType > getChannelTypes() const
BigInteger & setRange(int startBit, int numBits, bool shouldBeSet)
String joinIntoString(StringRef separatorString, int startIndex=0, int numberOfElements=-1) const
static StringArray fromTokens(StringRef stringToTokenise, bool preserveQuotedStrings)
void add(String stringToAdd)
int length() const noexcept
int getIntValue() const noexcept
void beginTest(const String &testName)
void expect(bool testResult, const String &failureMessage=String())