26#if ! DOXYGEN && (JUCE_MAC || JUCE_IOS)
28struct CoreAudioLayouts
33 coreAudioHOASN3DLayoutTag = (190U<<16) | 0
41 static AudioChannelSet fromCoreAudio (
const AudioChannelLayout& layout)
43 return AudioChannelSet::channelSetWithChannels (getCoreAudioLayoutChannels (layout));
50 static AudioChannelSet fromCoreAudio (AudioChannelLayoutTag layoutTag)
52 return AudioChannelSet::channelSetWithChannels (getSpeakerLayoutForCoreAudioTag (layoutTag));
59 static AudioChannelLayoutTag toCoreAudio (
const AudioChannelSet& set)
61 if (set.getAmbisonicOrder() >= 0)
62 return coreAudioHOASN3DLayoutTag |
static_cast<unsigned> (set.size());
64 for (
auto* tbl = SpeakerLayoutTable::get(); tbl->tag != 0; ++tbl)
66 AudioChannelSet caSet;
68 for (
int i = 0; i < numElementsInArray (tbl->channelTypes)
69 && tbl->channelTypes[i] != AudioChannelSet::unknown; ++i)
70 caSet.addChannel (tbl->channelTypes[i]);
76 return kAudioChannelLayoutTag_DiscreteInOrder |
static_cast<AudioChannelLayoutTag
> (set.size());
79 static const Array<AudioChannelLayoutTag>& getKnownCoreAudioTags()
81 static Array<AudioChannelLayoutTag> tags (createKnownCoreAudioTags());
87 static Array<AudioChannelSet::ChannelType> getCoreAudioLayoutChannels (
const AudioChannelLayout& layout)
89 switch (layout.mChannelLayoutTag & 0xffff0000)
91 case kAudioChannelLayoutTag_UseChannelBitmap:
92 return AudioChannelSet::fromWaveChannelMask (
static_cast<int> (layout.mChannelBitmap)).getChannelTypes();
93 case kAudioChannelLayoutTag_UseChannelDescriptions:
95 Array<AudioChannelSet::ChannelType> channels;
97 for (UInt32 i = 0; i < layout.mNumberChannelDescriptions; ++i)
98 channels.addIfNotAlreadyThere (getChannelTypeFromAudioChannelLabel (layout.mChannelDescriptions[i].mChannelLabel));
102 for (
int j = 0; channels.size() <
static_cast<int> (layout.mNumberChannelDescriptions); ++j)
103 channels.addIfNotAlreadyThere (
static_cast<AudioChannelSet::ChannelType
> (AudioChannelSet::discreteChannel0 + j));
107 case kAudioChannelLayoutTag_DiscreteInOrder:
108 return AudioChannelSet::discreteChannels (
static_cast<int> (layout.mChannelLayoutTag) & 0xffff).getChannelTypes();
113 return getSpeakerLayoutForCoreAudioTag (layout.mChannelLayoutTag);
116 static Array<AudioChannelSet::ChannelType> getSpeakerLayoutForCoreAudioTag (AudioChannelLayoutTag tag)
120 jassert (tag != kAudioChannelLayoutTag_UseChannelBitmap && tag != kAudioChannelLayoutTag_UseChannelDescriptions);
122 Array<AudioChannelSet::ChannelType> speakers;
124 for (
auto* tbl = SpeakerLayoutTable::get(); tbl->tag != 0; ++tbl)
128 for (
int i = 0; i < numElementsInArray (tbl->channelTypes)
129 && tbl->channelTypes[i] != AudioChannelSet::unknown; ++i)
130 speakers.add (tbl->channelTypes[i]);
136 auto numChannels = tag & 0xffff;
137 if (tag >= coreAudioHOASN3DLayoutTag && tag <= (coreAudioHOASN3DLayoutTag | 0xffff))
139 auto sqrtMinusOne = std::sqrt (
static_cast<float> (numChannels)) - 1.0f;
140 auto ambisonicOrder = jmax (0,
static_cast<int> (std::floor (sqrtMinusOne)));
142 if (
static_cast<float> (ambisonicOrder) == sqrtMinusOne)
143 return AudioChannelSet::ambisonic (ambisonicOrder).getChannelTypes();
146 for (UInt32 i = 0; i < numChannels; ++i)
147 speakers.add (
static_cast<AudioChannelSet::ChannelType
> (AudioChannelSet::discreteChannel0 + i));
154 struct LayoutTagSpeakerList
156 AudioChannelLayoutTag tag;
157 AudioChannelSet::ChannelType channelTypes[16];
160 static Array<AudioChannelLayoutTag> createKnownCoreAudioTags()
162 Array<AudioChannelLayoutTag> tags;
164 for (
auto* tbl = SpeakerLayoutTable::get(); tbl->tag != 0; ++tbl)
165 tags.addIfNotAlreadyThere (tbl->tag);
167 for (
unsigned order = 0; order <= 5; ++order)
168 tags.addIfNotAlreadyThere (coreAudioHOASN3DLayoutTag | ((order + 1) * (order + 1)));
184 struct SpeakerLayoutTable : AudioChannelSet
186 static LayoutTagSpeakerList* get() noexcept
188 static LayoutTagSpeakerList tbl[] = {
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 } },
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 , (ChannelType) (discreteChannel0 + 1) } },
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 } },
283 static AudioChannelSet::ChannelType getChannelTypeFromAudioChannelLabel (AudioChannelLabel label)
noexcept
285 if (label >= kAudioChannelLabel_Discrete_0 && label <= kAudioChannelLabel_Discrete_65535)
287 const unsigned int discreteChannelNum = label - kAudioChannelLabel_Discrete_0;
288 return static_cast<AudioChannelSet::ChannelType
> (AudioChannelSet::discreteChannel0 + discreteChannelNum);
293 case kAudioChannelLabel_Center:
294 case kAudioChannelLabel_Mono:
return AudioChannelSet::centre;
295 case kAudioChannelLabel_Left:
296 case kAudioChannelLabel_HeadphonesLeft:
return AudioChannelSet::left;
297 case kAudioChannelLabel_Right:
298 case kAudioChannelLabel_HeadphonesRight:
return AudioChannelSet::right;
299 case kAudioChannelLabel_LFEScreen:
return AudioChannelSet::LFE;
300 case kAudioChannelLabel_LeftSurround:
return AudioChannelSet::leftSurround;
301 case kAudioChannelLabel_RightSurround:
return AudioChannelSet::rightSurround;
302 case kAudioChannelLabel_LeftCenter:
return AudioChannelSet::leftCentre;
303 case kAudioChannelLabel_RightCenter:
return AudioChannelSet::rightCentre;
304 case kAudioChannelLabel_CenterSurround:
return AudioChannelSet::surround;
305 case kAudioChannelLabel_LeftSurroundDirect:
return AudioChannelSet::leftSurroundSide;
306 case kAudioChannelLabel_RightSurroundDirect:
return AudioChannelSet::rightSurroundSide;
307 case kAudioChannelLabel_TopCenterSurround:
return AudioChannelSet::topMiddle;
308 case kAudioChannelLabel_VerticalHeightLeft:
return AudioChannelSet::topFrontLeft;
309 case kAudioChannelLabel_VerticalHeightRight:
return AudioChannelSet::topFrontRight;
310 case kAudioChannelLabel_VerticalHeightCenter:
return AudioChannelSet::topFrontCentre;
311 case kAudioChannelLabel_TopBackLeft:
return AudioChannelSet::topRearLeft;
312 case kAudioChannelLabel_RearSurroundLeft:
return AudioChannelSet::leftSurroundRear;
313 case kAudioChannelLabel_TopBackRight:
return AudioChannelSet::topRearRight;
314 case kAudioChannelLabel_RearSurroundRight:
return AudioChannelSet::rightSurroundRear;
315 case kAudioChannelLabel_TopBackCenter:
return AudioChannelSet::topRearCentre;
316 case kAudioChannelLabel_LFE2:
return AudioChannelSet::LFE2;
317 case kAudioChannelLabel_LeftWide:
return AudioChannelSet::wideLeft;
318 case kAudioChannelLabel_RightWide:
return AudioChannelSet::wideRight;
319 case kAudioChannelLabel_Ambisonic_W:
return AudioChannelSet::ambisonicW;
320 case kAudioChannelLabel_Ambisonic_X:
return AudioChannelSet::ambisonicX;
321 case kAudioChannelLabel_Ambisonic_Y:
return AudioChannelSet::ambisonicY;
322 case kAudioChannelLabel_Ambisonic_Z:
return AudioChannelSet::ambisonicZ;
323 default:
return AudioChannelSet::unknown;