OpenShot Audio Library | OpenShotAudio  0.6.0
juce_CoreAudioLayouts_mac.h
1 /*
2  ==============================================================================
3 
4  This file is part of the JUCE library.
5  Copyright (c) 2022 - Raw Material Software Limited
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 #if ! defined (DOXYGEN) && (JUCE_MAC || JUCE_IOS)
27 
28 struct CoreAudioLayouts
29 {
30  //==============================================================================
31  struct LayoutTagSpeakerList
32  {
33  AudioChannelLayoutTag tag;
34  AudioChannelSet::ChannelType channelTypes[16];
35  };
36 
37  //==============================================================================
38  // This list has been derived from https://pastebin.com/24dQ4BPJ
39  // Apple channel labels have been replaced by JUCE channel names
40  // This means that some layouts will be identical in JUCE but not in CoreAudio
41 
42  // In Apple's official definition the following tags exist with the same speaker layout and order
43  // even when *not* represented in JUCE channels
44  // kAudioChannelLayoutTag_Binaural = kAudioChannelLayoutTag_Stereo
45  // kAudioChannelLayoutTag_MPEG_5_0_B = kAudioChannelLayoutTag_Pentagonal
46  // kAudioChannelLayoutTag_ITU_2_2 = kAudioChannelLayoutTag_Quadraphonic
47  // kAudioChannelLayoutTag_AudioUnit_6_0 = kAudioChannelLayoutTag_Hexagonal
48  struct SpeakerLayoutTable : AudioChannelSet // save us some typing
49  {
50  template <typename... Items>
51  static constexpr auto getArray (Items... items)
52  {
53  return std::array<LayoutTagSpeakerList, sizeof... (items)> { { items... } };
54  }
55 
56  static constexpr auto get()
57  {
58  using List = LayoutTagSpeakerList;
59 
60  return getArray (List { kAudioChannelLayoutTag_Mono, { centre } },
61  List { kAudioChannelLayoutTag_Stereo, { left, right } },
62  List { kAudioChannelLayoutTag_MPEG_3_0_A, { left, right, centre } },
63  List { kAudioChannelLayoutTag_ITU_2_1, { left, right, centreSurround } },
64  List { kAudioChannelLayoutTag_MPEG_4_0_A, { left, right, centre, centreSurround } },
65  List { kAudioChannelLayoutTag_MPEG_5_0_A, { left, right, centre, leftSurround, rightSurround } },
66  List { kAudioChannelLayoutTag_MPEG_5_1_A, { left, right, centre, LFE, leftSurround, rightSurround } },
67  List { kAudioChannelLayoutTag_AudioUnit_6_0, { left, right, leftSurround, rightSurround, centre, centreSurround } },
68  List { kAudioChannelLayoutTag_MPEG_6_1_A, { left, right, centre, LFE, leftSurround, rightSurround, centreSurround } },
69  List { kAudioChannelLayoutTag_DTS_6_0_A, { leftSurroundSide, rightSurroundSide, left, right, leftSurround, rightSurround } },
70  List { kAudioChannelLayoutTag_DTS_6_1_A, { leftSurroundSide, rightSurroundSide, left, right, leftSurround, rightSurround, LFE } },
71  List { kAudioChannelLayoutTag_AudioUnit_7_0, { left, right, leftSurroundSide, rightSurroundSide, centre, leftSurroundRear, rightSurroundRear } },
72  List { kAudioChannelLayoutTag_AudioUnit_7_0_Front, { left, right, leftSurround, rightSurround, centre, leftCentre, rightCentre } },
73  List { kAudioChannelLayoutTag_MPEG_7_1_C, { left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear } },
74  List { kAudioChannelLayoutTag_MPEG_7_1_A, { left, right, centre, LFE, leftSurround, rightSurround, leftCentre, rightCentre } },
75  List { kAudioChannelLayoutTag_Ambisonic_B_Format, { ambisonicW, ambisonicX, ambisonicY, ambisonicZ } },
76  List { kAudioChannelLayoutTag_Quadraphonic, { left, right, leftSurround, rightSurround } },
77  List { kAudioChannelLayoutTag_Pentagonal, { left, right, leftSurroundRear, rightSurroundRear, centre } },
78  List { kAudioChannelLayoutTag_Hexagonal, { left, right, leftSurroundRear, rightSurroundRear, centre, centreSurround } },
79  List { kAudioChannelLayoutTag_Octagonal, { left, right, leftSurround, rightSurround, centre, centreSurround, wideLeft, wideRight } },
80 
81  #if defined (MAC_OS_VERSION_11_0)
82  List { kAudioChannelLayoutTag_Atmos_5_1_4, { left, right, centre, LFE, leftSurround, rightSurround, topFrontLeft, topFrontRight, topRearLeft, topRearRight } },
83  List { kAudioChannelLayoutTag_Atmos_7_1_2, { left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, topSideLeft, topSideRight } },
84  #endif
85 
86  #if defined (MAC_OS_X_VERSION_10_15)
87  List { kAudioChannelLayoutTag_Atmos_5_1_2, { left, right, centre, LFE, leftSurround, rightSurround, topSideLeft, topSideRight } },
88  List { kAudioChannelLayoutTag_Atmos_7_1_4, { left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, topFrontLeft, topFrontRight, topRearLeft, topRearRight } },
89  List { kAudioChannelLayoutTag_Atmos_9_1_6, { left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, wideLeft, wideRight, topFrontLeft, topFrontRight, topSideLeft, topSideRight, topRearLeft, topRearRight } },
90  #endif
91 
92  // More uncommon layouts...
93  List { kAudioChannelLayoutTag_StereoHeadphones, { left, right } },
94  List { kAudioChannelLayoutTag_MatrixStereo, { left, right } },
95  List { kAudioChannelLayoutTag_MidSide, { centre, discreteChannel0 } },
96  List { kAudioChannelLayoutTag_XY, { ambisonicX, ambisonicY } },
97  List { kAudioChannelLayoutTag_Binaural, { left, right } },
98  List { kAudioChannelLayoutTag_Cube, { left, right, leftSurround, rightSurround, topFrontLeft, topFrontRight, topRearLeft, topRearRight } },
99  List { kAudioChannelLayoutTag_MPEG_3_0_B, { centre, left, right } },
100  List { kAudioChannelLayoutTag_MPEG_4_0_B, { centre, left, right, centreSurround } },
101  List { kAudioChannelLayoutTag_MPEG_5_0_B, { left, right, leftSurround, rightSurround, centre } },
102  List { kAudioChannelLayoutTag_MPEG_5_0_C, { left, centre, right, leftSurround, rightSurround } },
103  List { kAudioChannelLayoutTag_MPEG_5_0_D, { centre, left, right, leftSurround, rightSurround } },
104  List { kAudioChannelLayoutTag_MPEG_5_1_B, { left, right, leftSurround, rightSurround, centre, LFE } },
105  List { kAudioChannelLayoutTag_MPEG_5_1_C, { left, centre, right, leftSurround, rightSurround, LFE } },
106  List { kAudioChannelLayoutTag_MPEG_5_1_D, { centre, left, right, leftSurround, rightSurround, LFE } },
107  List { kAudioChannelLayoutTag_MPEG_7_1_B, { centre, leftCentre, rightCentre, left, right, leftSurround, rightSurround, LFE } },
108  List { kAudioChannelLayoutTag_Emagic_Default_7_1, { left, right, leftSurround, rightSurround, centre, LFE, leftCentre, rightCentre } },
109  List { kAudioChannelLayoutTag_SMPTE_DTV, { left, right, centre, LFE, leftSurround, rightSurround, discreteChannel0 /* leftMatrixTotal */, (ChannelType) (discreteChannel0 + 1) /* rightMatrixTotal */} },
110  List { kAudioChannelLayoutTag_ITU_2_2, { left, right, leftSurround, rightSurround } },
111  List { kAudioChannelLayoutTag_DVD_4, { left, right, LFE } },
112  List { kAudioChannelLayoutTag_DVD_5, { left, right, LFE, centreSurround } },
113  List { kAudioChannelLayoutTag_DVD_6, { left, right, LFE, leftSurround, rightSurround } },
114  List { kAudioChannelLayoutTag_DVD_10, { left, right, centre, LFE } },
115  List { kAudioChannelLayoutTag_DVD_11, { left, right, centre, LFE, centreSurround } },
116  List { kAudioChannelLayoutTag_DVD_18, { left, right, leftSurround, rightSurround, LFE } },
117  List { kAudioChannelLayoutTag_AAC_6_0, { centre, left, right, leftSurround, rightSurround, centreSurround } },
118  List { kAudioChannelLayoutTag_AAC_6_1, { centre, left, right, leftSurround, rightSurround, centreSurround, LFE } },
119  List { kAudioChannelLayoutTag_AAC_7_0, { centre, left, right, leftSurround, rightSurround, leftSurroundRear, rightSurroundRear } },
120  List { kAudioChannelLayoutTag_AAC_7_1_B, { centre, left, right, leftSurround, rightSurround, leftSurroundRear, rightSurroundRear, LFE } },
121  List { kAudioChannelLayoutTag_AAC_7_1_C, { centre, left, right, leftSurround, rightSurround, LFE, topFrontLeft, topFrontRight } },
122  List { kAudioChannelLayoutTag_AAC_Octagonal, { centre, left, right, leftSurround, rightSurround, leftSurroundRear, rightSurroundRear, centreSurround } },
123  List { kAudioChannelLayoutTag_TMH_10_2_std, { left, right, centre, topFrontCentre, leftSurroundSide, rightSurroundSide, leftSurround, rightSurround, topFrontLeft, topFrontRight, wideLeft, wideRight, topRearCentre, centreSurround, LFE, LFE2 } },
124  List { kAudioChannelLayoutTag_AC3_1_0_1, { centre, LFE } },
125  List { kAudioChannelLayoutTag_AC3_3_0, { left, centre, right } },
126  List { kAudioChannelLayoutTag_AC3_3_1, { left, centre, right, centreSurround } },
127  List { kAudioChannelLayoutTag_AC3_3_0_1, { left, centre, right, LFE } },
128  List { kAudioChannelLayoutTag_AC3_2_1_1, { left, right, centreSurround, LFE } },
129  List { kAudioChannelLayoutTag_AC3_3_1_1, { left, centre, right, centreSurround, LFE } },
130  List { kAudioChannelLayoutTag_EAC_6_0_A, { left, centre, right, leftSurround, rightSurround, centreSurround } },
131  List { kAudioChannelLayoutTag_EAC_7_0_A, { left, centre, right, leftSurround, rightSurround, leftSurroundRear, rightSurroundRear } },
132  List { kAudioChannelLayoutTag_EAC3_6_1_A, { left, centre, right, leftSurround, rightSurround, LFE, centreSurround } },
133  List { kAudioChannelLayoutTag_EAC3_6_1_B, { left, centre, right, leftSurround, rightSurround, LFE, centreSurround } },
134  List { kAudioChannelLayoutTag_EAC3_6_1_C, { left, centre, right, leftSurround, rightSurround, LFE, topFrontCentre } },
135  List { kAudioChannelLayoutTag_EAC3_7_1_A, { left, centre, right, leftSurround, rightSurround, LFE, leftSurroundRear, rightSurroundRear } },
136  List { kAudioChannelLayoutTag_EAC3_7_1_B, { left, centre, right, leftSurround, rightSurround, LFE, leftCentre, rightCentre } },
137  List { kAudioChannelLayoutTag_EAC3_7_1_C, { left, centre, right, leftSurround, rightSurround, LFE, leftSurroundSide, rightSurroundSide } },
138  List { kAudioChannelLayoutTag_EAC3_7_1_D, { left, centre, right, leftSurround, rightSurround, LFE, wideLeft, wideRight } },
139  List { kAudioChannelLayoutTag_EAC3_7_1_E, { left, centre, right, leftSurround, rightSurround, LFE, topFrontLeft, topFrontRight } },
140  List { kAudioChannelLayoutTag_EAC3_7_1_F, { left, centre, right, leftSurround, rightSurround, LFE, centreSurround, topMiddle } },
141  List { kAudioChannelLayoutTag_EAC3_7_1_G, { left, centre, right, leftSurround, rightSurround, LFE, centreSurround, topFrontCentre } },
142  List { kAudioChannelLayoutTag_EAC3_7_1_H, { left, centre, right, leftSurround, rightSurround, LFE, centreSurround, topFrontCentre } },
143  List { kAudioChannelLayoutTag_DTS_3_1, { centre, left, right, LFE } },
144  List { kAudioChannelLayoutTag_DTS_4_1, { centre, left, right, centreSurround, LFE } },
145  List { kAudioChannelLayoutTag_DTS_6_0_B, { centre, left, right, leftSurroundRear, rightSurroundRear, centreSurround } },
146  List { kAudioChannelLayoutTag_DTS_6_0_C, { centre, centreSurround, left, right, leftSurroundRear, rightSurroundRear } },
147  List { kAudioChannelLayoutTag_DTS_6_1_B, { centre, left, right, leftSurroundRear, rightSurroundRear, centreSurround, LFE } },
148  List { kAudioChannelLayoutTag_DTS_6_1_C, { centre, centreSurround, left, right, leftSurroundRear, rightSurroundRear, LFE } },
149  List { kAudioChannelLayoutTag_DTS_6_1_D, { centre, left, right, leftSurround, rightSurround, LFE, centreSurround } },
150  List { kAudioChannelLayoutTag_DTS_7_0, { leftCentre, centre, rightCentre, left, right, leftSurround, rightSurround } },
151  List { kAudioChannelLayoutTag_DTS_7_1, { leftCentre, centre, rightCentre, left, right, leftSurround, rightSurround, LFE } },
152  List { kAudioChannelLayoutTag_DTS_8_0_A, { leftCentre, rightCentre, left, right, leftSurround, rightSurround, leftSurroundRear, rightSurroundRear } },
153  List { kAudioChannelLayoutTag_DTS_8_0_B, { leftCentre, centre, rightCentre, left, right, leftSurround, centreSurround, rightSurround } },
154  List { kAudioChannelLayoutTag_DTS_8_1_A, { leftCentre, rightCentre, left, right, leftSurround, rightSurround, leftSurroundRear, rightSurroundRear, LFE } },
155  List { kAudioChannelLayoutTag_DTS_8_1_B, { leftCentre, centre, rightCentre, left, right, leftSurround, centreSurround, rightSurround, LFE } });
156  }
157  };
158 
159 public:
160  //==============================================================================
161  enum
162  {
163  coreAudioHOASN3DLayoutTag = (190U<<16) | 0 // kAudioChannelLayoutTag_HOA_ACN_SN3D
164  };
165 
166  //==============================================================================
171  static AudioChannelSet fromCoreAudio (const AudioChannelLayout& layout)
172  {
173  return AudioChannelSet::channelSetWithChannels (getCoreAudioLayoutChannels (layout));
174  }
175 
180  static AudioChannelSet fromCoreAudio (AudioChannelLayoutTag layoutTag)
181  {
182  return AudioChannelSet::channelSetWithChannels (getSpeakerLayoutForCoreAudioTag (layoutTag));
183  }
184 
189  static AudioChannelLayoutTag toCoreAudio (const AudioChannelSet& set)
190  {
191  if (set.getAmbisonicOrder() >= 0)
192  return coreAudioHOASN3DLayoutTag | static_cast<unsigned> (set.size());
193 
194  for (const auto& item : SpeakerLayoutTable::get())
195  {
196  AudioChannelSet caSet;
197 
198  for (int i = 0; i < numElementsInArray (item.channelTypes)
199  && item.channelTypes[i] != AudioChannelSet::unknown; ++i)
200  caSet.addChannel (item.channelTypes[i]);
201 
202  if (caSet == set)
203  return item.tag;
204  }
205 
206  return kAudioChannelLayoutTag_DiscreteInOrder | static_cast<AudioChannelLayoutTag> (set.size());
207  }
208 
209  static const Array<AudioChannelLayoutTag>& getKnownCoreAudioTags()
210  {
211  static Array<AudioChannelLayoutTag> tags (createKnownCoreAudioTags());
212  return tags;
213  }
214 
215  //==============================================================================
217  static Array<AudioChannelSet::ChannelType> getCoreAudioLayoutChannels (const AudioChannelLayout& layout)
218  {
219  switch (layout.mChannelLayoutTag & 0xffff0000)
220  {
221  case kAudioChannelLayoutTag_UseChannelBitmap:
222  return AudioChannelSet::fromWaveChannelMask (static_cast<int> (layout.mChannelBitmap)).getChannelTypes();
223  case kAudioChannelLayoutTag_UseChannelDescriptions:
224  {
225  Array<AudioChannelSet::ChannelType> channels;
226 
227  for (UInt32 i = 0; i < layout.mNumberChannelDescriptions; ++i)
228  channels.addIfNotAlreadyThere (getChannelTypeFromAudioChannelLabel (layout.mChannelDescriptions[i].mChannelLabel));
229 
230  // different speaker mappings may point to the same JUCE speaker so fill up
231  // this array with discrete channels
232  for (int j = 0; channels.size() < static_cast<int> (layout.mNumberChannelDescriptions); ++j)
233  channels.addIfNotAlreadyThere (static_cast<AudioChannelSet::ChannelType> (AudioChannelSet::discreteChannel0 + j));
234 
235  return channels;
236  }
237  case kAudioChannelLayoutTag_DiscreteInOrder:
238  return AudioChannelSet::discreteChannels (static_cast<int> (layout.mChannelLayoutTag) & 0xffff).getChannelTypes();
239  default:
240  break;
241  }
242 
243  return getSpeakerLayoutForCoreAudioTag (layout.mChannelLayoutTag);
244  }
245 
246  static Array<AudioChannelSet::ChannelType> getSpeakerLayoutForCoreAudioTag (AudioChannelLayoutTag tag)
247  {
248  // You need to specify the full AudioChannelLayout when using
249  // the UseChannelBitmap and UseChannelDescriptions layout tag
250  jassert (tag != kAudioChannelLayoutTag_UseChannelBitmap && tag != kAudioChannelLayoutTag_UseChannelDescriptions);
251 
252  Array<AudioChannelSet::ChannelType> speakers;
253 
254  for (const auto& item : SpeakerLayoutTable::get())
255  {
256  if (tag == item.tag)
257  {
258  for (int i = 0; i < numElementsInArray (item.channelTypes)
259  && item.channelTypes[i] != AudioChannelSet::unknown; ++i)
260  speakers.add (item.channelTypes[i]);
261 
262  return speakers;
263  }
264  }
265 
266  const auto numChannels = tag & 0xffff;
267 
268  if (tag >= coreAudioHOASN3DLayoutTag && tag <= (coreAudioHOASN3DLayoutTag | 0xffff))
269  {
270  const auto ambisonicOrder = AudioChannelSet::getAmbisonicOrderForNumChannels (static_cast<int> (numChannels));
271 
272  if (ambisonicOrder != -1)
273  return AudioChannelSet::ambisonic (ambisonicOrder).getChannelTypes();
274  }
275 
276  for (UInt32 i = 0; i < numChannels; ++i)
277  speakers.add (static_cast<AudioChannelSet::ChannelType> (AudioChannelSet::discreteChannel0 + i));
278 
279  return speakers;
280  }
281 
282 private:
283  static Array<AudioChannelLayoutTag> createKnownCoreAudioTags()
284  {
285  Array<AudioChannelLayoutTag> tags;
286 
287  for (const auto& item : SpeakerLayoutTable::get())
288  tags.addIfNotAlreadyThere (item.tag);
289 
290  for (unsigned order = 0; order <= 5; ++order)
291  tags.addIfNotAlreadyThere (coreAudioHOASN3DLayoutTag | ((order + 1) * (order + 1)));
292 
293  return tags;
294  }
295 
296  //==============================================================================
297  static AudioChannelSet::ChannelType getChannelTypeFromAudioChannelLabel (AudioChannelLabel label) noexcept
298  {
299  if (label >= kAudioChannelLabel_Discrete_0 && label <= kAudioChannelLabel_Discrete_65535)
300  {
301  const unsigned int discreteChannelNum = label - kAudioChannelLabel_Discrete_0;
302  return static_cast<AudioChannelSet::ChannelType> (AudioChannelSet::discreteChannel0 + discreteChannelNum);
303  }
304 
305  switch (label)
306  {
307  case kAudioChannelLabel_Center:
308  case kAudioChannelLabel_Mono: return AudioChannelSet::centre;
309  case kAudioChannelLabel_Left:
310  case kAudioChannelLabel_HeadphonesLeft: return AudioChannelSet::left;
311  case kAudioChannelLabel_Right:
312  case kAudioChannelLabel_HeadphonesRight: return AudioChannelSet::right;
313  case kAudioChannelLabel_LFEScreen: return AudioChannelSet::LFE;
314  case kAudioChannelLabel_LeftSurround: return AudioChannelSet::leftSurround;
315  case kAudioChannelLabel_RightSurround: return AudioChannelSet::rightSurround;
316  case kAudioChannelLabel_LeftCenter: return AudioChannelSet::leftCentre;
317  case kAudioChannelLabel_RightCenter: return AudioChannelSet::rightCentre;
318  case kAudioChannelLabel_CenterSurround: return AudioChannelSet::surround;
319  case kAudioChannelLabel_LeftSurroundDirect: return AudioChannelSet::leftSurroundSide;
320  case kAudioChannelLabel_RightSurroundDirect: return AudioChannelSet::rightSurroundSide;
321  case kAudioChannelLabel_TopCenterSurround: return AudioChannelSet::topMiddle;
322  case kAudioChannelLabel_VerticalHeightLeft: return AudioChannelSet::topFrontLeft;
323  case kAudioChannelLabel_VerticalHeightRight: return AudioChannelSet::topFrontRight;
324  case kAudioChannelLabel_VerticalHeightCenter: return AudioChannelSet::topFrontCentre;
325  case kAudioChannelLabel_TopBackLeft: return AudioChannelSet::topRearLeft;
326  case kAudioChannelLabel_RearSurroundLeft: return AudioChannelSet::leftSurroundRear;
327  case kAudioChannelLabel_TopBackRight: return AudioChannelSet::topRearRight;
328  case kAudioChannelLabel_RearSurroundRight: return AudioChannelSet::rightSurroundRear;
329  case kAudioChannelLabel_TopBackCenter: return AudioChannelSet::topRearCentre;
330  case kAudioChannelLabel_LFE2: return AudioChannelSet::LFE2;
331  case kAudioChannelLabel_LeftWide: return AudioChannelSet::wideLeft;
332  case kAudioChannelLabel_RightWide: return AudioChannelSet::wideRight;
333  case kAudioChannelLabel_Ambisonic_W: return AudioChannelSet::ambisonicW;
334  case kAudioChannelLabel_Ambisonic_X: return AudioChannelSet::ambisonicX;
335  case kAudioChannelLabel_Ambisonic_Y: return AudioChannelSet::ambisonicY;
336  case kAudioChannelLabel_Ambisonic_Z: return AudioChannelSet::ambisonicZ;
337  default: return AudioChannelSet::unknown;
338  }
339  }
340 };
341 
342 #endif
343 
344 } // namespace juce
static int getAmbisonicOrderForNumChannels(int numChannels, int maxOrderToCheck=7)
static AudioChannelSet JUCE_CALLTYPE channelSetWithChannels(const Array< ChannelType > &)
static AudioChannelSet JUCE_CALLTYPE ambisonic(int order=1)
static AudioChannelSet JUCE_CALLTYPE discreteChannels(int numChannels)
static AudioChannelSet JUCE_CALLTYPE fromWaveChannelMask(int32 dwChannelMask)
Array< ChannelType > getChannelTypes() const