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; }
44 if (type >= discreteChannel0)
45 return "Discrete " +
String (type - discreteChannel0 + 1);
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");
53 case leftSurround:
return NEEDS_TRANS (
"Left Surround");
54 case rightSurround:
return NEEDS_TRANS (
"Right Surround");
55 case leftCentre:
return NEEDS_TRANS (
"Left Centre");
56 case rightCentre:
return NEEDS_TRANS (
"Right Centre");
57 case centreSurround:
return NEEDS_TRANS (
"Centre Surround");
58 case leftSurroundRear:
return NEEDS_TRANS (
"Left Surround Rear");
59 case rightSurroundRear:
return NEEDS_TRANS (
"Right Surround Rear");
60 case topMiddle:
return NEEDS_TRANS (
"Top Middle");
61 case topFrontLeft:
return NEEDS_TRANS (
"Top Front Left");
62 case topFrontCentre:
return NEEDS_TRANS (
"Top Front Centre");
63 case topFrontRight:
return NEEDS_TRANS (
"Top Front Right");
64 case topRearLeft:
return NEEDS_TRANS (
"Top Rear Left");
65 case topRearCentre:
return NEEDS_TRANS (
"Top Rear Centre");
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");
70 case leftSurroundSide:
return NEEDS_TRANS (
"Left Surround Side");
71 case rightSurroundSide:
return NEEDS_TRANS (
"Right Surround Side");
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");
78 case ambisonicACN4:
return NEEDS_TRANS (
"Ambisonic 4");
79 case ambisonicACN5:
return NEEDS_TRANS (
"Ambisonic 5");
80 case ambisonicACN6:
return NEEDS_TRANS (
"Ambisonic 6");
81 case ambisonicACN7:
return NEEDS_TRANS (
"Ambisonic 7");
82 case ambisonicACN8:
return NEEDS_TRANS (
"Ambisonic 8");
83 case ambisonicACN9:
return NEEDS_TRANS (
"Ambisonic 9");
84 case ambisonicACN10:
return NEEDS_TRANS (
"Ambisonic 10");
85 case ambisonicACN11:
return NEEDS_TRANS (
"Ambisonic 11");
86 case ambisonicACN12:
return NEEDS_TRANS (
"Ambisonic 12");
87 case ambisonicACN13:
return NEEDS_TRANS (
"Ambisonic 13");
88 case ambisonicACN14:
return NEEDS_TRANS (
"Ambisonic 14");
89 case ambisonicACN15:
return NEEDS_TRANS (
"Ambisonic 15");
90 case ambisonicACN16:
return NEEDS_TRANS (
"Ambisonic 16");
91 case ambisonicACN17:
return NEEDS_TRANS (
"Ambisonic 17");
92 case ambisonicACN18:
return NEEDS_TRANS (
"Ambisonic 18");
93 case ambisonicACN19:
return NEEDS_TRANS (
"Ambisonic 19");
94 case ambisonicACN20:
return NEEDS_TRANS (
"Ambisonic 20");
95 case ambisonicACN21:
return NEEDS_TRANS (
"Ambisonic 21");
96 case ambisonicACN22:
return NEEDS_TRANS (
"Ambisonic 22");
97 case ambisonicACN23:
return NEEDS_TRANS (
"Ambisonic 23");
98 case ambisonicACN24:
return NEEDS_TRANS (
"Ambisonic 24");
99 case ambisonicACN25:
return NEEDS_TRANS (
"Ambisonic 25");
100 case ambisonicACN26:
return NEEDS_TRANS (
"Ambisonic 26");
101 case ambisonicACN27:
return NEEDS_TRANS (
"Ambisonic 27");
102 case ambisonicACN28:
return NEEDS_TRANS (
"Ambisonic 28");
103 case ambisonicACN29:
return NEEDS_TRANS (
"Ambisonic 29");
104 case ambisonicACN30:
return NEEDS_TRANS (
"Ambisonic 30");
105 case ambisonicACN31:
return NEEDS_TRANS (
"Ambisonic 31");
106 case ambisonicACN32:
return NEEDS_TRANS (
"Ambisonic 32");
107 case ambisonicACN33:
return NEEDS_TRANS (
"Ambisonic 33");
108 case ambisonicACN34:
return NEEDS_TRANS (
"Ambisonic 34");
109 case ambisonicACN35:
return NEEDS_TRANS (
"Ambisonic 35");
110 case ambisonicACN36:
return NEEDS_TRANS (
"Ambisonic 36");
111 case ambisonicACN37:
return NEEDS_TRANS (
"Ambisonic 37");
112 case ambisonicACN38:
return NEEDS_TRANS (
"Ambisonic 38");
113 case ambisonicACN39:
return NEEDS_TRANS (
"Ambisonic 39");
114 case ambisonicACN40:
return NEEDS_TRANS (
"Ambisonic 40");
115 case ambisonicACN41:
return NEEDS_TRANS (
"Ambisonic 41");
116 case ambisonicACN42:
return NEEDS_TRANS (
"Ambisonic 42");
117 case ambisonicACN43:
return NEEDS_TRANS (
"Ambisonic 43");
118 case ambisonicACN44:
return NEEDS_TRANS (
"Ambisonic 44");
119 case ambisonicACN45:
return NEEDS_TRANS (
"Ambisonic 45");
120 case ambisonicACN46:
return NEEDS_TRANS (
"Ambisonic 46");
121 case ambisonicACN47:
return NEEDS_TRANS (
"Ambisonic 47");
122 case ambisonicACN48:
return NEEDS_TRANS (
"Ambisonic 48");
123 case ambisonicACN49:
return NEEDS_TRANS (
"Ambisonic 49");
124 case ambisonicACN50:
return NEEDS_TRANS (
"Ambisonic 50");
125 case ambisonicACN51:
return NEEDS_TRANS (
"Ambisonic 51");
126 case ambisonicACN52:
return NEEDS_TRANS (
"Ambisonic 52");
127 case ambisonicACN53:
return NEEDS_TRANS (
"Ambisonic 53");
128 case ambisonicACN54:
return NEEDS_TRANS (
"Ambisonic 54");
129 case ambisonicACN55:
return NEEDS_TRANS (
"Ambisonic 55");
130 case ambisonicACN56:
return NEEDS_TRANS (
"Ambisonic 56");
131 case ambisonicACN57:
return NEEDS_TRANS (
"Ambisonic 57");
132 case ambisonicACN58:
return NEEDS_TRANS (
"Ambisonic 58");
133 case ambisonicACN59:
return NEEDS_TRANS (
"Ambisonic 59");
134 case ambisonicACN60:
return NEEDS_TRANS (
"Ambisonic 60");
135 case ambisonicACN61:
return NEEDS_TRANS (
"Ambisonic 61");
136 case ambisonicACN62:
return NEEDS_TRANS (
"Ambisonic 62");
137 case ambisonicACN63:
return NEEDS_TRANS (
"Ambisonic 63");
138 case bottomFrontLeft:
return NEEDS_TRANS (
"Bottom Front Left");
139 case bottomFrontCentre:
return NEEDS_TRANS (
"Bottom Front Centre");
140 case bottomFrontRight:
return NEEDS_TRANS (
"Bottom Front Right");
141 case proximityLeft:
return NEEDS_TRANS (
"Proximity Left");
142 case proximityRight:
return NEEDS_TRANS (
"Proximity Right");
143 case bottomSideLeft:
return NEEDS_TRANS (
"Bottom Side Left");
144 case bottomSideRight:
return NEEDS_TRANS (
"Bottom Side Right");
145 case bottomRearLeft:
return NEEDS_TRANS (
"Bottom Rear Left");
146 case bottomRearCentre:
return NEEDS_TRANS (
"Bottom Rear Centre");
147 case bottomRearRight:
return NEEDS_TRANS (
"Bottom Rear Right");
148 case discreteChannel0:
158 if (type >= discreteChannel0)
159 return String (type - discreteChannel0 + 1);
163 case left:
return "L";
164 case right:
return "R";
165 case centre:
return "C";
166 case LFE:
return "Lfe";
167 case leftSurround:
return "Ls";
168 case rightSurround:
return "Rs";
169 case leftCentre:
return "Lc";
170 case rightCentre:
return "Rc";
171 case centreSurround:
return "Cs";
172 case leftSurroundRear:
return "Lrs";
173 case rightSurroundRear:
return "Rrs";
174 case topMiddle:
return "Tm";
175 case topFrontLeft:
return "Tfl";
176 case topFrontCentre:
return "Tfc";
177 case topFrontRight:
return "Tfr";
178 case topRearLeft:
return "Trl";
179 case topRearCentre:
return "Trc";
180 case topRearRight:
return "Trr";
181 case wideLeft:
return "Wl";
182 case wideRight:
return "Wr";
183 case LFE2:
return "Lfe2";
184 case leftSurroundSide:
return "Lss";
185 case rightSurroundSide:
return "Rss";
186 case ambisonicACN0:
return "ACN0";
187 case ambisonicACN1:
return "ACN1";
188 case ambisonicACN2:
return "ACN2";
189 case ambisonicACN3:
return "ACN3";
190 case ambisonicACN4:
return "ACN4";
191 case ambisonicACN5:
return "ACN5";
192 case ambisonicACN6:
return "ACN6";
193 case ambisonicACN7:
return "ACN7";
194 case ambisonicACN8:
return "ACN8";
195 case ambisonicACN9:
return "ACN9";
196 case ambisonicACN10:
return "ACN10";
197 case ambisonicACN11:
return "ACN11";
198 case ambisonicACN12:
return "ACN12";
199 case ambisonicACN13:
return "ACN13";
200 case ambisonicACN14:
return "ACN14";
201 case ambisonicACN15:
return "ACN15";
202 case ambisonicACN16:
return "ACN16";
203 case ambisonicACN17:
return "ACN17";
204 case ambisonicACN18:
return "ACN18";
205 case ambisonicACN19:
return "ACN19";
206 case ambisonicACN20:
return "ACN20";
207 case ambisonicACN21:
return "ACN21";
208 case ambisonicACN22:
return "ACN22";
209 case ambisonicACN23:
return "ACN23";
210 case ambisonicACN24:
return "ACN24";
211 case ambisonicACN25:
return "ACN25";
212 case ambisonicACN26:
return "ACN26";
213 case ambisonicACN27:
return "ACN27";
214 case ambisonicACN28:
return "ACN28";
215 case ambisonicACN29:
return "ACN29";
216 case ambisonicACN30:
return "ACN30";
217 case ambisonicACN31:
return "ACN31";
218 case ambisonicACN32:
return "ACN32";
219 case ambisonicACN33:
return "ACN33";
220 case ambisonicACN34:
return "ACN34";
221 case ambisonicACN35:
return "ACN35";
222 case ambisonicACN36:
return "ACN36";
223 case ambisonicACN37:
return "ACN37";
224 case ambisonicACN38:
return "ACN38";
225 case ambisonicACN39:
return "ACN39";
226 case ambisonicACN40:
return "ACN40";
227 case ambisonicACN41:
return "ACN41";
228 case ambisonicACN42:
return "ACN42";
229 case ambisonicACN43:
return "ACN43";
230 case ambisonicACN44:
return "ACN44";
231 case ambisonicACN45:
return "ACN45";
232 case ambisonicACN46:
return "ACN46";
233 case ambisonicACN47:
return "ACN47";
234 case ambisonicACN48:
return "ACN48";
235 case ambisonicACN49:
return "ACN49";
236 case ambisonicACN50:
return "ACN50";
237 case ambisonicACN51:
return "ACN51";
238 case ambisonicACN52:
return "ACN52";
239 case ambisonicACN53:
return "ACN53";
240 case ambisonicACN54:
return "ACN54";
241 case ambisonicACN55:
return "ACN55";
242 case ambisonicACN56:
return "ACN56";
243 case ambisonicACN57:
return "ACN57";
244 case ambisonicACN58:
return "ACN58";
245 case ambisonicACN59:
return "ACN59";
246 case ambisonicACN60:
return "ACN60";
247 case ambisonicACN61:
return "ACN61";
248 case ambisonicACN62:
return "ACN62";
249 case ambisonicACN63:
return "ACN63";
250 case topSideLeft:
return "Tsl";
251 case topSideRight:
return "Tsr";
252 case bottomFrontLeft:
return "Bfl";
253 case bottomFrontCentre:
return "Bfc";
254 case bottomFrontRight:
return "Bfr";
255 case proximityLeft:
return "Pl";
256 case proximityRight:
return "Pr";
257 case bottomSideLeft:
return "Bsl";
258 case bottomSideRight:
return "Bsr";
259 case bottomRearLeft:
return "Brl";
260 case bottomRearCentre:
return "Brc";
261 case bottomRearRight:
return "Brr";
262 case discreteChannel0:
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;
280 if (abbr ==
"Ls")
return leftSurround;
281 if (abbr ==
"Rs")
return rightSurround;
282 if (abbr ==
"Lc")
return leftCentre;
283 if (abbr ==
"Rc")
return rightCentre;
284 if (abbr ==
"Cs")
return centreSurround;
285 if (abbr ==
"Lrs")
return leftSurroundRear;
286 if (abbr ==
"Rrs")
return rightSurroundRear;
287 if (abbr ==
"Tm")
return topMiddle;
288 if (abbr ==
"Tfl")
return topFrontLeft;
289 if (abbr ==
"Tfc")
return topFrontCentre;
290 if (abbr ==
"Tfr")
return topFrontRight;
291 if (abbr ==
"Trl")
return topRearLeft;
292 if (abbr ==
"Trc")
return topRearCentre;
293 if (abbr ==
"Trr")
return topRearRight;
294 if (abbr ==
"Wl")
return wideLeft;
295 if (abbr ==
"Wr")
return wideRight;
296 if (abbr ==
"Lfe2")
return LFE2;
297 if (abbr ==
"Lss")
return leftSurroundSide;
298 if (abbr ==
"Rss")
return rightSurroundSide;
299 if (abbr ==
"W")
return ambisonicW;
300 if (abbr ==
"X")
return ambisonicX;
301 if (abbr ==
"Y")
return ambisonicY;
302 if (abbr ==
"Z")
return ambisonicZ;
303 if (abbr ==
"ACN0")
return ambisonicACN0;
304 if (abbr ==
"ACN1")
return ambisonicACN1;
305 if (abbr ==
"ACN2")
return ambisonicACN2;
306 if (abbr ==
"ACN3")
return ambisonicACN3;
307 if (abbr ==
"ACN4")
return ambisonicACN4;
308 if (abbr ==
"ACN5")
return ambisonicACN5;
309 if (abbr ==
"ACN6")
return ambisonicACN6;
310 if (abbr ==
"ACN7")
return ambisonicACN7;
311 if (abbr ==
"ACN8")
return ambisonicACN8;
312 if (abbr ==
"ACN9")
return ambisonicACN9;
313 if (abbr ==
"ACN10")
return ambisonicACN10;
314 if (abbr ==
"ACN11")
return ambisonicACN11;
315 if (abbr ==
"ACN12")
return ambisonicACN12;
316 if (abbr ==
"ACN13")
return ambisonicACN13;
317 if (abbr ==
"ACN14")
return ambisonicACN14;
318 if (abbr ==
"ACN15")
return ambisonicACN15;
319 if (abbr ==
"ACN16")
return ambisonicACN16;
320 if (abbr ==
"ACN17")
return ambisonicACN17;
321 if (abbr ==
"ACN18")
return ambisonicACN18;
322 if (abbr ==
"ACN19")
return ambisonicACN19;
323 if (abbr ==
"ACN20")
return ambisonicACN20;
324 if (abbr ==
"ACN21")
return ambisonicACN21;
325 if (abbr ==
"ACN22")
return ambisonicACN22;
326 if (abbr ==
"ACN23")
return ambisonicACN23;
327 if (abbr ==
"ACN24")
return ambisonicACN24;
328 if (abbr ==
"ACN25")
return ambisonicACN25;
329 if (abbr ==
"ACN26")
return ambisonicACN26;
330 if (abbr ==
"ACN27")
return ambisonicACN27;
331 if (abbr ==
"ACN28")
return ambisonicACN28;
332 if (abbr ==
"ACN29")
return ambisonicACN29;
333 if (abbr ==
"ACN30")
return ambisonicACN30;
334 if (abbr ==
"ACN31")
return ambisonicACN31;
335 if (abbr ==
"ACN32")
return ambisonicACN32;
336 if (abbr ==
"ACN33")
return ambisonicACN33;
337 if (abbr ==
"ACN34")
return ambisonicACN34;
338 if (abbr ==
"ACN35")
return ambisonicACN35;
339 if (abbr ==
"ACN36")
return ambisonicACN36;
340 if (abbr ==
"ACN37")
return ambisonicACN37;
341 if (abbr ==
"ACN38")
return ambisonicACN38;
342 if (abbr ==
"ACN39")
return ambisonicACN39;
343 if (abbr ==
"ACN40")
return ambisonicACN40;
344 if (abbr ==
"ACN41")
return ambisonicACN41;
345 if (abbr ==
"ACN42")
return ambisonicACN42;
346 if (abbr ==
"ACN43")
return ambisonicACN43;
347 if (abbr ==
"ACN44")
return ambisonicACN44;
348 if (abbr ==
"ACN45")
return ambisonicACN45;
349 if (abbr ==
"ACN46")
return ambisonicACN46;
350 if (abbr ==
"ACN47")
return ambisonicACN47;
351 if (abbr ==
"ACN48")
return ambisonicACN48;
352 if (abbr ==
"ACN49")
return ambisonicACN49;
353 if (abbr ==
"ACN50")
return ambisonicACN50;
354 if (abbr ==
"ACN51")
return ambisonicACN51;
355 if (abbr ==
"ACN52")
return ambisonicACN52;
356 if (abbr ==
"ACN53")
return ambisonicACN53;
357 if (abbr ==
"ACN54")
return ambisonicACN54;
358 if (abbr ==
"ACN55")
return ambisonicACN55;
359 if (abbr ==
"ACN56")
return ambisonicACN56;
360 if (abbr ==
"ACN57")
return ambisonicACN57;
361 if (abbr ==
"ACN58")
return ambisonicACN58;
362 if (abbr ==
"ACN59")
return ambisonicACN59;
363 if (abbr ==
"ACN60")
return ambisonicACN60;
364 if (abbr ==
"ACN61")
return ambisonicACN61;
365 if (abbr ==
"ACN62")
return ambisonicACN62;
366 if (abbr ==
"ACN63")
return ambisonicACN63;
367 if (abbr ==
"Tsl")
return topSideLeft;
368 if (abbr ==
"Tsr")
return topSideRight;
369 if (abbr ==
"Bfl")
return bottomFrontLeft;
370 if (abbr ==
"Bfc")
return bottomFrontCentre;
371 if (abbr ==
"Bfr")
return bottomFrontRight;
372 if (abbr ==
"Bsl")
return bottomSideLeft;
373 if (abbr ==
"Bsr")
return bottomSideRight;
374 if (abbr ==
"Brl")
return bottomRearLeft;
375 if (abbr ==
"Brc")
return bottomRearCentre;
376 if (abbr ==
"Brr")
return bottomRearRight;
380String AudioChannelSet::getSpeakerArrangementAsString()
const
384 for (
auto& speaker : getChannelTypes())
386 auto name = getAbbreviatedChannelTypeName (speaker);
388 if (name.isNotEmpty())
389 speakerTypes.
add (name);
399 for (
auto& abbr : StringArray::fromTokens (str,
true))
401 auto type = getChannelTypeFromAbbreviation (abbr);
410String AudioChannelSet::getDescription()
const
412 if (isDiscreteLayout())
return "Discrete #" +
String (size());
413 if (*
this == disabled())
return "Disabled";
414 if (*
this == mono())
return "Mono";
415 if (*
this == stereo())
return "Stereo";
417 if (*
this == createLCR())
return "LCR";
418 if (*
this == createLRS())
return "LRS";
419 if (*
this == createLCRS())
return "LCRS";
421 if (*
this == create5point0())
return "5.0 Surround";
422 if (*
this == create5point0point2())
return "5.0.2 Surround";
423 if (*
this == create5point0point4())
return "5.0.4 Surround";
424 if (*
this == create5point1())
return "5.1 Surround";
425 if (*
this == create5point1point2())
return "5.1.2 Surround";
426 if (*
this == create5point1point4())
return "5.1.4 Surround";
427 if (*
this == create6point0())
return "6.0 Surround";
428 if (*
this == create6point1())
return "6.1 Surround";
429 if (*
this == create6point0Music())
return "6.0 (Music) Surround";
430 if (*
this == create6point1Music())
return "6.1 (Music) Surround";
431 if (*
this == create7point0())
return "7.0 Surround";
432 if (*
this == create7point1())
return "7.1 Surround";
433 if (*
this == create7point0SDDS())
return "7.0 Surround SDDS";
434 if (*
this == create7point1SDDS())
return "7.1 Surround SDDS";
435 if (*
this == create7point0point2())
return "7.0.2 Surround";
436 if (*
this == create7point0point4())
return "7.0.4 Surround";
437 if (*
this == create7point0point6())
return "7.0.6 Surround";
438 if (*
this == create7point1point2())
return "7.1.2 Surround";
439 if (*
this == create7point1point4())
return "7.1.4 Surround";
440 if (*
this == create7point1point6())
return "7.1.6 Surround";
441 if (*
this == create9point0point4())
return "9.0.4 Surround";
442 if (*
this == create9point1point4())
return "9.1.4 Surround";
443 if (*
this == create9point0point6())
return "9.0.6 Surround";
444 if (*
this == create9point1point6())
return "9.1.6 Surround";
446 if (*
this == quadraphonic())
return "Quadraphonic";
447 if (*
this == pentagonal())
return "Pentagonal";
448 if (*
this == hexagonal())
return "Hexagonal";
449 if (*
this == octagonal())
return "Octagonal";
453 auto order = getAmbisonicOrder();
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";
474bool AudioChannelSet::isDiscreteLayout() const noexcept
476 const auto channelTypes = getChannelTypes();
478 return std::none_of (std::begin (channelTypes),
479 std::end (channelTypes),
480 [] (
const auto& t) {
return t < discreteChannel0; });
483int AudioChannelSet::size() const noexcept
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);
547AudioChannelSet AudioChannelSet::create6point0Music() {
return AudioChannelSet ({ left, right, leftSurround, rightSurround, leftSurroundSide, rightSurroundSide }); }
548AudioChannelSet AudioChannelSet::create6point1Music() {
return AudioChannelSet ({ left, right, LFE, leftSurround, rightSurround, leftSurroundSide, rightSurroundSide }); }
549AudioChannelSet AudioChannelSet::create7point0() {
return AudioChannelSet ({ left, right, centre, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear }); }
551AudioChannelSet AudioChannelSet::create7point1() {
return AudioChannelSet ({ left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear }); }
552AudioChannelSet AudioChannelSet::create7point1SDDS() {
return AudioChannelSet ({ left, right, centre, LFE, leftSurround, rightSurround, leftCentre, rightCentre }); }
556AudioChannelSet AudioChannelSet::octagonal() {
return AudioChannelSet ({ left, right, centre, leftSurround, rightSurround, centreSurround, wideLeft, wideRight }); }
557AudioChannelSet AudioChannelSet::create5point0point2() {
return AudioChannelSet ({ left, right, centre, leftSurround, rightSurround, topSideLeft, topSideRight }); }
558AudioChannelSet AudioChannelSet::create5point1point2() {
return AudioChannelSet ({ left, right, centre, LFE, leftSurround, rightSurround, topSideLeft, topSideRight }); }
559AudioChannelSet AudioChannelSet::create5point0point4() {
return AudioChannelSet ({ left, right, centre, leftSurround, rightSurround, topFrontLeft, topFrontRight, topRearLeft, topRearRight }); }
560AudioChannelSet AudioChannelSet::create5point1point4() {
return AudioChannelSet ({ left, right, centre, LFE, leftSurround, rightSurround, topFrontLeft, topFrontRight, topRearLeft, topRearRight }); }
561AudioChannelSet AudioChannelSet::create7point0point2() {
return AudioChannelSet ({ left, right, centre, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, topSideLeft, topSideRight }); }
562AudioChannelSet AudioChannelSet::create7point1point2() {
return AudioChannelSet ({ left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, topSideLeft, topSideRight }); }
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));
576 static constexpr std::pair<int, int> continuousRanges[] { { ambisonicACN0, ambisonicACN3 },
577 { ambisonicACN4, ambisonicACN35 },
578 { ambisonicACN36, ambisonicACN63 } };
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);
599int AudioChannelSet::getAmbisonicOrder()
const
601 auto ambisonicOrder = getAmbisonicOrderForNumChannels (size());
603 if (ambisonicOrder >= 0)
604 return (*
this == ambisonic (ambisonicOrder) ? ambisonicOrder : -1);
612 s.channels.
setRange (discreteChannel0, numChannels,
true);
618 if (numChannels == 1)
return AudioChannelSet::mono();
619 if (numChannels == 2)
return AudioChannelSet::stereo();
620 if (numChannels == 3)
return AudioChannelSet::createLCR();
621 if (numChannels == 4)
return AudioChannelSet::quadraphonic();
622 if (numChannels == 5)
return AudioChannelSet::create5point0();
623 if (numChannels == 6)
return AudioChannelSet::create5point1();
624 if (numChannels == 7)
return AudioChannelSet::create7point0();
625 if (numChannels == 8)
return AudioChannelSet::create7point1();
627 return discreteChannels (numChannels);
632 if (numChannels == 1)
return AudioChannelSet::mono();
633 if (numChannels == 2)
return AudioChannelSet::stereo();
634 if (numChannels == 3)
return AudioChannelSet::createLCR();
635 if (numChannels == 4)
return AudioChannelSet::quadraphonic();
636 if (numChannels == 5)
return AudioChannelSet::create5point0();
637 if (numChannels == 6)
return AudioChannelSet::create5point1();
638 if (numChannels == 7)
return AudioChannelSet::create7point0();
639 if (numChannels == 8)
return AudioChannelSet::create7point1();
648 if (numChannels != 0)
650 retval.
add (AudioChannelSet::discreteChannels (numChannels));
657 return { AudioChannelSet::mono() };
659 return { AudioChannelSet::stereo() };
661 return { AudioChannelSet::createLCR(),
662 AudioChannelSet::createLRS() };
664 return { AudioChannelSet::quadraphonic(),
665 AudioChannelSet::createLCRS() };
667 return { AudioChannelSet::create5point0(),
668 AudioChannelSet::pentagonal() };
670 return { AudioChannelSet::create5point1(),
671 AudioChannelSet::create6point0(),
672 AudioChannelSet::create6point0Music(),
673 AudioChannelSet::hexagonal() };
675 return { AudioChannelSet::create7point0(),
676 AudioChannelSet::create7point0SDDS(),
677 AudioChannelSet::create6point1(),
678 AudioChannelSet::create6point1Music() };
680 return { AudioChannelSet::create7point1(),
681 AudioChannelSet::create7point1SDDS(),
682 AudioChannelSet::octagonal(),
683 AudioChannelSet::create5point1point2() };
685 return { AudioChannelSet::create7point0point2() };
687 return { AudioChannelSet::create5point1point4(),
688 AudioChannelSet::create7point1point2() };
690 return { AudioChannelSet::create7point0point4() };
692 return { AudioChannelSet::create7point1point4() };
694 return { AudioChannelSet::create7point1point6() };
696 return { AudioChannelSet::create9point1point6() };
702 auto order = getAmbisonicOrderForNumChannels (numChannels);
704 retval.
add (AudioChannelSet::ambisonic (order));
714 for (
auto ch : channelArray)
716 jassert (! set.channels[
static_cast<int> (ch)]);
725AudioChannelSet JUCE_CALLTYPE AudioChannelSet::fromWaveChannelMask (int32 dwChannelMask)
727 return AudioChannelSet (
static_cast<uint32
> ((dwChannelMask & ((1 << 18) - 1)) << 1));
730int32 AudioChannelSet::getWaveChannelMask() const noexcept
732 if (channels.getHighestBit() > topRearRight)
735 return (channels.toInteger() >> 1);
739int AudioChannelSet::getAmbisonicOrderForNumChannels (
int numChannels,
int maxOrderToCheck)
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);
783 checkAmbisonic (mask, 0,
"0th Order Ambisonics");
786 checkAmbisonic (mask, 1,
"1st Order Ambisonics");
790 checkAmbisonic (mask, 2,
"2nd Order Ambisonics");
795 checkAmbisonic (mask, 3,
"3rd Order Ambisonics");
800 checkAmbisonic (mask, 4,
"4th Order Ambisonics");
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)
AudioChannelSet()=default
static Array< AudioChannelSet > JUCE_CALLTYPE channelSetsWithNumberOfChannels(int numChannels)
void addChannel(ChannelType newChannelType)
static AudioChannelSet JUCE_CALLTYPE channelSetWithChannels(const Array< ChannelType > &)
static AudioChannelSet JUCE_CALLTYPE ambisonic(int order=1)
BigInteger & setRange(int startBit, int numBits, bool shouldBeSet)
String joinIntoString(StringRef separatorString, int startIndex=0, int numberOfElements=-1) const
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())