OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
mp3dec.c
Go to the documentation of this file.
1/* ***** BEGIN LICENSE BLOCK *****
2 * Version: RCSL 1.0/RPSL 1.0
3 *
4 * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved.
5 *
6 * The contents of this file, and the files included with this file, are
7 * subject to the current version of the RealNetworks Public Source License
8 * Version 1.0 (the "RPSL") available at
9 * http://www.helixcommunity.org/content/rpsl unless you have licensed
10 * the file under the RealNetworks Community Source License Version 1.0
11 * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
12 * in which case the RCSL will apply. You may also obtain the license terms
13 * directly from RealNetworks. You may not use this file except in
14 * compliance with the RPSL or, if you have a valid RCSL with RealNetworks
15 * applicable to this file, the RCSL. Please see the applicable RPSL or
16 * RCSL for the rights, obligations and limitations governing use of the
17 * contents of the file.
18 *
19 * This file is part of the Helix DNA Technology. RealNetworks is the
20 * developer of the Original Code and owns the copyrights in the portions
21 * it created.
22 *
23 * This file, and the files included with this file, is distributed and made
24 * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
25 * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
26 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
27 * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
28 *
29 * Technology Compatibility Kit Test Suite(s) Location:
30 * http://www.helixcommunity.org/content/tck
31 *
32 * Contributor(s):
33 *
34 * ***** END LICENSE BLOCK ***** */
35
36/**************************************************************************************
37 * Fixed-point MP3 decoder
38 * Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com)
39 * June 2003
40 *
41 * mp3dec.c - platform-independent top level MP3 decoder API
42 **************************************************************************************/
43
44#include "mp3compat.h"
45//#include "hlxclib/string.h" /* for memmove, memcpy (can replace with different implementations if desired) */
46#include "mp3common.h" /* includes mp3dec.h (public API) and internal, platform-independent API */
47
48//#define PROFILE
49#ifdef PROFILE
50#include "systime.h"
51#endif
52
53/**************************************************************************************
54 * Function: MP3InitDecoder
55 *
56 * Description: allocate memory for platform-specific data
57 * clear all the user-accessible fields
58 *
59 * Inputs: none
60 *
61 * Outputs: none
62 *
63 * Return: handle to mp3 decoder instance, 0 if malloc fails
64 **************************************************************************************/
66{
67 MP3DecInfo *mp3DecInfo;
68
69 mp3DecInfo = AllocateBuffers();
70
71 return (HMP3Decoder)mp3DecInfo;
72}
73
74/**************************************************************************************
75 * Function: MP3FreeDecoder
76 *
77 * Description: free platform-specific data allocated by InitMP3Decoder
78 * zero out the contents of MP3DecInfo struct
79 *
80 * Inputs: valid MP3 decoder instance pointer (HMP3Decoder)
81 *
82 * Outputs: none
83 *
84 * Return: none
85 **************************************************************************************/
86void MP3FreeDecoder(HMP3Decoder hMP3Decoder)
87{
88 MP3DecInfo *mp3DecInfo = (MP3DecInfo *)hMP3Decoder;
89
90 if (!mp3DecInfo)
91 return;
92
93 FreeBuffers(mp3DecInfo);
94}
95
96/**************************************************************************************
97 * Function: MP3FindSyncWord
98 *
99 * Description: locate the next byte-alinged sync word in the raw mp3 stream
100 *
101 * Inputs: buffer to search for sync word
102 * max number of bytes to search in buffer
103 *
104 * Outputs: none
105 *
106 * Return: offset to first sync word (bytes from start of buf)
107 * -1 if sync not found after searching nBytes
108 **************************************************************************************/
109int MP3FindSyncWord(unsigned char *buf, int nBytes)
110{
111 int i;
112
113 /* find byte-aligned syncword - need 12 (MPEG 1,2) or 11 (MPEG 2.5) matching bits */
114 for (i = 0; i < nBytes - 1; i++) {
115 if ( (buf[i+0] & SYNCWORDH) == SYNCWORDH && (buf[i+1] & SYNCWORDL) == SYNCWORDL )
116 return i;
117 }
118
119 return -1;
120}
121
122/**************************************************************************************
123 * Function: MP3FindFreeSync
124 *
125 * Description: figure out number of bytes between adjacent sync words in "free" mode
126 *
127 * Inputs: buffer to search for next sync word
128 * the 4-byte frame header starting at the current sync word
129 * max number of bytes to search in buffer
130 *
131 * Outputs: none
132 *
133 * Return: offset to next sync word, minus any pad byte (i.e. nSlots)
134 * -1 if sync not found after searching nBytes
135 *
136 * Notes: this checks that the first 22 bits of the next frame header are the
137 * same as the current frame header, but it's still not foolproof
138 * (could accidentally find a sequence in the bitstream which
139 * appears to match but is not actually the next frame header)
140 * this could be made more error-resilient by checking several frames
141 * in a row and verifying that nSlots is the same in each case
142 * since free mode requires CBR (see spec) we generally only call
143 * this function once (first frame) then store the result (nSlots)
144 * and just use it from then on
145 **************************************************************************************/
146static int MP3FindFreeSync(unsigned char *buf, unsigned char firstFH[4], int nBytes)
147{
148 int offset = 0;
149 unsigned char *bufPtr = buf;
150
151 /* loop until we either:
152 * - run out of nBytes (FindMP3SyncWord() returns -1)
153 * - find the next valid frame header (sync word, version, layer, CRC flag, bitrate, and sample rate
154 * in next header must match current header)
155 */
156 while (1) {
157 offset = MP3FindSyncWord(bufPtr, nBytes);
158 bufPtr += offset;
159 if (offset < 0) {
160 return -1;
161 } else if ( (bufPtr[0] == firstFH[0]) && (bufPtr[1] == firstFH[1]) && ((bufPtr[2] & 0xfc) == (firstFH[2] & 0xfc)) ) {
162 /* want to return number of bytes per frame, NOT counting the padding byte, so subtract one if padFlag == 1 */
163 if ((firstFH[2] >> 1) & 0x01)
164 bufPtr--;
165 return (int)(bufPtr - buf);
166 }
167 bufPtr += 3;
168 nBytes -= (offset + 3);
169 };
170
171 return -1;
172}
173
174/**************************************************************************************
175 * Function: MP3GetLastFrameInfo
176 *
177 * Description: get info about last MP3 frame decoded (number of sampled decoded,
178 * sample rate, bitrate, etc.)
179 *
180 * Inputs: valid MP3 decoder instance pointer (HMP3Decoder)
181 * pointer to MP3FrameInfo struct
182 *
183 * Outputs: filled-in MP3FrameInfo struct
184 *
185 * Return: none
186 *
187 * Notes: call this right after calling MP3Decode
188 **************************************************************************************/
189void MP3GetLastFrameInfo(HMP3Decoder hMP3Decoder, MP3FrameInfo *mp3FrameInfo)
190{
191 MP3DecInfo *mp3DecInfo = (MP3DecInfo *)hMP3Decoder;
192
193 if (!mp3DecInfo || mp3DecInfo->layer != 3) {
194 mp3FrameInfo->bitrate = 0;
195 mp3FrameInfo->nChans = 0;
196 mp3FrameInfo->samprate = 0;
197 mp3FrameInfo->bitsPerSample = 0;
198 mp3FrameInfo->outputSamps = 0;
199 mp3FrameInfo->layer = 0;
200 mp3FrameInfo->version = 0;
201 } else {
202 mp3FrameInfo->bitrate = mp3DecInfo->bitrate;
203 mp3FrameInfo->nChans = mp3DecInfo->nChans;
204 mp3FrameInfo->samprate = mp3DecInfo->samprate;
205 mp3FrameInfo->bitsPerSample = 16;
206 mp3FrameInfo->outputSamps = mp3DecInfo->nChans * (int)samplesPerFrameTab[mp3DecInfo->version][mp3DecInfo->layer - 1];
207 mp3FrameInfo->layer = mp3DecInfo->layer;
208 mp3FrameInfo->version = mp3DecInfo->version;
209 }
210}
211
212/**************************************************************************************
213 * Function: MP3GetNextFrameInfo
214 *
215 * Description: parse MP3 frame header
216 *
217 * Inputs: valid MP3 decoder instance pointer (HMP3Decoder)
218 * pointer to MP3FrameInfo struct
219 * pointer to buffer containing valid MP3 frame header (located using
220 * MP3FindSyncWord(), above)
221 *
222 * Outputs: filled-in MP3FrameInfo struct
223 *
224 * Return: error code, defined in mp3dec.h (0 means no error, < 0 means error)
225 **************************************************************************************/
226int MP3GetNextFrameInfo(HMP3Decoder hMP3Decoder, MP3FrameInfo *mp3FrameInfo, unsigned char *buf)
227{
228 MP3DecInfo *mp3DecInfo = (MP3DecInfo *)hMP3Decoder;
229
230 if (!mp3DecInfo)
232
233 if (UnpackFrameHeader(mp3DecInfo, buf) == -1 || mp3DecInfo->layer != 3)
235
236 MP3GetLastFrameInfo(mp3DecInfo, mp3FrameInfo);
237
238 return ERR_MP3_NONE;
239}
240
241/**************************************************************************************
242 * Function: MP3ClearBadFrame
243 *
244 * Description: zero out pcm buffer if error decoding MP3 frame
245 *
246 * Inputs: mp3DecInfo struct with correct frame size parameters filled in
247 * pointer pcm output buffer
248 *
249 * Outputs: zeroed out pcm buffer
250 *
251 * Return: none
252 **************************************************************************************/
253static void MP3ClearBadFrame(MP3DecInfo *mp3DecInfo, short *outbuf)
254{
255 int i;
256
257 if (!mp3DecInfo)
258 return;
259
260 for (i = 0; i < mp3DecInfo->nGrans * mp3DecInfo->nGranSamps * mp3DecInfo->nChans; i++)
261 outbuf[i] = 0;
262}
263
264/**************************************************************************************
265 * Function: MP3Decode
266 *
267 * Description: decode one frame of MP3 data
268 *
269 * Inputs: valid MP3 decoder instance pointer (HMP3Decoder)
270 * double pointer to buffer of MP3 data (containing headers + mainData)
271 * number of valid bytes remaining in inbuf
272 * pointer to outbuf, big enough to hold one frame of decoded PCM samples
273 * flag indicating whether MP3 data is normal MPEG format (useSize = 0)
274 * or reformatted as "self-contained" frames (useSize = 1)
275 *
276 * Outputs: PCM data in outbuf, interleaved LRLRLR... if stereo
277 * number of output samples = nGrans * nGranSamps * nChans
278 * updated inbuf pointer, updated bytesLeft
279 *
280 * Return: error code, defined in mp3dec.h (0 means no error, < 0 means error)
281 *
282 * Notes: switching useSize on and off between frames in the same stream
283 * is not supported (bit reservoir is not maintained if useSize on)
284 **************************************************************************************/
285int MP3Decode(HMP3Decoder hMP3Decoder, unsigned char **inbuf, int *bytesLeft, short *outbuf, int useSize)
286{
287 int offset, bitOffset, mainBits, gr, ch, fhBytes, siBytes, freeFrameBytes;
288 int prevBitOffset, sfBlockBits, huffBlockBits;
289 unsigned char *mainPtr;
290 MP3DecInfo *mp3DecInfo = (MP3DecInfo *)hMP3Decoder;
291
292 #ifdef PROFILE
293 long time;
294 #endif
295
296 if (!mp3DecInfo)
298
299 /* unpack frame header */
300 fhBytes = UnpackFrameHeader(mp3DecInfo, *inbuf);
301 if (fhBytes < 0)
302 return ERR_MP3_INVALID_FRAMEHEADER; /* don't clear outbuf since we don't know size (failed to parse header) */
303 *inbuf += fhBytes;
304
305#ifdef PROFILE
306 time = systime_get();
307#endif
308 /* unpack side info */
309 siBytes = UnpackSideInfo(mp3DecInfo, *inbuf);
310 if (siBytes < 0) {
311 MP3ClearBadFrame(mp3DecInfo, outbuf);
313 }
314 *inbuf += siBytes;
315 *bytesLeft -= (fhBytes + siBytes);
316#ifdef PROFILE
317 time = systime_get() - time;
318 printf("UnpackSideInfo: %i ms\n", time);
319#endif
320
321
322 /* if free mode, need to calculate bitrate and nSlots manually, based on frame size */
323 if (mp3DecInfo->bitrate == 0 || mp3DecInfo->freeBitrateFlag) {
324 if (!mp3DecInfo->freeBitrateFlag) {
325 /* first time through, need to scan for next sync word and figure out frame size */
326 mp3DecInfo->freeBitrateFlag = 1;
327 mp3DecInfo->freeBitrateSlots = MP3FindFreeSync(*inbuf, *inbuf - fhBytes - siBytes, *bytesLeft);
328 if (mp3DecInfo->freeBitrateSlots < 0) {
329 MP3ClearBadFrame(mp3DecInfo, outbuf);
331 }
332 freeFrameBytes = mp3DecInfo->freeBitrateSlots + fhBytes + siBytes;
333 mp3DecInfo->bitrate = (freeFrameBytes * mp3DecInfo->samprate * 8) / (mp3DecInfo->nGrans * mp3DecInfo->nGranSamps);
334 }
335 mp3DecInfo->nSlots = mp3DecInfo->freeBitrateSlots + CheckPadBit(mp3DecInfo); /* add pad byte, if required */
336 }
337
338 /* useSize != 0 means we're getting reformatted (RTP) packets (see RFC 3119)
339 * - calling function assembles "self-contained" MP3 frames by shifting any main_data
340 * from the bit reservoir (in previous frames) to AFTER the sync word and side info
341 * - calling function should set mainDataBegin to 0, and tell us exactly how large this
342 * frame is (in bytesLeft)
343 */
344 if (useSize) {
345 mp3DecInfo->nSlots = *bytesLeft;
346 if (mp3DecInfo->mainDataBegin != 0 || mp3DecInfo->nSlots <= 0) {
347 /* error - non self-contained frame, or missing frame (size <= 0), could do loss concealment here */
348 MP3ClearBadFrame(mp3DecInfo, outbuf);
350 }
351
352 /* can operate in-place on reformatted frames */
353 mp3DecInfo->mainDataBytes = mp3DecInfo->nSlots;
354 mainPtr = *inbuf;
355 *inbuf += mp3DecInfo->nSlots;
356 *bytesLeft -= (mp3DecInfo->nSlots);
357 } else {
358 /* out of data - assume last or truncated frame */
359 if (mp3DecInfo->nSlots > *bytesLeft) {
360 MP3ClearBadFrame(mp3DecInfo, outbuf);
362 }
363
364#ifdef PROFILE
365 time = systime_get();
366#endif
367 /* fill main data buffer with enough new data for this frame */
368 if (mp3DecInfo->mainDataBytes >= mp3DecInfo->mainDataBegin) {
369 /* adequate "old" main data available (i.e. bit reservoir) */
370 memmove(mp3DecInfo->mainBuf, mp3DecInfo->mainBuf + mp3DecInfo->mainDataBytes - mp3DecInfo->mainDataBegin, mp3DecInfo->mainDataBegin);
371 memcpy(mp3DecInfo->mainBuf + mp3DecInfo->mainDataBegin, *inbuf, mp3DecInfo->nSlots);
372
373 mp3DecInfo->mainDataBytes = mp3DecInfo->mainDataBegin + mp3DecInfo->nSlots;
374 *inbuf += mp3DecInfo->nSlots;
375 *bytesLeft -= (mp3DecInfo->nSlots);
376 mainPtr = mp3DecInfo->mainBuf;
377 } else {
378 /* not enough data in bit reservoir from previous frames (perhaps starting in middle of file) */
379 memcpy(mp3DecInfo->mainBuf + mp3DecInfo->mainDataBytes, *inbuf, mp3DecInfo->nSlots);
380 mp3DecInfo->mainDataBytes += mp3DecInfo->nSlots;
381 *inbuf += mp3DecInfo->nSlots;
382 *bytesLeft -= (mp3DecInfo->nSlots);
383 MP3ClearBadFrame(mp3DecInfo, outbuf);
385 }
386#ifdef PROFILE
387 time = systime_get() - time;
388 printf("data buffer filling: %i ms\n", time);
389#endif
390
391 }
392 bitOffset = 0;
393 mainBits = mp3DecInfo->mainDataBytes * 8;
394
395 /* decode one complete frame */
396 for (gr = 0; gr < mp3DecInfo->nGrans; gr++) {
397 for (ch = 0; ch < mp3DecInfo->nChans; ch++) {
398
399 #ifdef PROFILE
400 time = systime_get();
401 #endif
402 /* unpack scale factors and compute size of scale factor block */
403 prevBitOffset = bitOffset;
404 offset = UnpackScaleFactors(mp3DecInfo, mainPtr, &bitOffset, mainBits, gr, ch);
405 #ifdef PROFILE
406 time = systime_get() - time;
407 printf("UnpackScaleFactors: %i ms\n", time);
408 #endif
409
410 sfBlockBits = 8*offset - prevBitOffset + bitOffset;
411 huffBlockBits = mp3DecInfo->part23Length[gr][ch] - sfBlockBits;
412 mainPtr += offset;
413 mainBits -= sfBlockBits;
414
415 if (offset < 0 || mainBits < huffBlockBits) {
416 MP3ClearBadFrame(mp3DecInfo, outbuf);
418 }
419
420 #ifdef PROFILE
421 time = systime_get();
422 #endif
423 /* decode Huffman code words */
424 prevBitOffset = bitOffset;
425 offset = DecodeHuffman(mp3DecInfo, mainPtr, &bitOffset, huffBlockBits, gr, ch);
426 if (offset < 0) {
427 MP3ClearBadFrame(mp3DecInfo, outbuf);
429 }
430 #ifdef PROFILE
431 time = systime_get() - time;
432 printf("Huffman: %i ms\n", time);
433 #endif
434
435 mainPtr += offset;
436 mainBits -= (8*offset - prevBitOffset + bitOffset);
437 }
438
439 #ifdef PROFILE
440 time = systime_get();
441 #endif
442 /* dequantize coefficients, decode stereo, reorder short blocks */
443 if (Dequantize(mp3DecInfo, gr) < 0) {
444 MP3ClearBadFrame(mp3DecInfo, outbuf);
446 }
447 #ifdef PROFILE
448 time = systime_get() - time;
449 printf("Dequantize: %i ms\n", time);
450 #endif
451
452 /* alias reduction, inverse MDCT, overlap-add, frequency inversion */
453 for (ch = 0; ch < mp3DecInfo->nChans; ch++)
454 {
455 #ifdef PROFILE
456 time = systime_get();
457 #endif
458 if (IMDCT(mp3DecInfo, gr, ch) < 0) {
459 MP3ClearBadFrame(mp3DecInfo, outbuf);
460 return ERR_MP3_INVALID_IMDCT;
461 }
462 #ifdef PROFILE
463 time = systime_get() - time;
464 printf("IMDCT: %i ms\n", time);
465 #endif
466 }
467
468 #ifdef PROFILE
469 time = systime_get();
470 #endif
471 /* subband transform - if stereo, interleaves pcm LRLRLR */
472 if (Subband(mp3DecInfo, outbuf + gr*mp3DecInfo->nGranSamps*mp3DecInfo->nChans) < 0) {
473 MP3ClearBadFrame(mp3DecInfo, outbuf);
475 }
476 #ifdef PROFILE
477 time = systime_get() - time;
478 printf("Subband: %i ms\n", time);
479 #endif
480
481 }
482 return ERR_MP3_NONE;
483}
#define memmove(dst, src, len)
#define memcpy(Dst, Src, Size)
Definition lzvn.h:57
#define SYNCWORDL
Definition mp3common.h:62
#define SYNCWORDH
Definition mp3common.h:61
void MP3GetLastFrameInfo(HMP3Decoder hMP3Decoder, MP3FrameInfo *mp3FrameInfo)
Definition mp3dec.c:189
int MP3Decode(HMP3Decoder hMP3Decoder, unsigned char **inbuf, int *bytesLeft, short *outbuf, int useSize)
Definition mp3dec.c:285
void MP3FreeDecoder(HMP3Decoder hMP3Decoder)
Definition mp3dec.c:86
HMP3Decoder MP3InitDecoder(void)
Definition mp3dec.c:65
int MP3FindSyncWord(unsigned char *buf, int nBytes)
Definition mp3dec.c:109
int MP3GetNextFrameInfo(HMP3Decoder hMP3Decoder, MP3FrameInfo *mp3FrameInfo, unsigned char *buf)
Definition mp3dec.c:226
void * HMP3Decoder
Definition mp3dec.h:89
@ ERR_MP3_INVALID_SCALEFACT
Definition mp3dec.h:100
@ ERR_MP3_INVALID_IMDCT
Definition mp3dec.h:103
@ ERR_MP3_NONE
Definition mp3dec.h:92
@ ERR_MP3_INDATA_UNDERFLOW
Definition mp3dec.h:93
@ ERR_MP3_MAINDATA_UNDERFLOW
Definition mp3dec.h:94
@ ERR_MP3_INVALID_HUFFCODES
Definition mp3dec.h:101
@ ERR_MP3_INVALID_FRAMEHEADER
Definition mp3dec.h:98
@ ERR_MP3_INVALID_SUBBAND
Definition mp3dec.h:104
@ ERR_MP3_INVALID_DEQUANTIZE
Definition mp3dec.h:102
@ ERR_MP3_FREE_BITRATE_SYNC
Definition mp3dec.h:95
@ ERR_MP3_INVALID_SIDEINFO
Definition mp3dec.h:99
@ ERR_MP3_NULL_POINTER
Definition mp3dec.h:97
#define UnpackScaleFactors
Definition statname.h:71
#define AllocateBuffers
Definition statname.h:66
#define FreeBuffers
Definition statname.h:67
#define Dequantize
Definition statname.h:69
#define UnpackSideInfo
Definition statname.h:65
#define DecodeHuffman
Definition statname.h:68
#define samplesPerFrameTab
Definition statname.h:76
#define UnpackFrameHeader
Definition statname.h:64
#define IMDCT
Definition statname.h:70
#define CheckPadBit
Definition statname.h:63
#define Subband
Definition statname.h:72
MPEGVersion version
Definition mp3common.h:89
int part23Length[MAX_NGRAN][MAX_NCHAN]
Definition mp3common.h:94
int mainDataBegin
Definition mp3common.h:91
int mainDataBytes
Definition mp3common.h:92
int freeBitrateSlots
Definition mp3common.h:79
unsigned char mainBuf[MAINBUF_SIZE]
Definition mp3common.h:75
int freeBitrateFlag
Definition mp3common.h:78
int nGranSamps
Definition mp3common.h:86
int outputSamps
Definition mp3dec.h:114
int bitsPerSample
Definition mp3dec.h:113