1 /*
2  * Copyright (c) 2011 Apple Inc. All rights reserved.
3  *
4  * @APPLE_APACHE_LICENSE_HEADER_START@
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * @APPLE_APACHE_LICENSE_HEADER_END@
19  */
20 
21 /*
22 	File:		ALACAudioTypes.h
23 */
24 
25 #ifndef ALACAUDIOTYPES_H
26 #define ALACAUDIOTYPES_H
27 
28 #if PRAGMA_ONCE
29 #pragma once
30 #endif
31 
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35 
36 #if PRAGMA_STRUCT_ALIGN
37     #pragma options align=mac68k
38 #elif PRAGMA_STRUCT_PACKPUSH
39     #pragma pack(push, 2)
40 #elif PRAGMA_STRUCT_PACK
41     #pragma pack(2)
42 #endif
43 
44 #include <stdint.h>
45 
46 #if defined(__ppc__)
47 #define TARGET_RT_BIG_ENDIAN 1
48 #elif defined(__ppc64__)
49 #define TARGET_RT_BIG_ENDIAN 1
50 #endif
51 
52 #define kChannelAtomSize 12
53 
54 enum
55 {
56     kALAC_UnimplementedError   = -4,
57     kALAC_FileNotFoundError    = -43,
58     kALAC_ParamError           = -50,
59     kALAC_MemFullError         = -108
60 };
61 
62 enum
63 {
64     kALACFormatAppleLossless = 'alac',
65     kALACFormatLinearPCM = 'lpcm'
66 };
67 
68 enum
69 {
70     kALACMaxChannels	= 8,
71     kALACMaxEscapeHeaderBytes = 8,
72     kALACMaxSearches	= 16,
73     kALACMaxCoefs		= 16,
74     kALACDefaultFramesPerPacket = 4096
75 };
76 
77 typedef uint32_t ALACChannelLayoutTag;
78 
79 enum
80 {
81     kALACFormatFlagIsFloat                     = (1 << 0),     // 0x1
82     kALACFormatFlagIsBigEndian                 = (1 << 1),     // 0x2
83     kALACFormatFlagIsSignedInteger             = (1 << 2),     // 0x4
84     kALACFormatFlagIsPacked                    = (1 << 3),     // 0x8
85     kALACFormatFlagIsAlignedHigh               = (1 << 4),     // 0x10
86 };
87 
88 enum
89 {
90 #if TARGET_RT_BIG_ENDIAN
91     kALACFormatFlagsNativeEndian       = kALACFormatFlagIsBigEndian
92 #else
93     kALACFormatFlagsNativeEndian       = 0
94 #endif
95 };
96 
97 // this is required to be an IEEE 64bit float
98 typedef double alac_float64_t;
99 
100 // These are the Channel Layout Tags used in the Channel Layout Info portion of the ALAC magic cookie
101 enum
102 {
103     kALACChannelLayoutTag_Mono          = (100<<16) | 1,    // C
104     kALACChannelLayoutTag_Stereo        = (101<<16) | 2,	// L R
105     kALACChannelLayoutTag_MPEG_3_0_B    = (113<<16) | 3,	// C L R
106     kALACChannelLayoutTag_MPEG_4_0_B    = (116<<16) | 4,	// C L R Cs
107     kALACChannelLayoutTag_MPEG_5_0_D    = (120<<16) | 5,    // C L R Ls Rs
108     kALACChannelLayoutTag_MPEG_5_1_D    = (124<<16) | 6,	// C L R Ls Rs LFE
109     kALACChannelLayoutTag_AAC_6_1       = (142<<16) | 7,	// C L R Ls Rs Cs LFE
110     kALACChannelLayoutTag_MPEG_7_1_B	= (127<<16) | 8     // C Lc Rc L R Ls Rs LFE    (doc: IS-13818-7 MPEG2-AAC)
111 };
112 
113 // ALAC currently only utilizes these channels layouts. There is a one for one correspondance between a
114 // given number of channels and one of these layout tags
115 static const ALACChannelLayoutTag	ALACChannelLayoutTags[kALACMaxChannels] =
116 {
117     kALACChannelLayoutTag_Mono,         // C
118     kALACChannelLayoutTag_Stereo,		// L R
119     kALACChannelLayoutTag_MPEG_3_0_B,	// C L R
120     kALACChannelLayoutTag_MPEG_4_0_B,	// C L R Cs
121     kALACChannelLayoutTag_MPEG_5_0_D,	// C L R Ls Rs
122     kALACChannelLayoutTag_MPEG_5_1_D,	// C L R Ls Rs LFE
123     kALACChannelLayoutTag_AAC_6_1,		// C L R Ls Rs Cs LFE
124     kALACChannelLayoutTag_MPEG_7_1_B	// C Lc Rc L R Ls Rs LFE    (doc: IS-13818-7 MPEG2-AAC)
125 };
126 
127 // AudioChannelLayout from CoreAudioTypes.h. We never need the AudioChannelDescription so we remove it
128 struct ALACAudioChannelLayout
129 {
130     ALACChannelLayoutTag          mChannelLayoutTag;
131     uint32_t                      mChannelBitmap;
132     uint32_t                      mNumberChannelDescriptions;
133 };
134 typedef struct ALACAudioChannelLayout ALACAudioChannelLayout;
135 
136 struct AudioFormatDescription
137 {
138     alac_float64_t mSampleRate;
139     uint32_t  mFormatID;
140     uint32_t  mFormatFlags;
141     uint32_t  mBytesPerPacket;
142     uint32_t  mFramesPerPacket;
143     uint32_t  mBytesPerFrame;
144     uint32_t  mChannelsPerFrame;
145     uint32_t  mBitsPerChannel;
146     uint32_t  mReserved;
147 };
148 typedef struct AudioFormatDescription  AudioFormatDescription;
149 
150 /* Lossless Definitions */
151 
152 enum
153 {
154 	kALACCodecFormat		= 'alac',
155 	kALACVersion			= 0,
156 	kALACCompatibleVersion	= kALACVersion,
157 	kALACDefaultFrameSize	= 4096
158 };
159 
160 // note: this struct is wrapped in an 'alac' atom in the sample description extension area
161 // note: in QT movies, it will be further wrapped in a 'wave' atom surrounded by 'frma' and 'term' atoms
162 typedef struct ALACSpecificConfig
163 {
164 	uint32_t				frameLength;
165 	uint8_t					compatibleVersion;
166 	uint8_t					bitDepth;							// max 32
167 	uint8_t					pb;									// 0 <= pb <= 255
168 	uint8_t					mb;
169 	uint8_t					kb;
170 	uint8_t					numChannels;
171 	uint16_t				maxRun;
172 	uint32_t				maxFrameBytes;
173 	uint32_t				avgBitRate;
174 	uint32_t				sampleRate;
175 
176 } ALACSpecificConfig;
177 
178 
179 // The AudioChannelLayout atom type is not exposed yet so define it here
180 enum
181 {
182 	AudioChannelLayoutAID = 'chan'
183 };
184 
185 #if PRAGMA_STRUCT_ALIGN
186     #pragma options align=reset
187 #elif PRAGMA_STRUCT_PACKPUSH
188     #pragma pack(pop)
189 #elif PRAGMA_STRUCT_PACK
190     #pragma pack()
191 #endif
192 
193 #ifdef __cplusplus
194 }
195 #endif
196 
197 #endif	/* ALACAUDIOTYPES_H */
198