27 #if JUCE_MAC || JUCE_IOS
29 #include "../../juce_audio_basics/native/juce_mac_CoreAudioLayouts.h"
37 const char*
const coreAudioFormatName =
"CoreAudio supported file";
39 StringArray findFileExtensionsForCoreAudioCodecs()
41 StringArray extensionsArray;
42 CFArrayRef extensions =
nullptr;
43 UInt32 sizeOfArray =
sizeof (extensions);
45 if (AudioFileGetGlobalInfo (kAudioFileGlobalInfo_AllExtensions, 0,
nullptr, &sizeOfArray, &extensions) == noErr)
47 auto numValues = CFArrayGetCount (extensions);
49 for (CFIndex i = 0; i < numValues; ++i)
50 extensionsArray.add (
"." +
String::fromCFString ((CFStringRef) CFArrayGetValueAtIndex (extensions, i)));
52 CFRelease (extensions);
55 return extensionsArray;
115 uint32 bytesPerPacket;
116 uint32 framesPerPacket;
117 uint32 channelsPerFrame;
118 uint32 bitsPerChannel;
128 input.
read (uuid,
sizeof (uuid));
130 if (memcmp (uuid,
"\x29\x81\x92\x73\xB5\xBF\x4A\xEF\xB7\x8D\x62\xD1\xEF\x90\xBB\x2C", 16) == 0)
134 for (uint32 i = 0; i < numEntries && input.
getPosition() < originalPosition + size; ++i)
146 static StringPairArray parseMidiChunk (InputStream& input, int64 size)
148 auto originalPosition = input.getPosition();
150 MemoryBlock midiBlock;
151 input.readIntoMemoryBlock (midiBlock, (ssize_t) size);
152 MemoryInputStream midiInputStream (midiBlock,
false);
154 StringPairArray midiMetadata;
157 if (midiFile.readFrom (midiInputStream))
161 findTempoEvents (midiFile, midiMetadata);
162 findTimeSigEvents (midiFile, midiMetadata);
163 findKeySigEvents (midiFile, midiMetadata);
166 input.setPosition (originalPosition + size);
170 static void findTempoEvents (MidiFile& midiFile, StringPairArray& midiMetadata)
172 MidiMessageSequence tempoEvents;
173 midiFile.findAllTempoEvents (tempoEvents);
175 auto numTempoEvents = tempoEvents.getNumEvents();
176 MemoryOutputStream tempoSequence;
178 for (
int i = 0; i < numTempoEvents; ++i)
180 auto tempo = getTempoFromTempoMetaEvent (tempoEvents.getEventPointer (i));
187 if (numTempoEvents > 1)
188 tempoSequence << String (tempo) <<
',' << tempoEvents.getEventTime (i) <<
';';
192 if (tempoSequence.getDataSize() > 0)
193 midiMetadata.set (
"tempo sequence", tempoSequence.toUTF8());
196 static double getTempoFromTempoMetaEvent (MidiMessageSequence::MidiEventHolder* holder)
198 if (holder !=
nullptr)
200 auto& midiMessage = holder->message;
202 if (midiMessage.isTempoMetaEvent())
204 auto tempoSecondsPerQuarterNote = midiMessage.getTempoSecondsPerQuarterNote();
206 if (tempoSecondsPerQuarterNote > 0.0)
207 return 60.0 / tempoSecondsPerQuarterNote;
214 static void findTimeSigEvents (MidiFile& midiFile, StringPairArray& midiMetadata)
216 MidiMessageSequence timeSigEvents;
217 midiFile.findAllTimeSigEvents (timeSigEvents);
218 auto numTimeSigEvents = timeSigEvents.getNumEvents();
220 MemoryOutputStream timeSigSequence;
222 for (
int i = 0; i < numTimeSigEvents; ++i)
224 int numerator, denominator;
225 timeSigEvents.getEventPointer(i)->message.getTimeSignatureInfo (numerator, denominator);
227 String timeSigString;
228 timeSigString << numerator <<
'/' << denominator;
233 if (numTimeSigEvents > 1)
234 timeSigSequence << timeSigString <<
',' << timeSigEvents.getEventTime (i) <<
';';
237 if (timeSigSequence.getDataSize() > 0)
238 midiMetadata.set (
"time signature sequence", timeSigSequence.toUTF8());
241 static void findKeySigEvents (MidiFile& midiFile, StringPairArray& midiMetadata)
243 MidiMessageSequence keySigEvents;
244 midiFile.findAllKeySigEvents (keySigEvents);
245 auto numKeySigEvents = keySigEvents.getNumEvents();
247 MemoryOutputStream keySigSequence;
249 for (
int i = 0; i < numKeySigEvents; ++i)
251 auto& message (keySigEvents.getEventPointer (i)->message);
252 auto key = jlimit (0, 14, message.getKeySignatureNumberOfSharpsOrFlats() + 7);
253 bool isMajor = message.isKeySignatureMajorKey();
255 static const char* majorKeys[] = {
"Cb",
"Gb",
"Db",
"Ab",
"Eb",
"Bb",
"F",
"C",
"G",
"D",
"A",
"E",
"B",
"F#",
"C#" };
256 static const char* minorKeys[] = {
"Ab",
"Eb",
"Bb",
"F",
"C",
"G",
"D",
"A",
"E",
"B",
"F#",
"C#",
"G#",
"D#",
"A#" };
258 String keySigString (isMajor ? majorKeys[key]
267 if (numKeySigEvents > 1)
268 keySigSequence << keySigString <<
',' << keySigEvents.getEventTime (i) <<
';';
271 if (keySigSequence.getDataSize() > 0)
272 midiMetadata.set (
"key signature sequence", keySigSequence.toUTF8());
276 static StringPairArray parseInformationChunk (InputStream& input)
278 StringPairArray infoStrings;
279 auto numEntries = (uint32) input.readIntBigEndian();
281 for (uint32 i = 0; i < numEntries; ++i)
282 infoStrings.
set (input.readString(), input.readString());
288 static bool read (InputStream& input, StringPairArray& metadataValues)
290 auto originalPos = input.getPosition();
292 const FileHeader cafFileHeader (input);
293 const bool isCafFile = cafFileHeader.fileType == chunkName (
"caff");
297 while (! input.isExhausted())
299 const ChunkHeader chunkHeader (input);
301 if (chunkHeader.chunkType == chunkName (
"desc"))
303 AudioDescriptionChunk audioDescriptionChunk (input);
305 else if (chunkHeader.chunkType == chunkName (
"uuid"))
307 metadataValues.addArray (parseUserDefinedChunk (input, chunkHeader.chunkSize));
309 else if (chunkHeader.chunkType == chunkName (
"data"))
314 if (chunkHeader.chunkSize == -1)
317 input.setPosition (input.getPosition() + chunkHeader.chunkSize);
319 else if (chunkHeader.chunkType == chunkName (
"midi"))
321 metadataValues.addArray (parseMidiChunk (input, chunkHeader.chunkSize));
323 else if (chunkHeader.chunkType == chunkName (
"info"))
325 metadataValues.addArray (parseInformationChunk (input));
330 input.setPosition (input.getPosition() + chunkHeader.chunkSize);
335 input.setPosition (originalPos);
350 if (
input !=
nullptr)
353 auto status = AudioFileOpenWithCallbacks (
this,
362 status = ExtAudioFileWrapAudioFileID (audioFileID,
false, &audioFileRef);
366 AudioStreamBasicDescription sourceAudioFormat;
367 UInt32 audioStreamBasicDescriptionSize =
sizeof (AudioStreamBasicDescription);
368 ExtAudioFileGetProperty (audioFileRef,
369 kExtAudioFileProperty_FileDataFormat,
370 &audioStreamBasicDescriptionSize,
376 UInt32 sizeOfLengthProperty =
sizeof (int64);
377 ExtAudioFileGetProperty (audioFileRef,
378 kExtAudioFileProperty_FileLengthFrames,
379 &sizeOfLengthProperty,
383 bool hasLayout =
false;
384 UInt32 sizeOfLayout = 0, isWritable = 0;
386 status = AudioFileGetPropertyInfo (audioFileID, kAudioFilePropertyChannelLayout, &sizeOfLayout, &isWritable);
388 if (status == noErr && sizeOfLayout >= (
sizeof (AudioChannelLayout) -
sizeof (AudioChannelDescription)))
390 caLayout.
malloc (1,
static_cast<size_t> (sizeOfLayout));
392 status = AudioFileGetProperty (audioFileID, kAudioFilePropertyChannelLayout,
393 &sizeOfLayout, caLayout.
get());
397 auto fileLayout = CoreAudioLayouts::fromCoreAudio (*caLayout.
get());
399 if (fileLayout.size() ==
static_cast<int> (
numChannels))
402 channelSet = fileLayout;
407 destinationAudioFormat.mSampleRate =
sampleRate;
408 destinationAudioFormat.mFormatID = kAudioFormatLinearPCM;
409 destinationAudioFormat.mFormatFlags = kLinearPCMFormatFlagIsFloat | kLinearPCMFormatFlagIsNonInterleaved | kAudioFormatFlagsNativeEndian;
410 destinationAudioFormat.mBitsPerChannel =
sizeof (float) * 8;
411 destinationAudioFormat.mChannelsPerFrame =
numChannels;
412 destinationAudioFormat.mBytesPerFrame =
sizeof (float);
413 destinationAudioFormat.mFramesPerPacket = 1;
414 destinationAudioFormat.mBytesPerPacket = destinationAudioFormat.mFramesPerPacket * destinationAudioFormat.mBytesPerFrame;
416 status = ExtAudioFileSetProperty (audioFileRef,
417 kExtAudioFileProperty_ClientDataFormat,
418 sizeof (AudioStreamBasicDescription),
419 &destinationAudioFormat);
426 if (hasLayout && caLayout !=
nullptr)
428 auto caOrder = CoreAudioLayouts::getCoreAudioLayoutChannels (*caLayout);
430 for (
int i = 0; i < static_cast<int> (
numChannels); ++i)
433 jassert (isPositiveAndBelow (idx,
static_cast<int> (
numChannels)));
440 for (
int i = 0; i < static_cast<int> (
numChannels); ++i)
452 ExtAudioFileDispose (audioFileRef);
453 AudioFileClose (audioFileID);
457 bool readSamples (
int** destSamples,
int numDestChannels,
int startOffsetInDestBuffer,
458 int64 startSampleInFile,
int numSamples)
override
466 if (lastReadPosition != startSampleInFile)
468 OSStatus status = ExtAudioFileSeek (audioFileRef, startSampleInFile);
472 lastReadPosition = startSampleInFile;
475 while (numSamples > 0)
477 auto numThisTime = jmin (8192, numSamples);
478 auto numBytes =
sizeof (float) * (
size_t) numThisTime;
481 auto* data =
static_cast<float*
> (audioDataBlock.
getData());
485 bufferList->mBuffers[j].mNumberChannels = 1;
486 bufferList->mBuffers[j].mDataByteSize = (UInt32) numBytes;
487 bufferList->mBuffers[j].mData = data;
491 auto numFramesToRead = (UInt32) numThisTime;
492 auto status = ExtAudioFileRead (audioFileRef, &numFramesToRead, bufferList);
497 for (
int i = numDestChannels; --i >= 0;)
499 auto* dest = destSamples[(i < (int)
numChannels ? channelMap[i] : i)];
504 memcpy (dest + startOffsetInDestBuffer, bufferList->mBuffers[i].mData, numBytes);
506 zeromem (dest + startOffsetInDestBuffer, numBytes);
510 startOffsetInDestBuffer += numThisTime;
511 numSamples -= numThisTime;
512 lastReadPosition += numThisTime;
529 AudioFileID audioFileID;
530 ExtAudioFileRef audioFileRef;
532 AudioStreamBasicDescription destinationAudioFormat;
535 int64 lastReadPosition = 0;
538 static SInt64 getSizeCallback (
void* inClientData)
543 static OSStatus readCallback (
void* inClientData, SInt64 inPosition, UInt32 requestCount,
544 void* buffer, UInt32* actualCount)
546 auto* reader =
static_cast<CoreAudioReader*
> (inClientData);
547 reader->input->setPosition (inPosition);
548 *actualCount = (UInt32) reader->input->read (buffer, (
int) requestCount);
552 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CoreAudioReader)
557 :
AudioFormat (coreAudioFormatName, findFileExtensionsForCoreAudioCodecs())
571 bool deleteStreamIfOpeningFails)
573 std::unique_ptr<CoreAudioReader> r (
new CoreAudioReader (sourceStream));
578 if (! deleteStreamIfOpeningFails)
600 #define DEFINE_CHANNEL_LAYOUT_DFL_ENTRY(x) CoreAudioChannelLayoutTag { x, #x, AudioChannelSet() }
601 #define DEFINE_CHANNEL_LAYOUT_TAG_ENTRY(x, y) CoreAudioChannelLayoutTag { x, #x, y }
603 class CoreAudioLayoutsUnitTest :
public UnitTest
606 CoreAudioLayoutsUnitTest() :
UnitTest (
"Core Audio Layout <-> JUCE channel layout conversion",
"Audio") {}
611 kAudioChannelLayoutTag_HOA_ACN_SN3D_0Order = (190U<<16) | 1,
612 kAudioChannelLayoutTag_HOA_ACN_SN3D_1Order = (190U<<16) | 4,
613 kAudioChannelLayoutTag_HOA_ACN_SN3D_2Order = (190U<<16) | 9,
614 kAudioChannelLayoutTag_HOA_ACN_SN3D_3Order = (190U<<16) | 16,
615 kAudioChannelLayoutTag_HOA_ACN_SN3D_4Order = (190U<<16) | 25,
616 kAudioChannelLayoutTag_HOA_ACN_SN3D_5Order = (190U<<16) | 36
619 void runTest()
override
621 auto& knownTags = getAllKnownLayoutTags();
627 beginTest (
"All CA tags handled");
629 for (
auto tagEntry : knownTags)
631 auto labels = CoreAudioLayouts::fromCoreAudio (tagEntry.tag);
633 expect (! labels.isDiscreteLayout(),
"Tag \"" + String (tagEntry.name) +
"\" is not handled by JUCE");
638 beginTest (
"Number of speakers");
640 for (
auto tagEntry : knownTags)
642 auto labels = CoreAudioLayouts::getSpeakerLayoutForCoreAudioTag (tagEntry.tag);
644 expect (labels.size() == (tagEntry.tag & 0xffff),
"Tag \"" + String (tagEntry.name) +
"\" has incorrect channel count");
649 beginTest (
"No duplicate speaker");
651 for (
auto tagEntry : knownTags)
653 auto labels = CoreAudioLayouts::getSpeakerLayoutForCoreAudioTag (tagEntry.tag);
656 for (
int i = 0; i < (labels.size() - 1); ++i)
657 expect (labels.getReference (i) != labels.getReference (i + 1),
658 "Tag \"" + String (tagEntry.name) +
"\" has the same speaker twice");
663 beginTest (
"CA speaker list and juce layouts are consistent");
665 for (
auto tagEntry : knownTags)
667 == CoreAudioLayouts::fromCoreAudio (tagEntry.tag),
668 "Tag \"" + String (tagEntry.name) +
"\" is not converted consistently by JUCE");
672 beginTest (
"AudioChannelSet documentation is correct");
674 for (
auto tagEntry : knownTags)
676 if (tagEntry.equivalentChannelSet.isDisabled())
679 expect (CoreAudioLayouts::fromCoreAudio (tagEntry.tag) == tagEntry.equivalentChannelSet,
680 "Documentation for tag \"" + String (tagEntry.name) +
"\" is incorrect");
685 beginTest (
"CA tag reverse conversion");
687 for (
auto tagEntry : knownTags)
689 if (tagEntry.equivalentChannelSet.isDisabled())
692 expect (CoreAudioLayouts::toCoreAudio (tagEntry.equivalentChannelSet) == tagEntry.tag,
693 "Incorrect reverse conversion for tag \"" + String (tagEntry.name) +
"\"");
699 struct CoreAudioChannelLayoutTag
701 AudioChannelLayoutTag tag;
703 AudioChannelSet equivalentChannelSet;
707 const Array<CoreAudioChannelLayoutTag>& getAllKnownLayoutTags()
const
709 static CoreAudioChannelLayoutTag tags[] = {
712 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_StereoHeadphones),
713 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MatrixStereo),
714 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MidSide),
715 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_XY),
716 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_Binaural),
717 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_Ambisonic_B_Format),
722 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_Cube),
723 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MPEG_1_0),
724 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MPEG_2_0),
726 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MPEG_3_0_B),
728 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MPEG_4_0_B),
730 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MPEG_5_0_B),
731 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MPEG_5_0_C),
732 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MPEG_5_0_D),
734 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MPEG_5_1_B),
735 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MPEG_5_1_C),
736 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MPEG_5_1_D),
739 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MPEG_7_1_B),
741 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_Emagic_Default_7_1),
742 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_SMPTE_DTV),
743 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_ITU_1_0),
744 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_ITU_2_0),
746 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_ITU_2_2),
747 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_ITU_3_0),
748 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_ITU_3_1),
749 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_ITU_3_2),
750 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_ITU_3_2_1),
751 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_ITU_3_4_1),
752 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_0),
753 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_1),
754 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_2),
755 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_3),
756 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_4),
757 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_5),
758 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_6),
759 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_7),
760 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_8),
761 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_9),
762 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_10),
763 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_11),
764 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_12),
765 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_13),
766 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_14),
767 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_15),
768 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_16),
769 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_17),
770 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_18),
771 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_19),
772 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_20),
773 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AudioUnit_4),
774 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AudioUnit_5),
775 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AudioUnit_6),
776 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AudioUnit_8),
777 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AudioUnit_5_0),
781 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AudioUnit_5_1),
782 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AudioUnit_6_1),
783 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AudioUnit_7_1),
784 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AudioUnit_7_1_Front),
785 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AAC_3_0),
786 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AAC_Quadraphonic),
787 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AAC_4_0),
788 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AAC_5_0),
789 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AAC_5_1),
790 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AAC_6_0),
791 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AAC_6_1),
792 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AAC_7_0),
793 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AAC_7_1),
794 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AAC_7_1_B),
795 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AAC_7_1_C),
796 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AAC_Octagonal),
797 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_TMH_10_2_std),
799 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AC3_1_0_1),
800 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AC3_3_0),
801 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AC3_3_1),
802 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AC3_3_0_1),
803 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AC3_2_1_1),
804 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AC3_3_1_1),
805 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_EAC_6_0_A),
806 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_EAC_7_0_A),
807 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_EAC3_6_1_A),
808 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_EAC3_6_1_B),
809 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_EAC3_6_1_C),
810 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_EAC3_7_1_A),
811 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_EAC3_7_1_B),
812 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_EAC3_7_1_C),
813 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_EAC3_7_1_D),
814 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_EAC3_7_1_E),
815 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_EAC3_7_1_F),
816 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_EAC3_7_1_G),
817 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_EAC3_7_1_H),
818 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_3_1),
819 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_4_1),
821 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_6_0_B),
822 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_6_0_C),
824 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_6_1_B),
825 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_6_1_C),
826 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_7_0),
827 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_7_1),
828 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_8_0_A),
829 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_8_0_B),
830 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_8_1_A),
831 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_8_1_B),
832 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_6_1_D),
833 DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_6_1_D),
841 static Array<CoreAudioChannelLayoutTag> knownTags (tags,
sizeof (tags) /
sizeof (CoreAudioChannelLayoutTag));
847 static CoreAudioLayoutsUnitTest coreAudioLayoutsUnitTest;