/ src / scalfact.cpp
scalfact.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   * scalfact.c - scalefactor unpacking functions
 42   **************************************************************************************/
 43  
 44  #include "coder.h"
 45  
 46  /* scale factor lengths (num bits) */
 47  static const char SFLenTab[16][2] = {
 48  	{0, 0},    {0, 1},
 49  	{0, 2},    {0, 3},
 50  	{3, 0},    {1, 1},
 51  	{1, 2},    {1, 3},
 52  	{2, 1},    {2, 2},
 53  	{2, 3},    {3, 1},
 54  	{3, 2},    {3, 3},
 55  	{4, 2},    {4, 3},
 56  };
 57  
 58  /**************************************************************************************
 59   * Function:    UnpackSFMPEG1
 60   *
 61   * Description: unpack MPEG 1 scalefactors from bitstream
 62   *
 63   * Inputs:      BitStreamInfo, SideInfoSub, ScaleFactorInfoSub structs for this
 64   *                granule/channel
 65   *              vector of scfsi flags from side info, length = 4 (MAX_SCFBD)
 66   *              index of current granule
 67   *              ScaleFactorInfoSub from granule 0 (for granule 1, if scfsi[i] is set, 
 68   *                then we just replicate the scale factors from granule 0 in the
 69   *                i'th set of scalefactor bands)
 70   *
 71   * Outputs:     updated BitStreamInfo struct
 72   *              scalefactors in sfis (short and/or long arrays, as appropriate)
 73   *
 74   * Return:      none
 75   *
 76   * Notes:       set order of short blocks to s[band][window] instead of s[window][band]
 77   *                so that we index through consectutive memory locations when unpacking 
 78   *                (make sure dequantizer follows same convention)
 79   *              Illegal Intensity Position = 7 (always) for MPEG1 scale factors
 80   **************************************************************************************/
 81  static void UnpackSFMPEG1(BitStreamInfo *bsi, SideInfoSub *sis, ScaleFactorInfoSub *sfis, int *scfsi, int gr, ScaleFactorInfoSub *sfisGr0)
 82  {
 83  	int sfb;
 84  	int slen0, slen1;
 85  	
 86  	/* these can be 0, so make sure GetBits(bsi, 0) returns 0 (no >> 32 or anything) */
 87  	slen0 = (int)SFLenTab[sis->sfCompress][0];
 88  	slen1 = (int)SFLenTab[sis->sfCompress][1];
 89  	
 90  	if (sis->blockType == 2) {
 91  		/* short block, type 2 (implies winSwitchFlag == 1) */
 92  		if (sis->mixedBlock) {          
 93  			/* do long block portion */
 94  			for (sfb = 0; sfb < 8; sfb++)
 95  				sfis->l[sfb] =    (char)GetBits(bsi, slen0);
 96  			sfb = 3;
 97  		} else {
 98  			/* all short blocks */
 99  			sfb = 0;
100  		}
101  
102  		for (      ; sfb < 6; sfb++) {
103  			sfis->s[sfb][0] = (char)GetBits(bsi, slen0);
104  			sfis->s[sfb][1] = (char)GetBits(bsi, slen0);
105  			sfis->s[sfb][2] = (char)GetBits(bsi, slen0);
106  		}
107  
108  		for (      ; sfb < 12; sfb++) {
109  			sfis->s[sfb][0] = (char)GetBits(bsi, slen1);
110  			sfis->s[sfb][1] = (char)GetBits(bsi, slen1);
111  			sfis->s[sfb][2] = (char)GetBits(bsi, slen1);
112  		}
113  
114  		/* last sf band not transmitted */
115  		sfis->s[12][0] = sfis->s[12][1] = sfis->s[12][2] = 0;
116  	} else {
117  		/* long blocks, type 0, 1, or 3 */
118  		if(gr == 0) {
119  			/* first granule */
120  			for (sfb = 0;  sfb < 11; sfb++) 
121  				sfis->l[sfb] = (char)GetBits(bsi, slen0);
122  			for (sfb = 11; sfb < 21; sfb++) 
123  				sfis->l[sfb] = (char)GetBits(bsi, slen1);
124  			return;
125  		} else {
126  			/* second granule
127  			 * scfsi: 0 = different scalefactors for each granule, 1 = copy sf's from granule 0 into granule 1 
128  			 * for block type == 2, scfsi is always 0
129  			 */
130  			sfb = 0;
131  			if(scfsi[0])  for(  ; sfb < 6 ; sfb++) sfis->l[sfb] = sfisGr0->l[sfb];
132  			else          for(  ; sfb < 6 ; sfb++) sfis->l[sfb] = (char)GetBits(bsi, slen0);
133  			if(scfsi[1])  for(  ; sfb <11 ; sfb++) sfis->l[sfb] = sfisGr0->l[sfb];
134  			else          for(  ; sfb <11 ; sfb++) sfis->l[sfb] = (char)GetBits(bsi, slen0);
135  			if(scfsi[2])  for(  ; sfb <16 ; sfb++) sfis->l[sfb] = sfisGr0->l[sfb];
136  			else          for(  ; sfb <16 ; sfb++) sfis->l[sfb] = (char)GetBits(bsi, slen1);
137  			if(scfsi[3])  for(  ; sfb <21 ; sfb++) sfis->l[sfb] = sfisGr0->l[sfb];
138  			else          for(  ; sfb <21 ; sfb++) sfis->l[sfb] = (char)GetBits(bsi, slen1);
139  		}
140  		/* last sf band not transmitted */
141  		sfis->l[21] = 0;
142  		sfis->l[22] = 0;
143  	}
144  }
145  
146  /* NRTab[size + 3*is_right][block type][partition]
147   *   block type index: 0 = (bt0,bt1,bt3), 1 = bt2 non-mixed, 2 = bt2 mixed
148   *   partition: scale factor groups (sfb1 through sfb4)
149   * for block type = 2 (mixed or non-mixed) / by 3 is rolled into this table
150   *   (for 3 short blocks per long block)
151   * see 2.4.3.2 in MPEG 2 (low sample rate) spec
152   * stuff rolled into this table:
153   *   NRTab[x][1][y]   --> (NRTab[x][1][y])   / 3
154   *   NRTab[x][2][>=1] --> (NRTab[x][2][>=1]) / 3  (first partition is long block)
155   */
156  static const char NRTab[6][3][4] = {
157  	/* non-intensity stereo */
158  	{	{6, 5, 5, 5},		
159  		{3, 3, 3, 3},	/* includes / 3 */	
160  		{6, 3, 3, 3},   /* includes / 3 except for first entry */
161  	},
162  	{	{6, 5, 7, 3}, 
163  		{3, 3, 4, 2},
164  		{6, 3, 4, 2},
165  	},
166  	{	{11, 10, 0, 0},
167  		{6, 6, 0, 0},
168  		{6, 3, 6, 0},  /* spec = [15,18,0,0], but 15 = 6L + 9S, so move 9/3=3 into col 1, 18/3=6 into col 2 and adj. slen[1,2] below */
169  	},
170  	/* intensity stereo, right chan */
171  	{	{7, 7, 7, 0},
172  		{4, 4, 4, 0},
173  		{6, 5, 4, 0},
174  	},
175  	{	{6, 6, 6, 3}, 
176  		{4, 3, 3, 2},
177  		{6, 4, 3, 2},
178  	},
179  	{	{8, 8, 5, 0},
180  		{5, 4, 3, 0},
181  		{6, 6, 3, 0},
182  	}
183  };
184  
185  /**************************************************************************************
186   * Function:    UnpackSFMPEG2
187   *
188   * Description: unpack MPEG 2 scalefactors from bitstream
189   *
190   * Inputs:      BitStreamInfo, SideInfoSub, ScaleFactorInfoSub structs for this
191   *                granule/channel
192   *              index of current granule and channel
193   *              ScaleFactorInfoSub from this granule 
194   *              modeExt field from frame header, to tell whether intensity stereo is on
195   *              ScaleFactorJS struct for storing IIP info used in Dequant()
196   *
197   * Outputs:     updated BitStreamInfo struct
198   *              scalefactors in sfis (short and/or long arrays, as appropriate)
199   *              updated intensityScale and preFlag flags
200   *
201   * Return:      none
202   *
203   * Notes:       Illegal Intensity Position = (2^slen) - 1 for MPEG2 scale factors
204   *
205   * TODO:        optimize the / and % stuff (only do one divide, get modulo x 
206   *                with (x / m) * m, etc.)
207   **************************************************************************************/
208  static void UnpackSFMPEG2(BitStreamInfo *bsi, SideInfoSub *sis, ScaleFactorInfoSub *sfis, int gr, int ch, int modeExt, ScaleFactorJS *sfjs)
209  {
210  
211  	int i, sfb, sfcIdx, btIdx, nrIdx, iipTest;
212  	int slen[4], nr[4];
213  	int sfCompress, preFlag, intensityScale;
214  	
215  	sfCompress = sis->sfCompress;
216  	preFlag = 0;
217  	intensityScale = 0;
218  
219  	/* stereo mode bits (1 = on): bit 1 = mid-side on/off, bit 0 = intensity on/off */
220  	if (! ((modeExt & 0x01) && (ch == 1)) ) {
221  		/* in other words: if ((modeExt & 0x01) == 0 || ch == 0) */
222  		if (sfCompress < 400) {
223  			/* max slen = floor[(399/16) / 5] = 4 */
224  			slen[0] = (sfCompress >> 4) / 5;
225  			slen[1]= (sfCompress >> 4) % 5;
226  			slen[2]= (sfCompress & 0x0f) >> 2;
227  			slen[3]= (sfCompress & 0x03);
228  			sfcIdx = 0;
229  		} else if (sfCompress < 500) {
230  			/* max slen = floor[(99/4) / 5] = 4 */
231  			sfCompress -= 400;
232  			slen[0] = (sfCompress >> 2) / 5;
233  			slen[1]= (sfCompress >> 2) % 5;
234  			slen[2]= (sfCompress & 0x03);
235  			slen[3]= 0;
236  			sfcIdx = 1;
237  		} else {
238  			/* max slen = floor[11/3] = 3 (sfCompress = 9 bits in MPEG2) */
239  			sfCompress -= 500;
240  			slen[0] = sfCompress / 3;
241  			slen[1] = sfCompress % 3;
242  			slen[2] = slen[3] = 0;
243  			if (sis->mixedBlock) {
244  				/* adjust for long/short mix logic (see comment above in NRTab[] definition) */
245  				slen[2] = slen[1];  
246  				slen[1] = slen[0];
247  			}  
248  			preFlag = 1;
249  			sfcIdx = 2;
250  		}
251  	} else {    
252  		/* intensity stereo ch = 1 (right) */
253  		intensityScale = sfCompress & 0x01;
254  		sfCompress >>= 1;
255  		if (sfCompress < 180) {
256  			/* max slen = floor[35/6] = 5 (from mod 36) */
257  			slen[0] = (sfCompress / 36);
258  			slen[1] = (sfCompress % 36) / 6;
259  			slen[2] = (sfCompress % 36) % 6;
260  			slen[3] = 0;
261  			sfcIdx = 3;
262  		} else if (sfCompress < 244) {
263  			/* max slen = floor[63/16] = 3 */
264  			sfCompress -= 180;
265  			slen[0] = (sfCompress & 0x3f) >> 4;
266  			slen[1] = (sfCompress & 0x0f) >> 2;
267  			slen[2] = (sfCompress & 0x03);
268  			slen[3] = 0;
269  			sfcIdx = 4;
270  		} else {
271  			/* max slen = floor[11/3] = 3 (max sfCompress >> 1 = 511/2 = 255) */
272  			sfCompress -= 244;
273  			slen[0] = (sfCompress / 3);
274  			slen[1] = (sfCompress % 3);
275  			slen[2] = slen[3] = 0;
276  			sfcIdx = 5;
277  		}
278  	}
279  	
280  	/* set index based on block type: (0,1,3) --> 0, (2 non-mixed) --> 1, (2 mixed) ---> 2 */
281  	btIdx = 0;
282  	if (sis->blockType == 2) 
283  		btIdx = (sis->mixedBlock ? 2 : 1);
284  	for (i = 0; i < 4; i++)
285  		nr[i] = (int)NRTab[sfcIdx][btIdx][i];
286  
287  	/* save intensity stereo scale factor info */
288  	if( (modeExt & 0x01) && (ch == 1) ) {
289  		for (i = 0; i < 4; i++) {
290  			sfjs->slen[i] = slen[i];
291  			sfjs->nr[i] = nr[i];
292  		}
293  		sfjs->intensityScale = intensityScale;
294  	}
295  	sis->preFlag = preFlag;
296  
297  	/* short blocks */
298  	if(sis->blockType == 2) {
299  		if(sis->mixedBlock) {
300  			/* do long block portion */
301  			iipTest = (1 << slen[0]) - 1;
302  			for (sfb=0; sfb < 6; sfb++) {
303  				sfis->l[sfb] = (char)GetBits(bsi, slen[0]);
304  			}
305  			sfb = 3;  /* start sfb for short */
306  			nrIdx = 1;
307  		} else {      
308  			/* all short blocks, so start nr, sfb at 0 */
309  			sfb = 0;
310  			nrIdx = 0;
311  		}
312  
313  		/* remaining short blocks, sfb just keeps incrementing */
314  		for (    ; nrIdx <= 3; nrIdx++) {
315  			iipTest = (1 << slen[nrIdx]) - 1;
316  			for (i=0; i < nr[nrIdx]; i++, sfb++) {
317  				sfis->s[sfb][0] = (char)GetBits(bsi, slen[nrIdx]);
318  				sfis->s[sfb][1] = (char)GetBits(bsi, slen[nrIdx]);
319  				sfis->s[sfb][2] = (char)GetBits(bsi, slen[nrIdx]);
320  			}
321  		}
322  		/* last sf band not transmitted */
323  		sfis->s[12][0] = sfis->s[12][1] = sfis->s[12][2] = 0;
324  	} else {
325  		/* long blocks */
326  		sfb = 0;
327  		for (nrIdx = 0; nrIdx <= 3; nrIdx++) {
328  			iipTest = (1 << slen[nrIdx]) - 1;
329  			for(i=0; i < nr[nrIdx]; i++, sfb++) {
330  				sfis->l[sfb] = (char)GetBits(bsi, slen[nrIdx]);
331  			}
332  		}
333  		/* last sf band not transmitted */
334  		sfis->l[21] = sfis->l[22] = 0;
335  
336  	}
337  }
338  
339  /**************************************************************************************
340   * Function:    UnpackScaleFactors
341   *
342   * Description: parse the fields of the MP3 scale factor data section
343   *
344   * Inputs:      MP3DecInfo structure filled by UnpackFrameHeader() and UnpackSideInfo()
345   *              buffer pointing to the MP3 scale factor data
346   *              pointer to bit offset (0-7) indicating starting bit in buf[0]
347   *              number of bits available in data buffer
348   *              index of current granule and channel
349   *
350   * Outputs:     updated platform-specific ScaleFactorInfo struct
351   *              updated bitOffset
352   *
353   * Return:      length (in bytes) of scale factor data, -1 if null input pointers
354   **************************************************************************************/
355  int UnpackScaleFactors(MP3DecInfo *mp3DecInfo, unsigned char *buf, int *bitOffset, int bitsAvail, int gr, int ch)
356  {
357  	int bitsUsed;
358  	unsigned char *startBuf;
359  	BitStreamInfo bitStreamInfo, *bsi;
360  	FrameHeader *fh;
361  	SideInfo *si;
362  	ScaleFactorInfo *sfi;
363  
364  	/* validate pointers */
365  	if (!mp3DecInfo || !mp3DecInfo->FrameHeaderPS || !mp3DecInfo->SideInfoPS || !mp3DecInfo->ScaleFactorInfoPS)
366  		return -1;
367  	fh = ((FrameHeader *)(mp3DecInfo->FrameHeaderPS));
368  	si = ((SideInfo *)(mp3DecInfo->SideInfoPS));
369  	sfi = ((ScaleFactorInfo *)(mp3DecInfo->ScaleFactorInfoPS));
370  
371  	/* init GetBits reader */
372  	startBuf = buf;
373  	bsi = &bitStreamInfo;
374  	SetBitstreamPointer(bsi, (bitsAvail + *bitOffset + 7) / 8, buf);
375  	if (*bitOffset)
376  		GetBits(bsi, *bitOffset);
377  
378  	if (fh->ver == MPEG1) 
379  		UnpackSFMPEG1(bsi, &si->sis[gr][ch], &sfi->sfis[gr][ch], si->scfsi[ch], gr, &sfi->sfis[0][ch]);
380  	else 
381  		UnpackSFMPEG2(bsi, &si->sis[gr][ch], &sfi->sfis[gr][ch], gr, ch, fh->modeExt, &sfi->sfjs);
382  
383  	mp3DecInfo->part23Length[gr][ch] = si->sis[gr][ch].part23Length;
384  
385  	bitsUsed = CalcBitsUsed(bsi, buf, *bitOffset);
386  	buf += (bitsUsed + *bitOffset) >> 3;
387  	*bitOffset = (bitsUsed + *bitOffset) & 0x07;
388  
389  	return (buf - startBuf);
390  }
391