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

📄 layer3.c

📁 VC++视频开发实例集锦(包括“远程视频监控”"语音识别系统"等13个经典例子)
💻 C
📖 第 1 页 / 共 5 页
字号:
	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 */

      for (i = 0; i < lower; ++i)
	modes[i] = header->mode_extension & ~I_STEREO;

      /* short blocks */

      w = 0;
      for (i = start; i < max; ++i) {
	if (i < bound[w])
	  modes[i] = header->mode_extension & ~I_STEREO;

	w = (w + 1) % 3;
      }
    }
    else {  /* right_ch->block_type != 2 */
      unsigned int bound;

      bound = 0;
      for (sfbi = l = 0; l < 576; l += n) {
	n = sfbwidth[sfbi++];

	for (i = 0; i < n; ++i) {
	  if (right_xr[i]) {
	    bound = sfbi;
	    break;
	  }
	}

	right_xr += n;
      }

      for (i = 0; i < bound; ++i)
	modes[i] = header->mode_extension & ~I_STEREO;
    }

    /* now do the actual processing */

    if (header->flags & MAD_FLAG_LSF_EXT) {
      unsigned char const *illegal_pos = granule[1].ch[1].scalefac;
      mad_fixed_t const *lsf_scale;

      /* intensity_scale */
      lsf_scale = is_lsf_table[right_ch->scalefac_compress & 0x1];

      for (sfbi = l = 0; l < 576; ++sfbi, l += n) {
	n = sfbwidth[sfbi];

	if (!(modes[sfbi] & I_STEREO))
	  continue;

	if (illegal_pos[sfbi]) {
	  modes[sfbi] &= ~I_STEREO;
	  continue;
	}

	is_pos = right_ch->scalefac[sfbi];

	for (i = 0; i < n; ++i) {
	  register mad_fixed_t left;

	  left = xr[0][l + i];

	  if (is_pos == 0)
	    xr[1][l + i] = left;
	  else {
	    register mad_fixed_t opposite;

	    opposite = mad_f_mul(left, lsf_scale[(is_pos - 1) / 2]);

	    if (is_pos & 1) {
	      xr[0][l + i] = opposite;
	      xr[1][l + i] = left;
	    }
	    else
	      xr[1][l + i] = opposite;
	  }
	}
      }
    }
    else {  /* !(header->flags & MAD_FLAG_LSF_EXT) */
      for (sfbi = l = 0; l < 576; ++sfbi, l += n) {
	n = sfbwidth[sfbi];

⌨️ 快捷键说明

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