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

📄 layer3.c

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

 * NAME:	III_imdct_l()

 * DESCRIPTION:	perform IMDCT and windowing for long blocks

 */

static

void III_imdct_l(mad_fixed_t const X[18], mad_fixed_t z[36],

		 unsigned int block_type)

{

  unsigned int i;



  /* IMDCT */



  imdct36(X, z);



  /* windowing */



  switch (block_type) {

  case 0:  /* normal window */

# if defined(ASO_INTERLEAVE1)

    {

      register mad_fixed_t tmp1, tmp2;



      tmp1 = window_l[0];

      tmp2 = window_l[1];



      for (i = 0; i < 34; i += 2) {

	z[i + 0] = mad_f_mul(z[i + 0], tmp1);

	tmp1 = window_l[i + 2];

	z[i + 1] = mad_f_mul(z[i + 1], tmp2);

	tmp2 = window_l[i + 3];

      }



      z[34] = mad_f_mul(z[34], tmp1);

      z[35] = mad_f_mul(z[35], tmp2);

    }

# elif defined(ASO_INTERLEAVE2)

    {

      register mad_fixed_t tmp1, tmp2;



      tmp1 = z[0];

      tmp2 = window_l[0];



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

	z[i] = mad_f_mul(tmp1, tmp2);

	tmp1 = z[i + 1];

	tmp2 = window_l[i + 1];

      }



      z[35] = mad_f_mul(tmp1, tmp2);

    }

# elif 1

    for (i = 0; i < 36; i += 4) {

      z[i + 0] = mad_f_mul(z[i + 0], window_l[i + 0]);

      z[i + 1] = mad_f_mul(z[i + 1], window_l[i + 1]);

      z[i + 2] = mad_f_mul(z[i + 2], window_l[i + 2]);

      z[i + 3] = mad_f_mul(z[i + 3], window_l[i + 3]);

    }

# else

    for (i =  0; i < 36; ++i) z[i] = mad_f_mul(z[i], window_l[i]);

# endif

    break;



  case 1:  /* start block */

    for (i =  0; i < 18; ++i) z[i] = mad_f_mul(z[i], window_l[i]);

    /*  (i = 18; i < 24; ++i) z[i] unchanged */

    for (i = 24; i < 30; ++i) z[i] = mad_f_mul(z[i], window_s[i - 18]);

    for (i = 30; i < 36; ++i) z[i] = 0;

    break;



  case 3:  /* stop block */

    for (i =  0; i <  6; ++i) z[i] = 0;

    for (i =  6; i < 12; ++i) z[i] = mad_f_mul(z[i], window_s[i - 6]);

    /*  (i = 12; i < 18; ++i) z[i] unchanged */

    for (i = 18; i < 36; ++i) z[i] = mad_f_mul(z[i], window_l[i]);

    break;

  }

}

# endif  /* ASO_IMDCT */



/*

 * NAME:	III_imdct_s()

 * DESCRIPTION:	perform IMDCT and windowing for short blocks

 */

static

void III_imdct_s(mad_fixed_t const X[18], mad_fixed_t z[36])

{

  mad_fixed_t y[36], *yptr;

  mad_fixed_t const *wptr;

  int w, i;

  register mad_fixed64hi_t hi;

  register mad_fixed64lo_t lo;



  /* IMDCT */



  yptr = &y[0];



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

    register mad_fixed_t const (*s)[6];



    s = imdct_s;



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

      MAD_F_ML0(hi, lo, X[0], (*s)[0]);

      MAD_F_MLA(hi, lo, X[1], (*s)[1]);

      MAD_F_MLA(hi, lo, X[2], (*s)[2]);

      MAD_F_MLA(hi, lo, X[3], (*s)[3]);

      MAD_F_MLA(hi, lo, X[4], (*s)[4]);

      MAD_F_MLA(hi, lo, X[5], (*s)[5]);



      yptr[i + 0] = MAD_F_MLZ(hi, lo);

      yptr[5 - i] = -yptr[i + 0];



      ++s;



      MAD_F_ML0(hi, lo, X[0], (*s)[0]);

      MAD_F_MLA(hi, lo, X[1], (*s)[1]);

      MAD_F_MLA(hi, lo, X[2], (*s)[2]);

      MAD_F_MLA(hi, lo, X[3], (*s)[3]);

      MAD_F_MLA(hi, lo, X[4], (*s)[4]);

      MAD_F_MLA(hi, lo, X[5], (*s)[5]);



      yptr[ i + 6] = MAD_F_MLZ(hi, lo);

      yptr[11 - i] = yptr[i + 6];



      ++s;

    }



    yptr += 12;

    X    += 6;

  }



  /* windowing, overlapping and concatenation */



  yptr = &y[0];

  wptr = &window_s[0];



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

    z[i +  0] = 0;

    z[i +  6] = mad_f_mul(yptr[ 0 + 0], wptr[0]);



    MAD_F_ML0(hi, lo, yptr[ 0 + 6], wptr[6]);

    MAD_F_MLA(hi, lo, yptr[12 + 0], wptr[0]);



    z[i + 12] = MAD_F_MLZ(hi, lo);



    MAD_F_ML0(hi, lo, yptr[12 + 6], wptr[6]);

    MAD_F_MLA(hi, lo, yptr[24 + 0], wptr[0]);



    z[i + 18] = MAD_F_MLZ(hi, lo);



    z[i + 24] = mad_f_mul(yptr[24 + 6], wptr[6]);

    z[i + 30] = 0;



    ++yptr;

    ++wptr;

  }

}



/*

 * NAME:	III_overlap()

 * DESCRIPTION:	perform overlap-add of windowed IMDCT outputs

 */

static

void III_overlap(mad_fixed_t const output[36], mad_fixed_t overlap[18],

		 mad_fixed_t sample[18][32], unsigned int sb)

{

  unsigned int i;



# if defined(ASO_INTERLEAVE2)

  {

    register mad_fixed_t tmp1, tmp2;



    tmp1 = overlap[0];

    tmp2 = overlap[1];



    for (i = 0; i < 16; i += 2) {

      sample[i + 0][sb] = output[i + 0] + tmp1;

      overlap[i + 0]    = output[i + 0 + 18];

      tmp1 = overlap[i + 2];



      sample[i + 1][sb] = output[i + 1] + tmp2;

      overlap[i + 1]    = output[i + 1 + 18];

      tmp2 = overlap[i + 3];

    }



    sample[16][sb] = output[16] + tmp1;

    overlap[16]    = output[16 + 18];

    sample[17][sb] = output[17] + tmp2;

    overlap[17]    = output[17 + 18];

  }

# elif 0

  for (i = 0; i < 18; i += 2) {

    sample[i + 0][sb] = output[i + 0] + overlap[i + 0];

    overlap[i + 0]    = output[i + 0 + 18];



    sample[i + 1][sb] = output[i + 1] + overlap[i + 1];

    overlap[i + 1]    = output[i + 1 + 18];

  }

# else

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

    sample[i][sb] = output[i] + overlap[i];

    overlap[i]    = output[i + 18];

  }

# endif

}



/*

 * NAME:	III_overlap_z()

 * DESCRIPTION:	perform "overlap-add" of zero IMDCT outputs

 */

static inline

void III_overlap_z(mad_fixed_t overlap[18],

		   mad_fixed_t sample[18][32], unsigned int sb)

{

  unsigned int i;



# if defined(ASO_INTERLEAVE2)

  {

    register mad_fixed_t tmp1, tmp2;



    tmp1 = overlap[0];

    tmp2 = overlap[1];



    for (i = 0; i < 16; i += 2) {

      sample[i + 0][sb] = tmp1;

      overlap[i + 0]    = 0;

      tmp1 = overlap[i + 2];



      sample[i + 1][sb] = tmp2;

      overlap[i + 1]    = 0;

      tmp2 = overlap[i + 3];

    }



    sample[16][sb] = tmp1;

    overlap[16]    = 0;

    sample[17][sb] = tmp2;

    overlap[17]    = 0;

  }

# else

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

    sample[i][sb] = overlap[i];

    overlap[i]    = 0;

  }

# endif

}



/*

 * NAME:	III_freqinver()

 * DESCRIPTION:	perform subband frequency inversion for odd sample lines

 */

static

void III_freqinver(mad_fixed_t sample[18][32], unsigned int sb)

{

  unsigned int i;



# if 1 || defined(ASO_INTERLEAVE1) || defined(ASO_INTERLEAVE2)

  {

    register mad_fixed_t tmp1, tmp2;



    tmp1 = sample[1][sb];

    tmp2 = sample[3][sb];



    for (i = 1; i < 13; i += 4) {

      sample[i + 0][sb] = -tmp1;

      tmp1 = sample[i + 4][sb];

      sample[i + 2][sb] = -tmp2;

      tmp2 = sample[i + 6][sb];

    }



    sample[13][sb] = -tmp1;

    tmp1 = sample[17][sb];

    sample[15][sb] = -tmp2;

    sample[17][sb] = -tmp1;

  }

# else

  for (i = 1; i < 18; i += 2)

    sample[i][sb] = -sample[i][sb];

# endif

}



/*

 * NAME:	III_decode()

 * DESCRIPTION:	decode frame main_data

 */

static

enum mad_error III_decode(struct mad_bitptr *ptr, struct mad_frame *frame,

			  struct sideinfo *si, unsigned int nch)

{

  struct mad_header *header = &frame->header;

  unsigned int sfreqi, ngr, gr;



  {

    unsigned int sfreq;



    sfreq = header->samplerate;

    if (header->flags & MAD_FLAG_MPEG_2_5_EXT)

      sfreq *= 2;



    /* 48000 => 0, 44100 => 1, 32000 => 2,

       24000 => 3, 22050 => 4, 16000 => 5 */

    sfreqi = ((sfreq >>  7) & 0x000f) +

             ((sfreq >> 15) & 0x0001) - 8;



    if (header->flags & MAD_FLAG_MPEG_2_5_EXT)

      sfreqi += 3;

  }



  /* scalefactors, Huffman decoding, requantization */



  ngr = (header->flags & MAD_FLAG_LSF_EXT) ? 1 : 2;



  for (gr = 0; gr < ngr; ++gr) {

    struct granule *granule = &si->gr[gr];

    unsigned char const *sfbwidth[2];

    mad_fixed_t xr[2][576];

    unsigned int ch;

    enum mad_error error;



    for (ch = 0; ch < nch; ++ch) {

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

      unsigned int part2_length;



      sfbwidth[ch] = sfbwidth_table[sfreqi].l;

      if (channel->block_type == 2) {

	sfbwidth[ch] = (channel->flags & mixed_block_flag) ?

	  sfbwidth_table[sfreqi].m : sfbwidth_table[sfreqi].s;

      }



      if (header->flags & MAD_FLAG_LSF_EXT) {

	part2_length = III_scalefactors_lsf(ptr, channel,

					    ch == 0 ? 0 : &si->gr[1].ch[1],

					    header->mode_extension);

      }

      else {

	part2_length = III_scalefactors(ptr, channel, &si->gr[0].ch[ch],

					gr == 0 ? 0 : si->scfsi[ch]);

      }



      error = III_huffdecode(ptr, xr[ch], channel, sfbwidth[ch], part2_length);

      if (error)

	return error;

    }



    /* joint stereo processing */



    if (header->mode == MAD_MODE_JOINT_STEREO && header->mode_extension) {

      error = III_stereo(xr, granule, header, sfbwidth[0]);

      if (error)

	return error;

    }



    /* reordering, alias reduction, IMDCT, overlap-add, frequency inversion */



    for (ch = 0; ch < nch; ++ch) {

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

      mad_fixed_t (*sample)[32] = &frame->sbsample[ch][18 * gr];

      unsigned int sb, l, i, sblimit;

      mad_fixed_t output[36];



      if (channel->block_type == 2) {

	III_reorder(xr[ch], channel, sfbwidth[ch]);



# if !defined(OPT_STRICT)

	/*

	 * According to ISO/IEC 11172-3, "Alias reduction is not applied for

	 * granules with block_type == 2 (short block)." However, other

	 * sources suggest alias reduction should indeed be performed on the

	 * lower two subbands of mixed blocks. Most other implementations do

	 * this, so by default we will too.

	 */

	if (channel->flags & mixed_block_flag)

	  III_aliasreduce(xr[ch], 36);

# endif

      }

      else

	III_aliasreduce(xr[ch], 576);



      l = 0;



      /* subbands 0-1 */



      if (channel->block_type != 2 || (channel->flags & mixed_block_flag)) {

	unsigned int block_type;



	block_type = channel->block_type;

	if (channel->flags & mixed_block_flag)

	  block_type = 0;



	/* long blocks */

	for (sb = 0; sb < 2; ++sb, l += 18) {

	  III_imdct_l(&xr[ch][l], output, block_type);

	  III_overlap(output, (*frame->overlap)[ch][sb], sample, sb);

	}

      }

      else {

	/* short blocks */

	for (sb = 0; sb < 2; ++sb, l += 18) {

	  III_imdct_s(&xr[ch][l], output);

	  III_overlap(output, (*frame->overlap)[ch][sb], sample, sb);

	}

      }



      III_freqinver(sample, 1);



      /* (nonzero) subbands 2-31 */



      i = 576;

      while (i > 36 && xr[ch][i - 1] == 0)

	--i;



      sblimit = 32 - (576 - i) / 18;



      if (channel->block_type != 2) {

	/* long blocks */

	for (sb = 2; sb < sblimit; ++sb, l += 18) {

	  III_imdct_l(&xr[ch][l], output, channel->block_type);

	  III_overlap(output, (*frame->overlap)[ch][sb], sample, sb);



	  if (sb & 1)

	    III_freqinver(sample, sb);

	}

      }

      else {

	/* short blocks */

	for (sb = 2; sb < sblimit; ++sb, l += 18) {

	  III_imdct_s(&xr[ch][l], output);

	  III_overlap(output, (*frame->overlap)[ch][sb], sample, sb);



	  if (sb & 1)

	    III_freqinver(sample, sb);

	}

      }



      /* remaining (zero) subbands */



      for (sb = sblimit; sb < 32; ++sb) {

	III_overlap_z((*frame->overlap)[ch][sb], sample, sb);



	if (sb & 1)

	  III_freqinver(sample, sb);

      }

    }

  }



  return MAD_ERROR_NONE;

}



/*

 * NAME:	layer->III()

 * DESCRIPTION:	decode a single Layer III frame

 */

int mad_layer_III(struct mad_stream *stream, struct mad_frame *frame)

{

  struct mad_header *header = &frame->header;

  unsigned int nch, priv_bitlen, next_md_begin = 0;

  unsigned int si_len, data_bitlen, md_len;

  unsigned int frame_space, frame_used, frame_free;

  struct mad_bitptr ptr;

  struct sideinfo si;

  enum mad_error error;

  int result = 0;



 

⌨️ 快捷键说明

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