OpenShot Library | libopenshot-audio 0.2.0
juce_mac_CoreAudioLayouts.h
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
23namespace juce
24{
25
26#if ! DOXYGEN && (JUCE_MAC || JUCE_IOS)
27
28struct CoreAudioLayouts
29{
30 //==============================================================================
31 enum
32 {
33 coreAudioHOASN3DLayoutTag = (190U<<16) | 0 // kAudioChannelLayoutTag_HOA_ACN_SN3D
34 };
35
36 //==============================================================================
37 /** Convert CoreAudio's native AudioChannelLayout to JUCE's AudioChannelSet.
38
39 Note that this method cannot preserve the order of channels.
40 */
41 static AudioChannelSet fromCoreAudio (const AudioChannelLayout& layout)
42 {
44 }
45
46 /** Convert CoreAudio's native AudioChannelLayoutTag to JUCE's AudioChannelSet.
47
48 Note that this method cannot preserve the order of channels.
49 */
50 static AudioChannelSet fromCoreAudio (AudioChannelLayoutTag layoutTag)
51 {
53 }
54
55 /** Convert JUCE's AudioChannelSet to CoreAudio's AudioChannelLayoutTag.
56
57 Note that this method cannot preserve the order of channels.
58 */
59 static AudioChannelLayoutTag toCoreAudio (const AudioChannelSet& set)
60 {
61 if (set.getAmbisonicOrder() >= 0)
62 return coreAudioHOASN3DLayoutTag | static_cast<unsigned> (set.size());
63
64 for (auto* tbl = SpeakerLayoutTable::get(); tbl->tag != 0; ++tbl)
65 {
66 AudioChannelSet caSet;
67
68 for (int i = 0; i < numElementsInArray (tbl->channelTypes)
69 && tbl->channelTypes[i] != AudioChannelSet::unknown; ++i)
70 caSet.addChannel (tbl->channelTypes[i]);
71
72 if (caSet == set)
73 return tbl->tag;
74 }
75
77 }
78
80 {
82 return tags;
83 }
84
85 //==============================================================================
86 /** Convert CoreAudio's native AudioChannelLayout to an array of JUCE ChannelTypes. */
88 {
89 switch (layout.mChannelLayoutTag & 0xffff0000)
90 {
92 return AudioChannelSet::fromWaveChannelMask (static_cast<int> (layout.mChannelBitmap)).getChannelTypes();
94 {
96
97 for (UInt32 i = 0; i < layout.mNumberChannelDescriptions; ++i)
98 channels.addIfNotAlreadyThere (getChannelTypeFromAudioChannelLabel (layout.mChannelDescriptions[i].mChannelLabel));
99
100 // different speaker mappings may point to the same JUCE speaker so fill up
101 // this array with discrete channels
102 for (int j = 0; channels.size() < static_cast<int> (layout.mNumberChannelDescriptions); ++j)
104
105 return channels;
106 }
108 return AudioChannelSet::discreteChannels (static_cast<int> (layout.mChannelLayoutTag) & 0xffff).getChannelTypes();
109 default:
110 break;
111 }
112
113 return getSpeakerLayoutForCoreAudioTag (layout.mChannelLayoutTag);
114 }
115
117 {
118 // You need to specify the full AudioChannelLayout when using
119 // the UseChannelBitmap and UseChannelDescriptions layout tag
121
123
124 for (auto* tbl = SpeakerLayoutTable::get(); tbl->tag != 0; ++tbl)
125 {
126 if (tag == tbl->tag)
127 {
128 for (int i = 0; i < numElementsInArray (tbl->channelTypes)
129 && tbl->channelTypes[i] != AudioChannelSet::unknown; ++i)
130 speakers.add (tbl->channelTypes[i]);
131
132 return speakers;
133 }
134 }
135
136 auto numChannels = tag & 0xffff;
138 {
139 auto sqrtMinusOne = std::sqrt (static_cast<float> (numChannels)) - 1.0f;
140 auto ambisonicOrder = jmax (0, static_cast<int> (std::floor (sqrtMinusOne)));
141
142 if (static_cast<float> (ambisonicOrder) == sqrtMinusOne)
143 return AudioChannelSet::ambisonic (ambisonicOrder).getChannelTypes();
144 }
145
146 for (UInt32 i = 0; i < numChannels; ++i)
148
149 return speakers;
150 }
151
152private:
153 //==============================================================================
155 {
156 AudioChannelLayoutTag tag;
157 AudioChannelSet::ChannelType channelTypes[16];
158 };
159
161 {
163
164 for (auto* tbl = SpeakerLayoutTable::get(); tbl->tag != 0; ++tbl)
166
167 for (unsigned order = 0; order <= 5; ++order)
168 tags.addIfNotAlreadyThere (coreAudioHOASN3DLayoutTag | ((order + 1) * (order + 1)));
169
170 return tags;
171 }
172
173 //==============================================================================
174 // This list has been derived from https://pastebin.com/24dQ4BPJ
175 // Apple channel labels have been replaced by JUCE channel names
176 // This means that some layouts will be identical in JUCE but not in CoreAudio
177
178 // In Apple's official definition the following tags exist with the same speaker layout and order
179 // even when *not* represented in JUCE channels
180 // kAudioChannelLayoutTag_Binaural = kAudioChannelLayoutTag_Stereo
181 // kAudioChannelLayoutTag_MPEG_5_0_B = kAudioChannelLayoutTag_Pentagonal
182 // kAudioChannelLayoutTag_ITU_2_2 = kAudioChannelLayoutTag_Quadraphonic
183 // kAudioChannelLayoutTag_AudioUnit_6_0 = kAudioChannelLayoutTag_Hexagonal
184 struct SpeakerLayoutTable : AudioChannelSet // save us some typing
185 {
186 static LayoutTagSpeakerList* get() noexcept
187 {
188 static LayoutTagSpeakerList tbl[] = {
189 // list layouts for which there is a corresponding named AudioChannelSet first
190 { kAudioChannelLayoutTag_Mono, { centre } },
191 { kAudioChannelLayoutTag_Stereo, { left, right } },
192 { kAudioChannelLayoutTag_MPEG_3_0_A, { left, right, centre } },
193 { kAudioChannelLayoutTag_ITU_2_1, { left, right, centreSurround } },
194 { kAudioChannelLayoutTag_MPEG_4_0_A, { left, right, centre, centreSurround } },
195 { kAudioChannelLayoutTag_MPEG_5_0_A, { left, right, centre, leftSurround, rightSurround } },
196 { kAudioChannelLayoutTag_MPEG_5_1_A, { left, right, centre, LFE, leftSurround, rightSurround } },
197 { kAudioChannelLayoutTag_AudioUnit_6_0, { left, right, leftSurround, rightSurround, centre, centreSurround } },
198 { kAudioChannelLayoutTag_MPEG_6_1_A, { left, right, centre, LFE, leftSurround, rightSurround, centreSurround } },
199 { kAudioChannelLayoutTag_DTS_6_0_A, { leftSurroundSide, rightSurroundSide, left, right, leftSurround, rightSurround } },
200 { kAudioChannelLayoutTag_DTS_6_1_A, { leftSurroundSide, rightSurroundSide, left, right, leftSurround, rightSurround, LFE } },
201 { kAudioChannelLayoutTag_AudioUnit_7_0, { left, right, leftSurroundSide, rightSurroundSide, centre, leftSurroundRear, rightSurroundRear } },
202 { kAudioChannelLayoutTag_AudioUnit_7_0_Front, { left, right, leftSurround, rightSurround, centre, leftCentre, rightCentre } },
203 { kAudioChannelLayoutTag_MPEG_7_1_C, { left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear } },
204 { kAudioChannelLayoutTag_MPEG_7_1_A, { left, right, centre, LFE, leftSurround, rightSurround, leftCentre, rightCentre } },
205 { kAudioChannelLayoutTag_Ambisonic_B_Format, { ambisonicW, ambisonicX, ambisonicY, ambisonicZ } },
206 { kAudioChannelLayoutTag_Quadraphonic, { left, right, leftSurround, rightSurround } },
207 { kAudioChannelLayoutTag_Pentagonal, { left, right, leftSurroundRear, rightSurroundRear, centre } },
208 { kAudioChannelLayoutTag_Hexagonal, { left, right, leftSurroundRear, rightSurroundRear, centre, centreSurround } },
209 { kAudioChannelLayoutTag_Octagonal, { left, right, leftSurround, rightSurround, centre, centreSurround, wideLeft, wideRight } },
210
211 // more uncommon layouts
212 { kAudioChannelLayoutTag_StereoHeadphones, { left, right } },
213 { kAudioChannelLayoutTag_MatrixStereo, { left, right } },
214 { kAudioChannelLayoutTag_MidSide, { centre, discreteChannel0 } },
215 { kAudioChannelLayoutTag_XY, { ambisonicX, ambisonicY } },
216 { kAudioChannelLayoutTag_Binaural, { left, right } },
217 { kAudioChannelLayoutTag_Cube, { left, right, leftSurround, rightSurround, topFrontLeft, topFrontRight, topRearLeft, topRearRight } },
218 { kAudioChannelLayoutTag_MPEG_3_0_B, { centre, left, right } },
219 { kAudioChannelLayoutTag_MPEG_4_0_B, { centre, left, right, centreSurround } },
220 { kAudioChannelLayoutTag_MPEG_5_0_B, { left, right, leftSurround, rightSurround, centre } },
221 { kAudioChannelLayoutTag_MPEG_5_0_C, { left, centre, right, leftSurround, rightSurround } },
222 { kAudioChannelLayoutTag_MPEG_5_0_D, { centre, left, right, leftSurround, rightSurround } },
223 { kAudioChannelLayoutTag_MPEG_5_1_B, { left, right, leftSurround, rightSurround, centre, LFE } },
224 { kAudioChannelLayoutTag_MPEG_5_1_C, { left, centre, right, leftSurround, rightSurround, LFE } },
225 { kAudioChannelLayoutTag_MPEG_5_1_D, { centre, left, right, leftSurround, rightSurround, LFE } },
226 { kAudioChannelLayoutTag_MPEG_7_1_B, { centre, leftCentre, rightCentre, left, right, leftSurround, rightSurround, LFE } },
227 { kAudioChannelLayoutTag_Emagic_Default_7_1, { left, right, leftSurround, rightSurround, centre, LFE, leftCentre, rightCentre } },
228 { kAudioChannelLayoutTag_SMPTE_DTV, { left, right, centre, LFE, leftSurround, rightSurround, discreteChannel0 /* leftMatrixTotal */, (ChannelType) (discreteChannel0 + 1) /* rightMatrixTotal */} },
229 { kAudioChannelLayoutTag_ITU_2_2, { left, right, leftSurround, rightSurround } },
230 { kAudioChannelLayoutTag_DVD_4, { left, right, LFE } },
231 { kAudioChannelLayoutTag_DVD_5, { left, right, LFE, centreSurround } },
232 { kAudioChannelLayoutTag_DVD_6, { left, right, LFE, leftSurround, rightSurround } },
233 { kAudioChannelLayoutTag_DVD_10, { left, right, centre, LFE } },
234 { kAudioChannelLayoutTag_DVD_11, { left, right, centre, LFE, centreSurround } },
235 { kAudioChannelLayoutTag_DVD_18, { left, right, leftSurround, rightSurround, LFE } },
236 { kAudioChannelLayoutTag_AAC_6_0, { centre, left, right, leftSurround, rightSurround, centreSurround } },
237 { kAudioChannelLayoutTag_AAC_6_1, { centre, left, right, leftSurround, rightSurround, centreSurround, LFE } },
238 { kAudioChannelLayoutTag_AAC_7_0, { centre, left, right, leftSurround, rightSurround, leftSurroundRear, rightSurroundRear } },
239 { kAudioChannelLayoutTag_AAC_7_1_B, { centre, left, right, leftSurround, rightSurround, leftSurroundRear, rightSurroundRear, LFE } },
240 { kAudioChannelLayoutTag_AAC_7_1_C, { centre, left, right, leftSurround, rightSurround, LFE, topFrontLeft, topFrontRight } },
241 { kAudioChannelLayoutTag_AAC_Octagonal, { centre, left, right, leftSurround, rightSurround, leftSurroundRear, rightSurroundRear, centreSurround } },
242 { kAudioChannelLayoutTag_TMH_10_2_std, { left, right, centre, topFrontCentre, leftSurroundSide, rightSurroundSide, leftSurround, rightSurround, topFrontLeft, topFrontRight, wideLeft, wideRight, topRearCentre, centreSurround, LFE, LFE2 } },
243 { kAudioChannelLayoutTag_AC3_1_0_1, { centre, LFE } },
244 { kAudioChannelLayoutTag_AC3_3_0, { left, centre, right } },
245 { kAudioChannelLayoutTag_AC3_3_1, { left, centre, right, centreSurround } },
246 { kAudioChannelLayoutTag_AC3_3_0_1, { left, centre, right, LFE } },
247 { kAudioChannelLayoutTag_AC3_2_1_1, { left, right, centreSurround, LFE } },
248 { kAudioChannelLayoutTag_AC3_3_1_1, { left, centre, right, centreSurround, LFE } },
249 { kAudioChannelLayoutTag_EAC_6_0_A, { left, centre, right, leftSurround, rightSurround, centreSurround } },
250 { kAudioChannelLayoutTag_EAC_7_0_A, { left, centre, right, leftSurround, rightSurround, leftSurroundRear, rightSurroundRear } },
251 { kAudioChannelLayoutTag_EAC3_6_1_A, { left, centre, right, leftSurround, rightSurround, LFE, centreSurround } },
252 { kAudioChannelLayoutTag_EAC3_6_1_B, { left, centre, right, leftSurround, rightSurround, LFE, centreSurround } },
253 { kAudioChannelLayoutTag_EAC3_6_1_C, { left, centre, right, leftSurround, rightSurround, LFE, topFrontCentre } },
254 { kAudioChannelLayoutTag_EAC3_7_1_A, { left, centre, right, leftSurround, rightSurround, LFE, leftSurroundRear, rightSurroundRear } },
255 { kAudioChannelLayoutTag_EAC3_7_1_B, { left, centre, right, leftSurround, rightSurround, LFE, leftCentre, rightCentre } },
256 { kAudioChannelLayoutTag_EAC3_7_1_C, { left, centre, right, leftSurround, rightSurround, LFE, leftSurroundSide, rightSurroundSide } },
257 { kAudioChannelLayoutTag_EAC3_7_1_D, { left, centre, right, leftSurround, rightSurround, LFE, wideLeft, wideRight } },
258 { kAudioChannelLayoutTag_EAC3_7_1_E, { left, centre, right, leftSurround, rightSurround, LFE, topFrontLeft, topFrontRight } },
259 { kAudioChannelLayoutTag_EAC3_7_1_F, { left, centre, right, leftSurround, rightSurround, LFE, centreSurround, topMiddle } },
260 { kAudioChannelLayoutTag_EAC3_7_1_G, { left, centre, right, leftSurround, rightSurround, LFE, centreSurround, topFrontCentre } },
261 { kAudioChannelLayoutTag_EAC3_7_1_H, { left, centre, right, leftSurround, rightSurround, LFE, centreSurround, topFrontCentre } },
262 { kAudioChannelLayoutTag_DTS_3_1, { centre, left, right, LFE } },
263 { kAudioChannelLayoutTag_DTS_4_1, { centre, left, right, centreSurround, LFE } },
264 { kAudioChannelLayoutTag_DTS_6_0_B, { centre, left, right, leftSurroundRear, rightSurroundRear, centreSurround } },
265 { kAudioChannelLayoutTag_DTS_6_0_C, { centre, centreSurround, left, right, leftSurroundRear, rightSurroundRear } },
266 { kAudioChannelLayoutTag_DTS_6_1_B, { centre, left, right, leftSurroundRear, rightSurroundRear, centreSurround, LFE } },
267 { kAudioChannelLayoutTag_DTS_6_1_C, { centre, centreSurround, left, right, leftSurroundRear, rightSurroundRear, LFE } },
268 { kAudioChannelLayoutTag_DTS_6_1_D, { centre, left, right, leftSurround, rightSurround, LFE, centreSurround } },
269 { kAudioChannelLayoutTag_DTS_7_0, { leftCentre, centre, rightCentre, left, right, leftSurround, rightSurround } },
270 { kAudioChannelLayoutTag_DTS_7_1, { leftCentre, centre, rightCentre, left, right, leftSurround, rightSurround, LFE } },
271 { kAudioChannelLayoutTag_DTS_8_0_A, { leftCentre, rightCentre, left, right, leftSurround, rightSurround, leftSurroundRear, rightSurroundRear } },
272 { kAudioChannelLayoutTag_DTS_8_0_B, { leftCentre, centre, rightCentre, left, right, leftSurround, centreSurround, rightSurround } },
273 { kAudioChannelLayoutTag_DTS_8_1_A, { leftCentre, rightCentre, left, right, leftSurround, rightSurround, leftSurroundRear, rightSurroundRear, LFE } },
274 { kAudioChannelLayoutTag_DTS_8_1_B, { leftCentre, centre, rightCentre, left, right, leftSurround, centreSurround, rightSurround, LFE } },
275 { 0, {} }
276 };
277
278 return tbl;
279 }
280 };
281
282 //==============================================================================
284 {
286 {
289 }
290
291 switch (label)
292 {
323 default: return AudioChannelSet::unknown;
324 }
325 }
326};
327
328#endif
329
330} // namespace juce
int size() const noexcept
Returns the current number of elements in the array.
Definition juce_Array.h:219
Array()=default
Creates an empty array.
void add(const ElementType &newElement)
Appends a new element at the end of the array.
Definition juce_Array.h:375
void set(int indexToChange, ParameterType newValue)
Replaces an element with a new value.
Definition juce_Array.h:499
bool addIfNotAlreadyThere(ParameterType newElement)
Appends a new element at the end of the array as long as the array doesn't already contain it.
Definition juce_Array.h:479
ChannelType
Represents different audio channel types.
@ wideRight
Wide Right channel.
@ topFrontRight
Top Front Right channel.
@ topFrontLeft
Top Front Left channel.
@ ambisonicW
Same as zero-th ambisonic channel number 0.
@ topRearLeft
Top Rear Left channel.
@ surround
Same as Centre Surround channel.
@ unknown
Unknown channel type.
@ rightSurroundRear
Rsr (AAX), Rcs (VST), Rrs (AU) channel.
@ rightSurroundSide
Rss (AXX), Side right "Sr" (VST), Right Centre "Rc" (AU) channel.
@ ambisonicZ
Same as first-order ambisonic channel number 2.
@ wideLeft
Wide Left channel.
@ ambisonicY
Same as first-order ambisonic channel number 1.
@ topRearCentre
Top Rear Centre channel.
@ topMiddle
Top Middle channel.
@ topFrontCentre
Top Front Centre channel.
@ topRearRight
Top Rear Right channel.
@ LFE2
Second LFE channel.
@ rightCentre
Rc (AAX/VST), Rc used as Rss in AU for most layouts.
@ leftCentre
Lc (AAX/VST), Lc used as Lss in AU for most layouts.
@ ambisonicX
Same as first-order ambisonic channel number 3.
@ leftSurroundSide
Lss (AXX), Side Left "Sl" (VST), Left Centre "LC" (AU) channel.
@ discreteChannel0
Non-typed individual channels are indexed upwards from this value.
@ leftSurroundRear
Lsr (AAX), Lcs (VST), Rls (AU) channel.
static AudioChannelSet JUCE_CALLTYPE channelSetWithChannels(const Array< ChannelType > &)
Creates a channel set for a list of channel types.
static AudioChannelSet JUCE_CALLTYPE ambisonic(int order=1)
Creates a set for ACN, SN3D normalised ambisonic surround setups with a given order.
static AudioChannelSet JUCE_CALLTYPE discreteChannels(int numChannels)
Creates a set of untyped discrete channels.
static AudioChannelSet JUCE_CALLTYPE fromWaveChannelMask(int32 dwChannelMask)
Create an AudioChannelSet from a WAVEFORMATEXTENSIBLE channelMask (typically used in ....