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 External Objects Needed |
|
22 *************************************************************************/ |
|
23 |
|
24 /*-- Project Headers --*/ |
|
25 #include "mstream.h" |
|
26 #include "mpheader.h" |
|
27 #include "mp3Tool.h" |
|
28 |
|
29 |
|
30 |
|
31 CIII_Channel_Info* CIII_Channel_Info::NewL() |
|
32 { |
|
33 |
|
34 |
|
35 CIII_Channel_Info* self = new (ELeave) CIII_Channel_Info(); |
|
36 CleanupStack::PushL(self); |
|
37 self->ConstructL(); |
|
38 CleanupStack::Pop(self); |
|
39 return self; |
|
40 } |
|
41 |
|
42 void CIII_Channel_Info::ConstructL() |
|
43 { |
|
44 |
|
45 } |
|
46 |
|
47 CIII_Channel_Info::CIII_Channel_Info() |
|
48 { |
|
49 |
|
50 |
|
51 } |
|
52 |
|
53 CIII_Channel_Info::~CIII_Channel_Info() |
|
54 { |
|
55 |
|
56 |
|
57 } |
|
58 |
|
59 |
|
60 CIII_SfbData* CIII_SfbData::NewL() |
|
61 { |
|
62 |
|
63 CIII_SfbData* self = new (ELeave) CIII_SfbData(); |
|
64 CleanupStack::PushL(self); |
|
65 self->ConstructL(); |
|
66 CleanupStack::Pop(self); |
|
67 return self; |
|
68 } |
|
69 |
|
70 void CIII_SfbData::ConstructL() |
|
71 { |
|
72 sfbOffsetLong = new (ELeave) int16[MAX_LONG_SFB_BANDS + 1]; |
|
73 sfbOffsetShort = new (ELeave) int16[MAX_SHORT_SFB_BANDS + 1]; |
|
74 sfbWidthShort = new (ELeave) int16[MAX_SHORT_SFB_BANDS + 1]; |
|
75 } |
|
76 |
|
77 CIII_SfbData::CIII_SfbData() |
|
78 { |
|
79 |
|
80 |
|
81 } |
|
82 |
|
83 CIII_SfbData::~CIII_SfbData() |
|
84 { |
|
85 if (sfbOffsetLong != 0) delete[] sfbOffsetLong; |
|
86 if (sfbOffsetShort != 0) delete[] sfbOffsetShort; |
|
87 if (sfbWidthShort != 0) delete[] sfbWidthShort; |
|
88 |
|
89 } |
|
90 |
|
91 CIII_Side_Info* CIII_Side_Info::NewL() |
|
92 { |
|
93 |
|
94 CIII_Side_Info* self = new (ELeave) CIII_Side_Info(); |
|
95 CleanupStack::PushL(self); |
|
96 self->ConstructL(); |
|
97 CleanupStack::Pop(self); |
|
98 return self; |
|
99 } |
|
100 |
|
101 void CIII_Side_Info::ConstructL() |
|
102 { |
|
103 sfbData = GET_SYMBIAN_CHUNK(CIII_SfbData); |
|
104 |
|
105 } |
|
106 |
|
107 CIII_Side_Info::CIII_Side_Info() |
|
108 { |
|
109 |
|
110 } |
|
111 |
|
112 CIII_Side_Info::~CIII_Side_Info() |
|
113 { |
|
114 if (sfbData != 0) SAFE_SYMBIAN_DELETE(sfbData); |
|
115 |
|
116 } |
|
117 |
|
118 CMCUBuf* CMCUBuf::NewL(TInt aBufLen) |
|
119 { |
|
120 |
|
121 CMCUBuf* self = new (ELeave) CMCUBuf(); |
|
122 CleanupStack::PushL(self); |
|
123 self->ConstructL(aBufLen); |
|
124 CleanupStack::Pop(self); |
|
125 return self; |
|
126 } |
|
127 |
|
128 void CMCUBuf::ConstructL(TInt aBufLen) |
|
129 { |
|
130 |
|
131 bs = new (ELeave) TBitStream(); |
|
132 |
|
133 mcuBufbits = new (ELeave) uint8[aBufLen]; |
|
134 |
|
135 |
|
136 } |
|
137 |
|
138 CMCUBuf::CMCUBuf() |
|
139 { |
|
140 |
|
141 } |
|
142 |
|
143 CMCUBuf::~CMCUBuf() |
|
144 { |
|
145 |
|
146 if (bs != 0) delete bs; |
|
147 if (mcuBufbits != 0) |
|
148 { |
|
149 delete[] mcuBufbits; |
|
150 mcuBufbits = 0; |
|
151 } |
|
152 |
|
153 } |
|
154 |
|
155 /************************************************************************** |
|
156 Title : decode_header |
|
157 |
|
158 Purpose : Reads header information (excluding syncword) from the bitstream. |
|
159 |
|
160 Usage : decode_header(mp) |
|
161 |
|
162 Input : mp - mp3 bitstream parameters |
|
163 |
|
164 Explanation : Header information is commmon to all layers. Note also that |
|
165 this function doesn't interprete the fields of the header. |
|
166 |
|
167 Author(s) : Juha Ojanpera |
|
168 *************************************************************************/ |
|
169 |
|
170 void |
|
171 decode_header(CMP_Stream *mp, TBitStream *bs) |
|
172 { |
|
173 uint32 header; |
|
174 |
|
175 mp->headerOld.header = mp->header->header; |
|
176 header = (!mp->side_info->mpeg25) << HEADER_BITS; |
|
177 header |= BsGetBits(bs, HEADER_BITS); |
|
178 mp->header->header = header; |
|
179 |
|
180 /*-- Store the header bits 16-31 for CRC error checking. --*/ |
|
181 mp->mp3_crc.crc_payload[0] = (uint8)((header >> 8) & 255); |
|
182 mp->mp3_crc.crc_payload[1] = (uint8) (header & 255); |
|
183 |
|
184 if(error_protection(mp->header)) |
|
185 mp->mp3_crc.crc = (int16)(BsGetBits(bs, 16)); |
|
186 } |
|
187 |
|
188 /************************************************************************** |
|
189 Title : FillDataSlotTable |
|
190 |
|
191 Purpose : Pre-computes (to avoid division operation during decoding) |
|
192 the payload size of layer III for all bitrates. |
|
193 |
|
194 Usage : y = FillDataSlotTable(mp) |
|
195 |
|
196 Input : mp - mp3 stream parameters |
|
197 |
|
198 Author(s) : Juha Ojanpera |
|
199 *************************************************************************/ |
|
200 |
|
201 void |
|
202 FillDataSlotTable(CMP_Stream *mp) |
|
203 { |
|
204 const int16 *brTbl; |
|
205 int16 nSlots; |
|
206 |
|
207 brTbl = GetBitRateTable(mp->header); |
|
208 /* |
|
209 * index 0 is free format and index 14 illegal bitrate. |
|
210 */ |
|
211 for(int16 i = 1; i < 15; i++) |
|
212 { |
|
213 nSlots = (int16)((144 * brTbl[i]) / (frequency(mp->header) / 1000.0f)); |
|
214 |
|
215 if(version(mp->header) == MPEG_PHASE2_LSF) |
|
216 nSlots >>= 1; |
|
217 |
|
218 mp->FrameTable[i] = nSlots; |
|
219 |
|
220 nSlots = (int16)(nSlots - (GetSideInfoSlots(mp->header) + 4)); |
|
221 mp->SlotTable[i] = nSlots; |
|
222 } |
|
223 } |
|
224 |
|
225 /************************************************************************** |
|
226 Title : main_data_slots |
|
227 |
|
228 Purpose : Computes the number of bytes for the layer III payload. The |
|
229 payload consists of the scalefactors and quantized data of |
|
230 the channel(s). |
|
231 |
|
232 Usage : y = main_data_slots(mp) |
|
233 |
|
234 Input : mp - mp3 stream parameters |
|
235 |
|
236 Output : y - # of payload bytes for this frame |
|
237 |
|
238 Author(s) : Juha Ojanpera |
|
239 *************************************************************************/ |
|
240 |
|
241 int32 |
|
242 main_data_slots(CMP_Stream *mp) |
|
243 { |
|
244 int16 nSlots; |
|
245 |
|
246 if(bit_rate(mp->header)) |
|
247 { |
|
248 nSlots = mp->SlotTable[bit_rate_idx(mp->header)]; |
|
249 |
|
250 if(padding(mp->header)) |
|
251 nSlots++; |
|
252 if(error_protection(mp->header)) |
|
253 nSlots -= 2; |
|
254 } |
|
255 else |
|
256 { |
|
257 nSlots = mp->FreeFormatSlots; |
|
258 |
|
259 if(padding(mp->header)) |
|
260 nSlots++; |
|
261 } |
|
262 |
|
263 return(nSlots); |
|
264 } |
|
265 |
|
266 /************************************************************************** |
|
267 Title : ReleaseMP3Decoder |
|
268 |
|
269 Purpose : Releases resources allocated to the mp3 decoder core. |
|
270 |
|
271 Usage : ReleaseMP3Decoder(mp) |
|
272 |
|
273 Input : mp - mp3 decoder core |
|
274 |
|
275 Author(s) : Juha Ojanpera |
|
276 *************************************************************************/ |
|
277 |
|
278 void |
|
279 ReleaseMP3Decoder(CMP_Stream *mp) |
|
280 { |
|
281 int16 i, j; |
|
282 |
|
283 if(mp) |
|
284 { |
|
285 /* Scalefactors. */ |
|
286 SAFE_DELETE(mp->frame->scale_factors); |
|
287 |
|
288 /* Quantized samples. */ |
|
289 SAFE_DELETE(mp->frame->quant); |
|
290 |
|
291 /* Synthesis buffer. */ |
|
292 for(i = 0; i < MAX_CHANNELS; i++) |
|
293 { |
|
294 SAFE_DELETE(mp->buffer->synthesis_buffer[i]); |
|
295 } |
|
296 |
|
297 |
|
298 /* Dequantized samples. */ |
|
299 SAFE_DELETE(mp->buffer->reconstructed); |
|
300 |
|
301 /* Huffman codebooks. */ |
|
302 SAFE_DELETE(mp->huffman); |
|
303 |
|
304 if(mp->side_info) |
|
305 { |
|
306 for(i = 0; i < MAX_CHANNELS; i++) |
|
307 { |
|
308 SAFE_DELETE(mp->side_info->ch_info[i]->scale_fac); |
|
309 |
|
310 for(j = 0; j < 2; j++) |
|
311 { |
|
312 SAFE_DELETE(mp->side_info->ch_info[i]->gr_info[j]); |
|
313 } |
|
314 |
|
315 |
|
316 SAFE_SYMBIAN_DELETE(mp->side_info->ch_info[i]); |
|
317 } |
|
318 |
|
319 SAFE_DELETE(mp->side_info->s_mode_long); |
|
320 |
|
321 for(i = 0; i < 3; i++) |
|
322 { |
|
323 SAFE_DELETE(mp->side_info->s_mode_short[i]); |
|
324 } |
|
325 |
|
326 |
|
327 SAFE_SYMBIAN_DELETE(mp->side_info); |
|
328 } |
|
329 |
|
330 SAFE_DELETE(mp->header); |
|
331 SAFE_DELETE(mp->frame); |
|
332 SAFE_DELETE(mp->buffer); |
|
333 SAFE_DELETE(mp->br); |
|
334 // SAFE_DELETE(mp->bs); |
|
335 } |
|
336 } |
|
337 |
|
338 /************************************************************************** |
|
339 Title : GetMP3Handle |
|
340 |
|
341 Purpose : Returns mp3 decoder core handle to the callee. |
|
342 |
|
343 Usage : GetMP3Handle() |
|
344 |
|
345 Output : mp - handle of mp3 decoder core |
|
346 |
|
347 Author(s) : Juha Ojanpera |
|
348 *************************************************************************/ |
|
349 |
|
350 CMP_Stream * |
|
351 GetMP3HandleL(void) |
|
352 { |
|
353 int16 i, j, groups, idx[] = {0, 23, 36, 49, 62, 85, 98, 111}; |
|
354 CIII_Scale_Factors *scale_fac; |
|
355 CMP_Stream *mp; |
|
356 |
|
357 //mp = (CMP_Stream *) GET_CHUNK(sizeof(CMP_Stream)); |
|
358 |
|
359 mp = new (ELeave) CMP_Stream(); |
|
360 IS_ERROR(mp); |
|
361 |
|
362 |
|
363 |
|
364 //mp->bs = (TBitStream *) GET_CHUNK(sizeof(TBitStream)); |
|
365 //IS_ERROR(mp->bs); |
|
366 |
|
367 mp->header = (TMPEG_Header *) GET_CHUNK(sizeof(TMPEG_Header)); |
|
368 IS_ERROR(mp->header); |
|
369 |
|
370 mp->frame = (TMPEG_Frame *) GET_CHUNK(sizeof(TMPEG_Frame)); |
|
371 IS_ERROR(mp->frame); |
|
372 |
|
373 mp->buffer = (TMPEG_Buffer *) GET_CHUNK(sizeof(TMPEG_Buffer)); |
|
374 IS_ERROR(mp->buffer); |
|
375 |
|
376 mp->side_info = (CIII_Side_Info *) GET_SYMBIAN_CHUNK(CIII_Side_Info); |
|
377 IS_ERROR(mp->side_info); |
|
378 |
|
379 mp->frame->scale_factors = (uint8 *) GET_CHUNK(MAX_CHANNELS * SBLIMIT * 3 * sizeof(uint8)); |
|
380 Mem::FillZ (mp->frame->scale_factors, MAX_CHANNELS * SBLIMIT * 3 * sizeof(uint8)); |
|
381 |
|
382 IS_ERROR(mp->frame->scale_factors); |
|
383 |
|
384 mp->huffman = (CHuffman *) GET_CHUNK(33 * sizeof(CHuffman)); |
|
385 IS_ERROR(mp->huffman); |
|
386 |
|
387 mp->br = (TBitStream *) GET_CHUNK(sizeof(TBitStream)); |
|
388 IS_ERROR(mp->br); |
|
389 |
|
390 Mem::Fill(mp->PrevStreamInfo, sizeof(uint32) * 2, 0); |
|
391 |
|
392 for(i = 0; i < MAX_CHANNELS; i++) |
|
393 { |
|
394 //mp->side_info->ch_info[i] = (CIII_Channel_Info *) GET_CHUNK(sizeof(CIII_Channel_Info)); |
|
395 mp->side_info->ch_info[i] = GET_SYMBIAN_CHUNK(CIII_Channel_Info); |
|
396 IS_ERROR(mp->side_info->ch_info[i]); |
|
397 for(j = 0; j < 2; j++) |
|
398 { |
|
399 mp->side_info->ch_info[i]->gr_info[j] = (TGranule_Info *) GET_CHUNK(sizeof(TGranule_Info)); |
|
400 IS_ERROR(mp->side_info->ch_info[i]->gr_info[j]); |
|
401 } |
|
402 } |
|
403 |
|
404 mp->side_info->s_mode_long = (StereoMode *) GET_CHUNK(22 * sizeof(StereoMode)); |
|
405 IS_ERROR(mp->side_info->s_mode_long); |
|
406 for(i = 0; i < 3; i++) |
|
407 { |
|
408 mp->side_info->s_mode_short[i] = (StereoMode *) GET_CHUNK(13 * sizeof(StereoMode)); |
|
409 IS_ERROR(mp->side_info->s_mode_short[i]); |
|
410 } |
|
411 |
|
412 for(i = j = 0; i < MAX_CHANNELS; i++) |
|
413 { |
|
414 mp->side_info->ch_info[i]->scale_fac = (CIII_Scale_Factors *) GET_CHUNK(sizeof(CIII_Scale_Factors)); |
|
415 IS_ERROR(mp->side_info->ch_info[i]->scale_fac); |
|
416 scale_fac = mp->side_info->ch_info[i]->scale_fac; |
|
417 |
|
418 scale_fac->scalefac_long = mp->frame->scale_factors + idx[j++]; |
|
419 scale_fac->scalefac_short[0] = mp->frame->scale_factors + idx[j++]; |
|
420 scale_fac->scalefac_short[1] = mp->frame->scale_factors + idx[j++]; |
|
421 scale_fac->scalefac_short[2] = mp->frame->scale_factors + idx[j++]; |
|
422 } |
|
423 |
|
424 groups = MAX_MONO_SAMPLES * MAX_CHANNELS; |
|
425 |
|
426 TInt a = 0; |
|
427 mp->frame->quant = (int16 *) GET_CHUNK((groups + 10) * sizeof(int16)); |
|
428 for (a = 0 ; a < groups ; a++) mp->frame->quant[a] = 0; |
|
429 |
|
430 IS_ERROR(mp->frame->quant); |
|
431 |
|
432 mp->buffer->reconstructed = (FLOAT *) GET_CHUNK(groups * sizeof(FLOAT)); |
|
433 IS_ERROR(mp->buffer->reconstructed); |
|
434 for (a = 0 ; a < groups ; a++) mp->buffer->reconstructed[a] = 0; |
|
435 |
|
436 for(i = 0; i < MAX_CHANNELS; i++) |
|
437 { |
|
438 mp->frame->ch_quant[i] = mp->frame->quant + i * MAX_MONO_SAMPLES; |
|
439 mp->buffer->ch_reconstructed[i] = mp->buffer->reconstructed + i * MAX_MONO_SAMPLES; |
|
440 for(j = 0; j < SBLIMIT; j++) |
|
441 mp->spectrum[i][j] = &mp->buffer->ch_reconstructed[i][j * SSLIMIT]; |
|
442 } |
|
443 |
|
444 for(i = 0; i < MAX_CHANNELS; i++) |
|
445 { |
|
446 mp->buffer->buf_idx[i] = mp->buffer->dct_idx[i] = 0; |
|
447 mp->buffer->synthesis_buffer[i] = (FLOAT *) GET_CHUNK((HAN_SIZE << 1) * sizeof(FLOAT)); |
|
448 IS_ERROR(mp->buffer->synthesis_buffer[i]); |
|
449 } |
|
450 |
|
451 //-- Get the Huffman codebooks. -- |
|
452 //init_huffman(mp->huffman); |
|
453 InitL3Huffman(mp->huffman); |
|
454 return (mp); |
|
455 |
|
456 // error_exit: |
|
457 |
|
458 //ReleaseMP3Decoder(mp); |
|
459 |
|
460 //return (NULL); |
|
461 } |
|
462 |
|
463 /************************************************************************** |
|
464 Title : MP3DecPrepareInit |
|
465 |
|
466 Purpose : Prepares the core engine parameters for the search of |
|
467 first mp3 frame. |
|
468 |
|
469 Usage : MP3DecPrepareInit(mp, out_param, complex, br_buffer, br_size) |
|
470 |
|
471 Input : mp - handle of mp3 decoder core |
|
472 out_param - output parameters of current track |
|
473 complex - decoding complexity parameters |
|
474 br_buffer - address of bit reservoir buffer |
|
475 br_size - size of bit reservoir buffer |
|
476 |
|
477 Author(s) : Juha Ojanpera |
|
478 *************************************************************************/ |
|
479 |
|
480 void |
|
481 MP3DecPrepareInit(CMP_Stream *mp, Out_Param *out_param, Out_Complexity *complex, |
|
482 DSP_BYTE *br_buffer, uint32 br_size) |
|
483 { |
|
484 mp->complex = complex; |
|
485 mp->out_param = out_param; |
|
486 |
|
487 BsInit2(mp->br, br_buffer, br_size); |
|
488 |
|
489 mp->mp3_crc.crc = 0; |
|
490 |
|
491 mp->header->header = 0; |
|
492 |
|
493 mp->syncInfo.sync_word = (int16)SYNC_WORD; |
|
494 mp->syncInfo.sync_length = (int16)SYNC_WORD_LENGTH; |
|
495 mp->syncInfo.sync_mask = (int16)((1 << mp->syncInfo.sync_length) - 1); |
|
496 mp->syncInfo.sync_status = FIRST_FRAME_WITH_LAYER3; |
|
497 |
|
498 mp->FreeFormatSlots = 0; |
|
499 mp->idx_increment = 0; |
|
500 mp->PrevSlots = 0; |
|
501 mp->FrameStart = 0; |
|
502 mp->SkipBr = FALSE; |
|
503 mp->WasSeeking = FALSE; |
|
504 mp->OverlapBufPtr[0] = mp->OverlapBufPtr[1] = 0; |
|
505 } |
|
506 |
|
507 /************************************************************************** |
|
508 Title : MP3DecCompleteInit |
|
509 |
|
510 Purpose : Completes the initialization of the core engine parameters. |
|
511 |
|
512 Usage : MP3DecPrepareInit(mp, frameBytes) |
|
513 |
|
514 Input : mp - handle of mp3 decoder core |
|
515 |
|
516 Output : frameBytes - # of bytes for the first frame |
|
517 |
|
518 Author(s) : Juha Ojanpera |
|
519 *************************************************************************/ |
|
520 |
|
521 void |
|
522 MP3DecCompleteInit(CMP_Stream *mp, int16 *frameBytes) |
|
523 { |
|
524 //-- Fixed size (unit is bytes !!). -- |
|
525 mp->mp3_crc.bufLen = (uint16)(2 + GetSideInfoSlots(mp->header)); |
|
526 |
|
527 //-- MPEG-1 --/ |
|
528 if(version(mp->header) == MPEG_AUDIO_ID) |
|
529 { |
|
530 mp->side_info->lsf = FALSE; |
|
531 mp->side_info->max_gr = 2; |
|
532 } |
|
533 //-- MPEG-2 LSF or MPEG-2.5 -- |
|
534 else |
|
535 { |
|
536 mp->side_info->lsf = TRUE; |
|
537 mp->side_info->max_gr = 1; |
|
538 } |
|
539 |
|
540 //-- Determine the size of the payload only when necessary. --/ |
|
541 if(bit_rate(mp->header)) |
|
542 { |
|
543 mp->FreeFormatSlots = 0; |
|
544 |
|
545 if((int32)(frequency(mp->header) != mp->PrevStreamInfo[0]) || |
|
546 (int32)(channels(mp->header) != mp->PrevStreamInfo[1])) |
|
547 FillDataSlotTable(mp); |
|
548 } |
|
549 else FillDataSlotTable(mp); |
|
550 |
|
551 mp->PrevStreamInfo[0] = frequency(mp->header); |
|
552 mp->PrevStreamInfo[1] = channels(mp->header); |
|
553 |
|
554 //-- Get the scalefactor band related parameters. --/ |
|
555 III_SfbDataInit(mp->side_info->sfbData, mp->header); |
|
556 |
|
557 //-- Init re-ordering table. --// |
|
558 init_III_reorder(mp->reorder_idx, mp->side_info->sfbData->sfbShort, |
|
559 mp->side_info->sfbData->sfbWidth); |
|
560 |
|
561 //-- Number of bytes for next frame. --/ |
|
562 *frameBytes = (int16)(main_data_slots(mp) + GetSideInfoSlots(mp->header) + 3); |
|
563 if(error_protection(mp->header)) |
|
564 *frameBytes += 2; |
|
565 } |
|