Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

337 lines
16KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2015 - ROLI Ltd.
  5. Permission is granted to use this software under the terms of either:
  6. a) the GPL v2 (or any later version)
  7. b) the Affero GPL v3
  8. Details of these licenses can be found at: www.gnu.org/licenses
  9. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  10. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  11. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  12. ------------------------------------------------------------------------------
  13. To release a closed-source product which uses JUCE, commercial licenses are
  14. available: visit www.juce.com for more information.
  15. ==============================================================================
  16. */
  17. AudioChannelSet::AudioChannelSet (uint32 c) : channels (c) {}
  18. bool AudioChannelSet::operator== (const AudioChannelSet& other) const noexcept { return channels == other.channels; }
  19. bool AudioChannelSet::operator!= (const AudioChannelSet& other) const noexcept { return channels != other.channels; }
  20. bool AudioChannelSet::operator< (const AudioChannelSet& other) const noexcept { return channels < other.channels; }
  21. String AudioChannelSet::getChannelTypeName (AudioChannelSet::ChannelType type)
  22. {
  23. if (type >= discreteChannel0)
  24. return String ("Discrete ") + String (type - discreteChannel0 + 1);
  25. switch (type)
  26. {
  27. case left: return NEEDS_TRANS("Left");
  28. case right: return NEEDS_TRANS("Right");
  29. case centre: return NEEDS_TRANS("Centre");
  30. case LFE: return NEEDS_TRANS("LFE");
  31. case leftSurround: return NEEDS_TRANS("Left Surround");
  32. case rightSurround: return NEEDS_TRANS("Right Surround");
  33. case leftCentre: return NEEDS_TRANS("Left Centre");
  34. case rightCentre: return NEEDS_TRANS("Right Centre");
  35. case centreSurround: return NEEDS_TRANS("Centre Surround");
  36. case leftSurroundRear: return NEEDS_TRANS("Left Surround Rear");
  37. case rightSurroundRear: return NEEDS_TRANS("Right Surround Rear");
  38. case topMiddle: return NEEDS_TRANS("Top Middle");
  39. case topFrontLeft: return NEEDS_TRANS("Top Front Left");
  40. case topFrontCentre: return NEEDS_TRANS("Top Front Centre");
  41. case topFrontRight: return NEEDS_TRANS("Top Front Right");
  42. case topRearLeft: return NEEDS_TRANS("Top Rear Left");
  43. case topRearCentre: return NEEDS_TRANS("Top Rear Centre");
  44. case topRearRight: return NEEDS_TRANS("Top Rear Right");
  45. case wideLeft: return NEEDS_TRANS("Wide Left");
  46. case wideRight: return NEEDS_TRANS("Wide Right");
  47. case LFE2: return NEEDS_TRANS("LFE 2");
  48. case leftSurroundSide: return NEEDS_TRANS ("Left Surround Side");
  49. case rightSurroundSide: return NEEDS_TRANS ("Right Surround Side");
  50. case ambisonicW: return NEEDS_TRANS("Ambisonic W");
  51. case ambisonicX: return NEEDS_TRANS("Ambisonic X");
  52. case ambisonicY: return NEEDS_TRANS("Ambisonic Y");
  53. case ambisonicZ: return NEEDS_TRANS("Ambisonic Z");
  54. default: break;
  55. }
  56. return "Unknown";
  57. }
  58. String AudioChannelSet::getAbbreviatedChannelTypeName (AudioChannelSet::ChannelType type)
  59. {
  60. if (type >= discreteChannel0)
  61. return String (type - discreteChannel0 + 1);
  62. switch (type)
  63. {
  64. case left: return "L";
  65. case right: return "R";
  66. case centre: return "C";
  67. case LFE: return "Lfe";
  68. case leftSurround: return "Ls";
  69. case rightSurround: return "Rs";
  70. case leftCentre: return "Lc";
  71. case rightCentre: return "Rc";
  72. case centreSurround: return "Cs";
  73. case leftSurroundRear: return "Lrs";
  74. case rightSurroundRear: return "Rrs";
  75. case topMiddle: return "Tm";
  76. case topFrontLeft: return "Tfl";
  77. case topFrontCentre: return "Tfc";
  78. case topFrontRight: return "Tfr";
  79. case topRearLeft: return "Trl";
  80. case topRearCentre: return "Trc";
  81. case topRearRight: return "Trr";
  82. case wideLeft: return "Wl";
  83. case wideRight: return "Wr";
  84. case LFE2: return "Lfe2";
  85. case leftSurroundSide: return "Lss";
  86. case rightSurroundSide: return "Rss";
  87. case ambisonicW: return "W";
  88. case ambisonicX: return "X";
  89. case ambisonicY: return "Y";
  90. case ambisonicZ: return "Z";
  91. default: break;
  92. }
  93. return "";
  94. }
  95. String AudioChannelSet::getSpeakerArrangementAsString() const
  96. {
  97. StringArray speakerTypes;
  98. Array<AudioChannelSet::ChannelType> speakers = getChannelTypes();
  99. for (int i = 0; i < speakers.size(); ++i)
  100. {
  101. String name = getAbbreviatedChannelTypeName (speakers.getReference (i));
  102. if (name.isNotEmpty())
  103. speakerTypes.add (name);
  104. }
  105. return speakerTypes.joinIntoString (" ");
  106. }
  107. String AudioChannelSet::getDescription() const
  108. {
  109. if (isDiscreteLayout()) return String ("Discrete #") + String (size());
  110. if (*this == disabled()) return "Disabled";
  111. if (*this == mono()) return "Mono";
  112. if (*this == stereo()) return "Stereo";
  113. if (*this == createLCR()) return "LCR";
  114. if (*this == createLRS()) return "LRS";
  115. if (*this == createLCRS()) return "LCRS";
  116. if (*this == create5point0()) return "5.1 Surround";
  117. if (*this == create5point1()) return "5.1 Surround (+Lfe)";
  118. if (*this == create6point0()) return "6.1 Surround";
  119. if (*this == create6point1()) return "6.1 Surround (+Lfe)";
  120. if (*this == create6point0Music()) return "6.1 (Music) Surround";
  121. if (*this == create6point1Music()) return "6.1 (Music) Surround (+Lfe)";
  122. if (*this == create7point0()) return "7.1 Surround";
  123. if (*this == create7point1()) return "7.1 Surround (Lfe)";
  124. if (*this == create7point0SDDS()) return "7.1 Surround SDDS";
  125. if (*this == create7point1SDDS()) return "7.1 Surround SDDS (+Lfe)";
  126. if (*this == quadraphonic()) return "Quadraphonic";
  127. if (*this == pentagonal()) return "Pentagonal";
  128. if (*this == hexagonal()) return "Hexagonal";
  129. if (*this == octagonal()) return "Octagonal";
  130. if (*this == ambisonic()) return "Ambisonic";
  131. return "Unknown";
  132. }
  133. bool AudioChannelSet::isDiscreteLayout() const noexcept
  134. {
  135. Array<AudioChannelSet::ChannelType> speakers = getChannelTypes();
  136. for (int i = 0; i < speakers.size(); ++i)
  137. if (speakers.getReference (i) > ambisonicZ)
  138. return true;
  139. return false;
  140. }
  141. int AudioChannelSet::size() const noexcept
  142. {
  143. return channels.countNumberOfSetBits();
  144. }
  145. AudioChannelSet::ChannelType AudioChannelSet::getTypeOfChannel (int index) const noexcept
  146. {
  147. int bit = channels.findNextSetBit(0);
  148. for (int i = 0; i < index && bit >= 0; ++i)
  149. bit = channels.findNextSetBit (bit + 1);
  150. return static_cast<ChannelType> (bit);
  151. }
  152. int AudioChannelSet::getChannelIndexForType (AudioChannelSet::ChannelType type) const noexcept
  153. {
  154. int idx = 0;
  155. for (int bit = channels.findNextSetBit (0); bit >= 0; bit = channels.findNextSetBit (bit + 1))
  156. {
  157. if (static_cast<ChannelType> (bit) == type)
  158. return idx;
  159. idx++;
  160. }
  161. return -1;
  162. }
  163. Array<AudioChannelSet::ChannelType> AudioChannelSet::getChannelTypes() const
  164. {
  165. Array<ChannelType> result;
  166. for (int bit = channels.findNextSetBit(0); bit >= 0; bit = channels.findNextSetBit (bit + 1))
  167. result.add (static_cast<ChannelType> (bit));
  168. return result;
  169. }
  170. void AudioChannelSet::addChannel (ChannelType newChannel)
  171. {
  172. const int bit = static_cast<int> (newChannel);
  173. jassert (bit >= 0 && bit < 1024);
  174. channels.setBit (bit);
  175. }
  176. void AudioChannelSet::removeChannel (ChannelType newChannel)
  177. {
  178. const int bit = static_cast<int> (newChannel);
  179. jassert (bit >= 0 && bit < 1024);
  180. channels.clearBit (bit);
  181. }
  182. AudioChannelSet AudioChannelSet::disabled() { return AudioChannelSet(); }
  183. AudioChannelSet AudioChannelSet::mono() { return AudioChannelSet (1u << centre); }
  184. AudioChannelSet AudioChannelSet::stereo() { return AudioChannelSet ((1u << left) | (1u << right)); }
  185. AudioChannelSet AudioChannelSet::createLCR() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre)); }
  186. AudioChannelSet AudioChannelSet::createLRS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << surround)); }
  187. AudioChannelSet AudioChannelSet::createLCRS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << surround)); }
  188. AudioChannelSet AudioChannelSet::create5point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround)); }
  189. AudioChannelSet AudioChannelSet::create5point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround) | (1u << LFE)); }
  190. AudioChannelSet AudioChannelSet::create6point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround) | (1u << centreSurround)); }
  191. AudioChannelSet AudioChannelSet::create6point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround) | (1u << centreSurround) | (1u << LFE)); }
  192. AudioChannelSet AudioChannelSet::create6point0Music() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftSurroundSide) | (1u << rightSurroundSide)); }
  193. AudioChannelSet AudioChannelSet::create6point1Music() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftSurroundSide) | (1u << rightSurroundSide) | (1u << LFE)); }
  194. AudioChannelSet AudioChannelSet::create7point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurroundSide) | (1u << rightSurroundSide) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); }
  195. AudioChannelSet AudioChannelSet::create7point0SDDS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftCentre) | (1u << rightCentre)); }
  196. AudioChannelSet AudioChannelSet::create7point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurroundSide) | (1u << rightSurroundSide) | (1u << leftSurroundRear) | (1u << rightSurroundRear) | (1u << LFE)); }
  197. AudioChannelSet AudioChannelSet::create7point1SDDS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftCentre) | (1u << rightCentre) | (1u << LFE)); }
  198. AudioChannelSet AudioChannelSet::ambisonic() { return AudioChannelSet ((1u << ambisonicW) | (1u << ambisonicX) | (1u << ambisonicY) | (1u << ambisonicZ)); }
  199. AudioChannelSet AudioChannelSet::quadraphonic() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << leftSurround) | (1u << rightSurround)); }
  200. AudioChannelSet AudioChannelSet::pentagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); }
  201. AudioChannelSet AudioChannelSet::hexagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << leftSurroundRear) | (1u << rightSurroundRear) | (1u << centre) | (1u << centreSurround)); }
  202. AudioChannelSet AudioChannelSet::octagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << leftSurround) | (1u << rightSurround) | (1u << centre) | (1u << centreSurround) | (1u << wideLeft) | (1u << wideRight)); }
  203. AudioChannelSet AudioChannelSet::discreteChannels (int numChannels)
  204. {
  205. AudioChannelSet s;
  206. s.channels.setRange (discreteChannel0, numChannels, true);
  207. return s;
  208. }
  209. AudioChannelSet AudioChannelSet::canonicalChannelSet (int numChannels)
  210. {
  211. if (numChannels == 1) return AudioChannelSet::mono();
  212. if (numChannels == 2) return AudioChannelSet::stereo();
  213. if (numChannels == 3) return AudioChannelSet::createLCR();
  214. if (numChannels == 4) return AudioChannelSet::quadraphonic();
  215. if (numChannels == 5) return AudioChannelSet::create5point0();
  216. if (numChannels == 6) return AudioChannelSet::create5point1();
  217. if (numChannels == 7) return AudioChannelSet::create7point0();
  218. if (numChannels == 8) return AudioChannelSet::create7point1();
  219. return discreteChannels (numChannels);
  220. }
  221. AudioChannelSet AudioChannelSet::namedChannelSet (int numChannels)
  222. {
  223. if (numChannels == 1) return AudioChannelSet::mono();
  224. if (numChannels == 2) return AudioChannelSet::stereo();
  225. if (numChannels == 3) return AudioChannelSet::createLCR();
  226. if (numChannels == 4) return AudioChannelSet::quadraphonic();
  227. if (numChannels == 5) return AudioChannelSet::create5point0();
  228. if (numChannels == 6) return AudioChannelSet::create5point1();
  229. if (numChannels == 7) return AudioChannelSet::create7point0();
  230. if (numChannels == 8) return AudioChannelSet::create7point1();
  231. return AudioChannelSet();
  232. }
  233. Array<AudioChannelSet> AudioChannelSet::channelSetsWithNumberOfChannels (int numChannels)
  234. {
  235. Array<AudioChannelSet> retval;
  236. if (numChannels != 0)
  237. {
  238. retval.add (AudioChannelSet::discreteChannels (numChannels));
  239. if (numChannels == 1)
  240. {
  241. retval.add (AudioChannelSet::mono());
  242. }
  243. else if (numChannels == 2)
  244. {
  245. retval.add (AudioChannelSet::stereo());
  246. }
  247. else if (numChannels == 3)
  248. {
  249. retval.add (AudioChannelSet::createLCR());
  250. retval.add (AudioChannelSet::createLRS());
  251. }
  252. else if (numChannels == 4)
  253. {
  254. retval.add (AudioChannelSet::quadraphonic());
  255. retval.add (AudioChannelSet::createLCRS());
  256. retval.add (AudioChannelSet::ambisonic());
  257. }
  258. else if (numChannels == 5)
  259. {
  260. retval.add (AudioChannelSet::create5point0());
  261. retval.add (AudioChannelSet::pentagonal());
  262. }
  263. else if (numChannels == 6)
  264. {
  265. retval.add (AudioChannelSet::create5point1());
  266. retval.add (AudioChannelSet::create6point0());
  267. retval.add (AudioChannelSet::create6point0Music());
  268. retval.add (AudioChannelSet::hexagonal());
  269. }
  270. else if (numChannels == 7)
  271. {
  272. retval.add (AudioChannelSet::create7point0());
  273. retval.add (AudioChannelSet::create7point0SDDS());
  274. retval.add (AudioChannelSet::create6point1());
  275. retval.add (AudioChannelSet::create6point1Music());
  276. }
  277. else if (numChannels == 8)
  278. {
  279. retval.add (AudioChannelSet::create7point1());
  280. retval.add (AudioChannelSet::create7point1SDDS());
  281. retval.add (AudioChannelSet::octagonal());
  282. }
  283. }
  284. return retval;
  285. }