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

📄 c8_35pf.c

📁 完整的EVRC压缩解压缩算法源码,附带一个简单的例子程序。
💻 C
📖 第 1 页 / 共 2 页
字号:
	/* storage order --> i4i0, i3i4, i2i3, i1i2, i0i1 */

	pos = MSIZE - 1;
	ptr_hf = h + 4;

	for (k = 0; k < NB_POS; k++)
	{
		p4 = &rrixiy[4][pos];
		p3 = &rrixiy[3][pos - 1];
		p2 = &rrixiy[2][pos - 1];
		p1 = &rrixiy[1][pos - 1];
		p0 = &rrixiy[0][pos - 1];

		cor = 0x00008000L;		/* 0.5 (for rounding) */
		ptr_h1 = h;
		ptr_h2 = ptr_hf;

		for (i = k + (Shortword) 1; i < NB_POS; i++)
		{
			cor = L_mac(cor, *ptr_h1, *ptr_h2);
			ptr_h1++;
			ptr_h2++;
			*p4 = extract_h(cor);
			cor = L_mac(cor, *ptr_h1, *ptr_h2);
			ptr_h1++;
			ptr_h2++;
			*p3 = extract_h(cor);
			cor = L_mac(cor, *ptr_h1, *ptr_h2);
			ptr_h1++;
			ptr_h2++;
			*p2 = extract_h(cor);
			cor = L_mac(cor, *ptr_h1, *ptr_h2);
			ptr_h1++;
			ptr_h2++;
			*p1 = extract_h(cor);
			cor = L_mac(cor, *ptr_h1, *ptr_h2);
			ptr_h1++;
			ptr_h2++;
			*p0 = extract_h(cor);

			p4 -= (NB_POS + 1);
			p3 -= (NB_POS + 1);
			p2 -= (NB_POS + 1);
			p1 -= (NB_POS + 1);
			p0 -= (NB_POS + 1);
		}
		cor = L_mac(cor, *ptr_h1, *ptr_h2);
		ptr_h1++;
		ptr_h2++;
		*p4 = extract_h(cor);

		pos--;
		ptr_hf += STEP;
	}

 /*------------------------------------------------------------*
  * Modification of rrixiy[][] to take signs into account.     *
  *------------------------------------------------------------*/

	p0 = &rrixiy[0][0];

	for (k = 0; k < NB_TRACK; k++)
	{
		for (i = k; i < L_SUBFR; i += STEP)
		{
			psign=sign;

			if (psign[i] < 0)
				psign = vec;

			for (j = ((k + 1) % NB_TRACK); j < L_SUBFR; j += STEP)
			{
				*p0++ = mult(*p0, psign[j]);
			}
		}
	}

 /*-------------------------------------------------------------------*
  * Deep first search: 4 iterations of 264 tests = 1056 tests.        *
  *                                                                   *
  * Stages of deep first search:                                      *
  *     stage 1 : fix i0 and i1 --> try 6x11 = 66 positions           *
  *     stage 2 : fix i2 and i3 --> try 6x11 = 66 positions.          *
  *     stage 3 : fix i4 and i5 --> try 6x11 = 66 positions.          *
  *     stage 4 : fix i6 and i7 --> try 6x11 = 66 positions.          *
  *-------------------------------------------------------------------*/

	/* default value */
	psk = -1;
	alpk = 1;
	for (i = 0; i < NB_PULSE; i++)
		codvec[i] = i;

	for (k = 0; k < NB_ITER; k++)
	{
             /* Change  back to the search strategy used in the float point simulation */

		
		alp = 0;
                ps = 0;

               
		
                search_ixiy(ipos[k], ipos[k + 1], &ps, &alp, &ix, &iy,
		dn, cn, rrixix[ipos[k]], rrixix[ipos[k+1]], rrixiy);

			ip[0] = ix;
			ip[1] = iy;

 	       for (i = 0; i < L_SUBFR; i++)
		{
			vec[i] = 0;
		}
                

		/* stage 2..5: fix pulse i2,i3,i4,i5,i6 and i7 */

		for (j = 2; j < NB_PULSE; j += 2)
		{
     /*--------------------------------------------------*
      * Store all impulse response of all fixed pulses   *
      * in vector vec[] for the "cor_h_vec()" function.  *
      *--------------------------------------------------*/

			if (sign[ix] < 0)
				p0 = h_inv - ix;
			else
				p0 = h - ix;
			if (sign[iy] < 0)
				p1 = h_inv - iy;
			else
				p1 = h - iy;

			for (i = 0; i < L_SUBFR; i++)
			{
				vec[i] = add(vec[i], add(*p0++, *p1++));
			}

     /*--------------------------------------------------*
      * Calculate correlation of all possible positions  *
      * of the next 2 pulses with previous fixed pulses. *
      * Each pulse can have 8 possible positions         *
      *--------------------------------------------------*/

			cor_h_vec(h, vec, ipos[k + j], sign, rrixix, cor_x);
			cor_h_vec(h, vec, ipos[k + j + 1], sign, rrixix, cor_y);

      /*--------------------------------------------------*
      * Fix 2 pulses, try 6x11 = 66 positions.            *
      *--------------------------------------------------*/

		search_ixiy(ipos[k + j], ipos[k + j + 1], &ps, &alp, &ix, &iy,
		dn, cn, cor_x, cor_y, rrixiy);

			ip[j] = ix;
			ip[j + 1] = iy;
		}

		/* memorise new codevector if it's better than the last one. */

		ps = mult(ps, ps);
		s = L_msu(L_mult(alpk, ps), psk, alp);

		if (s > 0)
		{
			psk = ps;
			alpk = alp;
			for (i = 0; i < NB_PULSE; i++)
				codvec[i] = ip[i];
			codvec[8] = k;
		}

	}							/* end of for (k=0; k<NB_ITER; k++) */

 /*-------------------------------------------------------------------*
  * Build the codeword, the filtered codeword and index of codevector.*
  *-------------------------------------------------------------------*/

	for (i = 0; i < l_subfr; i++)
	{
		code[i] = 0;
	}

	for (i = 0; i < NB_TRACK; i++)
	{
		indx[i] = -1;
	}

	for (k = 0; k < NB_PULSE; k++)
	{
		i = codvec[k];			/* read pulse position */
		j = sign[i];			/* read sign           */

		index = mult(i, Q15_1_5);	/* index = pos/5       */
		/* track = pos%5 */
		track = sub(i, extract_l(L_shr(L_mult(index, 5), 1)));

		if (j > 0)
		{
			if (i < l_subfr)
				code[i] = add(code[i], 4096);	/* codeword in Q12 format */
			codvec[k] += (2 * L_SUBFR);
		}
		else
		{
			if (i < l_subfr)
				code[i] = sub(code[i], 4096);	/* codeword in Q12 format */
			index = add(index, 16);
		}

	/*-------------------------------------------------------*
	 * Quantization of 2 pulses with 8 or 9 bits:            *
	 *     1 bit  for 2 pulses sign.     (b8)                *
	 *     7 bits for 2 pulses in same track  (b7..b4)       *
	 *     8 bits for 2 pulses in different track  (b7..b4)  *
	 *-------------------------------------------------------*/
		if (indx[track] < 0)
		{
			indx[track] = index;
		}
		else
		{
			if (((index ^ indx[track]) & 16) == 0)
			{
				/* sign of 1st pulse == sign of 2th pulse */

				if (sub(indx[track], index) <= 0)
				{
					indx[track] = shl((indx[track] & 16), 3)
						+ shr(extract_l(L_mult((indx[track] & 15), NB_POS)), 1)
						+ (index & 15);
				}
				else
				{
					indx[track] = shl((index & 16), 3)
						+ shr(extract_l(L_mult((index & 15), NB_POS)), 1)
						+ (indx[track] & 15);
				}
			}
			else
			{
				/* sign of 1st pulse != sign of 2th pulse */

				if (sub((indx[track] & 15), (index & 15)) <= 0)
				{
					indx[track] = shl((index & 16), 3)
						+ shr(extract_l(L_mult((index & 15), NB_POS)), 1)
						+ (indx[track] & 15);
				}
				else
				{
					indx[track] = shl((indx[track] & 16), 3)
						+ shr(extract_l(L_mult((indx[track] & 15), NB_POS)), 1)
						+ (index & 15);
				}
			}
		}
	}

	if (codvec[8] == 0)
	{
		i = indx[3];
		j = indx[4];
	}
	else if (codvec[8] == 1)
	{
		i = indx[4];
		j = indx[0];
		indx[0] = indx[1];
		indx[1] = indx[2];
		indx[2] = indx[3];
	}
	else if (codvec[8] == 2)
	{
		i = indx[0];
		j = indx[1];
		indx[0] = indx[2];
		indx[1] = indx[3];
		indx[2] = indx[4];
	}
	else if (codvec[8] == 3)
	{
		i = indx[1];
		j = indx[2];
		indx[1] = indx[4];
		indx[2] = indx[0];
		indx[0] = indx[3];
	}

	indx[3] = shl(codvec[8], 9)
		+ shl((i & 16), 4)
		+ shl((j & 16), 3)
		+ shr(extract_l(L_mult((i & 15), NB_POS)), 1)
		+ (j & 15);

	for (i = 0; i < l_subfr; i++)
	{
		h[i] = H[i];
		h_inv[i] = negate(h[i]);
	}

	p0 = h_inv - codvec[0];
	p1 = h_inv - codvec[1];
	p2 = h_inv - codvec[2];
	p3 = h_inv - codvec[3];
	p4 = h_inv - codvec[4];
	p5 = h_inv - codvec[5];
	p6 = h_inv - codvec[6];
	p7 = h_inv - codvec[7];

	for (i = 0; i < l_subfr; i++)
	{
		s = L_mult(*p0++, 8192);	/* Q12 --> Q10 */
		s = L_mac(s, *p1++, 8192);
		s = L_mac(s, *p2++, 8192);
		s = L_mac(s, *p3++, 8192);
		s = L_mac(s, *p4++, 8192);
		s = L_mac(s, *p5++, 8192);
		s = L_mac(s, *p6++, 8192);
		s = L_mac(s, *p7++, 8192);
		y[i] = round32(s);
	}

	return;
}

/*-------------------------------------------------------------------*
 * Function  cor_h_vec()                                             *
 * ~~~~~~~~~~~~~~~~~~~~~                                             *
 * Compute correlations of h[] with vec[] for the specified track.   *
 *-------------------------------------------------------------------*/

static void cor_h_vec(
						 Shortword h[],		/* (i) scaled impulse response */
						 Shortword vec[],	/* (i) vector to correlate with h[] */
						 Shortword track,	/* (i) track to use */
						 Shortword sign[],	/* (i) sign vector */
						 Shortword rrixix[][NB_POS],	/* (i) correlation of h[x] with h[x] */
						 Shortword cor[]	/* (o) result of correlation (NB_POS elements) */
)
{
	Shortword i, j, pos;
	Shortword *p0, *p1, *p2;
	Longword s;

	p0 = rrixix[track];

	pos = track;
	for (i = 0; i < NB_POS; i++, pos += STEP)
	{
		s = 0;
		p1 = h;
		p2 = &vec[pos];
		for (j = pos; j < L_SUBFR; j++)
			s = L_mac(s, *p1++, *p2++);

		cor[i] = add(mult(round32(s), sign[pos]), *p0++);
	}

	return;
}

/*-------------------------------------------------------------------*
 * Function  search_ixiy()                                           *
 * ~~~~~~~~~~~~~~~~~~~~~~~                                           *
 * Find the best positions of 2 pulses in a subframe.                *
 *-------------------------------------------------------------------*/

static void search_ixiy(
						   Shortword track_x,	/* (i) track of pulse 1 */
						   Shortword track_y,	/* (i) track of pulse 2 */
						   Shortword * ps,	/* (i/o) correlation of all fixed pulses */
						   Shortword * alp,		/* (i/o) energy of all fixed pulses */
						   Shortword * ix,	/* (o) position of pulse 1 */
						   Shortword * iy,	/* (o) position of pulse 2 */
						   Shortword dn[],	/* (i) corr. between target and h[] */
						   Shortword cn[],	/* (i) corr. vector (search if cn[]>=0)   */
						   Shortword cor_x[],	/* (i) corr. of pulse 1 with fixed pulses */
						   Shortword cor_y[],	/* (i) corr. of pulse 2 with fixed pulses */
						   Shortword rrixiy[][MSIZE]	/* (i) corr. of pulse 1 with pulse 2 */
)
{
	Shortword x, y, pos;
	Shortword ps1, ps2, sq, sqk;
	Shortword alp1, alp2, alpk;
	Shortword *p0, *p1, *p2;
	Longword s;

	p0 = cor_x;
	p1 = cor_y;
	p2 = rrixiy[track_x];

	/* default value */
	sqk = -1;
	alpk = 1;
	*ix = track_x;
	*iy = track_y;

	for (x = track_x; x < L_SUBFR; x += STEP)
	{
		ps1 = add(*ps, dn[x]);
		alp1 = add(*alp, *p0++);

		if (cn[x] >= 0)
		{
			pos = -1;
			for (y = track_y; y < L_SUBFR; y += STEP)
			{
				ps2 = add(ps1, dn[y]);
				alp2 = add(alp1, add(*p1++, *p2++));
				sq = mult(ps2, ps2);

				s = L_msu(L_mult(alpk, sq), sqk, alp2);

				if (s > 0)
				{
					sqk = sq;
					alpk = alp2;
					pos = y;
				}
			}
			p1 -= NB_POS;

			if (pos >= 0)
			{
				*ix = x;
				*iy = pos;
			}
		}
		else
		{
			p2 += NB_POS;
		}
	}

	*ps = add(*ps, add(dn[*ix], dn[*iy]));
	*alp = alpk;

	return;
}

⌨️ 快捷键说明

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