OpenShot Library | OpenShotAudio  0.2.1
juce_AudioChannelSet.cpp
1 /*
2  ==============================================================================
3 
4  This file is part of the JUCE library.
5  Copyright (c) 2017 - ROLI Ltd.
6 
7  JUCE is an open source library subject to commercial or open-source
8  licensing.
9 
10  The code included in this file is provided under the terms of the ISC license
11  http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12  To use, copy, modify, and/or distribute this software for any purpose with or
13  without fee is hereby granted provided that the above copyright notice and
14  this permission notice appear in all copies.
15 
16  JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17  EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18  DISCLAIMED.
19 
20  ==============================================================================
21 */
22 
23 namespace juce
24 {
25 
26 
27 
28 AudioChannelSet::AudioChannelSet (uint32 c) : channels (static_cast<int64> (c))
29 {
30 }
31 
32 AudioChannelSet::AudioChannelSet (const Array<ChannelType>& c)
33 {
34  for (auto channel : c)
35  addChannel (channel);
36 }
37 
38 bool AudioChannelSet::operator== (const AudioChannelSet& other) const noexcept { return channels == other.channels; }
39 bool AudioChannelSet::operator!= (const AudioChannelSet& other) const noexcept { return channels != other.channels; }
40 bool AudioChannelSet::operator< (const AudioChannelSet& other) const noexcept { return channels < other.channels; }
41 
43 {
44  if (type >= discreteChannel0)
45  return "Discrete " + String (type - discreteChannel0 + 1);
46 
47  switch (type)
48  {
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 bottomFrontLeft: return NEEDS_TRANS("Bottom Front Left");
91  case bottomFrontCentre: return NEEDS_TRANS("Bottom Front Centre");
92  case bottomFrontRight: return NEEDS_TRANS("Bottom Front Right");
93  case bottomSideLeft: return NEEDS_TRANS("Bottom Side Left");
94  case bottomSideRight: return NEEDS_TRANS("Bottom Side Right");
95  case bottomRearLeft: return NEEDS_TRANS("Bottom Rear Left");
96  case bottomRearCentre: return NEEDS_TRANS("Bottom Rear Centre");
97  case bottomRearRight: return NEEDS_TRANS("Bottom Rear Right");
98  case discreteChannel0: return NEEDS_TRANS("Discrete channel");
99  default: break;
100  }
101 
102  return "Unknown";
103 }
104 
106 {
107  if (type >= discreteChannel0)
108  return String (type - discreteChannel0 + 1);
109 
110  switch (type)
111  {
112  case left: return "L";
113  case right: return "R";
114  case centre: return "C";
115  case LFE: return "Lfe";
116  case leftSurround: return "Ls";
117  case rightSurround: return "Rs";
118  case leftCentre: return "Lc";
119  case rightCentre: return "Rc";
120  case centreSurround: return "Cs";
121  case leftSurroundRear: return "Lrs";
122  case rightSurroundRear: return "Rrs";
123  case topMiddle: return "Tm";
124  case topFrontLeft: return "Tfl";
125  case topFrontCentre: return "Tfc";
126  case topFrontRight: return "Tfr";
127  case topRearLeft: return "Trl";
128  case topRearCentre: return "Trc";
129  case topRearRight: return "Trr";
130  case wideLeft: return "Wl";
131  case wideRight: return "Wr";
132  case LFE2: return "Lfe2";
133  case leftSurroundSide: return "Lss";
134  case rightSurroundSide: return "Rss";
135  case ambisonicACN0: return "ACN0";
136  case ambisonicACN1: return "ACN1";
137  case ambisonicACN2: return "ACN2";
138  case ambisonicACN3: return "ACN3";
139  case ambisonicACN4: return "ACN4";
140  case ambisonicACN5: return "ACN5";
141  case ambisonicACN6: return "ACN6";
142  case ambisonicACN7: return "ACN7";
143  case ambisonicACN8: return "ACN8";
144  case ambisonicACN9: return "ACN9";
145  case ambisonicACN10: return "ACN10";
146  case ambisonicACN11: return "ACN11";
147  case ambisonicACN12: return "ACN12";
148  case ambisonicACN13: return "ACN13";
149  case ambisonicACN14: return "ACN14";
150  case ambisonicACN15: return "ACN15";
151  case topSideLeft: return "Tsl";
152  case topSideRight: return "Tsr";
153  case bottomFrontLeft: return "Bfl";
154  case bottomFrontCentre: return "Bfc";
155  case bottomFrontRight: return "Bfr";
156  case bottomSideLeft: return "Bsl";
157  case bottomSideRight: return "Bsr";
158  case bottomRearLeft: return "Brl";
159  case bottomRearCentre: return "Brc";
160  case bottomRearRight: return "Brr";
161  default: break;
162  }
163 
164  if (type >= ambisonicACN4 && type <= ambisonicACN35)
165  return "ACN" + String (type - ambisonicACN4 + 4);
166 
167  return {};
168 }
169 
171 {
172  if (abbr.length() > 0 && (abbr[0] >= '0' && abbr[0] <= '9'))
173  return static_cast<AudioChannelSet::ChannelType> (static_cast<int> (discreteChannel0)
174  + abbr.getIntValue() - 1);
175 
176  if (abbr == "L") return left;
177  if (abbr == "R") return right;
178  if (abbr == "C") return centre;
179  if (abbr == "Lfe") return LFE;
180  if (abbr == "Ls") return leftSurround;
181  if (abbr == "Rs") return rightSurround;
182  if (abbr == "Lc") return leftCentre;
183  if (abbr == "Rc") return rightCentre;
184  if (abbr == "Cs") return centreSurround;
185  if (abbr == "Lrs") return leftSurroundRear;
186  if (abbr == "Rrs") return rightSurroundRear;
187  if (abbr == "Tm") return topMiddle;
188  if (abbr == "Tfl") return topFrontLeft;
189  if (abbr == "Tfc") return topFrontCentre;
190  if (abbr == "Tfr") return topFrontRight;
191  if (abbr == "Trl") return topRearLeft;
192  if (abbr == "Trc") return topRearCentre;
193  if (abbr == "Trr") return topRearRight;
194  if (abbr == "Wl") return wideLeft;
195  if (abbr == "Wr") return wideRight;
196  if (abbr == "Lfe2") return LFE2;
197  if (abbr == "Lss") return leftSurroundSide;
198  if (abbr == "Rss") return rightSurroundSide;
199  if (abbr == "W") return ambisonicW;
200  if (abbr == "X") return ambisonicX;
201  if (abbr == "Y") return ambisonicY;
202  if (abbr == "Z") return ambisonicZ;
203  if (abbr == "ACN0") return ambisonicACN0;
204  if (abbr == "ACN1") return ambisonicACN1;
205  if (abbr == "ACN2") return ambisonicACN2;
206  if (abbr == "ACN3") return ambisonicACN3;
207  if (abbr == "ACN4") return ambisonicACN4;
208  if (abbr == "ACN5") return ambisonicACN5;
209  if (abbr == "ACN6") return ambisonicACN6;
210  if (abbr == "ACN7") return ambisonicACN7;
211  if (abbr == "ACN8") return ambisonicACN8;
212  if (abbr == "ACN9") return ambisonicACN9;
213  if (abbr == "ACN10") return ambisonicACN10;
214  if (abbr == "ACN11") return ambisonicACN11;
215  if (abbr == "ACN12") return ambisonicACN12;
216  if (abbr == "ACN13") return ambisonicACN13;
217  if (abbr == "ACN14") return ambisonicACN14;
218  if (abbr == "ACN15") return ambisonicACN15;
219  if (abbr == "Tsl") return topSideLeft;
220  if (abbr == "Tsr") return topSideRight;
221  if (abbr == "Bfl") return bottomFrontLeft;
222  if (abbr == "Bfc") return bottomFrontCentre;
223  if (abbr == "Bfr") return bottomFrontRight;
224  if (abbr == "Bsl") return bottomSideLeft;
225  if (abbr == "Bsr") return bottomSideRight;
226  if (abbr == "Brl") return bottomRearLeft;
227  if (abbr == "Brc") return bottomRearCentre;
228  if (abbr == "Brr") return bottomRearRight;
229  return unknown;
230 }
231 
233 {
234  StringArray speakerTypes;
235 
236  for (auto& speaker : getChannelTypes())
237  {
238  auto name = getAbbreviatedChannelTypeName (speaker);
239 
240  if (name.isNotEmpty())
241  speakerTypes.add (name);
242  }
243 
244  return speakerTypes.joinIntoString (" ");
245 }
246 
248 {
249  AudioChannelSet set;
250 
251  for (auto& abbr : StringArray::fromTokens (str, true))
252  {
253  auto type = getChannelTypeFromAbbreviation (abbr);
254 
255  if (type != unknown)
256  set.addChannel (type);
257  }
258 
259  return set;
260 }
261 
263 {
264  if (isDiscreteLayout()) return "Discrete #" + String (size());
265  if (*this == disabled()) return "Disabled";
266  if (*this == mono()) return "Mono";
267  if (*this == stereo()) return "Stereo";
268 
269  if (*this == createLCR()) return "LCR";
270  if (*this == createLRS()) return "LRS";
271  if (*this == createLCRS()) return "LCRS";
272 
273  if (*this == create5point0()) return "5.0 Surround";
274  if (*this == create5point1()) return "5.1 Surround";
275  if (*this == create6point0()) return "6.0 Surround";
276  if (*this == create6point1()) return "6.1 Surround";
277  if (*this == create6point0Music()) return "6.0 (Music) Surround";
278  if (*this == create6point1Music()) return "6.1 (Music) Surround";
279  if (*this == create7point0()) return "7.0 Surround";
280  if (*this == create7point1()) return "7.1 Surround";
281  if (*this == create7point0SDDS()) return "7.0 Surround SDDS";
282  if (*this == create7point1SDDS()) return "7.1 Surround SDDS";
283  if (*this == create7point0point2()) return "7.0.2 Surround";
284  if (*this == create7point1point2()) return "7.1.2 Surround";
285 
286  if (*this == quadraphonic()) return "Quadraphonic";
287  if (*this == pentagonal()) return "Pentagonal";
288  if (*this == hexagonal()) return "Hexagonal";
289  if (*this == octagonal()) return "Octagonal";
290 
291  // ambisonics
292  {
293  auto order = getAmbisonicOrder();
294 
295  if (order >= 0)
296  {
297  String suffix;
298 
299  switch (order)
300  {
301  case 1: suffix = "st"; break;
302  case 2: suffix = "nd"; break;
303  case 3: suffix = "rd"; break;
304  default: suffix = "th"; break;
305  }
306 
307  return String (order) + suffix + " Order Ambisonics";
308  }
309  }
310 
311  return "Unknown";
312 }
313 
315 {
316  for (auto& speaker : getChannelTypes())
317  if (speaker <= ambisonicACN35)
318  return false;
319 
320  return true;
321 }
322 
323 int AudioChannelSet::size() const noexcept
324 {
325  return channels.countNumberOfSetBits();
326 }
327 
329 {
330  int bit = channels.findNextSetBit(0);
331 
332  for (int i = 0; i < index && bit >= 0; ++i)
333  bit = channels.findNextSetBit (bit + 1);
334 
335  return static_cast<ChannelType> (bit);
336 }
337 
339 {
340  int idx = 0;
341 
342  for (int bit = channels.findNextSetBit (0); bit >= 0; bit = channels.findNextSetBit (bit + 1))
343  {
344  if (static_cast<ChannelType> (bit) == type)
345  return idx;
346 
347  idx++;
348  }
349 
350  return -1;
351 }
352 
354 {
355  Array<ChannelType> result;
356 
357  for (int bit = channels.findNextSetBit(0); bit >= 0; bit = channels.findNextSetBit (bit + 1))
358  result.add (static_cast<ChannelType> (bit));
359 
360  return result;
361 }
362 
364 {
365  const int bit = static_cast<int> (newChannel);
366  jassert (bit >= 0 && bit < 1024);
367  channels.setBit (bit);
368 }
369 
371 {
372  const int bit = static_cast<int> (newChannel);
373  jassert (bit >= 0 && bit < 1024);
374  channels.clearBit (bit);
375 }
376 
379 AudioChannelSet AudioChannelSet::stereo() { return AudioChannelSet ((1u << left) | (1u << right)); }
380 AudioChannelSet AudioChannelSet::createLCR() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre)); }
381 AudioChannelSet AudioChannelSet::createLRS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << surround)); }
382 AudioChannelSet AudioChannelSet::createLCRS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << surround)); }
383 AudioChannelSet AudioChannelSet::create5point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround)); }
384 AudioChannelSet AudioChannelSet::create5point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurround) | (1u << rightSurround)); }
385 AudioChannelSet AudioChannelSet::create6point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround) | (1u << centreSurround)); }
386 AudioChannelSet AudioChannelSet::create6point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurround) | (1u << rightSurround) | (1u << centreSurround)); }
387 AudioChannelSet AudioChannelSet::create6point0Music() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftSurroundSide) | (1u << rightSurroundSide)); }
388 AudioChannelSet AudioChannelSet::create6point1Music() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << LFE) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftSurroundSide) | (1u << rightSurroundSide)); }
389 AudioChannelSet AudioChannelSet::create7point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurroundSide) | (1u << rightSurroundSide) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); }
390 AudioChannelSet AudioChannelSet::create7point0SDDS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftCentre) | (1u << rightCentre)); }
391 AudioChannelSet AudioChannelSet::create7point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurroundSide) | (1u << rightSurroundSide) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); }
392 AudioChannelSet AudioChannelSet::create7point1SDDS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftCentre) | (1u << rightCentre)); }
393 AudioChannelSet AudioChannelSet::quadraphonic() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << leftSurround) | (1u << rightSurround)); }
394 AudioChannelSet AudioChannelSet::pentagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); }
395 AudioChannelSet AudioChannelSet::hexagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << centreSurround) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); }
396 AudioChannelSet AudioChannelSet::octagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround) | (1u << centreSurround) | (1u << wideLeft) | (1u << wideRight)); }
397 AudioChannelSet AudioChannelSet::create7point0point2() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurroundSide) | (1u << rightSurroundSide) | (1u << leftSurroundRear) | (1u << rightSurroundRear) | (1u << topSideLeft) | (1u << topSideRight)); }
398 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)); }
399 
401 {
402  jassert (isPositiveAndBelow (order, 6));
403 
404  if (order == 0)
405  return AudioChannelSet ((uint32) (1 << ambisonicACN0));
406 
407  AudioChannelSet set ((1u << ambisonicACN0) | (1u << ambisonicACN1) | (1u << ambisonicACN2) | (1u << ambisonicACN3));
408 
409  auto numAmbisonicChannels = (order + 1) * (order + 1);
410  set.channels.setRange (ambisonicACN4, numAmbisonicChannels - 4, true);
411 
412  return set;
413 }
414 
416 {
417  auto ambisonicOrder = getAmbisonicOrderForNumChannels (size());
418 
419  if (ambisonicOrder >= 0)
420  return (*this == ambisonic (ambisonicOrder) ? ambisonicOrder : -1);
421 
422  return -1;
423 }
424 
426 {
427  AudioChannelSet s;
428  s.channels.setRange (discreteChannel0, numChannels, true);
429  return s;
430 }
431 
433 {
434  if (numChannels == 1) return AudioChannelSet::mono();
435  if (numChannels == 2) return AudioChannelSet::stereo();
436  if (numChannels == 3) return AudioChannelSet::createLCR();
437  if (numChannels == 4) return AudioChannelSet::quadraphonic();
438  if (numChannels == 5) return AudioChannelSet::create5point0();
439  if (numChannels == 6) return AudioChannelSet::create5point1();
440  if (numChannels == 7) return AudioChannelSet::create7point0();
441  if (numChannels == 8) return AudioChannelSet::create7point1();
442 
443  return discreteChannels (numChannels);
444 }
445 
447 {
448  if (numChannels == 1) return AudioChannelSet::mono();
449  if (numChannels == 2) return AudioChannelSet::stereo();
450  if (numChannels == 3) return AudioChannelSet::createLCR();
451  if (numChannels == 4) return AudioChannelSet::quadraphonic();
452  if (numChannels == 5) return AudioChannelSet::create5point0();
453  if (numChannels == 6) return AudioChannelSet::create5point1();
454  if (numChannels == 7) return AudioChannelSet::create7point0();
455  if (numChannels == 8) return AudioChannelSet::create7point1();
456 
457  return {};
458 }
459 
461 {
462  Array<AudioChannelSet> retval;
463 
464  if (numChannels != 0)
465  {
466  retval.add (AudioChannelSet::discreteChannels (numChannels));
467 
468  if (numChannels == 1)
469  {
470  retval.add (AudioChannelSet::mono());
471  }
472  else if (numChannels == 2)
473  {
474  retval.add (AudioChannelSet::stereo());
475  }
476  else if (numChannels == 3)
477  {
478  retval.add (AudioChannelSet::createLCR());
479  retval.add (AudioChannelSet::createLRS());
480  }
481  else if (numChannels == 4)
482  {
484  retval.add (AudioChannelSet::createLCRS());
485  }
486  else if (numChannels == 5)
487  {
489  retval.add (AudioChannelSet::pentagonal());
490  }
491  else if (numChannels == 6)
492  {
496  retval.add (AudioChannelSet::hexagonal());
497  }
498  else if (numChannels == 7)
499  {
504  }
505  else if (numChannels == 8)
506  {
509  retval.add (AudioChannelSet::octagonal());
510  }
511 
512  auto order = getAmbisonicOrderForNumChannels (numChannels);
513  if (order >= 0)
514  retval.add (AudioChannelSet::ambisonic (order));
515  }
516 
517  return retval;
518 }
519 
521 {
522  AudioChannelSet set;
523 
524  for (auto ch : channelArray)
525  {
526  jassert (! set.channels[static_cast<int> (ch)]);
527 
528  set.addChannel (ch);
529  }
530 
531  return set;
532 }
533 
534 //==============================================================================
535 AudioChannelSet JUCE_CALLTYPE AudioChannelSet::fromWaveChannelMask (int32 dwChannelMask)
536 {
537  return AudioChannelSet (static_cast<uint32> ((dwChannelMask & ((1 << 18) - 1)) << 1));
538 }
539 
541 {
542  if (channels.getHighestBit() > topRearRight)
543  return -1;
544 
545  return (channels.toInteger() >> 1);
546 }
547 
548 //==============================================================================
549 int JUCE_CALLTYPE AudioChannelSet::getAmbisonicOrderForNumChannels (int numChannels)
550 {
551  auto sqrtMinusOne = std::sqrt (static_cast<float> (numChannels)) - 1.0f;
552  auto ambisonicOrder = jmax (0, static_cast<int> (std::floor (sqrtMinusOne)));
553 
554  if (ambisonicOrder > 5)
555  return -1;
556 
557  return (static_cast<float> (ambisonicOrder) == sqrtMinusOne ? ambisonicOrder : -1);
558 }
559 
560 
561 //==============================================================================
562 //==============================================================================
563 #if JUCE_UNIT_TESTS
564 
565 class AudioChannelSetUnitTest : public UnitTest
566 {
567 public:
568  AudioChannelSetUnitTest()
569  : UnitTest ("AudioChannelSetUnitTest", UnitTestCategories::audio)
570  {}
571 
572  void runTest() override
573  {
574  auto max = AudioChannelSet::maxChannelsOfNamedLayout;
575 
576  beginTest ("maxChannelsOfNamedLayout is non-discrete");
578 
579  beginTest ("channelSetsWithNumberOfChannels returns correct speaker count");
580  {
581  for (auto ch = 1; ch <= max; ++ch)
582  {
583  auto channelSets = AudioChannelSet::channelSetsWithNumberOfChannels (ch);
584 
585  for (auto set : channelSets)
586  expect (set.size() == ch);
587  }
588  }
589 
590  beginTest ("Ambisonics");
591  {
592  uint64 mask = 0;
593 
594  mask |= (1ull << AudioChannelSet::ambisonicACN0);
595  checkAmbisonic (mask, 0, "0th Order Ambisonics");
596 
598  checkAmbisonic (mask, 1, "1st Order Ambisonics");
599 
602  checkAmbisonic (mask, 2, "2nd Order Ambisonics");
603 
607  checkAmbisonic (mask, 3, "3rd Order Ambisonics");
608 
612  checkAmbisonic (mask, 4, "4th Order Ambisonics");
613 
618  checkAmbisonic (mask, 5, "5th Order Ambisonics");
619  }
620  }
621 
622 private:
623  void checkAmbisonic (uint64 mask, int order, const char* layoutName)
624  {
625  auto expected = AudioChannelSet::ambisonic (order);
626  auto numChannels = expected.size();
627 
628  expect (numChannels == BigInteger ((int64) mask).countNumberOfSetBits());
629  expect (channelSetFromMask (mask) == expected);
630 
631  expect (order == expected.getAmbisonicOrder());
632  expect (expected.getDescription() == layoutName);
633 
634  auto layouts = AudioChannelSet::channelSetsWithNumberOfChannels (numChannels);
635  expect (layouts.contains (expected));
636 
637  for (auto layout : layouts)
638  expect (layout.getAmbisonicOrder() == (layout == expected ? order : -1));
639  }
640 
641  static AudioChannelSet channelSetFromMask (uint64 mask)
642  {
644  for (int bit = 0; bit <= 62; ++bit)
645  if ((mask & (1ull << bit)) != 0)
646  channels.add (static_cast<AudioChannelSet::ChannelType> (bit));
647 
648  return AudioChannelSet::channelSetWithChannels (channels);
649  }
650 };
651 
652 static AudioChannelSetUnitTest audioChannelSetUnitTest;
653 
654 #endif
655 
656 } // namespace juce
First-order ambisonic channel number 3.
static AudioChannelSet JUCE_CALLTYPE create6point1()
Creates a set for a 6.1 Cine surround setup (left, right, centre, leftSurround, rightSurround, centreSurround, LFE).
Represents a set of audio channel types.
int getChannelIndexForType(ChannelType type) const noexcept
Returns the index for a particular channel-type.
static AudioChannelSet JUCE_CALLTYPE create6point1Music()
Creates a set for a 6.0 Music surround setup (left, right, leftSurround, rightSurround, leftSurroundSide, rightSurroundSide, LFE).
static Array< AudioChannelSet > JUCE_CALLTYPE channelSetsWithNumberOfChannels(int numChannels)
Return an array of channel sets which have a given number of channels.
static AudioChannelSet JUCE_CALLTYPE pentagonal()
Creates a set for pentagonal surround setup (left, right, centre, leftSurroundRear, rightSurroundRear).
Second-order ambisonic channel number 4.
Fifth-order ambisonic channel number 27.
Fourth-order ambisonic channel number 23.
static AudioChannelSet JUCE_CALLTYPE disabled()
Creates a zero-channel set which can be used to indicate that a bus is disabled.
void removeChannel(ChannelType newChannelType)
Removes a channel from the set.
static AudioChannelSet JUCE_CALLTYPE create6point0Music()
Creates a set for a 6.0 Music surround setup (left, right, leftSurround, rightSurround, leftSurroundSide, rightSurroundSide).
First-order ambisonic channel number 1.
Fourth-order ambisonic channel number 24.
static AudioChannelSet JUCE_CALLTYPE create7point1SDDS()
Creates a set for a 7.1 surround setup (left, right, centre, leftSurround, rightSurround, leftCentre, rightCentre, LFE).
void add(const ElementType &newElement)
Appends a new element at the end of the array.
Definition: juce_Array.h:422
static AudioChannelSet JUCE_CALLTYPE namedChannelSet(int numChannels)
Create a channel set for a given number of channels which is non-discrete.
Fifth-order ambisonic channel number 33.
UnitTest(const String &name, const String &category=String())
Creates a test with the given name and optionally places it in a category.
ChannelType
Represents different audio channel types.
int size() const noexcept
Returns the number of channels in the set.
Fifth-order ambisonic channel number 25.
Fourth-order ambisonic channel number 18.
static AudioChannelSet JUCE_CALLTYPE channelSetWithChannels(const Array< ChannelType > &)
Creates a channel set for a list of channel types.
Fifth-order ambisonic channel number 30.
ChannelType getTypeOfChannel(int channelIndex) const noexcept
Returns the type of one of the channels in the set, by index.
Array< ChannelType > getChannelTypes() const
Returns an array of all the types in this channel set.
A special array for holding a list of strings.
Fourth-order ambisonic channel number 19.
The JUCE String class!
Definition: juce_String.h:42
void addChannel(ChannelType newChannelType)
Adds a channel to the set.
Third-order ambisonic channel number 12.
Fourth-order ambisonic channel number 22.
static AudioChannelSet JUCE_CALLTYPE createLCRS()
Creates a set containing an LCRS set (left, right, centre, surround).
An arbitrarily large integer class.
static AudioChannelSet JUCE_CALLTYPE ambisonic(int order=1)
Creates a set for ACN, SN3D normalised ambisonic surround setups with a given order.
This is a base class for classes that perform a unit test.
Definition: juce_UnitTest.h:73
static AudioChannelSet JUCE_CALLTYPE mono()
Creates a one-channel mono set (centre).
void runTest() override
Implement this method in your subclass to actually run your tests.
static String JUCE_CALLTYPE getChannelTypeName(ChannelType)
Returns the name of a given channel type.
static AudioChannelSet JUCE_CALLTYPE create7point0SDDS()
Creates a set for a SDDS 7.0 surround setup (left, right, centre, leftSurround, rightSurround, leftCentre, rightCentre).
Fourth-order ambisonic channel number 16.
static AudioChannelSet fromAbbreviatedString(const String &set)
Returns an AudioChannelSet from a string returned by getSpeakerArrangementAsString.
First-order ambisonic channel number 2.
bool isDiscreteLayout() const noexcept
Returns if this is a channel layout made-up of discrete channels.
void beginTest(const String &testName)
Tells the system that a new subsection of tests is beginning.
int32 getWaveChannelMask() const noexcept
Returns a WAVEFORMATEXTENSIBLE channelMask representation (typically used in .wav files) of the recei...
Fifth-order ambisonic channel number 35.
static ChannelType JUCE_CALLTYPE getChannelTypeFromAbbreviation(const String &abbreviation)
Returns the channel type from an abbreviated name.
static AudioChannelSet JUCE_CALLTYPE create7point0point2()
Creates a set for Dolby Atmos 7.0.2 surround setup (left, right, centre, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, topSideLeft, topSideRight).
Fourth-order ambisonic channel number 20.
Zero-th ambisonic channel number 0.
static AudioChannelSet JUCE_CALLTYPE create5point1()
Creates a set for a 5.1 surround setup (left, right, centre, leftSurround, rightSurround, LFE).
static AudioChannelSet JUCE_CALLTYPE create5point0()
Creates a set for a 5.0 surround setup (left, right, centre, leftSurround, rightSurround).
Third-order ambisonic channel number 14.
Fourth-order ambisonic channel number 21.
static StringArray fromTokens(StringRef stringToTokenise, bool preserveQuotedStrings)
Returns an array containing the tokens in a given string.
Holds a resizable array of primitive or copy-by-value objects.
Definition: juce_Array.h:59
static AudioChannelSet JUCE_CALLTYPE create7point1()
Creates a set for a DTS 7.1 surround setup (left, right, centre, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, LFE).
Third-order ambisonic channel number 9.
Fifth-order ambisonic channel number 31.
static AudioChannelSet JUCE_CALLTYPE canonicalChannelSet(int numChannels)
Create a canonical channel set for a given number of channels.
Fifth-order ambisonic channel number 28.
static AudioChannelSet JUCE_CALLTYPE createLRS()
Creates a set containing an LRS set (left, right, surround).
String joinIntoString(StringRef separatorString, int startIndex=0, int numberOfElements=-1) const
Joins the strings in the array together into one string.
static AudioChannelSet JUCE_CALLTYPE createLCR()
Creates a set containing an LCR set (left, right, centre).
Third-order ambisonic channel number 11.
void expect(bool testResult, const String &failureMessage=String())
Checks that the result of a test is true, and logs this result.
AudioChannelSet()=default
Creates an empty channel set.
static AudioChannelSet JUCE_CALLTYPE create6point0()
Creates a set for a 6.0 Cine surround setup (left, right, centre, leftSurround, rightSurround, centreSurround).
Second-order ambisonic channel number 7.
Third-order ambisonic channel number 10.
static AudioChannelSet JUCE_CALLTYPE stereo()
Creates a set containing a stereo set (left, right).
Third-order ambisonic channel number 15.
static AudioChannelSet JUCE_CALLTYPE octagonal()
Creates a set for octagonal surround setup (left, right, leftSurround, rightSurround, centre, centreSurround, wideLeft, wideRight).
static String JUCE_CALLTYPE getAbbreviatedChannelTypeName(ChannelType)
Returns the abbreviated name of a channel type.
int getIntValue() const noexcept
Reads the value of the string as a decimal number (up to 32 bits in size).
static AudioChannelSet JUCE_CALLTYPE discreteChannels(int numChannels)
Creates a set of untyped discrete channels.
Fifth-order ambisonic channel number 32.
Third-order ambisonic channel number 13.
String getDescription() const
Returns the description of the current layout.
Second-order ambisonic channel number 6.
String getSpeakerArrangementAsString() const
Returns a string containing a whitespace-separated list of speaker types corresponding to each channe...
static AudioChannelSet JUCE_CALLTYPE create7point1point2()
Creates a set for Dolby Atmos 7.1.2 surround setup (left, right, centre, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, LFE, topSideLeft, topSideRight).
static AudioChannelSet JUCE_CALLTYPE create7point0()
Creates a set for a DTS 7.0 surround setup (left, right, centre, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear).
static AudioChannelSet JUCE_CALLTYPE fromWaveChannelMask(int32 dwChannelMask)
Create an AudioChannelSet from a WAVEFORMATEXTENSIBLE channelMask (typically used in ...
Fourth-order ambisonic channel number 17.
Fifth-order ambisonic channel number 29.
Fifth-order ambisonic channel number 26.
static AudioChannelSet JUCE_CALLTYPE hexagonal()
Creates a set for hexagonal surround setup (left, right, leftSurroundRear, rightSurroundRear, centre, surroundCentre).
Second-order ambisonic channel number 8.
static AudioChannelSet JUCE_CALLTYPE quadraphonic()
Creates a set for quadraphonic surround setup (left, right, leftSurround, rightSurround) ...
Fifth-order ambisonic channel number 34.
int length() const noexcept
Returns the number of characters in the string.
Second-order ambisonic channel number 5.
int getAmbisonicOrder() const
Returns the order of the ambisonic layout represented by this AudioChannelSet.
void add(String stringToAdd)
Appends a string at the end of the array.
void setRange(int startBit, int numBits, bool shouldBeSet)
Sets a range of bits to be either on or off.