⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 layer3.c

📁 基于mips架构的ATI-XILLEON 226的mp3解码程序
💻 C
📖 第 1 页 / 共 5 页
字号:
			      unsigned char const *sfbwidth,

			      unsigned int part2_length)

{

  signed int exponents[39], exp;

  signed int const *expptr;

  struct mad_bitptr peek;

  signed int bits_left, cachesz;

  register mad_fixed_t *xrptr;

  mad_fixed_t const *sfbound;

  register unsigned long bitcache;



  bits_left = (signed) channel->part2_3_length - (signed) part2_length;

  if (bits_left < 0)

    return MAD_ERROR_BADPART3LEN;



  III_exponents(channel, sfbwidth, exponents);



  peek = *ptr;

  mad_bit_skip(ptr, bits_left);



  /* align bit reads to byte boundaries */

  cachesz  = mad_bit_bitsleft(&peek);

  cachesz += ((32 - 1 - 24) + (24 - cachesz)) & ~7;



  bitcache   = mad_bit_read(&peek, cachesz);

  bits_left -= cachesz;



  xrptr = &xr[0];



  /* big_values */

  {

    unsigned int region, rcount;

    struct hufftable const *entry;

    union huffpair const *table;

    unsigned int linbits, startbits, big_values, reqhits;

    mad_fixed_t reqcache[16];



    sfbound = xrptr + *sfbwidth++;

    rcount  = channel->region0_count + 1;



    entry     = &mad_huff_pair_table[channel->table_select[region = 0]];

    table     = entry->table;

    linbits   = entry->linbits;

    startbits = entry->startbits;



    if (table == 0)

      return MAD_ERROR_BADHUFFTABLE;



    expptr  = &exponents[0];

    exp     = *expptr++;

    reqhits = 0;



    big_values = channel->big_values;



    while (big_values-- && cachesz + bits_left > 0) {

      union huffpair const *pair;

      unsigned int clumpsz, value;

      register mad_fixed_t requantized;



      if (xrptr == sfbound) {

	sfbound += *sfbwidth++;



	/* change table if region boundary */



	if (--rcount == 0) {

	  if (region == 0)

	    rcount = channel->region1_count + 1;

	  else

	    rcount = 0;  /* all remaining */



	  entry     = &mad_huff_pair_table[channel->table_select[++region]];

	  table     = entry->table;

	  linbits   = entry->linbits;

	  startbits = entry->startbits;



	  if (table == 0)

	    return MAD_ERROR_BADHUFFTABLE;

	}



	if (exp != *expptr) {

	  exp = *expptr;

	  reqhits = 0;

	}



	++expptr;

      }



      if (cachesz < 21) {

	unsigned int bits;



	bits       = ((32 - 1 - 21) + (21 - cachesz)) & ~7;

	bitcache   = (bitcache << bits) | mad_bit_read(&peek, bits);

	cachesz   += bits;

	bits_left -= bits;

      }



      /* hcod (0..19) */



      clumpsz = startbits;

      pair    = &table[MASK(bitcache, cachesz, clumpsz)];



      while (!pair->final) {

	cachesz -= clumpsz;



	clumpsz = pair->ptr.bits;

	pair    = &table[pair->ptr.offset + MASK(bitcache, cachesz, clumpsz)];

      }



      cachesz -= pair->value.hlen;



      if (linbits) {

	/* x (0..14) */



	value = pair->value.x;



	switch (value) {

	case 0:

	  xrptr[0] = 0;

	  break;



	case 15:

	  if (cachesz < linbits + 2) {

	    bitcache   = (bitcache << 16) | mad_bit_read(&peek, 16);

	    cachesz   += 16;

	    bits_left -= 16;

	  }



	  value += MASK(bitcache, cachesz, linbits);

	  cachesz -= linbits;



	  requantized = III_requantize(value, exp);

	  goto x_final;



	default:

	  if (reqhits & (1 << value))

	    requantized = reqcache[value];

	  else {

	    reqhits |= (1 << value);

	    requantized = reqcache[value] = III_requantize(value, exp);

	  }



	x_final:

	  xrptr[0] = MASK1BIT(bitcache, cachesz--) ?

	    -requantized : requantized;

	}



	/* y (0..14) */



	value = pair->value.y;



	switch (value) {

	case 0:

	  xrptr[1] = 0;

	  break;



	case 15:

	  if (cachesz < linbits + 1) {

	    bitcache   = (bitcache << 16) | mad_bit_read(&peek, 16);

	    cachesz   += 16;

	    bits_left -= 16;

	  }



	  value += MASK(bitcache, cachesz, linbits);

	  cachesz -= linbits;



	  requantized = III_requantize(value, exp);

	  goto y_final;



	default:

	  if (reqhits & (1 << value))

	    requantized = reqcache[value];

	  else {

	    reqhits |= (1 << value);

	    requantized = reqcache[value] = III_requantize(value, exp);

	  }



	y_final:

	  xrptr[1] = MASK1BIT(bitcache, cachesz--) ?

	    -requantized : requantized;

	}

      }

      else {

	/* x (0..1) */



	value = pair->value.x;



	if (value == 0)

	  xrptr[0] = 0;

	else {

	  if (reqhits & (1 << value))

	    requantized = reqcache[value];

	  else {

	    reqhits |= (1 << value);

	    requantized = reqcache[value] = III_requantize(value, exp);

	  }



	  xrptr[0] = MASK1BIT(bitcache, cachesz--) ?

	    -requantized : requantized;

	}



	/* y (0..1) */



	value = pair->value.y;



	if (value == 0)

	  xrptr[1] = 0;

	else {

	  if (reqhits & (1 << value))

	    requantized = reqcache[value];

	  else {

	    reqhits |= (1 << value);

	    requantized = reqcache[value] = III_requantize(value, exp);

	  }



	  xrptr[1] = MASK1BIT(bitcache, cachesz--) ?

	    -requantized : requantized;

	}

      }



      xrptr += 2;

    }

  }



  if (cachesz + bits_left < 0)

    return MAD_ERROR_BADHUFFDATA;  /* big_values overrun */



  /* count1 */

  {

    union huffquad const *table;

    register mad_fixed_t requantized;



    table = mad_huff_quad_table[channel->flags & count1table_select];



    requantized = III_requantize(1, exp);



    while (cachesz + bits_left > 0 && xrptr <= &xr[572]) {

      union huffquad const *quad;



      /* hcod (1..6) */



      if (cachesz < 10) {

	bitcache   = (bitcache << 16) | mad_bit_read(&peek, 16);

	cachesz   += 16;

	bits_left -= 16;

      }



      quad = &table[MASK(bitcache, cachesz, 4)];



      /* quad tables guaranteed to have at most one extra lookup */

      if (!quad->final) {

	cachesz -= 4;



	quad = &table[quad->ptr.offset +

		      MASK(bitcache, cachesz, quad->ptr.bits)];

      }



      cachesz -= quad->value.hlen;



      if (xrptr == sfbound) {

	sfbound += *sfbwidth++;



	if (exp != *expptr) {

	  exp = *expptr;

	  requantized = III_requantize(1, exp);

	}



	++expptr;

      }



      /* v (0..1) */



      xrptr[0] = quad->value.v ?

	(MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0;



      /* w (0..1) */



      xrptr[1] = quad->value.w ?

	(MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0;



      xrptr += 2;



      if (xrptr == sfbound) {

	sfbound += *sfbwidth++;



	if (exp != *expptr) {

	  exp = *expptr;

	  requantized = III_requantize(1, exp);

	}



	++expptr;

      }



      /* x (0..1) */



      xrptr[0] = quad->value.x ?

	(MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0;



      /* y (0..1) */



      xrptr[1] = quad->value.y ?

	(MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0;



      xrptr += 2;

    }



    if (cachesz + bits_left < 0) {

# if 0 && defined(DEBUG)

      fprintf(stderr, "huffman count1 overrun (%d bits)\n",

	      -(cachesz + bits_left));

# endif



      /* technically the bitstream is misformatted, but apparently

	 some encoders are just a bit sloppy with stuffing bits */



      xrptr -= 4;

    }

  }



  assert(-bits_left <= MAD_BUFFER_GUARD * CHAR_BIT);



# if 0 && defined(DEBUG)

  if (bits_left < 0)

    fprintf(stderr, "read %d bits too many\n", -bits_left);

  else if (cachesz + bits_left > 0)

    fprintf(stderr, "%d stuffing bits\n", cachesz + bits_left);

# endif



  /* rzero */

  while (xrptr < &xr[576]) {

    xrptr[0] = 0;

    xrptr[1] = 0;



    xrptr += 2;

  }



  return MAD_ERROR_NONE;

}



# undef MASK

# undef MASK1BIT



/*

 * NAME:	III_reorder()

 * DESCRIPTION:	reorder frequency lines of a short block into subband order

 */

static

void III_reorder(mad_fixed_t xr[576], struct channel const *channel,

		 unsigned char const sfbwidth[39])

{

  mad_fixed_t tmp[32][3][6];

  unsigned int sb, l, f, w, sbw[3], sw[3];



  /* this is probably wrong for 8000 Hz mixed blocks */



  sb = 0;

  if (channel->flags & mixed_block_flag) {

    sb = 2;



    l = 0;

    while (l < 36)

      l += *sfbwidth++;

  }



  for (w = 0; w < 3; ++w) {

    sbw[w] = sb;

    sw[w]  = 0;

  }



  f = *sfbwidth++;

  w = 0;



  for (l = 18 * sb; l < 576; ++l) {

    if (f-- == 0) {

      f = *sfbwidth++ - 1;

      w = (w + 1) % 3;

    }



    tmp[sbw[w]][w][sw[w]++] = xr[l];



    if (sw[w] == 6) {

      sw[w] = 0;

      ++sbw[w];

    }

  }



  memcpy(&xr[18 * sb], &tmp[sb], (576 - 18 * sb) * sizeof(mad_fixed_t));

}



/*

 * NAME:	III_stereo()

 * DESCRIPTION:	perform joint stereo processing on a granule

 */

static

enum mad_error III_stereo(mad_fixed_t xr[2][576],

			  struct granule const *granule,

			  struct mad_header *header,

			  unsigned char const *sfbwidth)

{

  short modes[39];

  unsigned int sfbi, l, n, i;



  if (granule->ch[0].block_type !=

      granule->ch[1].block_type ||

      (granule->ch[0].flags & mixed_block_flag) !=

      (granule->ch[1].flags & mixed_block_flag))

    return MAD_ERROR_BADSTEREO;



  for (i = 0; i < 39; ++i)

    modes[i] = header->mode_extension;



  /* intensity stereo */



  if (header->mode_extension & I_STEREO) {

    struct channel const *right_ch = &granule->ch[1];

    mad_fixed_t const *right_xr = xr[1];

    unsigned int is_pos;



    header->flags |= MAD_FLAG_I_STEREO;



    /* first determine which scalefactor bands are to be processed */



    if (right_ch->block_type == 2) {

      unsigned int lower, start, max, bound[3], w;



      lower = start = max = bound[0] = bound[1] = bound[2] = 0;



      sfbi = l = 0;



      if (right_ch->flags & mixed_block_flag) {

	while (l < 36) {

	  n = sfbwidth[sfbi++];



	  for (i = 0; i < n; ++i) {

	    if (right_xr[i]) {

	      lower = sfbi;

	      break;

	    }

	  }



	  right_xr += n;

	  l += n;

	}



	start = sfbi;

      }



      w = 0;

      while (l < 576) {

	n = sfbwidth[sfbi++];



	for (i = 0; i < n; ++i) {

	  if (right_xr[i]) {

	    max = bound[w] = sfbi;

	    break;

	  }

	}



	right_xr += n;

	l += n;

	w = (w + 1) % 3;

      }



      if (max)

	lower = start;



      /* long blocks */



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -