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

📄 fec_code.c

📁 MELPe 1200 bps, fixed point
💻 C
📖 第 1 页 / 共 3 页
字号:
	INVAL_PIND,	/* 493 */
	INVAL_PIND,	/* 494 */
	INVAL_PIND,	/* 495 */
	INVAL_PIND,	/* 496 */
	82,			/* 497 */ /* UUV */
	83,			/* 498 */ /* UUV */
	INVAL_PIND,	/* 499 */
	84,			/* 500 */ /* UUV */
	INVAL_PIND,	/* 501 */
	INVAL_PIND,	/* 502 */
	INVAL_PIND,	/* 503 */
	85,			/* 504 */ /* UUV */
	INVAL_PIND,	/* 505 */
	INVAL_PIND,	/* 506 */
	INVAL_PIND,	/* 507 */
	INVAL_PIND,	/* 508 */
	INVAL_PIND,	/* 509 */
	INVAL_PIND,	/* 510 */
	INVAL_PIND,	/* 511 */
};

/* ----- Prototypes ----- */
static Shortword	binprod_int(Shortword x[], const Shortword y[],
								Shortword n);

static void		vgetbits(Shortword dest[], Shortword source, Shortword bit_pos,
						 Shortword n);

static void		vsetbits(Shortword *dest, Shortword bit_pos, Shortword n,
						 Shortword source[]);

static void		sbc_enc(Shortword x[], Shortword n, Shortword k,
						const Shortword pmat[]);

static Shortword	sbc_dec(Shortword x[], Shortword n, Shortword k,
							const Shortword pmat[], const Shortword syntab[]);

static Shortword	sbc_syn(Shortword x[], Shortword n, Shortword k,
							const Shortword pmat[]);

static void		crc4_enc(Shortword bit[], Shortword num_bits);

static Shortword	crc4_dec(Shortword bit[], Shortword num_bits);


/*
    Name: fec_code.c, fec_decode.c
    Description: Encode/decode FEC (Hamming codes) on selected MELP parameters
    Inputs:
      MELP parameter structure
    Outputs:
      updated MELP parameter structure
    Returns: void

    Copyright (c) 1995 by Texas Instruments, Inc.  All rights reserved.
*/

void fec_code(struct quant_param *qpar)
{
	/* Increment pitch index to allow for unvoiced pitch code */
	qpar->pitch_index ++;

	/* Unvoiced case - use spare parameter bits for error protection. */
	if (qpar->uv_flag[0]){
		/* Set pitch index to unvoiced value */
		qpar->pitch_index = UV_PIND;

		/* Code 4 MSB of first vq stage index using (8,4) Hamming code;       */
		/* parity bits in bpvc index.                                         */

		vgetbits(codewd84, qpar->msvq_index[0], 6, 4);
		sbc_enc(codewd84, 8, 4, &pmat84[0][0]);
		vsetbits(qpar->bpvc_index, 3, 4, &codewd84[4]);

		/* Code 3 LSB of first vq stage index using (7,4) Hamming code;       */
		/* parity bits in 3 MSB of fsvq index.                                */

		vgetbits(codewd74, qpar->msvq_index[0], 2, 3);
		codewd74[3] = 0;
		sbc_enc(codewd74, 7, 4, &pmat74[0][0]);
		vsetbits(&(qpar->fsvq_index), 7, 3, &codewd74[4]);

		/* Code 4 MSB of second gain index using (7,4) Hamming code; parity   */
		/* bits in next 3 MSB of fsvq index.                                  */

		vgetbits(codewd74, qpar->gain_index[1], 4, 4);
		sbc_enc(codewd74, 7, 4, &pmat74[0][0]);
		vsetbits(&(qpar->fsvq_index), 4, 3, &codewd74[4]);

		/* Code LSB of second gain index, first gain index using (7,4)        */
		/* Hamming code; parity bits in 2 LSB of fsvq index, jitter index     */
		/* bit.                                                               */

		vgetbits(codewd74, qpar->gain_index[1], 0, 1);
		vgetbits(&codewd74[1], qpar->gain_index[0], 2, 3);
		sbc_enc(codewd74, 7, 4, &pmat74[0][0]);
		vsetbits(&(qpar->fsvq_index), 1, 2, &codewd74[4]);
		vsetbits(qpar->jit_index, 0, 1, &codewd74[6]);
	}

	/* Encode pitch index */
	qpar->pitch_index = pitch_enc[qpar->pitch_index];
}


void	low_rate_fec_code(struct quant_param *par)
{
	if (par->uv_flag[0] && par->uv_flag[1] && par->uv_flag[2]){

		/* for 4 MSB of Gain */
		vgetbits(codewd84, par->gain_index[0], 9, 4);
		sbc_enc(codewd84, 8, 4, &pmat84[0][0]);
		vsetbits(&(par->fs_index), 7, 4, &codewd84[4]);

		/* for next 4 MSB of Gain */
		vgetbits(codewd84, par->gain_index[0], 5, 4);
		sbc_enc(codewd84, 8, 4, &pmat84[0][0]);
		vsetbits(&(par->fs_index), 3, 4, &codewd84[4]);

		/* for 3 LSB of Gain */
		vgetbits(codewd74, par->gain_index[0], 1, 2);
		codewd74[2] = codewd74[3] = 0;
		sbc_enc(codewd74, 7, 4, &pmat74[0][0]);
		vsetbits(&(par->bpvc_index[0]), 1, 2, &codewd74[4]);
		vsetbits(&(par->jit_index[0]), 0, 1, &codewd74[6]);

		/* for LSPs of 1st frame */
		vgetbits(&codewd_13x9[4], par->lsf_index[0][0], 8, 9);
		crc4_enc(codewd_13x9, 9);
		vsetbits(&(par->lsf_index[0][1]), 3, 4, &codewd_13x9[0]);

		/* for LSPs of 2nd frame */
		vgetbits(&codewd_13x9[4], par->lsf_index[1][0], 8, 9);
		crc4_enc(codewd_13x9, 9);
		vsetbits(&(par->lsf_index[1][1]), 3, 4, &codewd_13x9[0]);

		/* for LSPs of 3rd frame */
		vgetbits(&codewd_13x9[4], par->lsf_index[2][0], 8, 9);
		crc4_enc(codewd_13x9, 9);
		vsetbits(&(par->lsf_index[2][1]), 3, 4, &codewd_13x9[0]);
	}
}


Shortword fec_decode(struct quant_param *qpar, Shortword erase)
{
	Shortword	berr_pos;


	/* Decode pitch index */
	qpar->pitch_index = pitch_dec[qpar->pitch_index];

	/* Set unvoiced flag for pitch index of UV_PIND; set erase flag for       */
	/* invalid pitch index INVAL_PIND.  Otherwise, convert pitch index into   */
	/* quantization level.                                                    */

	qpar->uv_flag[0] = (BOOLEAN) (qpar->pitch_index == UV_PIND);
	if (!qpar->uv_flag[0]){
		erase |= (qpar->pitch_index == INVAL_PIND);
		if (!erase)
			qpar->pitch_index -= 2;                  /* Subtract to acct. for */
                                                     /* reserved pitch codes. */
	}

	if (qpar->uv_flag[0] && !erase){

		/* Unvoiced case - use spare parameter bits for error control coding. */
        /* Decode 4 MSB of first vq stage index using (8,4) Hamming code;     */
        /* parity bits in bpvc index.  Set bpvc index to zero.                */

		vgetbits(codewd84, qpar->msvq_index[0], 6, 4);
		vgetbits(&codewd84[4], qpar->bpvc_index[0], 3, 4);
		berr_pos = sbc_dec(codewd84, 8, 4, &pmat84[0][0], syntab84);
		erase |= (berr_pos == BEP_UNCORR);
		vsetbits(qpar->msvq_index, 6, 4, codewd84);
		qpar->bpvc_index[0] = 0;

		/* Perform remaining decoding only if no frame repeat flagged. */
		if (!erase){

			/* Decode 3 LSB of first vq stage index using (7,4) Hamming code; */
			/* parity bits in 3 MSB of fsvq index.                            */

			vgetbits(codewd74, qpar->msvq_index[0], 2, 3);
			codewd74[3] = 0;
			vgetbits(&codewd74[4], qpar->fsvq_index, 7, 3);
			berr_pos = sbc_dec(codewd74, 7, 4, &pmat74[0][0], syntab74);
			vsetbits(qpar->msvq_index, 2, 3, codewd74);

			/* Decode 4 MSB of second gain index using (7,4) Hamming code;    */
            /* parity bits in next 3 MSB of fsvq index.                       */

			vgetbits(codewd74, qpar->gain_index[1], 4, 4);
			vgetbits(&codewd74[4], qpar->fsvq_index, 4, 3);
			berr_pos = sbc_dec(codewd74, 7, 4, &pmat74[0][0], syntab74);
			vsetbits(&(qpar->gain_index[1]), 4, 4, codewd74);

			/* Decode LSB of second gain index, first gain index using (7,4)  */
			/* Hamming code; parity bits in 2 LSB of fsvq index, jitter index */
			/* bit.  Set jitter index bits to one.                            */

			vgetbits(codewd74, qpar->gain_index[1], 0, 1);
			vgetbits(&codewd74[1], qpar->gain_index[0], 2, 3);
			vgetbits(&codewd74[4], qpar->fsvq_index, 1, 2);
			vgetbits(&codewd74[6], qpar->jit_index[0], 0, 1);
			berr_pos = sbc_dec(codewd74, 7, 4, &pmat74[0][0], syntab74);
			vsetbits(&(qpar->gain_index[1]), 0, 1, codewd74);
			vsetbits(qpar->gain_index, 2, 3, &codewd74[1]);
			qpar->jit_index[0] = 1;
		}
	}
	return(erase);
}


Shortword	low_rate_fec_decode(struct quant_param *qpar, Shortword erase,
								Shortword lsp_check[])
{
	Shortword	berr_pos;


	if (qpar->uv_flag[0] && qpar->uv_flag[1] && qpar->uv_flag[2]){
		/* for 4 MSB of Gain */
		vgetbits(codewd84, qpar->gain_index[0], 9, 4);
		vgetbits(&codewd84[4], qpar->fs_index, 7, 4);
		berr_pos = sbc_dec(codewd84, 8, 4, &pmat84[0][0], syntab84);
		erase |= berr_pos == BEP_UNCORR;
		vsetbits(qpar->gain_index, 9, 4, codewd84);

		/* for next 4 MSB of Gain */
		vgetbits(codewd84, qpar->gain_index[0], 5, 4);
		vgetbits(&codewd84[4], qpar->fs_index, 3, 4);
		berr_pos = sbc_dec(codewd84, 8, 4, &pmat84[0][0], syntab84);
		erase |= berr_pos == BEP_UNCORR;
		vsetbits(qpar->gain_index, 5, 4, codewd84);

		if (!erase){

			/* for 2 LSB of Gain */
			vgetbits(codewd74, qpar->gain_index[0], 1, 2);
			codewd74[2] = codewd74[3] = 0;
			vgetbits(&codewd74[4], qpar->bpvc_index[0], 1, 2);
			vgetbits(&codewd74[6], qpar->jit_index[0], 0, 1);
			berr_pos = sbc_dec(codewd74, 7, 4, &pmat74[0][0], syntab74);
			vsetbits(qpar->gain_index, 1, 2, codewd74);

			/* for LSPs of 1st frame */
			vgetbits(&codewd_13x9[4], qpar->lsf_index[0][0], 8, 9);
			vgetbits(&codewd_13x9[0], qpar->lsf_index[0][1], 3, 4);
			lsp_check[0] = crc4_dec(codewd_13x9, 13);

			/* for LSPs of 1st frame */
			vgetbits(&codewd_13x9[4], qpar->lsf_index[1][0], 8, 9);
			vgetbits(&codewd_13x9[0], qpar->lsf_index[1][1], 3, 4);
			lsp_check[1] = crc4_dec(codewd_13x9, 13);

			/* for LSPs of 1st frame */
			vgetbits(&codewd_13x9[4], qpar->lsf_index[2][0], 8, 9);
			vgetbits(&codewd_13x9[0], qpar->lsf_index[2][1], 3, 4);
			lsp_check[2] = crc4_dec(codewd_13x9, 13);
		}
	}
	return(erase);
}


/* binprod returns a bitwise modulo-2 inner product between int arrays x[]    */
/* and y[].                                                                   */

static Shortword	binprod_int(Shortword x[], const Shortword y[],
								Shortword n)
{
	register Shortword	i;
	Shortword	val = 0;


	for (i = 0; i < n; i++)
		val ^= *x++ & *y++;

	return(val);
}


/* vgetbits() extracts an n-bit pattern beginning at bit position p from an   */
/* integer x, and returns a bit vector containing the pattern.  Conversely,   */
/* vsetbits() takes a length n bit vector and sets the bit pattern in an      */
/* integer.                                                                   */

static void		vgetbits(Shortword dest[], Shortword source, Shortword bit_pos,
						 Shortword n)
{
	register Shortword	i;
	const Shortword		lsb_mask = 0x1;         /* least significant bit mask */


	if ((n >= 0) && (bit_pos >= sub(n, 1))){
		source = shr(source, (Shortword) (bit_pos - n + 1));
		for (i = sub(n, 1); i >= 0; i--){
			dest[i] = (Shortword) (source & lsb_mask);
			source = shr(source, 1);
		}
	}
}


static void		vsetbits(Shortword *dest, Shortword bit_pos, Shortword n,
						 Shortword source[])
{
	register Shortword	i, j;
	const Shortword		lsb_mask = 0x1;


	if ((n >= 0) && (bit_pos >= n - 1)){
		for (i = 0, j = bit_pos; i < n; i++, j--){
			*dest &= ~(lsb_mask << j);             /* mask out bit position j */
			*dest |= *(source ++) << j;  /* set bit position j to array value */
		}
	}
}


/* Name: code_blk - systematic block error control code functions.            */
/*                                                                            */
/* Description:                                                               */
/*                                                                            */
/*   These functions are designed to implement systematic block codes given   */
/*   input vector and a parity matrix.  These codes are characterized by an   */
/*   leaving the data bits of the protected n-bit block unaltered.  The       */
/*   parity matrix used in these functions is a (n-k) x k matrix which        */
/*   generated the parity bits for a given input block.                       */
/*                                                                            */
/*   sbc_enc() takes a length n bit vector x, applies parity matrix pmat,     */
/*   and writes the parity bits into the last n-k positions of x.             */
/*                                                                            */
/*   sbc_dec() takes x (after processing by sbc_enc) and corrects x for bit   */
/*   errors using a syndrome table lookup.  sbc_dec() returns the index of a  */
/*   detected bit error in x.  sbc_dec() returns -1 if no error is found.     */
/*                                                                            */
/*   sbc_syn() takes x (after processing by sbc_enc) and computes a syndrome  */
/*   index used to look up a bit error position in the syndrome table.        */

static void		sbc_enc(Shortword x[], Shortword n, Shortword k,
						const Shortword pmat[])
{
	register Shortword	i;


	for (i = k; i < n; i++, pmat += k)
		x[i] = binprod_int(x, pmat, k);
}


static Shortword	sbc_dec(Shortword x[], Shortword n, Shortword k,
							const Shortword pmat[], const Shortword syntab[])
{
	Shortword	bep;


	bep = syntab[sbc_syn(x, n, k, pmat)];
	if (bep > -1)
		x[bep] ^= 0x1;
	return(bep);
}


static Shortword	sbc_syn(Shortword x[], Shortword n, Shortword k,
							const Shortword pmat[])
{
	register Shortword	i, j;
	Shortword	retval = 0;


	for (i = k, j = (Shortword) (n - k - 1); i < n; i++, j--, pmat += k)
		retval = add(retval,
					 (Shortword) ((x[i] ^ binprod_int(x, pmat, k)) << j));
	return(retval);
}


static void		crc4_enc(Shortword bit[], Shortword num_bits)
{
	register Shortword	i;
	Shortword	delay[4], x, ll;


	ll = add(num_bits, 4);
	v_zap(delay, 4);

	for (i = 1; i <= num_bits; i++){
		x = (Shortword) (delay[3] ^ bit[ll - i]);

		delay[3] = delay[2];
		delay[2] = delay[1];
		delay[1] = (Shortword) (x ^ delay[0]);
		delay[0] = x;
	}

	v_equ(bit, delay, 4);
}


static Shortword	crc4_dec(Shortword bit[], Shortword num_bits)
{
	register Shortword	i;
	Shortword	delay[4], x;

	for (i = 1; i <= 4; i++)
		delay[4 - i] = bit[num_bits - i];

	for (i = 5; i <= num_bits; i++){
		x = delay[3];
		delay[3] = delay[2];
		delay[2] = delay[1];
		delay[1] = (Shortword) (x ^ delay[0]);
		delay[0] = (Shortword) (x ^ bit[num_bits - i]);
	}

	x = 0x0;
	for (i = 0; i < 4; i++)
		x |= delay[i];

	return(x);
}

⌨️ 快捷键说明

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