1 /* |
|
2 * Copyright (c) 2010 Ixonos Plc. |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - Initial contribution |
|
11 * |
|
12 * Contributors: |
|
13 * Ixonos Plc |
|
14 * |
|
15 * Description: |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 /************************************************************************** |
|
21 mp4aud.cpp - MPEG-4 Audio interface to MPEG-4 Systems layer. |
|
22 |
|
23 Author(s): Juha Ojanpera |
|
24 Copyright (c) 2001-2004 by Nokia Research Center, Speech and Audio Systems. |
|
25 *************************************************************************/ |
|
26 |
|
27 /*-- Project Headers. --*/ |
|
28 #include "nok_bits.h" |
|
29 #include "mp4aud.h" |
|
30 #include "AACAPI.h" |
|
31 const int32 sample_rates[] = { |
|
32 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, |
|
33 11025, 8000, 0, 0, 0, 0 |
|
34 }; |
|
35 |
|
36 /* |
|
37 * Reads program configuration element from the specified bitstream. |
|
38 */ |
|
39 static INLINE int16 |
|
40 GetPCE(TBitStream *bs, ProgConfig *p, TInt *numChans) |
|
41 { |
|
42 int16 i; |
|
43 |
|
44 p->tag = (int16) BsGetBits(bs, LEN_TAG); |
|
45 p->profile = (int16) BsGetBits(bs, LEN_PROFILE); |
|
46 p->sample_rate_idx = (int16) BsGetBits(bs, LEN_SAMP_IDX); |
|
47 p->front.num_ele = (int16) BsGetBits(bs, LEN_NUM_ELE); |
|
48 p->side.num_ele = (int16) BsGetBits(bs, LEN_NUM_ELE); |
|
49 p->back.num_ele = (int16) BsGetBits(bs, LEN_NUM_ELE); |
|
50 p->lfe.num_ele = (int16) BsGetBits(bs, LEN_NUM_LFE); |
|
51 p->data.num_ele = (int16) BsGetBits(bs, LEN_NUM_DAT); |
|
52 p->coupling.num_ele = (int16) BsGetBits(bs, LEN_NUM_CCE); |
|
53 |
|
54 p->mono_mix.present = (int16) BsGetBits(bs, 1); |
|
55 if(p->mono_mix.present == 1) |
|
56 p->mono_mix.ele_tag = (int16) BsGetBits(bs, LEN_TAG); |
|
57 |
|
58 p->stereo_mix.present = (int16) BsGetBits(bs, 1); |
|
59 if(p->stereo_mix.present == 1) |
|
60 p->stereo_mix.ele_tag = (int16) BsGetBits(bs, LEN_TAG); |
|
61 |
|
62 p->matrix_mix.present = (int16) BsGetBits(bs, 1); |
|
63 if(p->matrix_mix.present == 1) |
|
64 { |
|
65 p->matrix_mix.ele_tag = (int16) BsGetBits(bs, LEN_MMIX_IDX); |
|
66 p->matrix_mix.pseudo_enab = (int16) BsGetBits(bs, LEN_PSUR_ENAB); |
|
67 } |
|
68 |
|
69 for(i = 0; i < p->front.num_ele; i++) |
|
70 { |
|
71 p->front.ele_is_cpe[i] = (int16) BsGetBits(bs, LEN_ELE_IS_CPE); |
|
72 p->front.ele_tag[i] = (int16) BsGetBits(bs, LEN_TAG); |
|
73 |
|
74 *numChans += (p->front.ele_is_cpe[i] == 1) ? 2 : 1; |
|
75 } |
|
76 |
|
77 for(i = 0; i < p->side.num_ele; i++) |
|
78 { |
|
79 p->side.ele_is_cpe[i] = (int16) BsGetBits(bs, LEN_ELE_IS_CPE); |
|
80 p->side.ele_tag[i] = (int16) BsGetBits(bs, LEN_TAG); |
|
81 |
|
82 *numChans += (p->front.ele_is_cpe[i] == 1) ? 2 : 1; |
|
83 } |
|
84 |
|
85 for(i = 0; i < p->back.num_ele; i++) |
|
86 { |
|
87 p->back.ele_is_cpe[i] = (int16) BsGetBits(bs, LEN_ELE_IS_CPE); |
|
88 p->back.ele_tag[i] = (int16) BsGetBits(bs, LEN_TAG); |
|
89 |
|
90 *numChans += (p->front.ele_is_cpe[i] == 1) ? 2 : 1; |
|
91 } |
|
92 |
|
93 for(i = 0; i < p->lfe.num_ele; i++) |
|
94 { |
|
95 *numChans += 1; |
|
96 |
|
97 p->lfe.ele_is_cpe[i] = 0; |
|
98 p->lfe.ele_tag[i] = (int16) BsGetBits(bs, LEN_TAG); |
|
99 } |
|
100 |
|
101 for(i = 0; i < p->data.num_ele; i++) |
|
102 { |
|
103 p->data.ele_is_cpe[i] = 0; |
|
104 p->data.ele_tag[i] = (int16) BsGetBits(bs, LEN_TAG); |
|
105 } |
|
106 |
|
107 for(i = 0; i < p->coupling.num_ele; i++) |
|
108 { |
|
109 p->coupling.ele_is_cpe[i] = (int16) BsGetBits(bs, LEN_ELE_IS_CPE); |
|
110 p->coupling.ele_tag[i] = (int16) BsGetBits(bs, LEN_TAG); |
|
111 } |
|
112 |
|
113 BsByteAlign(bs); |
|
114 |
|
115 p->num_comment_bytes = (int16) BsGetBits(bs, LEN_COMMENT_BYTES); |
|
116 for(i = 0; i < p->num_comment_bytes; i++) |
|
117 p->comments[i] = (uint8) BsGetBits(bs, LEN_BYTE); |
|
118 p->comments[i] = 0; |
|
119 |
|
120 return (p->tag); |
|
121 } |
|
122 |
|
123 /* |
|
124 * Determines sampling rate index for the MPEG-4 decoder. The input sampling |
|
125 * rate as specified in the audio config part is not one of the rates listed |
|
126 * in the standard. |
|
127 */ |
|
128 static INLINE int16 |
|
129 DetermineSamplingFreqIdx(int32 samplingFreq) |
|
130 { |
|
131 int16 idx; |
|
132 |
|
133 if(samplingFreq >= 92017L) idx = 0; |
|
134 else if(samplingFreq < 92017L && samplingFreq >= 75132L) idx = 1; |
|
135 else if(samplingFreq < 75132L && samplingFreq >= 55426) idx = 2; |
|
136 else if(samplingFreq < 55426L && samplingFreq >= 46009L) idx = 3; |
|
137 else if(samplingFreq < 46009L && samplingFreq >= 37566L) idx = 4; |
|
138 else if(samplingFreq < 37566L && samplingFreq >= 27713L) idx = 5; |
|
139 else if(samplingFreq < 27713L && samplingFreq >= 23004L) idx = 6; |
|
140 else if(samplingFreq < 23004L && samplingFreq >= 18783L) idx = 7; |
|
141 else if(samplingFreq < 18783L && samplingFreq >= 13856L) idx = 8; |
|
142 else if(samplingFreq < 13856L && samplingFreq >= 11502L) idx = 9; |
|
143 else if(samplingFreq < 11502L && samplingFreq >= 9391L) idx = 10; |
|
144 else idx = 11; |
|
145 |
|
146 return (idx); |
|
147 } |
|
148 |
|
149 /* |
|
150 * Reads GA decoder configuration information from the specified bitstream. |
|
151 */ |
|
152 static INLINE BOOL |
|
153 ReadGASpecificInfo(TBitStream *bs, AudioSpecificInfo *audInfo, ProgConfig *progCfg) |
|
154 { |
|
155 int16 extensionFlag; |
|
156 GaSpecificInfo *gaInfo = &audInfo->gaInfo; |
|
157 |
|
158 gaInfo->FrameLengthFlag = (BOOL) BsGetBits(bs, 1); |
|
159 gaInfo->DependsOnCoreCoder = (BOOL) BsGetBits(bs, 1); |
|
160 gaInfo->CoreCoderDelay = (gaInfo->DependsOnCoreCoder) ? (int16) BsGetBits(bs, 14) : (int16)0; |
|
161 extensionFlag = (int16) BsGetBits(bs, 1); |
|
162 |
|
163 if(audInfo->channelConfiguration == 0) |
|
164 { |
|
165 TInt numChans = 0; |
|
166 |
|
167 GetPCE(bs, progCfg, &numChans); |
|
168 audInfo->channelConfiguration = (uint8) numChans; |
|
169 if (audInfo->samplingFreqIdx != (uint8) progCfg->sample_rate_idx) |
|
170 { |
|
171 return FALSE; |
|
172 } |
|
173 } |
|
174 |
|
175 /* |
|
176 * Determine the sampling rate index so that sampling rate dependent |
|
177 * tables can be initialized. |
|
178 */ |
|
179 if(audInfo->samplingFreqIdx == 0xf && audInfo->channelConfiguration != 0) |
|
180 { |
|
181 audInfo->samplingFreqIdx = (uint8) DetermineSamplingFreqIdx(audInfo->samplingFrequency); |
|
182 progCfg->sample_rate_idx = audInfo->samplingFreqIdx; |
|
183 } |
|
184 else |
|
185 { |
|
186 |
|
187 audInfo->samplingFreqIdx = (uint8) progCfg->sample_rate_idx; |
|
188 |
|
189 } |
|
190 |
|
191 if(audInfo->audioObject == AAC_SCALABLE || audInfo->audioObject == ER_AAC_SCALABLE) |
|
192 gaInfo->layerNr = (uint8) BsGetBits(bs, 3); |
|
193 |
|
194 if(extensionFlag) |
|
195 { |
|
196 if(audInfo->audioObject == ER_BSAC) |
|
197 { |
|
198 gaInfo->numOfSubframe = (uint8) BsGetBits(bs, 5); |
|
199 gaInfo->layer_length = (uint8) BsGetBits(bs, 11); |
|
200 } |
|
201 |
|
202 switch(audInfo->audioObject) |
|
203 { |
|
204 case ER_AAC_LC: |
|
205 case ER_AAC_LTP: |
|
206 case ER_AAC_SCALABLE: |
|
207 case ER_TWINVQ: |
|
208 case ER_AAC_LD: |
|
209 gaInfo->aacSectionDataResilienceFlag = (BOOL) BsGetBits(bs, 1); |
|
210 gaInfo->aacScalefactorDataResilienceFlag = (BOOL) BsGetBits(bs, 1); |
|
211 gaInfo->aacSpectralDataResilienceFlag = (BOOL) BsGetBits(bs, 1); |
|
212 break; |
|
213 |
|
214 default: |
|
215 break; |
|
216 } |
|
217 |
|
218 extensionFlag = (int16) BsGetBits(bs, 1); |
|
219 if(extensionFlag) |
|
220 { |
|
221 ; |
|
222 } |
|
223 } |
|
224 return TRUE; |
|
225 } |
|
226 |
|
227 /* |
|
228 * Reads MPEG-4 audio decoder specific configuration information. |
|
229 * |
|
230 * Retuns TRUE on success, FALSE otherwise. FALSE indicates that |
|
231 * unsupported decoder configuration (e.g., object type) was detected. |
|
232 */ |
|
233 static INLINE BOOL |
|
234 ReadAudioSpecificConfig(TBitStream *bs, AudioSpecificInfo *audInfo, |
|
235 ProgConfig *progCfg, int32 bufLen) |
|
236 { |
|
237 int16 bitsLeft; |
|
238 AudioObjectType audObj; |
|
239 |
|
240 /*-- Read common configuration information. --*/ |
|
241 audObj = audInfo->audioObject = (AudioObjectType)(BsGetBits(bs, 5) - 1); |
|
242 audInfo->samplingFreqIdx = (uint8) BsGetBits(bs, 4); |
|
243 audInfo->samplingFrequency = sample_rates[audInfo->samplingFreqIdx]; |
|
244 if(audInfo->samplingFreqIdx == 0xf) |
|
245 audInfo->samplingFrequency = (int32) BsGetBits(bs, 24); |
|
246 audInfo->channelConfiguration = (uint8) BsGetBits(bs, 4); |
|
247 |
|
248 audInfo->extAudioObject = (AudioObjectType) 0; |
|
249 audInfo->sbrPresentFlag = 0; |
|
250 |
|
251 if(audInfo->audioObject == AAC_SBR) |
|
252 { |
|
253 audInfo->extAudioObject = audInfo->audioObject; |
|
254 audInfo->sbrPresentFlag = 1; |
|
255 audInfo->extSamplingFreqIdx = (uint8) BsGetBits(bs, 4); |
|
256 if(audInfo->extSamplingFreqIdx == 0xf) |
|
257 audInfo->extSamplingFrequency = (int32) BsGetBits(bs, 24); |
|
258 audObj = audInfo->audioObject = (AudioObjectType)(BsGetBits(bs, 5) - 1); |
|
259 } |
|
260 |
|
261 /*-- Read object type specific configuration information. --*/ |
|
262 switch(audInfo->audioObject) |
|
263 { |
|
264 case AAC_MAIN: |
|
265 case AAC_LC: |
|
266 case AAC_LTP: |
|
267 progCfg->profile = (int16) audObj; |
|
268 progCfg->sample_rate_idx = audInfo->samplingFreqIdx; |
|
269 if (ReadGASpecificInfo(bs, audInfo, progCfg) == FALSE) |
|
270 { |
|
271 return FALSE; |
|
272 } |
|
273 if(audInfo->samplingFreqIdx != 0xf) |
|
274 audInfo->samplingFrequency = sample_rates[audInfo->samplingFreqIdx]; |
|
275 break; |
|
276 |
|
277 default: |
|
278 audObj = NULL_OBJECT; |
|
279 break; |
|
280 } |
|
281 |
|
282 bitsLeft = (int16) ((bufLen << 3) - BsGetBitsRead(bs)); |
|
283 if(audInfo->extAudioObject != AAC_SBR && bitsLeft >= 16) |
|
284 { |
|
285 audInfo->syncExtensionType = (int16) BsGetBits(bs, 11); |
|
286 if(audInfo->syncExtensionType == 0x2b7) |
|
287 { |
|
288 audInfo->extAudioObject = (AudioObjectType)(BsGetBits(bs, 5) - 1); |
|
289 if(audInfo->extAudioObject == AAC_SBR) |
|
290 { |
|
291 audInfo->sbrPresentFlag = (uint8) BsGetBits(bs, 1); |
|
292 if(audInfo->sbrPresentFlag) |
|
293 { |
|
294 audInfo->extSamplingFreqIdx = (uint8) BsGetBits(bs, 4); |
|
295 if(audInfo->extSamplingFreqIdx == 0xf) |
|
296 audInfo->extSamplingFrequency = (int32) BsGetBits(bs, 24); |
|
297 } |
|
298 } |
|
299 } |
|
300 } |
|
301 |
|
302 return ((audObj == NULL_OBJECT) ? (BOOL) FALSE : (BOOL) TRUE); |
|
303 } |
|
304 |
|
305 BOOL |
|
306 ReadMP4AudioConfig(uint8 *buffer, uint32 bufLen, mp4AACTransportHandle *mp4AAC_ff) |
|
307 { |
|
308 TBitStream bs; |
|
309 BOOL retValue; |
|
310 |
|
311 BsInit(&bs, buffer, bufLen); |
|
312 |
|
313 retValue = ReadAudioSpecificConfig(&bs, &mp4AAC_ff->audioInfo, &mp4AAC_ff->progCfg, bufLen); |
|
314 |
|
315 return (retValue); |
|
316 } |
|
317 |
|
318 void |
|
319 WriteMP4AudioConfig(uint8 *buffer, uint32 bufLen, mp4AACTransportHandle /* *mp4AAC_ff*/) |
|
320 { |
|
321 |
|
322 TBitStream bs; |
|
323 |
|
324 BsInit(&bs, buffer, bufLen); |
|
325 |
|
326 /*-- Change object type to LC. --*/ |
|
327 BsPutBits(&bs, 5, 2); |
|
328 |
|
329 } |
|
330 |
|