| __________________________________________________________________________________________________________________________________ |
| __________________________________________________________________________________________________________________________________ |
| Apple Lossless Format "Magic Cookie" Description |
| __________________________________________________________________________________________________________________________________ |
| __________________________________________________________________________________________________________________________________ |
| |
| Many encoded formats for audio require additional, codec specific configuration information in order to operate successfully. |
| This codec specific information is often called a 'magic cookie'. The Apple Lossless codec's 'magic cookie' contains the |
| ALACSpecificConfig and optional ALACChannelLayoutInfo (both described below). |
| |
| The 'magic cookie' must accompany the bitstream when stored in any file container (M4A/MP4, CAF) so that it may be provided to the |
| decoder when decoding the bitstream. From the caller's perspective, the 'magic cookie' is opaque and should be stored in the file |
| and presented to the decoder exactly as it is vended from the encoder (and consequently stored in the file). |
| |
| The ALAC 'magic cookie' as stored in a file has all fields described in big-endian order (regardless of file format). |
| |
| The layout of the 'magic cookie' is as follows: |
| |
| |
| ---------------- ALAC Specific Info (24 bytes) (mandatory) --------------------------- |
| (ALACSpecificConfig) Decoder Info |
| |
| ---------------- Channel Layout Info (24 bytes) (optional) ---------------------------- |
| (ALAC Channel Layout Info) Channel Layout Info |
| |
| |
| If the channel layout is absent from the cookie, then the following assumptions are made: |
| 1 channel - mono |
| 2 channels - stereo in left, right order |
| > 2 channels - no specific channel designation or role. |
| |
| |
| __________________________________________________________________________________________________________________________________ |
| * ALAC Specific Info (24 bytes) (mandatory) |
| __________________________________________________________________________________________________________________________________ |
| |
| The Apple Lossless codec stores specific information about the encoded stream in the ALACSpecificConfig. This |
| info is vended by the encoder and is used to setup the decoder for a given encoded bitstream. |
| |
| When read from and written to a file, the fields of this struct must be in big-endian order. |
| When vended by the encoder (and received by the decoder) the struct values will be in big-endian order. |
| |
| /* |
| struct ALACSpecificConfig (defined in ALACAudioTypes.h) |
| abstract This struct is used to describe codec provided information about the encoded Apple Lossless bitstream. |
| It must accompany the encoded stream in the containing audio file and be provided to the decoder. |
| |
| field frameLength uint32_t indicating the frames per packet when no explicit frames per packet setting is |
| present in the packet header. The encoder frames per packet can be explicitly set |
| but for maximum compatibility, the default encoder setting of 4096 should be used. |
| |
| field compatibleVersion uint8_t indicating compatible version, |
| value must be set to 0 |
| |
| field bitDepth uint8_t describes the bit depth of the source PCM data (maximum value = 32) |
| |
| field pb uint8_t currently unused tuning parameter. |
| value should be set to 40 |
| |
| field mb uint8_t currently unused tuning parameter. |
| value should be set to 14 |
| |
| field kb uint8_t currently unused tuning parameter. |
| value should be set to 10 |
| |
| field numChannels uint8_t describes the channel count (1 = mono, 2 = stereo, etc...) |
| when channel layout info is not provided in the 'magic cookie', a channel count > 2 |
| describes a set of discreet channels with no specific ordering |
| |
| field maxRun uint16_t currently unused. |
| value should be set to 255 |
| |
| field maxFrameBytes uint32_t the maximum size of an Apple Lossless packet within the encoded stream. |
| value of 0 indicates unknown |
| |
| field avgBitRate uint32_t the average bit rate in bits per second of the Apple Lossless stream. |
| value of 0 indicates unknown |
| |
| field sampleRate uint32_t sample rate of the encoded stream |
| */ |
| |
| typedef struct ALACSpecificConfig |
| { |
| uint32_t frameLength; |
| uint8_t compatibleVersion; |
| uint8_t bitDepth; |
| uint8_t pb; |
| uint8_t mb; |
| uint8_t kb; |
| uint8_t numChannels; |
| uint16_t maxRun; |
| uint32_t maxFrameBytes; |
| uint32_t avgBitRate; |
| uint32_t sampleRate; |
| |
| } ALACSpecificConfig; |
| |
| |
| __________________________________________________________________________________________________________________________________ |
| Channel Layout Info (24 bytes) (optional) |
| __________________________________________________________________________________________________________________________________ |
| |
| The Apple Lossless codec can support a specific set of channel layouts. When channel information is vended |
| by the encoder (in the 'magic cookie'), it is formatted in the the ALACChannelLayoutInfo. |
| |
| When read from and written to a file, the fields of this struct must be in big-endian order. |
| When vended by the encoder (and received by the decoder) the struct values will be in big-endian order. |
| |
| /* |
| struct ALACChannelLayoutInfo (defined in ALACAudioTypes.h) |
| abstract This struct is used to specify particular channel orderings or configurations. |
| It is an optional portion of the 'magic cookie', being required to describe specific channel layouts (see below) |
| of more than 2 channels. |
| |
| field channelLayoutInfoSize uint32_t indicates the size of the channel layout data |
| value should be set to 24 |
| |
| field channelLayoutInfoID uint32_t identifier indicating that channel layout info is present |
| value = 'chan' |
| |
| field versionFlags uint32_t version flags |
| value should be set to 0 |
| |
| field channelLayoutTag uint32_t channel layout type |
| from defined list in ALACAudioTypes.h (see below) |
| |
| field reserved1 uint32_t currently unused field |
| value should be set to 0 |
| |
| field reserved2 uint32_t currently unused field |
| value should be set to 0 |
| */ |
| |
| typedef struct ALACChannelLayoutInfo |
| { |
| uint32_t channelLayoutInfoSize; |
| uint32_t channelLayoutInfoID; |
| uint32_t versionFlags; |
| uint32_t channelLayoutTag; |
| uint32_t reserved1; |
| uint32_t reserved2; |
| } ALACChannelLayoutInfo; |
| |
| |
| * Channel Layout Tags |
| |
| These constants will be used to describe the bitstream's channel layout. (defined in ALACAudioTypes.h) |
| |
| enum |
| { |
| kALACChannelLayoutTag_Mono = (100<<16) | 1, // C |
| kALACChannelLayoutTag_Stereo = (101<<16) | 2, // L R |
| kALACChannelLayoutTag_MPEG_3_0_B = (113<<16) | 3, // C L R |
| kALACChannelLayoutTag_MPEG_4_0_B = (116<<16) | 4, // C L R Cs |
| kALACChannelLayoutTag_MPEG_5_0_D = (120<<16) | 5, // C L R Ls Rs |
| kALACChannelLayoutTag_MPEG_5_1_D = (124<<16) | 6, // C L R Ls Rs LFE |
| kALACChannelLayoutTag_AAC_6_1 = (142<<16) | 7, // C L R Ls Rs Cs LFE |
| kALACChannelLayoutTag_MPEG_7_1_B = (127<<16) | 8 // C Lc Rc L R Ls Rs LFE (doc: IS-13818-7 MPEG2-AAC) |
| }; |
| |
| |
| __________________________________________________________________________________________________________________________________ |
| __________________________________________________________________________________________________________________________________ |
| * Storing Apple Lossless Magic Cookie in Audio Files |
| __________________________________________________________________________________________________________________________________ |
| __________________________________________________________________________________________________________________________________ |
| |
| The Apple Lossless Magic Cookie is treated as opaque by file parsing code. The 'magic cookie' vended by the encoder |
| is placed without modification into the audio file and the read from that file and passed (unmodified) to the decoder. |
| |
| __________________________________________________________________________________________________________________________________ |
| * CAF File |
| |
| In a CAF file (Core Audio File), the 'magic cookie' is stored in CAF's Magic Cookie chunk ('kuki'). |
| |
| __________________________________________________________________________________________________________________________________ |
| * MP4/M4A File |
| |
| In an MP4/M4A file, the 'magic cookie' is encapsulated in the AudioSample entry of a Sound Description box ('stsd'). |
| An ISO style full box header to describe the ALACSpecificConfig portion is appended to the AudioSampleEntry, followed by the |
| 'magic cookie' as it is vended by the encoder. |
| |
| (All fields are stored in big-endian order: see ISO/IEC 14496-12 for a full description of the SoundDescription and AudioSampleEntry boxes, etc.) |
| |
| ---------------- SoundDescriptionBox (FullBox) ---------------------------- |
| |
| SampleEntrySize // = sizeof(SoundDescriptionBox)(16) + sizeof (AudioSampleEntry)(AudioSampleEntry.SampleEntrySize) |
| SampleEntryType // = 'stsd' |
| VersionFlags // = 0 |
| EntryCount // = 1 |
| |
| ---------------- Audio Sample Entry (REQUIRED) ----------------------------- |
| |
| SampleEntrySize // sizeof(AudioSampleEntry)(36) + sizeof(full ISO box header)(12) + sizeof(Apple Lossless Magic Cookie) |
| SampleEntryType // = 'alac', specifies that the AudioSampleEntry describes an Apple Lossless bitstream |
| mReserved[6] // = 0 |
| dref index // = 1 |
| reserved[2] // = 0 |
| channel count // = number of channels as a uint_16 value |
| sample size // = source pcm bitdepth (example = 16bit source pcm) |
| predefined // = 0 |
| reserved // = 0 |
| sample rate // sample rate as a uint_32 value |
| |
| Appended to AudioSampleEntry: |
| |
| ALAC Specific Info Size // uint_32 value, = 36 (12 + sizeof(ALACSpecificConfig)) |
| ALAC Specific Info ID // uint_32 value, = 'alac', format ID which matches the Audio Sample Entry SampleEntryType field |
| Version Flags // uint_32 value, = 0 |
| |
| Apple Lossless Magic Cookie // 'magic cookie' vended from ALAC encoder (24 or 48 Bytes) |
| |
| __________________________________________________________________________________________________________________________________ |
| __________________________________________________________________________________________________________________________________ |
| * Compatibility |
| __________________________________________________________________________________________________________________________________ |
| __________________________________________________________________________________________________________________________________ |
| |
| Previous versions of the Apple Lossless encoder vended a different 'magic cookie'. To ensure compatibility, the Apple Lossless decoder |
| must be prepared to parse a 'magic cookie' in the format described below. Note that the 'magic cookie' defined above is |
| encapsulated in the following method and can be extracted as a contiguous set of bytes. |
| |
| |
| ---------------- Format Atom (12 bytes) -------------------------------- |
| (uint_32) Format Atom Size // = 12 |
| (uint_32) Channel Layout Info ID // = 'frma' |
| (uint_32) Format Type // = 'alac' |
| |
| ---------------- ALAC Specific Info (36 bytes) (required) -------------- |
| (uint_32) ALAC Specific Info Size // = 36 (12 + sizeof(ALACSpecificConfig)) |
| (uint_32) ALAC Specific Info ID // = 'alac', format ID which matches the Audio Sample Entry SampleEntryType field |
| (uint_32) Version Flags // = 0 |
| |
| [ Apple Lossless Magic Cookie (see above) ] |
| |
| ---------------- Terminator Atom (8 bytes) ----------------------------- |
| (uint_32) Channel Layout Info Size // = 8 |
| (uint_32) Channel Layout Info ID // = 0 |
| |
| |
| |