📄 fec_code.c
字号:
/*
2.4 kbps MELP Proposed Federal Standard speech coder
Fixed-point C 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 fixed-point version of the voice codec Mixed Excitation Linear
Prediction (MELP) is based on specifications on the C-language software
simulation contained in GSM 06.06 which is protected by copyright and
is the property of the European Telecommunications Standards Institute
(ETSI). This standard is available from the ETSI publication office
tel. +33 (0)4 92 94 42 58. ETSI has granted a license to United States
Department of Defense to use the C-language software simulation contained
in GSM 06.06 for the purposes of the development of a fixed-point
version of the voice codec Mixed Excitation Linear Prediction (MELP).
Requests for authorization to make other use of the GSM 06.06 or
otherwise distribute or modify them need to be addressed to the ETSI
Secretariat fax: +33 493 65 47 16.
*/
/*
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 <stdio.h>
#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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -