CAFFileALAC.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /*
  2. Copyright © 2011 Apple Inc. All rights reserved.
  3. IMPORTANT: This Apple software is supplied to you by Apple Inc. (“Apple”) in consideration of your agreement to the following terms, and your use, installation, modification or redistribution of this Apple software constitutes acceptance of these terms. If you do not agree with these terms, please do not use, install, modify or redistribute this Apple software.
  4. In consideration of your agreement to abide by the following terms, and subject to these terms, Apple grants you a personal, non-exclusive license, under Apple’s copyrights in this original Apple software (the “Apple Software”), to use, reproduce, modify and redistribute the Apple Software, with or without modifications, in source and/or binary forms; provided that if you redistribute the Apple Software in its entirety and without modifications, you must retain this notice and the following text and disclaimers in all such redistributions of the Apple Software. Neither the name, trademarks, service marks or logos of Apple Inc. may be used to endorse or promote products derived from the Apple Software without specific prior written permission from Apple. Except as expressly stated in this notice, no other rights or licenses, express or implied, are granted by Apple herein, including but not limited to any patent rights that may be infringed by your derivative works or by other works in which the Apple Software may be incorporated.
  5. The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
  6. IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  7. */
  8. //
  9. // CAFFileALAC.h
  10. // based CAFFile.h in the CoreAudio headers, ALAC specific
  11. //
  12. // Copyright 2011 Apple Inc. All rights reserved.
  13. //
  14. #ifndef _CAFFilePortable_h
  15. #define _CAFFilePortable_h
  16. #if TARGET_OS_WIN32
  17. #define ATTRIBUTE_PACKED
  18. #pragma pack(push, 1)
  19. #else
  20. #define ATTRIBUTE_PACKED __attribute__((__packed__))
  21. #endif
  22. #include "ALACAudioTypes.h"
  23. #define kMinCAFFPacketTableHeaderSize 24
  24. typedef uint32_t CAFFChannelLayoutTag;
  25. // These are subset of the channel layout tags listed in CoreAudioTypes.h
  26. // ALAC and caff both use the same tag values
  27. enum
  28. {
  29. kCAFFChannelLayoutTag_Mono = (100<<16) | 1, // C
  30. kCAFFChannelLayoutTag_Stereo = (101<<16) | 2, // L R
  31. kCAFFChannelLayoutTag_MPEG_3_0_B = (113<<16) | 3, // C L R
  32. kCAFFChannelLayoutTag_MPEG_4_0_B = (116<<16) | 4, // C L R Cs
  33. kCAFFChannelLayoutTag_MPEG_5_0_D = (120<<16) | 5, // C L R Ls Rs
  34. kCAFFChannelLayoutTag_MPEG_5_1_D = (124<<16) | 6, // C L R Ls Rs LFE
  35. kCAFFChannelLayoutTag_AAC_6_1 = (142<<16) | 7, // C L R Ls Rs Cs LFE
  36. kCAFFChannelLayoutTag_MPEG_7_1_B = (127<<16) | 8 // C Lc Rc L R Ls Rs LFE
  37. };
  38. // ALAC currently only utilizes these channels layouts. CAFF supports all those listed in
  39. // CoreAudioTypes.h.
  40. static const CAFFChannelLayoutTag CAFFChannelLayoutTags[kALACMaxChannels] =
  41. {
  42. kCAFFChannelLayoutTag_Mono, // C
  43. kCAFFChannelLayoutTag_Stereo, // L R
  44. kCAFFChannelLayoutTag_MPEG_3_0_B, // C L R
  45. kCAFFChannelLayoutTag_MPEG_4_0_B, // C L R Cs
  46. kCAFFChannelLayoutTag_MPEG_5_0_D, // C L R Ls Rs
  47. kCAFFChannelLayoutTag_MPEG_5_1_D, // C L R Ls Rs LFE
  48. kCAFFChannelLayoutTag_AAC_6_1, // C L R Ls Rs Cs LFE
  49. kCAFFChannelLayoutTag_MPEG_7_1_B // C Lc Rc L R Ls Rs LFE (doc: IS-13818-7 MPEG2-AAC)
  50. };
  51. // In a CAF File all of these types' byte order is big endian.
  52. // When reading or writing these values the program will need to flip byte order to native endian
  53. // CAF File Header
  54. enum {
  55. k_port__port_CAF_FileType = 'caff',
  56. k_port_CAF_FileVersion_Initial = 1
  57. };
  58. // CAF Chunk Types
  59. enum {
  60. k_port_CAF_StreamDescriptionChunkID = 'desc',
  61. k_port_CAF_AudioDataChunkID = 'data',
  62. k_port_CAF_ChannelLayoutChunkID = 'chan',
  63. k_port_CAF_MagicCookieID = 'kuki',
  64. k_port_CAF_PacketTableChunkID = 'pakt',
  65. k_port_CAF_FreeTableChunkID = 'free'
  66. };
  67. struct port_CAFFileHeader
  68. {
  69. uint32_t mFileType; // 'caff'
  70. uint16_t mFileVersion; //initial revision set to 1
  71. uint16_t mFileFlags; //initial revision set to 0
  72. } ATTRIBUTE_PACKED;
  73. typedef struct CAFFileHeader CAFFileHeader;
  74. struct port_CAFChunkHeader
  75. {
  76. uint32_t mChunkType; // four char code
  77. int64_t mChunkSize; // size in bytes of the chunk data (not including this header).
  78. // mChunkSize is int64_t not uint64_t because negative values for
  79. // the data size can have a special meaning
  80. } ATTRIBUTE_PACKED;
  81. typedef struct port_CAFChunkHeader port_CAFChunkHeader;
  82. // Every file MUST have this chunk. It MUST be the first chunk in the file
  83. struct port_CAFAudioDescription
  84. {
  85. double mSampleRate;
  86. uint32_t mFormatID;
  87. uint32_t mFormatFlags;
  88. uint32_t mBytesPerPacket;
  89. uint32_t mFramesPerPacket;
  90. uint32_t mChannelsPerFrame;
  91. uint32_t mBitsPerChannel;
  92. } ATTRIBUTE_PACKED;
  93. typedef struct port_CAFAudioDescription port_CAFAudioDescription;
  94. // these are the flags if the format ID is 'lpcm'
  95. // <CoreAudio/CoreAudioTypes.h> declares some of the format constants
  96. // that can be used as Data Formats in a CAF file
  97. enum
  98. {
  99. k_port_CAFLinearPCMFormatFlagIsFloat = (1L << 0),
  100. k_port_CAFLinearPCMFormatFlagIsLittleEndian = (1L << 1)
  101. };
  102. // 'chan' Optional chunk.
  103. // struct AudioChannelLayout as defined in CoreAudioTypes.h.
  104. // 'free'
  105. // this is a padding chunk for reserving space in the file. content is meaningless.
  106. // 'kuki'
  107. // this is the magic cookie chunk. bag of bytes.
  108. // 'data' Every file MUST have this chunk.
  109. // actual audio data can be any format as described by the 'asbd' chunk.
  110. // if mChunkSize is < 0 then this is the last chunk in the file and the actual length
  111. // should be determined from the file size.
  112. // The motivation for this is to allow writing the files without seeking to update size fields after every
  113. // write in order to keep the file legal.
  114. // The program can put a -1 in the mChunkSize field and
  115. // update it only once at the end of recording.
  116. // If the program were to crash during recording then the file is still well defined.
  117. // 'pakt' Required if either/or mBytesPerPacket or mFramesPerPacket in the Format Description are zero
  118. // For formats that are packetized and have variable sized packets.
  119. // The table is stored as an array of one or two variable length integers.
  120. // (a) size in bytes of the data of a given packet.
  121. // (b) number of frames in a given packet.
  122. // These sizes are encoded as variable length integers
  123. // The packet description entries are either one or two values depending on the format.
  124. // There are three possibilities
  125. // (1)
  126. // If the format has variable bytes per packets (desc.mBytesPerPacket == 0) and constant frames per packet
  127. // (desc.mFramesPerPacket != 0) then the packet table contains single entries representing the bytes in a given packet
  128. // (2)
  129. // If the format is a constant bit rate (desc.mBytesPerPacket != 0) but variable frames per packet
  130. // (desc.mFramesPerPacket == 0) then the packet table entries contains single entries
  131. // representing the number of frames in a given packet
  132. // (3)
  133. // If the format has variable frames per packet (asbd.mFramesPerPacket == 0) and variable bytes per packet
  134. // (desc.mBytesPerPacket == 0) then the packet table entries are a duple of two values. The first value
  135. // is the number of bytes in a given packet, the second value is the number of frames in a given packet
  136. struct port_CAFPacketTableHeader
  137. {
  138. int64_t mNumberPackets;
  139. int64_t mNumberValidFrames;
  140. int32_t mPrimingFrames;
  141. int32_t mRemainderFrames;
  142. uint8_t mPacketDescriptions[1]; // this is a variable length array of mNumberPackets elements
  143. } ATTRIBUTE_PACKED;
  144. typedef struct port_CAFPacketTableHeader port_CAFPacketTableHeader;
  145. struct port_CAFDataChunk
  146. {
  147. uint32_t mEditCount;
  148. uint8_t mData[1]; // this is a variable length data field based off the size of the data chunk
  149. } ATTRIBUTE_PACKED;
  150. typedef struct port_CAFDataChunk port_CAFDataChunk;
  151. // prototypes
  152. int32_t FindCAFFPacketTableStart(FILE * inputFile, int32_t * paktPos, int32_t * paktSize);
  153. void WriteCAFFcaffChunk(FILE * outputFile);
  154. void WriteCAFFdescChunk(FILE * outputFile, AudioFormatDescription theOutputFormat);
  155. void WriteCAFFdataChunk(FILE * outputFile);
  156. void WriteCAFFkukiChunk(FILE * outputFile, void * inCookie, uint32_t inCookieSize);
  157. void WriteCAFFChunkSize(FILE * outputFile, int64_t numDataBytes);
  158. void WriteCAFFchanChunk(FILE * outputFile, uint32_t inChannelTag);
  159. void WriteCAFFfreeChunk(FILE * outputFile, uint32_t theSize);
  160. void WriteCAFFpaktChunkHeader(FILE * outputFile, port_CAFPacketTableHeader * thePacketTableHeader, uint32_t thePacketTableSize);
  161. void GetBERInteger(int32_t theOriginalValue, uint8_t * theBuffer, int32_t * theBERSize);
  162. uint32_t ReadBERInteger(uint8_t * theInputBuffer, int32_t * ioNumBytes);
  163. int32_t BuildBasePacketTable(AudioFormatDescription theInputFormat, int32_t inputDataSize, int32_t * thePacketTableSize, port_CAFPacketTableHeader * thePacketTableHeader);
  164. uint32_t GetMagicCookieSizeFromCAFFkuki(FILE * inputFile);
  165. int32_t GetMagicCookieFromCAFFkuki(FILE * inputFile, uint8_t * outMagicCookie, uint32_t * ioMagicCookieSize);
  166. bool FindCAFFDataStart(FILE * inputFile, int32_t * dataPos, int32_t * dataSize);
  167. bool GetCAFFdescFormat(FILE * inputFile, AudioFormatDescription * theInputFormat);
  168. #if TARGET_OS_WIN32
  169. #pragma pack(pop)
  170. #endif
  171. ////////////////////////////////////////////////////////////////////////////////////////////////
  172. #endif