/ src / mp3dec.cpp
mp3dec.cpp
  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 <string.h>		/* for memmove, memcpy (can replace with different implementations if desired) */
 45  #include "mp3common.h"	/* includes mp3dec.h (public API) and internal, platform-independent API */
 46  //#include "hxthreadyield.h"
 47  
 48  /**************************************************************************************
 49   * Function:    MP3InitDecoder
 50   *
 51   * Description: allocate memory for platform-specific data
 52   *              clear all the user-accessible fields
 53   *
 54   * Inputs:      none
 55   *
 56   * Outputs:     none
 57   *
 58   * Return:      handle to mp3 decoder instance, 0 if malloc fails
 59   **************************************************************************************/
 60  HMP3Decoder MP3InitDecoder(void)
 61  {
 62  	MP3DecInfo *mp3DecInfo;
 63  
 64  	mp3DecInfo = AllocateBuffers();
 65  
 66  	return (HMP3Decoder)mp3DecInfo;
 67  }
 68  
 69  /**************************************************************************************
 70   * Function:    MP3FreeDecoder
 71   *
 72   * Description: free platform-specific data allocated by InitMP3Decoder
 73   *              zero out the contents of MP3DecInfo struct
 74   *
 75   * Inputs:      valid MP3 decoder instance pointer (HMP3Decoder)
 76   *
 77   * Outputs:     none
 78   *
 79   * Return:      none
 80   **************************************************************************************/
 81  void MP3FreeDecoder(HMP3Decoder hMP3Decoder)
 82  {
 83  	MP3DecInfo *mp3DecInfo = (MP3DecInfo *)hMP3Decoder;
 84  
 85  	if (!mp3DecInfo)
 86  		return;
 87  
 88  	FreeBuffers(mp3DecInfo);
 89  }
 90  
 91  /**************************************************************************************
 92   * Function:    MP3FindSyncWord
 93   *
 94   * Description: locate the next byte-alinged sync word in the raw mp3 stream
 95   *
 96   * Inputs:      buffer to search for sync word
 97   *              max number of bytes to search in buffer
 98   *
 99   * Outputs:     none
100   *
101   * Return:      offset to first sync word (bytes from start of buf)
102   *              -1 if sync not found after searching nBytes
103   **************************************************************************************/
104  int MP3FindSyncWord(unsigned char *buf, int nBytes)
105  {
106  	int i;
107  
108  	/* find byte-aligned syncword - need 12 (MPEG 1,2) or 11 (MPEG 2.5) matching bits */
109  	for (i = 0; i < nBytes - 1; i++) {
110  		if ( (buf[i+0] & SYNCWORDH) == SYNCWORDH && (buf[i+1] & SYNCWORDL) == SYNCWORDL )
111  			return i;
112  	}
113  	
114  	return -1;
115  }
116  
117  /**************************************************************************************
118   * Function:    MP3FindFreeSync
119   *
120   * Description: figure out number of bytes between adjacent sync words in "free" mode
121   *
122   * Inputs:      buffer to search for next sync word
123   *              the 4-byte frame header starting at the current sync word
124   *              max number of bytes to search in buffer
125   *
126   * Outputs:     none
127   *
128   * Return:      offset to next sync word, minus any pad byte (i.e. nSlots)
129   *              -1 if sync not found after searching nBytes
130   *
131   * Notes:       this checks that the first 22 bits of the next frame header are the
132   *                same as the current frame header, but it's still not foolproof
133   *                (could accidentally find a sequence in the bitstream which 
134   *                 appears to match but is not actually the next frame header)
135   *              this could be made more error-resilient by checking several frames
136   *                in a row and verifying that nSlots is the same in each case
137   *              since free mode requires CBR (see spec) we generally only call
138   *                this function once (first frame) then store the result (nSlots)
139   *                and just use it from then on
140   **************************************************************************************/
141  static int MP3FindFreeSync(unsigned char *buf, unsigned char firstFH[4], int nBytes)
142  {
143  	int offset = 0;
144  	unsigned char *bufPtr = buf;
145  
146  	/* loop until we either: 
147  	 *  - run out of nBytes (FindMP3SyncWord() returns -1)
148  	 *  - find the next valid frame header (sync word, version, layer, CRC flag, bitrate, and sample rate
149  	 *      in next header must match current header)
150  	 */
151  	while (1) {
152  		offset = MP3FindSyncWord(bufPtr, nBytes);
153  		bufPtr += offset;
154  		if (offset < 0) {
155  			return -1;
156  		} else if ( (bufPtr[0] == firstFH[0]) && (bufPtr[1] == firstFH[1]) && ((bufPtr[2] & 0xfc) == (firstFH[2] & 0xfc)) ) {
157  			/* want to return number of bytes per frame, NOT counting the padding byte, so subtract one if padFlag == 1 */
158  			if ((firstFH[2] >> 1) & 0x01)
159  				bufPtr--;
160  			return bufPtr - buf;
161  		}
162  		bufPtr += 3;
163  		nBytes -= (offset + 3);
164  	};
165  
166  	return -1;
167  }
168  
169  /**************************************************************************************
170   * Function:    MP3GetLastFrameInfo
171   *
172   * Description: get info about last MP3 frame decoded (number of sampled decoded, 
173   *                sample rate, bitrate, etc.)
174   *
175   * Inputs:      valid MP3 decoder instance pointer (HMP3Decoder)
176   *              pointer to MP3FrameInfo struct
177   *
178   * Outputs:     filled-in MP3FrameInfo struct
179   *
180   * Return:      none
181   *
182   * Notes:       call this right after calling MP3Decode
183   **************************************************************************************/
184  void MP3GetLastFrameInfo(HMP3Decoder hMP3Decoder, MP3FrameInfo *mp3FrameInfo)
185  {
186  	MP3DecInfo *mp3DecInfo = (MP3DecInfo *)hMP3Decoder;
187  
188  	if (!mp3DecInfo || mp3DecInfo->layer != 3) {
189  		mp3FrameInfo->bitrate = 0;
190  		mp3FrameInfo->nChans = 0;
191  		mp3FrameInfo->samprate = 0;
192  		mp3FrameInfo->bitsPerSample = 0;
193  		mp3FrameInfo->outputSamps = 0;
194  		mp3FrameInfo->layer = 0;
195  		mp3FrameInfo->version = 0;
196  	} else {
197  		mp3FrameInfo->bitrate = mp3DecInfo->bitrate;
198  		mp3FrameInfo->nChans = mp3DecInfo->nChans;
199  		mp3FrameInfo->samprate = mp3DecInfo->samprate;
200  		mp3FrameInfo->bitsPerSample = 16;
201  		mp3FrameInfo->outputSamps = mp3DecInfo->nChans * (int)samplesPerFrameTab[mp3DecInfo->version][mp3DecInfo->layer - 1];
202  		mp3FrameInfo->layer = mp3DecInfo->layer;
203  		mp3FrameInfo->version = mp3DecInfo->version;
204  	}
205  }
206  
207  /**************************************************************************************
208   * Function:    MP3GetNextFrameInfo
209   *
210   * Description: parse MP3 frame header
211   *
212   * Inputs:      valid MP3 decoder instance pointer (HMP3Decoder)
213   *              pointer to MP3FrameInfo struct
214   *              pointer to buffer containing valid MP3 frame header (located using 
215   *                MP3FindSyncWord(), above)
216   *
217   * Outputs:     filled-in MP3FrameInfo struct
218   *
219   * Return:      error code, defined in mp3dec.h (0 means no error, < 0 means error)
220   **************************************************************************************/
221  int MP3GetNextFrameInfo(HMP3Decoder hMP3Decoder, MP3FrameInfo *mp3FrameInfo, unsigned char *buf)
222  {
223  	MP3DecInfo *mp3DecInfo = (MP3DecInfo *)hMP3Decoder;
224  
225  	if (!mp3DecInfo)
226  		return ERR_MP3_NULL_POINTER;
227  
228  	if (UnpackFrameHeader(mp3DecInfo, buf) == -1 || mp3DecInfo->layer != 3)
229  		return ERR_MP3_INVALID_FRAMEHEADER;
230  
231  	MP3GetLastFrameInfo(mp3DecInfo, mp3FrameInfo);
232  
233  	return ERR_MP3_NONE;
234  }
235  
236  /**************************************************************************************
237   * Function:    MP3ClearBadFrame
238   *
239   * Description: zero out pcm buffer if error decoding MP3 frame
240   *
241   * Inputs:      mp3DecInfo struct with correct frame size parameters filled in
242   *              pointer pcm output buffer
243   *
244   * Outputs:     zeroed out pcm buffer
245   *
246   * Return:      none
247   **************************************************************************************/
248  static void MP3ClearBadFrame(MP3DecInfo *mp3DecInfo, short *outbuf)
249  {
250  	int i;
251  
252  	if (!mp3DecInfo)
253  		return;
254  
255  	for (i = 0; i < mp3DecInfo->nGrans * mp3DecInfo->nGranSamps * mp3DecInfo->nChans; i++)
256  		outbuf[i] = 0;
257  }
258  
259  /**************************************************************************************
260   * Function:    MP3Decode
261   *
262   * Description: decode one frame of MP3 data
263   *
264   * Inputs:      valid MP3 decoder instance pointer (HMP3Decoder)
265   *              double pointer to buffer of MP3 data (containing headers + mainData)
266   *              number of valid bytes remaining in inbuf
267   *              pointer to outbuf, big enough to hold one frame of decoded PCM samples
268   *              flag indicating whether MP3 data is normal MPEG format (useSize = 0)
269   *                or reformatted as "self-contained" frames (useSize = 1)
270   *
271   * Outputs:     PCM data in outbuf, interleaved LRLRLR... if stereo
272   *                number of output samples = nGrans * nGranSamps * nChans
273   *              updated inbuf pointer, updated bytesLeft
274   *
275   * Return:      error code, defined in mp3dec.h (0 means no error, < 0 means error)
276   *
277   * Notes:       switching useSize on and off between frames in the same stream 
278   *                is not supported (bit reservoir is not maintained if useSize on)
279   **************************************************************************************/
280  int MP3Decode(HMP3Decoder hMP3Decoder, unsigned char **inbuf, int *bytesLeft, short *outbuf, int useSize)
281  {
282  	int offset, bitOffset, mainBits, gr, ch, fhBytes, siBytes, freeFrameBytes;
283  	int prevBitOffset, sfBlockBits, huffBlockBits;
284  	unsigned char *mainPtr;
285  	MP3DecInfo *mp3DecInfo = (MP3DecInfo *)hMP3Decoder;
286  //	ULONG32 ulTime;
287  //	StartYield(&ulTime);
288  	if (!mp3DecInfo)
289  		return ERR_MP3_NULL_POINTER;
290  
291  	/* unpack frame header */
292  	fhBytes = UnpackFrameHeader(mp3DecInfo, *inbuf);
293  	if (fhBytes < 0)	
294  		return ERR_MP3_INVALID_FRAMEHEADER;		/* don't clear outbuf since we don't know size (failed to parse header) */
295  	*inbuf += fhBytes;
296  	
297  	/* unpack side info */
298  	siBytes = UnpackSideInfo(mp3DecInfo, *inbuf);
299  	if (siBytes < 0) {
300  		MP3ClearBadFrame(mp3DecInfo, outbuf);
301  		return ERR_MP3_INVALID_SIDEINFO;
302  	}
303  	*inbuf += siBytes;
304  	*bytesLeft -= (fhBytes + siBytes);
305  	
306  	/* if free mode, need to calculate bitrate and nSlots manually, based on frame size */
307  	if (mp3DecInfo->bitrate == 0 || mp3DecInfo->freeBitrateFlag) {
308  		if (!mp3DecInfo->freeBitrateFlag) {
309  			/* first time through, need to scan for next sync word and figure out frame size */
310  			mp3DecInfo->freeBitrateFlag = 1;
311  			mp3DecInfo->freeBitrateSlots = MP3FindFreeSync(*inbuf, *inbuf - fhBytes - siBytes, *bytesLeft);
312  			if (mp3DecInfo->freeBitrateSlots < 0) {
313  				MP3ClearBadFrame(mp3DecInfo, outbuf);
314  				return ERR_MP3_FREE_BITRATE_SYNC;
315  			}
316  			freeFrameBytes = mp3DecInfo->freeBitrateSlots + fhBytes + siBytes;
317  			mp3DecInfo->bitrate = (freeFrameBytes * mp3DecInfo->samprate * 8) / (mp3DecInfo->nGrans * mp3DecInfo->nGranSamps);
318  		}
319  		mp3DecInfo->nSlots = mp3DecInfo->freeBitrateSlots + CheckPadBit(mp3DecInfo);	/* add pad byte, if required */
320  	}
321  
322  	/* useSize != 0 means we're getting reformatted (RTP) packets (see RFC 3119)
323  	 *  - calling function assembles "self-contained" MP3 frames by shifting any main_data 
324  	 *      from the bit reservoir (in previous frames) to AFTER the sync word and side info
325  	 *  - calling function should set mainDataBegin to 0, and tell us exactly how large this
326  	 *      frame is (in bytesLeft)
327  	 */
328  	if (useSize) {
329  		mp3DecInfo->nSlots = *bytesLeft;
330  		if (mp3DecInfo->mainDataBegin != 0 || mp3DecInfo->nSlots <= 0) {
331  			/* error - non self-contained frame, or missing frame (size <= 0), could do loss concealment here */
332  			MP3ClearBadFrame(mp3DecInfo, outbuf);
333  			return ERR_MP3_INVALID_FRAMEHEADER;
334  		}
335  
336  		/* can operate in-place on reformatted frames */
337  		mp3DecInfo->mainDataBytes = mp3DecInfo->nSlots;
338  		mainPtr = *inbuf;
339  		*inbuf += mp3DecInfo->nSlots;
340  		*bytesLeft -= (mp3DecInfo->nSlots);
341  	} else {
342  		/* out of data - assume last or truncated frame */
343  		if (mp3DecInfo->nSlots > *bytesLeft) {
344  			MP3ClearBadFrame(mp3DecInfo, outbuf);
345  			return ERR_MP3_INDATA_UNDERFLOW;	
346  		}
347  		/* fill main data buffer with enough new data for this frame */
348  		if (mp3DecInfo->mainDataBytes >= mp3DecInfo->mainDataBegin) {
349  			/* adequate "old" main data available (i.e. bit reservoir) */
350  			memmove(mp3DecInfo->mainBuf, mp3DecInfo->mainBuf + mp3DecInfo->mainDataBytes - mp3DecInfo->mainDataBegin, mp3DecInfo->mainDataBegin);
351  			memcpy(mp3DecInfo->mainBuf + mp3DecInfo->mainDataBegin, *inbuf, mp3DecInfo->nSlots);
352  
353  			mp3DecInfo->mainDataBytes = mp3DecInfo->mainDataBegin + mp3DecInfo->nSlots;
354  			*inbuf += mp3DecInfo->nSlots;
355  			*bytesLeft -= (mp3DecInfo->nSlots);
356  			mainPtr = mp3DecInfo->mainBuf;
357  		} else {
358  			/* not enough data in bit reservoir from previous frames (perhaps starting in middle of file) */
359  			memcpy(mp3DecInfo->mainBuf + mp3DecInfo->mainDataBytes, *inbuf, mp3DecInfo->nSlots);
360  			mp3DecInfo->mainDataBytes += mp3DecInfo->nSlots;
361  			*inbuf += mp3DecInfo->nSlots;
362  			*bytesLeft -= (mp3DecInfo->nSlots);
363  			MP3ClearBadFrame(mp3DecInfo, outbuf);
364  			return ERR_MP3_MAINDATA_UNDERFLOW;
365  		}
366  	}
367  	bitOffset = 0;
368  	mainBits = mp3DecInfo->mainDataBytes * 8;
369  
370  	/* decode one complete frame */
371  	for (gr = 0; gr < mp3DecInfo->nGrans; gr++) {
372  		for (ch = 0; ch < mp3DecInfo->nChans; ch++) {
373  			/* unpack scale factors and compute size of scale factor block */
374  			prevBitOffset = bitOffset;
375  			offset = UnpackScaleFactors(mp3DecInfo, mainPtr, &bitOffset, mainBits, gr, ch);
376  
377  			sfBlockBits = 8*offset - prevBitOffset + bitOffset;
378  			huffBlockBits = mp3DecInfo->part23Length[gr][ch] - sfBlockBits;
379  			mainPtr += offset;
380  			mainBits -= sfBlockBits;
381  
382  			if (offset < 0 || mainBits < huffBlockBits) {
383  				MP3ClearBadFrame(mp3DecInfo, outbuf);
384  				return ERR_MP3_INVALID_SCALEFACT;
385  			}
386  
387  			/* decode Huffman code words */
388  			prevBitOffset = bitOffset;
389  			offset = DecodeHuffman(mp3DecInfo, mainPtr, &bitOffset, huffBlockBits, gr, ch);
390  			if (offset < 0) {
391  				MP3ClearBadFrame(mp3DecInfo, outbuf);
392  				return ERR_MP3_INVALID_HUFFCODES;
393  			}
394  
395  			mainPtr += offset;
396  			mainBits -= (8*offset - prevBitOffset + bitOffset);
397  		}
398  //		YieldIfRequired(&ulTime);
399  		/* dequantize coefficients, decode stereo, reorder short blocks */
400  		if (Dequantize(mp3DecInfo, gr) < 0) {
401  			MP3ClearBadFrame(mp3DecInfo, outbuf);
402  			return ERR_MP3_INVALID_DEQUANTIZE;			
403  		}
404  
405  		/* alias reduction, inverse MDCT, overlap-add, frequency inversion */
406  		for (ch = 0; ch < mp3DecInfo->nChans; ch++)
407  			if (IMDCT(mp3DecInfo, gr, ch) < 0) {
408  				MP3ClearBadFrame(mp3DecInfo, outbuf);
409  				return ERR_MP3_INVALID_IMDCT;			
410  			}
411  
412  		/* subband transform - if stereo, interleaves pcm LRLRLR */
413  		if (Subband(mp3DecInfo, outbuf + gr*mp3DecInfo->nGranSamps*mp3DecInfo->nChans) < 0) {
414  			MP3ClearBadFrame(mp3DecInfo, outbuf);
415  			return ERR_MP3_INVALID_SUBBAND;			
416  		}
417  	}
418  	return ERR_MP3_NONE;
419  }