OpenShot Library | libopenshot-audio  0.2.0
juce_CoreAudioFormat.cpp
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  By using JUCE, you agree to the terms of both the JUCE 5 End-User License
11  Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
12  27th April 2017).
13 
14  End User License Agreement: www.juce.com/juce-5-licence
15  Privacy Policy: www.juce.com/juce-5-privacy-policy
16 
17  Or: You may also use this code under the terms of the GPL v3 (see
18  www.gnu.org/licenses).
19 
20  JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
21  EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
22  DISCLAIMED.
23 
24  ==============================================================================
25 */
26 
27 #if JUCE_MAC || JUCE_IOS
28 
29 #include "../../juce_audio_basics/native/juce_mac_CoreAudioLayouts.h"
30 
31 namespace juce
32 {
33 
34 //==============================================================================
35 namespace
36 {
37  const char* const coreAudioFormatName = "CoreAudio supported file";
38 
39  StringArray findFileExtensionsForCoreAudioCodecs()
40  {
41  StringArray extensionsArray;
42  CFArrayRef extensions = nullptr;
43  UInt32 sizeOfArray = sizeof (extensions);
44 
45  if (AudioFileGetGlobalInfo (kAudioFileGlobalInfo_AllExtensions, 0, nullptr, &sizeOfArray, &extensions) == noErr)
46  {
47  auto numValues = CFArrayGetCount (extensions);
48 
49  for (CFIndex i = 0; i < numValues; ++i)
50  extensionsArray.add ("." + String::fromCFString ((CFStringRef) CFArrayGetValueAtIndex (extensions, i)));
51 
52  CFRelease (extensions);
53  }
54 
55  return extensionsArray;
56  }
57 }
58 
59 //==============================================================================
60 const char* const CoreAudioFormat::midiDataBase64 = "midiDataBase64";
61 const char* const CoreAudioFormat::tempo = "tempo";
62 const char* const CoreAudioFormat::timeSig = "time signature";
63 const char* const CoreAudioFormat::keySig = "key signature";
64 
65 //==============================================================================
67 {
68  static uint32 chunkName (const char* const name) noexcept { return ByteOrder::bigEndianInt (name); }
69 
70  //==============================================================================
71  struct FileHeader
72  {
73  FileHeader (InputStream& input)
74  {
75  fileType = (uint32) input.readIntBigEndian();
76  fileVersion = (uint16) input.readShortBigEndian();
77  fileFlags = (uint16) input.readShortBigEndian();
78  }
79 
80  uint32 fileType;
81  uint16 fileVersion;
82  uint16 fileFlags;
83  };
84 
85  //==============================================================================
86  struct ChunkHeader
87  {
88  ChunkHeader (InputStream& input)
89  {
90  chunkType = (uint32) input.readIntBigEndian();
91  chunkSize = (int64) input.readInt64BigEndian();
92  }
93 
94  uint32 chunkType;
95  int64 chunkSize;
96  };
97 
98  //==============================================================================
100  {
102  {
103  sampleRate = input.readDoubleBigEndian();
104  formatID = (uint32) input.readIntBigEndian();
105  formatFlags = (uint32) input.readIntBigEndian();
106  bytesPerPacket = (uint32) input.readIntBigEndian();
107  framesPerPacket = (uint32) input.readIntBigEndian();
108  channelsPerFrame = (uint32) input.readIntBigEndian();
109  bitsPerChannel = (uint32) input.readIntBigEndian();
110  }
111 
112  double sampleRate;
113  uint32 formatID;
114  uint32 formatFlags;
115  uint32 bytesPerPacket;
116  uint32 framesPerPacket;
117  uint32 channelsPerFrame;
118  uint32 bitsPerChannel;
119  };
120 
121  //==============================================================================
122  static StringPairArray parseUserDefinedChunk (InputStream& input, int64 size)
123  {
124  StringPairArray infoStrings;
125  auto originalPosition = input.getPosition();
126 
127  uint8 uuid[16];
128  input.read (uuid, sizeof (uuid));
129 
130  if (memcmp (uuid, "\x29\x81\x92\x73\xB5\xBF\x4A\xEF\xB7\x8D\x62\xD1\xEF\x90\xBB\x2C", 16) == 0)
131  {
132  auto numEntries = (uint32) input.readIntBigEndian();
133 
134  for (uint32 i = 0; i < numEntries && input.getPosition() < originalPosition + size; ++i)
135  {
136  String keyName = input.readString();
137  infoStrings.set (keyName, input.readString());
138  }
139  }
140 
141  input.setPosition (originalPosition + size);
142  return infoStrings;
143  }
144 
145  //==============================================================================
146  static StringPairArray parseMidiChunk (InputStream& input, int64 size)
147  {
148  auto originalPosition = input.getPosition();
149 
150  MemoryBlock midiBlock;
151  input.readIntoMemoryBlock (midiBlock, (ssize_t) size);
152  MemoryInputStream midiInputStream (midiBlock, false);
153 
154  StringPairArray midiMetadata;
155  MidiFile midiFile;
156 
157  if (midiFile.readFrom (midiInputStream))
158  {
159  midiMetadata.set (CoreAudioFormat::midiDataBase64, midiBlock.toBase64Encoding());
160 
161  findTempoEvents (midiFile, midiMetadata);
162  findTimeSigEvents (midiFile, midiMetadata);
163  findKeySigEvents (midiFile, midiMetadata);
164  }
165 
166  input.setPosition (originalPosition + size);
167  return midiMetadata;
168  }
169 
170  static void findTempoEvents (MidiFile& midiFile, StringPairArray& midiMetadata)
171  {
172  MidiMessageSequence tempoEvents;
173  midiFile.findAllTempoEvents (tempoEvents);
174 
175  auto numTempoEvents = tempoEvents.getNumEvents();
176  MemoryOutputStream tempoSequence;
177 
178  for (int i = 0; i < numTempoEvents; ++i)
179  {
180  auto tempo = getTempoFromTempoMetaEvent (tempoEvents.getEventPointer (i));
181 
182  if (tempo > 0.0)
183  {
184  if (i == 0)
185  midiMetadata.set (CoreAudioFormat::tempo, String (tempo));
186 
187  if (numTempoEvents > 1)
188  tempoSequence << String (tempo) << ',' << tempoEvents.getEventTime (i) << ';';
189  }
190  }
191 
192  if (tempoSequence.getDataSize() > 0)
193  midiMetadata.set ("tempo sequence", tempoSequence.toUTF8());
194  }
195 
196  static double getTempoFromTempoMetaEvent (MidiMessageSequence::MidiEventHolder* holder)
197  {
198  if (holder != nullptr)
199  {
200  auto& midiMessage = holder->message;
201 
202  if (midiMessage.isTempoMetaEvent())
203  {
204  auto tempoSecondsPerQuarterNote = midiMessage.getTempoSecondsPerQuarterNote();
205 
206  if (tempoSecondsPerQuarterNote > 0.0)
207  return 60.0 / tempoSecondsPerQuarterNote;
208  }
209  }
210 
211  return 0.0;
212  }
213 
214  static void findTimeSigEvents (MidiFile& midiFile, StringPairArray& midiMetadata)
215  {
216  MidiMessageSequence timeSigEvents;
217  midiFile.findAllTimeSigEvents (timeSigEvents);
218  auto numTimeSigEvents = timeSigEvents.getNumEvents();
219 
220  MemoryOutputStream timeSigSequence;
221 
222  for (int i = 0; i < numTimeSigEvents; ++i)
223  {
224  int numerator, denominator;
225  timeSigEvents.getEventPointer(i)->message.getTimeSignatureInfo (numerator, denominator);
226 
227  String timeSigString;
228  timeSigString << numerator << '/' << denominator;
229 
230  if (i == 0)
231  midiMetadata.set (CoreAudioFormat::timeSig, timeSigString);
232 
233  if (numTimeSigEvents > 1)
234  timeSigSequence << timeSigString << ',' << timeSigEvents.getEventTime (i) << ';';
235  }
236 
237  if (timeSigSequence.getDataSize() > 0)
238  midiMetadata.set ("time signature sequence", timeSigSequence.toUTF8());
239  }
240 
241  static void findKeySigEvents (MidiFile& midiFile, StringPairArray& midiMetadata)
242  {
243  MidiMessageSequence keySigEvents;
244  midiFile.findAllKeySigEvents (keySigEvents);
245  auto numKeySigEvents = keySigEvents.getNumEvents();
246 
247  MemoryOutputStream keySigSequence;
248 
249  for (int i = 0; i < numKeySigEvents; ++i)
250  {
251  auto& message (keySigEvents.getEventPointer (i)->message);
252  auto key = jlimit (0, 14, message.getKeySignatureNumberOfSharpsOrFlats() + 7);
253  bool isMajor = message.isKeySignatureMajorKey();
254 
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#" };
257 
258  String keySigString (isMajor ? majorKeys[key]
259  : minorKeys[key]);
260 
261  if (! isMajor)
262  keySigString << 'm';
263 
264  if (i == 0)
265  midiMetadata.set (CoreAudioFormat::keySig, keySigString);
266 
267  if (numKeySigEvents > 1)
268  keySigSequence << keySigString << ',' << keySigEvents.getEventTime (i) << ';';
269  }
270 
271  if (keySigSequence.getDataSize() > 0)
272  midiMetadata.set ("key signature sequence", keySigSequence.toUTF8());
273  }
274 
275  //==============================================================================
276  static StringPairArray parseInformationChunk (InputStream& input)
277  {
278  StringPairArray infoStrings;
279  auto numEntries = (uint32) input.readIntBigEndian();
280 
281  for (uint32 i = 0; i < numEntries; ++i)
282  infoStrings.set (input.readString(), input.readString());
283 
284  return infoStrings;
285  }
286 
287  //==============================================================================
288  static bool read (InputStream& input, StringPairArray& metadataValues)
289  {
290  auto originalPos = input.getPosition();
291 
292  const FileHeader cafFileHeader (input);
293  const bool isCafFile = cafFileHeader.fileType == chunkName ("caff");
294 
295  if (isCafFile)
296  {
297  while (! input.isExhausted())
298  {
299  const ChunkHeader chunkHeader (input);
300 
301  if (chunkHeader.chunkType == chunkName ("desc"))
302  {
303  AudioDescriptionChunk audioDescriptionChunk (input);
304  }
305  else if (chunkHeader.chunkType == chunkName ("uuid"))
306  {
307  metadataValues.addArray (parseUserDefinedChunk (input, chunkHeader.chunkSize));
308  }
309  else if (chunkHeader.chunkType == chunkName ("data"))
310  {
311  // -1 signifies an unknown data size so the data has to be at the
312  // end of the file so we must have finished the header
313 
314  if (chunkHeader.chunkSize == -1)
315  break;
316 
317  input.setPosition (input.getPosition() + chunkHeader.chunkSize);
318  }
319  else if (chunkHeader.chunkType == chunkName ("midi"))
320  {
321  metadataValues.addArray (parseMidiChunk (input, chunkHeader.chunkSize));
322  }
323  else if (chunkHeader.chunkType == chunkName ("info"))
324  {
325  metadataValues.addArray (parseInformationChunk (input));
326  }
327  else
328  {
329  // we aren't decoding this chunk yet so just skip over it
330  input.setPosition (input.getPosition() + chunkHeader.chunkSize);
331  }
332  }
333  }
334 
335  input.setPosition (originalPos);
336 
337  return isCafFile;
338  }
339 };
340 
341 //==============================================================================
343 {
344 public:
345  CoreAudioReader (InputStream* inp) : AudioFormatReader (inp, coreAudioFormatName)
346  {
347  usesFloatingPointData = true;
348  bitsPerSample = 32;
349 
350  if (input != nullptr)
351  CoreAudioFormatMetatdata::read (*input, metadataValues);
352 
353  auto status = AudioFileOpenWithCallbacks (this,
354  &readCallback,
355  nullptr, // write needs to be null to avoid permisisions errors
356  &getSizeCallback,
357  nullptr, // setSize needs to be null to avoid permisisions errors
358  0, // AudioFileTypeID inFileTypeHint
359  &audioFileID);
360  if (status == noErr)
361  {
362  status = ExtAudioFileWrapAudioFileID (audioFileID, false, &audioFileRef);
363 
364  if (status == noErr)
365  {
366  AudioStreamBasicDescription sourceAudioFormat;
367  UInt32 audioStreamBasicDescriptionSize = sizeof (AudioStreamBasicDescription);
368  ExtAudioFileGetProperty (audioFileRef,
369  kExtAudioFileProperty_FileDataFormat,
370  &audioStreamBasicDescriptionSize,
371  &sourceAudioFormat);
372 
373  numChannels = sourceAudioFormat.mChannelsPerFrame;
374  sampleRate = sourceAudioFormat.mSampleRate;
375 
376  UInt32 sizeOfLengthProperty = sizeof (int64);
377  ExtAudioFileGetProperty (audioFileRef,
378  kExtAudioFileProperty_FileLengthFrames,
379  &sizeOfLengthProperty,
380  &lengthInSamples);
381 
383  bool hasLayout = false;
384  UInt32 sizeOfLayout = 0, isWritable = 0;
385 
386  status = AudioFileGetPropertyInfo (audioFileID, kAudioFilePropertyChannelLayout, &sizeOfLayout, &isWritable);
387 
388  if (status == noErr && sizeOfLayout >= (sizeof (AudioChannelLayout) - sizeof (AudioChannelDescription)))
389  {
390  caLayout.malloc (1, static_cast<size_t> (sizeOfLayout));
391 
392  status = AudioFileGetProperty (audioFileID, kAudioFilePropertyChannelLayout,
393  &sizeOfLayout, caLayout.get());
394 
395  if (status == noErr)
396  {
397  auto fileLayout = CoreAudioLayouts::fromCoreAudio (*caLayout.get());
398 
399  if (fileLayout.size() == static_cast<int> (numChannels))
400  {
401  hasLayout = true;
402  channelSet = fileLayout;
403  }
404  }
405  }
406 
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;
415 
416  status = ExtAudioFileSetProperty (audioFileRef,
417  kExtAudioFileProperty_ClientDataFormat,
418  sizeof (AudioStreamBasicDescription),
419  &destinationAudioFormat);
420  if (status == noErr)
421  {
422  bufferList.malloc (1, sizeof (AudioBufferList) + numChannels * sizeof (::AudioBuffer));
423  bufferList->mNumberBuffers = numChannels;
424  channelMap.malloc (numChannels);
425 
426  if (hasLayout && caLayout != nullptr)
427  {
428  auto caOrder = CoreAudioLayouts::getCoreAudioLayoutChannels (*caLayout);
429 
430  for (int i = 0; i < static_cast<int> (numChannels); ++i)
431  {
432  auto idx = channelSet.getChannelIndexForType (caOrder.getReference (i));
433  jassert (isPositiveAndBelow (idx, static_cast<int> (numChannels)));
434 
435  channelMap[i] = idx;
436  }
437  }
438  else
439  {
440  for (int i = 0; i < static_cast<int> (numChannels); ++i)
441  channelMap[i] = i;
442  }
443 
444  ok = true;
445  }
446  }
447  }
448  }
449 
450  ~CoreAudioReader() override
451  {
452  ExtAudioFileDispose (audioFileRef);
453  AudioFileClose (audioFileID);
454  }
455 
456  //==============================================================================
457  bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer,
458  int64 startSampleInFile, int numSamples) override
459  {
460  clearSamplesBeyondAvailableLength (destSamples, numDestChannels, startOffsetInDestBuffer,
461  startSampleInFile, numSamples, lengthInSamples);
462 
463  if (numSamples <= 0)
464  return true;
465 
466  if (lastReadPosition != startSampleInFile)
467  {
468  OSStatus status = ExtAudioFileSeek (audioFileRef, startSampleInFile);
469  if (status != noErr)
470  return false;
471 
472  lastReadPosition = startSampleInFile;
473  }
474 
475  while (numSamples > 0)
476  {
477  auto numThisTime = jmin (8192, numSamples);
478  auto numBytes = sizeof (float) * (size_t) numThisTime;
479 
480  audioDataBlock.ensureSize (numBytes * numChannels, false);
481  auto* data = static_cast<float*> (audioDataBlock.getData());
482 
483  for (int j = (int) numChannels; --j >= 0;)
484  {
485  bufferList->mBuffers[j].mNumberChannels = 1;
486  bufferList->mBuffers[j].mDataByteSize = (UInt32) numBytes;
487  bufferList->mBuffers[j].mData = data;
488  data += numThisTime;
489  }
490 
491  auto numFramesToRead = (UInt32) numThisTime;
492  auto status = ExtAudioFileRead (audioFileRef, &numFramesToRead, bufferList);
493 
494  if (status != noErr)
495  return false;
496 
497  for (int i = numDestChannels; --i >= 0;)
498  {
499  auto* dest = destSamples[(i < (int) numChannels ? channelMap[i] : i)];
500 
501  if (dest != nullptr)
502  {
503  if (i < (int) numChannels)
504  memcpy (dest + startOffsetInDestBuffer, bufferList->mBuffers[i].mData, numBytes);
505  else
506  zeromem (dest + startOffsetInDestBuffer, numBytes);
507  }
508  }
509 
510  startOffsetInDestBuffer += numThisTime;
511  numSamples -= numThisTime;
512  lastReadPosition += numThisTime;
513  }
514 
515  return true;
516  }
517 
519  {
520  if (channelSet.size() == static_cast<int> (numChannels))
521  return channelSet;
522 
524  }
525 
526  bool ok = false;
527 
528 private:
529  AudioFileID audioFileID;
530  ExtAudioFileRef audioFileRef;
531  AudioChannelSet channelSet;
532  AudioStreamBasicDescription destinationAudioFormat;
533  MemoryBlock audioDataBlock;
534  HeapBlock<AudioBufferList> bufferList;
535  int64 lastReadPosition = 0;
536  HeapBlock<int> channelMap;
537 
538  static SInt64 getSizeCallback (void* inClientData)
539  {
540  return static_cast<CoreAudioReader*> (inClientData)->input->getTotalLength();
541  }
542 
543  static OSStatus readCallback (void* inClientData, SInt64 inPosition, UInt32 requestCount,
544  void* buffer, UInt32* actualCount)
545  {
546  auto* reader = static_cast<CoreAudioReader*> (inClientData);
547  reader->input->setPosition (inPosition);
548  *actualCount = (UInt32) reader->input->read (buffer, (int) requestCount);
549  return noErr;
550  }
551 
552  JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CoreAudioReader)
553 };
554 
555 //==============================================================================
557  : AudioFormat (coreAudioFormatName, findFileExtensionsForCoreAudioCodecs())
558 {
559 }
560 
562 
565 
566 bool CoreAudioFormat::canDoStereo() { return true; }
567 bool CoreAudioFormat::canDoMono() { return true; }
568 
569 //==============================================================================
571  bool deleteStreamIfOpeningFails)
572 {
573  std::unique_ptr<CoreAudioReader> r (new CoreAudioReader (sourceStream));
574 
575  if (r->ok)
576  return r.release();
577 
578  if (! deleteStreamIfOpeningFails)
579  r->input = nullptr;
580 
581  return nullptr;
582 }
583 
585  double /*sampleRateToUse*/,
586  unsigned int /*numberOfChannels*/,
587  int /*bitsPerSample*/,
588  const StringPairArray& /*metadataValues*/,
589  int /*qualityOptionIndex*/)
590 {
591  jassertfalse; // not yet implemented!
592  return nullptr;
593 }
594 
595 //==============================================================================
596 // Unit tests for Core Audio layout conversions
597 //==============================================================================
598 #if JUCE_UNIT_TESTS
599 
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 }
602 
603 class CoreAudioLayoutsUnitTest : public UnitTest
604 {
605 public:
606  CoreAudioLayoutsUnitTest() : UnitTest ("Core Audio Layout <-> JUCE channel layout conversion", "Audio") {}
607 
608  // some ambisonic tags which are not explicitely defined
609  enum
610  {
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
617  };
618 
619  void runTest() override
620  {
621  auto& knownTags = getAllKnownLayoutTags();
622 
623  {
624  // Check that all known tags defined in CoreAudio SDK version 10.12.4 are known to JUCE
625  // Include all defined tags even if there are duplicates as Apple will sometimes change
626  // definitions
627  beginTest ("All CA tags handled");
628 
629  for (auto tagEntry : knownTags)
630  {
631  auto labels = CoreAudioLayouts::fromCoreAudio (tagEntry.tag);
632 
633  expect (! labels.isDiscreteLayout(), "Tag \"" + String (tagEntry.name) + "\" is not handled by JUCE");
634  }
635  }
636 
637  {
638  beginTest ("Number of speakers");
639 
640  for (auto tagEntry : knownTags)
641  {
642  auto labels = CoreAudioLayouts::getSpeakerLayoutForCoreAudioTag (tagEntry.tag);
643 
644  expect (labels.size() == (tagEntry.tag & 0xffff), "Tag \"" + String (tagEntry.name) + "\" has incorrect channel count");
645  }
646  }
647 
648  {
649  beginTest ("No duplicate speaker");
650 
651  for (auto tagEntry : knownTags)
652  {
653  auto labels = CoreAudioLayouts::getSpeakerLayoutForCoreAudioTag (tagEntry.tag);
654  labels.sort();
655 
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");
659  }
660  }
661 
662  {
663  beginTest ("CA speaker list and juce layouts are consistent");
664 
665  for (auto tagEntry : knownTags)
666  expect (AudioChannelSet::channelSetWithChannels (CoreAudioLayouts::getSpeakerLayoutForCoreAudioTag (tagEntry.tag))
667  == CoreAudioLayouts::fromCoreAudio (tagEntry.tag),
668  "Tag \"" + String (tagEntry.name) + "\" is not converted consistently by JUCE");
669  }
670 
671  {
672  beginTest ("AudioChannelSet documentation is correct");
673 
674  for (auto tagEntry : knownTags)
675  {
676  if (tagEntry.equivalentChannelSet.isDisabled())
677  continue;
678 
679  expect (CoreAudioLayouts::fromCoreAudio (tagEntry.tag) == tagEntry.equivalentChannelSet,
680  "Documentation for tag \"" + String (tagEntry.name) + "\" is incorrect");
681  }
682  }
683 
684  {
685  beginTest ("CA tag reverse conversion");
686 
687  for (auto tagEntry : knownTags)
688  {
689  if (tagEntry.equivalentChannelSet.isDisabled())
690  continue;
691 
692  expect (CoreAudioLayouts::toCoreAudio (tagEntry.equivalentChannelSet) == tagEntry.tag,
693  "Incorrect reverse conversion for tag \"" + String (tagEntry.name) + "\"");
694  }
695  }
696  }
697 
698 private:
699  struct CoreAudioChannelLayoutTag
700  {
701  AudioChannelLayoutTag tag;
702  const char* name;
703  AudioChannelSet equivalentChannelSet; /* referred to this in the AudioChannelSet documentation */
704  };
705 
706  //==============================================================================
707  const Array<CoreAudioChannelLayoutTag>& getAllKnownLayoutTags() const
708  {
709  static CoreAudioChannelLayoutTag tags[] = {
710  DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_Mono, AudioChannelSet::mono()),
711  DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_Stereo, AudioChannelSet::stereo()),
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),
718  DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_Quadraphonic, AudioChannelSet::quadraphonic()),
719  DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_Pentagonal, AudioChannelSet::pentagonal()),
720  DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_Hexagonal, AudioChannelSet::hexagonal()),
721  DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_Octagonal, AudioChannelSet::octagonal()),
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),
725  DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_MPEG_3_0_A, AudioChannelSet::createLCR()),
726  DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MPEG_3_0_B),
727  DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_MPEG_4_0_A, AudioChannelSet::createLCRS()),
728  DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MPEG_4_0_B),
729  DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_MPEG_5_0_A, AudioChannelSet::create5point0()),
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),
733  DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_MPEG_5_1_A, AudioChannelSet::create5point1()),
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),
737  DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_MPEG_6_1_A, AudioChannelSet::create6point1()),
738  DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_MPEG_7_1_A, AudioChannelSet::create7point1SDDS()),
739  DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MPEG_7_1_B),
740  DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_MPEG_7_1_C, AudioChannelSet::create7point1()),
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),
745  DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_ITU_2_1, AudioChannelSet::createLRS()),
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),
778  DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_AudioUnit_6_0, AudioChannelSet::create6point0()),
779  DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_AudioUnit_7_0, AudioChannelSet::create7point0()),
780  DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_AudioUnit_7_0_Front, AudioChannelSet::create7point0SDDS()),
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),
798  // DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_TMH_10_2_full), no indication on how to handle this tag
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),
820  DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_DTS_6_0_A, AudioChannelSet::create6point0Music()),
821  DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_6_0_B),
822  DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_6_0_C),
823  DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_DTS_6_1_A, AudioChannelSet::create6point1Music()),
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),
834  DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_HOA_ACN_SN3D_0Order, AudioChannelSet::ambisonic (0)),
835  DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_HOA_ACN_SN3D_1Order, AudioChannelSet::ambisonic (1)),
836  DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_HOA_ACN_SN3D_2Order, AudioChannelSet::ambisonic (2)),
837  DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_HOA_ACN_SN3D_3Order, AudioChannelSet::ambisonic (3)),
838  DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_HOA_ACN_SN3D_4Order, AudioChannelSet::ambisonic (4)),
839  DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_HOA_ACN_SN3D_5Order, AudioChannelSet::ambisonic (5))
840  };
841  static Array<CoreAudioChannelLayoutTag> knownTags (tags, sizeof (tags) / sizeof (CoreAudioChannelLayoutTag));
842 
843  return knownTags;
844  }
845 };
846 
847 static CoreAudioLayoutsUnitTest coreAudioLayoutsUnitTest;
848 
849 #endif
850 
851 } // namespace juce
852 
853 #endif
juce::AudioChannelSet::create7point0
static AudioChannelSet JUCE_CALLTYPE create7point0()
Creates a set for a DTS 7.0 surround setup (left, right, centre, leftSurroundSide,...
Definition: juce_AudioChannelSet.cpp:389
juce::CoreAudioFormatMetatdata::FileHeader
Definition: juce_CoreAudioFormat.cpp:71
juce::AudioFormatReader::sampleRate
double sampleRate
The sample-rate of the stream.
Definition: juce_AudioFormatReader.h:226
juce::CoreAudioReader::getChannelLayout
AudioChannelSet getChannelLayout() override
Get the channel layout of the audio stream.
Definition: juce_CoreAudioFormat.cpp:518
juce::AudioChannelSet::ambisonic
static AudioChannelSet JUCE_CALLTYPE ambisonic(int order=1)
Creates a set for ACN, SN3D normalised ambisonic surround setups with a given order.
Definition: juce_AudioChannelSet.cpp:400
juce::AudioFormatReader::clearSamplesBeyondAvailableLength
static void clearSamplesBeyondAvailableLength(int **destChannels, int numDestChannels, int startOffsetInDestBuffer, int64 startSampleInFile, int &numSamples, int64 fileLengthInSamples)
Used by AudioFormatReader subclasses to clear any parts of the data blocks that lie beyond the end of...
Definition: juce_AudioFormatReader.h:310
juce::MemoryBlock::getData
void * getData() const noexcept
Returns a void pointer to the data.
Definition: juce_MemoryBlock.h:95
juce::AudioChannelSet::create6point1
static AudioChannelSet JUCE_CALLTYPE create6point1()
Creates a set for a 6.1 Cine surround setup (left, right, centre, leftSurround, rightSurround,...
Definition: juce_AudioChannelSet.cpp:386
juce::HeapBlock
Very simple container class to hold a pointer to some data on the heap.
Definition: juce_HeapBlock.h:90
juce::AudioFormatReader::lengthInSamples
int64 lengthInSamples
The total number of samples in the audio stream.
Definition: juce_AudioFormatReader.h:232
juce::CoreAudioFormatMetatdata::ChunkHeader
Definition: juce_CoreAudioFormat.cpp:86
juce::AudioBuffer
A multi-channel buffer containing floating point audio samples.
Definition: juce_AudioSampleBuffer.h:37
juce::CoreAudioReader
Definition: juce_CoreAudioFormat.cpp:342
juce::AudioChannelSet::create7point1
static AudioChannelSet JUCE_CALLTYPE create7point1()
Creates a set for a DTS 7.1 surround setup (left, right, centre, leftSurroundSide,...
Definition: juce_AudioChannelSet.cpp:391
juce::AudioChannelSet::createLCR
static AudioChannelSet JUCE_CALLTYPE createLCR()
Creates a set containing an LCR set (left, right, centre).
Definition: juce_AudioChannelSet.cpp:380
juce::InputStream::readDoubleBigEndian
virtual double readDoubleBigEndian()
Reads eight bytes as a 64-bit floating point value.
Definition: juce_InputStream.cpp:155
juce::InputStream
The base class for streams that read data.
Definition: juce_InputStream.h:40
juce::InputStream::read
virtual int read(void *destBuffer, int maxBytesToRead)=0
Reads some data from the stream into a memory buffer.
juce::AudioFormat
Subclasses of AudioFormat are used to read and write different audio file formats.
Definition: juce_AudioFormat.h:43
juce::AudioChannelSet::create5point1
static AudioChannelSet JUCE_CALLTYPE create5point1()
Creates a set for a 5.1 surround setup (left, right, centre, leftSurround, rightSurround,...
Definition: juce_AudioChannelSet.cpp:384
juce::CoreAudioFormatMetatdata::AudioDescriptionChunk
Definition: juce_CoreAudioFormat.cpp:99
juce::Array< int >
juce::String::fromCFString
static String fromCFString(CFStringRef cfString)
OSX ONLY - Creates a String from an OSX CFString.
juce::AudioChannelSet::create6point1Music
static AudioChannelSet JUCE_CALLTYPE create6point1Music()
Creates a set for a 6.0 Music surround setup (left, right, leftSurround, rightSurround,...
Definition: juce_AudioChannelSet.cpp:388
juce::CoreAudioFormat::tempo
static const char *const tempo
Metadata property name used when reading a caf file with tempo information.
Definition: juce_CoreAudioFormat.h:61
juce::AudioFormatReader::getChannelLayout
virtual AudioChannelSet getChannelLayout()
Get the channel layout of the audio stream.
Definition: juce_AudioFormatReader.cpp:387
juce::AudioChannelSet::getChannelIndexForType
int getChannelIndexForType(ChannelType type) const noexcept
Returns the index for a particular channel-type.
Definition: juce_AudioChannelSet.cpp:338
juce::InputStream::getPosition
virtual int64 getPosition()=0
Returns the offset of the next byte that will be read from the stream.
juce::InputStream::setPosition
virtual bool setPosition(int64 newPosition)=0
Tries to move the current read position of the stream.
juce::AudioChannelSet::create7point0SDDS
static AudioChannelSet JUCE_CALLTYPE create7point0SDDS()
Creates a set for a SDDS 7.0 surround setup (left, right, centre, leftSurround, rightSurround,...
Definition: juce_AudioChannelSet.cpp:390
juce::CoreAudioFormat::CoreAudioFormat
CoreAudioFormat()
Creates a format object.
Definition: juce_CoreAudioFormat.cpp:556
juce::AudioChannelSet::create6point0Music
static AudioChannelSet JUCE_CALLTYPE create6point0Music()
Creates a set for a 6.0 Music surround setup (left, right, leftSurround, rightSurround,...
Definition: juce_AudioChannelSet.cpp:387
juce::OutputStream
The base class for streams that write data to some kind of destination.
Definition: juce_OutputStream.h:41
juce::AudioChannelSet::octagonal
static AudioChannelSet JUCE_CALLTYPE octagonal()
Creates a set for octagonal surround setup (left, right, leftSurround, rightSurround,...
Definition: juce_AudioChannelSet.cpp:396
juce::CoreAudioFormatMetatdata
Definition: juce_CoreAudioFormat.cpp:66
juce::AudioFormatReader::metadataValues
StringPairArray metadataValues
A set of metadata values that the reader has pulled out of the stream.
Definition: juce_AudioFormatReader.h:246
juce::MemoryBlock::ensureSize
void ensureSize(const size_t minimumSize, bool initialiseNewSpaceToZero=false)
Increases the block's size only if it's smaller than a given size.
Definition: juce_MemoryBlock.cpp:148
juce::AudioChannelSet::createLRS
static AudioChannelSet JUCE_CALLTYPE createLRS()
Creates a set containing an LRS set (left, right, surround).
Definition: juce_AudioChannelSet.cpp:381
juce::AudioChannelSet::create7point1SDDS
static AudioChannelSet JUCE_CALLTYPE create7point1SDDS()
Creates a set for a 7.1 surround setup (left, right, centre, leftSurround, rightSurround,...
Definition: juce_AudioChannelSet.cpp:392
juce::StringPairArray
A container for holding a set of strings which are keyed by another string.
Definition: juce_StringPairArray.h:38
juce::AudioChannelSet
Represents a set of audio channel types.
Definition: juce_AudioChannelSet.h:50
juce::AudioChannelSet::create6point0
static AudioChannelSet JUCE_CALLTYPE create6point0()
Creates a set for a 6.0 Cine surround setup (left, right, centre, leftSurround, rightSurround,...
Definition: juce_AudioChannelSet.cpp:385
juce::AudioFormatReader::AudioFormatReader
AudioFormatReader(InputStream *sourceStream, const String &formatName)
Creates an AudioFormatReader object.
Definition: juce_AudioFormatReader.cpp:30
juce::AudioFormatReader::input
InputStream * input
The input stream, for use by subclasses.
Definition: juce_AudioFormatReader.h:249
juce::StringPairArray::set
void set(const String &key, const String &value)
Adds or amends a key/value pair.
Definition: juce_StringPairArray.cpp:105
juce::CoreAudioFormat::midiDataBase64
static const char *const midiDataBase64
Metadata property name used when reading a caf file with a MIDI chunk.
Definition: juce_CoreAudioFormat.h:59
juce::AudioChannelSet::pentagonal
static AudioChannelSet JUCE_CALLTYPE pentagonal()
Creates a set for pentagonal surround setup (left, right, centre, leftSurroundRear,...
Definition: juce_AudioChannelSet.cpp:394
juce::AudioChannelSet::mono
static AudioChannelSet JUCE_CALLTYPE mono()
Creates a one-channel mono set (centre).
Definition: juce_AudioChannelSet.cpp:378
juce::InputStream::readShortBigEndian
virtual short readShortBigEndian()
Reads two bytes from the stream as a little-endian 16-bit value.
Definition: juce_InputStream.cpp:58
juce::AudioFormatReader::bitsPerSample
unsigned int bitsPerSample
The number of bits per sample, e.g.
Definition: juce_AudioFormatReader.h:229
juce::HeapBlock::malloc
void malloc(SizeType newNumElements, size_t elementSize=sizeof(ElementType))
Allocates a specified amount of memory.
Definition: juce_HeapBlock.h:256
juce::InputStream::readIntBigEndian
virtual int readIntBigEndian()
Reads four bytes from the stream as a big-endian 32-bit value.
Definition: juce_InputStream.cpp:78
juce::InputStream::readString
virtual String readString()
Reads a zero-terminated UTF-8 string from the stream.
Definition: juce_InputStream.cpp:162
juce::AudioFormatReader::numChannels
unsigned int numChannels
The total number of channels in the audio stream.
Definition: juce_AudioFormatReader.h:235
juce::CoreAudioFormat::getPossibleSampleRates
Array< int > getPossibleSampleRates() override
Returns a set of sample rates that the format can read and write.
Definition: juce_CoreAudioFormat.cpp:563
juce::CoreAudioFormat::getPossibleBitDepths
Array< int > getPossibleBitDepths() override
Returns a set of bit depths that the format can read and write.
Definition: juce_CoreAudioFormat.cpp:564
juce::InputStream::getTotalLength
virtual int64 getTotalLength()=0
Returns the total number of bytes available for reading in this stream.
juce::UnitTest
This is a base class for classes that perform a unit test.
Definition: juce_UnitTest.h:73
juce::AudioChannelSet::hexagonal
static AudioChannelSet JUCE_CALLTYPE hexagonal()
Creates a set for hexagonal surround setup (left, right, leftSurroundRear, rightSurroundRear,...
Definition: juce_AudioChannelSet.cpp:395
juce::CoreAudioFormat::timeSig
static const char *const timeSig
Metadata property name used when reading a caf file time signature information.
Definition: juce_CoreAudioFormat.h:63
juce::String
The JUCE String class!
Definition: juce_String.h:42
juce::AudioFormatWriter
Writes samples to an audio file stream.
Definition: juce_AudioFormatWriter.h:48
juce::HeapBlock::get
ElementType * get() const noexcept
Returns a raw pointer to the allocated data.
Definition: juce_HeapBlock.h:192
juce::AudioChannelSet::channelSetWithChannels
static AudioChannelSet JUCE_CALLTYPE channelSetWithChannels(const Array< ChannelType > &)
Creates a channel set for a list of channel types.
Definition: juce_AudioChannelSet.cpp:520
juce::InputStream::readInt64BigEndian
virtual int64 readInt64BigEndian()
Reads eight bytes from the stream as a big-endian 64-bit value.
Definition: juce_InputStream.cpp:123
juce::ByteOrder::bigEndianInt
static JUCE_CONSTEXPR uint32 bigEndianInt(const void *bytes) noexcept
Turns 4 bytes into a big-endian integer.
Definition: juce_ByteOrder.h:211
juce::AudioChannelSet::quadraphonic
static AudioChannelSet JUCE_CALLTYPE quadraphonic()
Creates a set for quadraphonic surround setup (left, right, leftSurround, rightSurround)
Definition: juce_AudioChannelSet.cpp:393
juce::CoreAudioFormat::createReaderFor
AudioFormatReader * createReaderFor(InputStream *, bool deleteStreamIfOpeningFails) override
Tries to create an object that can read from a stream containing audio data in this format.
Definition: juce_CoreAudioFormat.cpp:570
juce::CoreAudioFormat::canDoMono
bool canDoMono() override
Returns true if the format can do 1-channel audio.
Definition: juce_CoreAudioFormat.cpp:567
juce::CoreAudioReader::readSamples
bool readSamples(int **destSamples, int numDestChannels, int startOffsetInDestBuffer, int64 startSampleInFile, int numSamples) override
Subclasses must implement this method to perform the low-level read operation.
Definition: juce_CoreAudioFormat.cpp:457
juce::CoreAudioFormat::createWriterFor
AudioFormatWriter * createWriterFor(OutputStream *, double sampleRateToUse, unsigned int numberOfChannels, int bitsPerSample, const StringPairArray &metadataValues, int qualityOptionIndex) override
Tries to create an object that can write to a stream with this audio format.
Definition: juce_CoreAudioFormat.cpp:584
juce::AudioChannelSet::create5point0
static AudioChannelSet JUCE_CALLTYPE create5point0()
Creates a set for a 5.0 surround setup (left, right, centre, leftSurround, rightSurround).
Definition: juce_AudioChannelSet.cpp:383
juce::AudioFormatReader::usesFloatingPointData
bool usesFloatingPointData
Indicates whether the data is floating-point or fixed.
Definition: juce_AudioFormatReader.h:238
juce::AudioChannelSet::size
int size() const noexcept
Returns the number of channels in the set.
Definition: juce_AudioChannelSet.cpp:323
juce::AudioFormatReader
Reads samples from an audio file stream.
Definition: juce_AudioFormatReader.h:48
juce::CoreAudioFormat::~CoreAudioFormat
~CoreAudioFormat() override
Destructor.
Definition: juce_CoreAudioFormat.cpp:561
juce::CoreAudioFormat::keySig
static const char *const keySig
Metadata property name used when reading a caf file time signature information.
Definition: juce_CoreAudioFormat.h:65
juce::CoreAudioFormat::canDoStereo
bool canDoStereo() override
Returns true if the format can do 2-channel audio.
Definition: juce_CoreAudioFormat.cpp:566
juce::AudioChannelSet::stereo
static AudioChannelSet JUCE_CALLTYPE stereo()
Creates a set containing a stereo set (left, right).
Definition: juce_AudioChannelSet.cpp:379
juce::MemoryBlock
A class to hold a resizable block of raw data.
Definition: juce_MemoryBlock.h:36
juce::AudioChannelSet::createLCRS
static AudioChannelSet JUCE_CALLTYPE createLCRS()
Creates a set containing an LCRS set (left, right, centre, surround).
Definition: juce_AudioChannelSet.cpp:382