📄 fec_code.c
字号:
/*
*2.4 kbps MELP Proposed Federal Standard speech coder
*
*TMS320C5x assembly code
*
*version 1.0
*
*Copyright (c) 1998, Texas Instruments, Inc.
*
*Texas Instruments has intellectual property rights on the MELP
*algorithm. The Texas Instruments contact for licensing issues for
*commercial and non-government use is William Gordon, Director,
*Government Contracts, Texas Instruments Incorporated, Semiconductor
*Group (phone 972 480 7442).
*
*/
/*************************************************************************
*
* The following code was hand optimized for the Texas Instuments
* TMS320C5x DSP by DSPCon, Inc. For information, please contact DSPCon
* at:
*
* DSPCon, Inc.
* 380 Foothill Road
* Bridgewater, New Jersey 08807
* (908) 722-5656
* info@dspcon.com
* www.dspcon.com
*
*************************************************************************/
/*
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.
*/
#include "typedefs.h"
#include "melp.h"
/* Prototypes */
Shortword binprod_int(Shortword *x, Shortword *y, Shortword n);
Shortword *vgetbits(Shortword *y, Shortword x, Shortword p, Shortword n);
Shortword vsetbits(Shortword x, Shortword p, Shortword n, Shortword *y);
void sbc_enc(Shortword x[], Shortword n, Shortword k, Shortword *pmat);
Shortword sbc_dec(Shortword x[], Shortword n, Shortword k, Shortword *pmat,
Shortword syntab[]);
Shortword sbc_syn(Shortword x[], Shortword n, Shortword k, Shortword *pmat);
/* Macros */
#define null_function() exit(1)
/* Set vector to scalar value. */
#define V_SET(x,sc,n) if (1)\
{Shortword u__i;\
for(u__i=0; u__i < (n); u__i++)\
*((x)+u__i) = (sc);\
} else null_function()
/* Compiler constants */
#define UV_PIND 0 /* Unvoiced pitch index */
#define INVAL_PIND 1 /* Invalid pitch index */
#define BEP_CORR -1 /* "Correct" bit error position */
#define BEP_UNCORR -2 /* "Uncorrectable" bit error position */
extern Shortword pitch_enc[PIT_QLEV+1]; /* Pitch index encoding table */
extern Shortword pmat74[3][4]; /* (7,4) Hamming code parity matrix */
extern Shortword syntab74[8]; /* (7,4) Hamming code syndrome->bep table */
extern Shortword pmat84[4][4]; /* (8,4) Hamming code parity matrix */
extern Shortword syntab84[16]; /* (8,4) Hamming code syndrome->bep table */
static Shortword codewd74[7];
static Shortword codewd84[8];
void fec_code(struct melp_param *par)
{
/* Increment pitch index to allow for unvoiced pitch code */
par->pitch_index++;
/*
** Unvoiced case - use spare parameter bits for error protection.
*/
if (par->uv_flag)
{
/* Set pitch index to unvoiced value */
par->pitch_index = UV_PIND;
/*
** Code 4 MSB of first vq stage index using (8,4) Hamming code; parity bits in
** bpvc index.
*/
vgetbits(codewd84,par->msvq_index[0],6,4);
sbc_enc(codewd84,8,4,&pmat84[0][0]);
par->bpvc_index=vsetbits(par->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,par->msvq_index[0],2,3);
codewd74[3] = 0;
sbc_enc(codewd74,7,4,&pmat74[0][0]);
par->fsvq_index[0]=vsetbits(par->fsvq_index[0],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,par->gain_index[1],4,4);
sbc_enc(codewd74,7,4,&pmat74[0][0]);
par->fsvq_index[0]=vsetbits(par->fsvq_index[0],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,par->gain_index[1],0,1);
vgetbits(&codewd74[1],par->gain_index[0],2,3);
sbc_enc(codewd74,7,4,&pmat74[0][0]);
par->fsvq_index[0]=vsetbits(par->fsvq_index[0],1,2,&codewd74[4]);
par->jit_index=vsetbits(par->jit_index,0,1,&codewd74[6]);
}
/* Encode pitch index */
par->pitch_index = pitch_enc[par->pitch_index];
} /* fec_code */
Shortword fec_decode(struct melp_param *par,Shortword erase)
{
extern Shortword pitch_dec[1<<PIT_BITS]; /* Pitch index decoding table */
Shortword berr_pos;
/* Decode pitch index */
par->pitch_index = pitch_dec[par->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.
*/
if (!(par->uv_flag = par->pitch_index == UV_PIND) &&
!(erase |= par->pitch_index == INVAL_PIND))
par->pitch_index-=2; /* Subtract to acct. for reserved pitch codes.*/
if (par->uv_flag && !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,par->msvq_index[0],6,4);
vgetbits(&codewd84[4],par->bpvc_index,3,4);
berr_pos=sbc_dec(codewd84,8,4,&pmat84[0][0],syntab84);
erase |= berr_pos == BEP_UNCORR;
par->msvq_index[0]=vsetbits(par->msvq_index[0],6,4,codewd84);
par->bpvc_index = 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,par->msvq_index[0],2,3);
codewd74[3] = 0;
vgetbits(&codewd74[4],par->fsvq_index[0],7,3);
berr_pos=sbc_dec(codewd74,7,4,&pmat74[0][0],syntab74);
par->msvq_index[0]=vsetbits(par->msvq_index[0],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,par->gain_index[1],4,4);
vgetbits(&codewd74[4],par->fsvq_index[0],4,3);
berr_pos=sbc_dec(codewd74,7,4,&pmat74[0][0],syntab74);
par->gain_index[1]=vsetbits(par->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,par->gain_index[1],0,1);
vgetbits(&codewd74[1],par->gain_index[0],2,3);
vgetbits(&codewd74[4],par->fsvq_index[0],1,2);
vgetbits(&codewd74[6],par->jit_index,0,1);
berr_pos=sbc_dec(codewd74,7,4,&pmat74[0][0],syntab74);
par->gain_index[1]=vsetbits(par->gain_index[1],0,1,codewd74);
par->gain_index[0]=vsetbits(par->gain_index[0],2,3,&codewd74[1]);
par->jit_index = 1;
}
} /* if (par->uv_flag && !erase) */
return(erase);
} /* fec_decode */
/*
binprod returns a
bitwise modulo-2 inner product between x and y.
*/
Shortword binprod_int(Shortword *x, Shortword *y, Shortword n)
{
Shortword val=(Shortword) 0;
register Shortword i;
for (i=0; i<n; i++)
val ^= *x++ & *y++;
return(val);
}
/*
vgetbits extracts an n-bit pattern beginning at bit position p from an
int, and returns a bit vector containing the pattern. Conversely,
vsetbits takes a length n bit vector and sets the bit pattern in an
integer.
*/
Shortword *vgetbits(Shortword *y, Shortword x, Shortword p, Shortword n)
{
Shortword lsb=0x1; /* least significant bit mask */
Shortword *retval=y;
if (n < 0 || p < n-1)
return(NULL);
for (y+=n-1,x>>=p-n+1; y>=retval; y--,x>>=1)
*y = x & lsb;
return(retval);
}
Shortword vsetbits(Shortword x, Shortword p, Shortword n, Shortword *y)
{
register Shortword i,j;
if (n < 0 || p < n-1)
return(x);
for (i=0,j=p; i<n; i++,j--)
{
x &= ~(0x1 << j); /* mask out bit position j */
x |= *(y++) << j; /* set bit position j to array value */
}
return(x);
}
/*
Name: code_blk - systematic block error control code functions.
Description:
These functions are designed to implement systematic block codes given an
input vector and a parity matrix. These codes are characterized by
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.
*/
void sbc_enc(Shortword x[], Shortword n, Shortword k, Shortword *pmat)
{
register Shortword i;
for (i=k; i<n; i++,pmat+=k)
x[i] = binprod_int(x,pmat,k);
}
Shortword sbc_dec(Shortword x[], Shortword n, Shortword k, Shortword *pmat, Shortword syntab[])
{
Shortword bep=syntab[sbc_syn(x,n,k,pmat)];
if (bep > -1)
x[bep] ^= 0x1;
return(bep);
}
Shortword sbc_syn(Shortword x[], Shortword n, Shortword k, Shortword *pmat)
{
Shortword retval=0;
register Shortword i,j;
for (i=k,j=n-k-1; i<n; i++,j--,pmat+=k)
retval += (x[i] ^ binprod_int(x,pmat,k)) << j;
return(retval);
}
/*
** (7,4) Hamming code tables.
*/
/* Parity generator matrix. */
Shortword pmat74[3][4] = {{1,1,0,1},{1,0,1,1},{0,1,1,1}};
/* Syndrome table. */
Shortword syntab74[8] = {BEP_CORR,6,5,2,4,1,0,3};
/*
** (8,4) extended Hamming code tables.
*/
/* Parity generator matrix. */
Shortword pmat84[4][4] = {{1,1,0,1},{1,0,1,1},{0,1,1,1},{1,1,1,0}};
/* Syndrome->error position lookup table. */
Shortword syntab84[16] =
{
BEP_CORR, /* 0x0 */
7, /* 0x1 */
6, /* 0x2 */
BEP_UNCORR, /* 0x3 */
5, /* 0x4 */
BEP_UNCORR, /* 0x5 */
BEP_UNCORR, /* 0x6 */
2, /* 0x7 */
4, /* 0x8 */
BEP_UNCORR, /* 0x9 */
BEP_UNCORR, /* 0xA */
1, /* 0xB */
BEP_UNCORR, /* 0xC */
0, /* 0xD */
3, /* 0xE */
BEP_UNCORR /* 0xF */
};
/*
** Pitch index encoding table. Reserve Hamming weight 0,1 words for
** unvoiced pitch value. Reserve Hamming weight 2 words for invalid (protect
** against single bit voiced pitch errors. Assign voiced pitch codes to
** values having Hamming weight > 2.
*/
Shortword pitch_enc[PIT_QLEV+1] =
{
0x0, /* UV_PIND */
0x7, /* 1 (first pitch QL - note offset) */
0xB, /* 2 */
0xD, /* 3 */
0xE, /* 4 */
0xF, /* 5 */
0x13, /* 6 */
0x15, /* 7 */
0x16, /* 8 */
0x17, /* 9 */
0x19, /* 10 */
0x1A, /* 11 */
0x1B, /* 12 */
0x1C, /* 13 */
0x1D, /* 14 */
0x1E, /* 15 */
0x1F, /* 16 */
0x23, /* 17 */
0x25, /* 18 */
0x26, /* 19 */
0x27, /* 20 */
0x29, /* 21 */
0x2A, /* 22 */
0x2B, /* 23 */
0x2C, /* 24 */
0x2D, /* 25 */
0x2E, /* 26 */
0x2F, /* 27 */
0x31, /* 28 */
0x32, /* 29 */
0x33, /* 30 */
0x34, /* 31 */
0x35, /* 32 */
0x36, /* 33 */
0x37, /* 34 */
0x38, /* 35 */
0x39, /* 36 */
0x3A, /* 37 */
0x3B, /* 38 */
0x3C, /* 39 */
0x3D, /* 40 */
0x3E, /* 41 */
0x3F, /* 42 */
0x43, /* 43 */
0x45, /* 44 */
0x46, /* 45 */
0x47, /* 46 */
0x49, /* 47 */
0x4A, /* 48 */
0x4B, /* 49 */
0x4C, /* 50 */
0x4D, /* 51 */
0x4E, /* 52 */
0x4F, /* 53 */
0x51, /* 54 */
0x52, /* 55 */
0x53, /* 56 */
0x54, /* 57 */
0x55, /* 58 */
0x56, /* 59 */
0x57, /* 60 */
0x58, /* 61 */
0x59, /* 62 */
0x5A, /* 63 */
0x5B, /* 64 */
0x5C, /* 65 */
0x5D, /* 66 */
0x5E, /* 67 */
0x5F, /* 68 */
0x61, /* 69 */
0x62, /* 70 */
0x63, /* 71 */
0x64, /* 72 */
0x65, /* 73 */
0x66, /* 74 */
0x67, /* 75 */
0x68, /* 76 */
0x69, /* 77 */
0x6A, /* 78 */
0x6B, /* 79 */
0x6C, /* 80 */
0x6D, /* 81 */
0x6E, /* 82 */
0x6F, /* 83 */
0x70, /* 84 */
0x71, /* 85 */
0x72, /* 86 */
0x73, /* 87 */
0x74, /* 88 */
0x75, /* 89 */
0x76, /* 90 */
0x77, /* 91 */
0x78, /* 92 */
0x79, /* 93 */
0x7A, /* 94 */
0x7B, /* 95 */
0x7C, /* 96 */
0x7D, /* 97 */
0x7E, /* 98 */
0x7F /* 99 */
};
/*
** Pitch index decoding table. Hamming weight 1 codes map to UV_PIND,
** allowing for 1-bit error correction of unvoiced marker. Hamming weight 2
** codes map to INVAL_PIND, protecting against 1-bit errors in voiced pitches
** creating false unvoiced condition.
*/
Shortword pitch_dec[1<<PIT_BITS] =
{
UV_PIND, /* 0x0 */
UV_PIND, /* 0x1 */
UV_PIND, /* 0x2 */
INVAL_PIND, /* 0x3 */
UV_PIND, /* 0x4 */
INVAL_PIND, /* 0x5 */
INVAL_PIND, /* 0x6 */
2, /* 0x7 */
UV_PIND, /* 0x8 */
INVAL_PIND, /* 0x9 */
INVAL_PIND, /* 0xA */
3, /* 0xB */
INVAL_PIND, /* 0xC */
4, /* 0xD */
5, /* 0xE */
6, /* 0xF */
UV_PIND, /* 0x10 */
INVAL_PIND, /* 0x11 */
INVAL_PIND, /* 0x12 */
7, /* 0x13 */
INVAL_PIND, /* 0x14 */
8, /* 0x15 */
9, /* 0x16 */
10, /* 0x17 */
INVAL_PIND, /* 0x18 */
11, /* 0x19 */
12, /* 0x1A */
13, /* 0x1B */
14, /* 0x1C */
15, /* 0x1D */
16, /* 0x1E */
17, /* 0x1F */
UV_PIND, /* 0x20 */
INVAL_PIND, /* 0x21 */
INVAL_PIND, /* 0x22 */
18, /* 0x23 */
INVAL_PIND, /* 0x24 */
19, /* 0x25 */
20, /* 0x26 */
21, /* 0x27 */
INVAL_PIND, /* 0x28 */
22, /* 0x29 */
23, /* 0x2A */
24, /* 0x2B */
25, /* 0x2C */
26, /* 0x2D */
27, /* 0x2E */
28, /* 0x2F */
INVAL_PIND, /* 0x30 */
29, /* 0x31 */
30, /* 0x32 */
31, /* 0x33 */
32, /* 0x34 */
33, /* 0x35 */
34, /* 0x36 */
35, /* 0x37 */
36, /* 0x38 */
37, /* 0x39 */
38, /* 0x3A */
39, /* 0x3B */
40, /* 0x3C */
41, /* 0x3D */
42, /* 0x3E */
43, /* 0x3F */
UV_PIND, /* 0x40 */
INVAL_PIND, /* 0x41 */
INVAL_PIND, /* 0x42 */
44, /* 0x43 */
INVAL_PIND, /* 0x44 */
45, /* 0x45 */
46, /* 0x46 */
47, /* 0x47 */
INVAL_PIND, /* 0x48 */
48, /* 0x49 */
49, /* 0x4A */
50, /* 0x4B */
51, /* 0x4C */
52, /* 0x4D */
53, /* 0x4E */
54, /* 0x4F */
INVAL_PIND, /* 0x50 */
55, /* 0x51 */
56, /* 0x52 */
57, /* 0x53 */
58, /* 0x54 */
59, /* 0x55 */
60, /* 0x56 */
61, /* 0x57 */
62, /* 0x58 */
63, /* 0x59 */
64, /* 0x5A */
65, /* 0x5B */
66, /* 0x5C */
67, /* 0x5D */
68, /* 0x5E */
69, /* 0x5F */
INVAL_PIND, /* 0x60 */
70, /* 0x61 */
71, /* 0x62 */
72, /* 0x63 */
73, /* 0x64 */
74, /* 0x65 */
75, /* 0x66 */
76, /* 0x67 */
77, /* 0x68 */
78, /* 0x69 */
79, /* 0x6A */
80, /* 0x6B */
81, /* 0x6C */
82, /* 0x6D */
83, /* 0x6E */
84, /* 0x6F */
85, /* 0x70 */
86, /* 0x71 */
87, /* 0x72 */
88, /* 0x73 */
89, /* 0x74 */
90, /* 0x75 */
91, /* 0x76 */
92, /* 0x77 */
93, /* 0x78 */
94, /* 0x79 */
95, /* 0x7A */
96, /* 0x7B */
97, /* 0x7C */
98, /* 0x7D */
99, /* 0x7E */
100 /* 0x7F */
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -