OpenShot Audio Library | OpenShotAudio 0.4.0
 
Loading...
Searching...
No Matches
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
23namespace juce
24{
25
26#if ! defined (DOXYGEN) && (JUCE_MAC || JUCE_IOS)
27
28struct 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
159public:
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
282private:
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