📄 fec_code.c
字号:
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 + -