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

📄 fec_code.c

📁 C50_melp.tar.gz为美军2400bps语音压缩编码算法
💻 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 + -