Files
rtphone/src/libs/gsmhr/gsmhr_utils.c
2018-06-05 11:05:37 +03:00

1107 lines
35 KiB
C

/*___________________________________________________________________________
| |
| |
| Residual Error Insertion Device |
| |
| |
| File : REID.C |
| |
| Date : February 03, 1995 |
| |
| Version: 4.1 |
| |
| |
| Description: |
| ------------ |
| This routine transforms the output file format of the GSM Half |
| Rate Encoder module consisting of: |
| * 18 speech parameters (see GSM TS 06.20) |
| * 1 speech flag SP (see GSM TS 06.41) |
| * 1 voice activity flag VAD (see GSM TS 06.42) |
| |
| to the input file format of the GSM Half Rate Decoder module |
| requiring: |
| * 18 speech parameters (see GSM TS 06.20) |
| * 1 channel condition flag BFI (see GSM TS 06.21, 05.05) |
| * 1 channel condition flag UFI (see GSM TS 06.21, 05.05) |
| * 1 SID flag (2 bits) (see GSM TS 06.41, 05.05) |
| * 1 time alignment flag TAF (see GSM TS 06.41) |
| |
| Between SID updates the speech parameters are replaced by random |
| values simulating an interrupted transmission on the air interface |
| |
| The actual implementation only supports error free transmission (EP0)|
| |
| The shell for the future use of error patterns (residual error |
| pattern insertion) is already included. If necessary, byte swapping |
| is performed on the input speech parameters so that they are always |
| represented internally in PC byte order (assuming that the byte |
| order of the input file is compatible with the machine on which the |
| program is run). However, byte swapping is not done on the flag |
| words (input: SP and VAD, output: BFI, UFI, SID, and TAF). Thus, |
| the residual error pattern insertion code may be written to handle |
| the speech parameter words on a byte basis, but the flag words must |
| always be handled on a word basis. |
|___________________________________________________________________________|
*/
/*___________________________________________________________________________
| |
| Creation: 19.12.94 |
| |
| Changes: |
| 22.12.94: Removal of BCI flag, instead: determination of SID flag |
| 12.01.95: SID update period = 12 (instead of 24) |
| 13.01.95: When in CNI mode, the parameters between SID updates are |
| random values. This simulates the interrupted transmission|
| 03.02.95: int32_t main( int32_t...) replaced by int main(int ...),|
| initial value of swTAFCnt set to 1 |
|___________________________________________________________________________|
*/
/*___________________________________________________________________________
| |
| Include-Files |
|___________________________________________________________________________|
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#ifdef VAX
# define OPEN_WI "wb","mrs=512","rfm=fix","ctx=stm"
# define OPEN_RI "rb","mrs=512","rfm=fix","ctx=stm"
# define OPEN_WB "wb","mrs=512","rfm=fix","ctx=stm"
# define OPEN_RB "rb","mrs=2","rfm=fix","ctx=stm"
# define OPEN_WT "w","mrs=256","rat=cr","rfm=var"
# define OPEN_RT "r","mrs=256","rat=cr","rfm=var"
#else
# define OPEN_WB "wb"
# define OPEN_RB "rb"
# define OPEN_WI "wb"
# define OPEN_RI "rb"
# define OPEN_WT "wt"
# define OPEN_RT "rt"
#endif
#define LW_SIGN (long)0x80000000 /* sign bit */
#define LW_MIN (long)0x80000000
#define LW_MAX (long)0x7fffffff
#define SW_MIN (short)0x8000 /* smallest Ram */
#define SW_MAX (short)0x7fff /* largest Ram */
typedef char Byte;
typedef long int int32_t; /* 32 bit "accumulator" (L_*) */
typedef short int int16_t; /* 16 bit "register" (sw*) */
/*___________________________________________________________________________
| |
| local Functions |
|___________________________________________________________________________|
*/
static int32_t error_free( FILE *infile, FILE *outfile);
static void SwapBytes( int16_t buffer[], int32_t len );
static int32_t ByteOrder( void );
static size_t ReadInputFile( int16_t buffer[], FILE *fp );
static size_t WriteOutputFile( int16_t buffer[], FILE *fp );
static int32_t EncoderInterface( FILE *infile, int16_t swInPara[] );
static int16_t swSidDetection(int16_t pswParameters[],
int16_t pswErrorFlag[]);
static void RandomParameters(int16_t pswParameters[]);
static int16_t getPnBits(int16_t iBits, int32_t *pL_PNSeed);
FILE *OpenBinfile( char *name, char *mode );
int32_t Strincmp( const char *s, const char *t, size_t max );
int32_t Stricmp( const char *s, const char *t );
int32_t L_shr(int32_t L_var1, int16_t var2); /* 2 ops */
int32_t L_shl(int32_t L_var1, int16_t var2); /* 2 ops */
int16_t shr(int16_t var1, int16_t var2); /* 1 ops */
int16_t shl(int16_t var1, int16_t var2); /* 1 ops */
/*___________________________________________________________________________
| |
| Subroutines |
|___________________________________________________________________________|
*/
static int32_t error_free( FILE *infile, FILE *outfile)
{
#define SPEECH 1
#define CNIFIRSTSID 2
#define CNICONT 3
#define VALIDSID 11
#define GOODSPEECH 33
static int16_t swDecoMode = {SPEECH};
static int16_t swTAFCnt = {1};
int16_t swInPara[20], i, swFrameType;
int16_t swOutPara[22],pswErrorFlag[3];
if( EncoderInterface( infile, swInPara )) return( 1 );
/* Copy input parameters to output parameters (error free transmission) */
/* -------------------------------------------------------------------- */
for (i=0;i<18;i++)
swOutPara[i] = swInPara[i];
/* Set channel status flags (error free transmission) */
/* -------------------------------------------------- */
swOutPara[18] = 0; /* BFI flag */
swOutPara[19] = 0; /* UFI flag */
/* Evaluate SID flag */
/* ----------------- */
pswErrorFlag[0] = 0; /* BFI flag */
pswErrorFlag[1] = 0; /* UFI flag */
pswErrorFlag[2] = 0; /* BCI flag */
swOutPara[20] = swSidDetection(swOutPara, pswErrorFlag);
/* Evaluate TAF flag */
/* ----------------- */
if (swTAFCnt == 0) swOutPara[21] = 1;
else swOutPara[21] = 0;
swTAFCnt = (swTAFCnt + 1) % 12;
/* Frame classification: */
/* Since the transmission is error free, the received frames are either */
/* valid speech or valid SID frames */
/* -------------------------------------------------------------------- */
if ( swOutPara[20] == 2) swFrameType = VALIDSID;
else if ( swOutPara[20] == 0) swFrameType = GOODSPEECH;
else {
printf( "Error in SID detection\n" );
return( 1 );
}
/* Update of decoder state */
/* ----------------------- */
if (swDecoMode == SPEECH) {
if (swFrameType == VALIDSID) swDecoMode = CNIFIRSTSID;
else if (swFrameType == GOODSPEECH) swDecoMode = SPEECH;
}
else { /* comfort noise insertion mode */
if (swFrameType == VALIDSID) swDecoMode = CNICONT;
else if (swFrameType == GOODSPEECH) swDecoMode = SPEECH;
}
/* Replace parameters by random data if in CNICONT-mode and TAF=0 */
/* -------------------------------------------------------------- */
if ((swDecoMode == CNICONT) && (swOutPara[21] == 0)){
RandomParameters(swOutPara);
/* Set flags such, that an "unusable frame" is produced */
swOutPara[18] = 1; /* BFI flag */
swOutPara[19] = 1; /* UFI flag */
swOutPara[20] = 0; /* SID flag */
}
if( outfile ) {
if( WriteOutputFile( swOutPara, outfile )) {
printf( "Error writing File\n" );
return( 1 );
}
}
return( 0 );
}
static int32_t EncoderInterface( FILE *infile, int16_t swInPara[] )
{
size_t i = 0;
i = ReadInputFile( swInPara, infile );
return(( i == 0 ) ? 1 : 0 );
}
static size_t ReadInputFile( int16_t buffer[], FILE *fp )
{
size_t i;
i = fread( buffer, sizeof( int16_t ), 20, fp );
SwapBytes( buffer, 18 );
return( i );
}
static size_t WriteOutputFile( int16_t buffer[], FILE *fp )
{
size_t i;
SwapBytes( buffer, 18 );
i = fwrite( buffer, sizeof( int16_t ), 22, fp );
return( ( i == 22 ) ? 0 : 1 );
}
static void SwapBytes( int16_t buffer[], int32_t len )
{
Byte *pc, tmp;
int32_t i;
if( !ByteOrder())
return;
pc = (Byte *)buffer;
for( i = 0; i < len; i++ ) {
tmp = pc[0];
pc[0] = pc[1];
pc[1] = tmp;
pc += 2;
}
}
static int32_t ByteOrder( void )
{
int16_t si;
Byte *pc;
si = 0x1234;
pc = (Byte *)&si;
if (pc[1] == 0x12 && pc[0] == 0x34 )
return( 0 );
if (pc[0] == 0x12 && pc[1] == 0x34 )
return( 1 );
printf( "Error in ByteOrder: %X, %X\n", (int)pc[0], (int)pc[1] );
exit( 1 );
return( 2 );
}
FILE *OpenBinfile( char *name, char *mode )
{
FILE *fp;
if( toupper( *mode ) == 'W' ) { /* Write access */
if(( fp = fopen( name, OPEN_WB )) == NULL ) {
printf( "Can't open output file '%s'\n", name );
exit( 1 );
}
} else { /* Read access */
if(( fp = fopen( name, OPEN_RB )) == NULL ) {
printf( "Can't open file '%s'\n", name );
exit( 1 );
}
}
return( fp );
}
int32_t Strincmp( const char *s, const char *t, size_t max )
{
for( ; max > 1; ++s, ++t, --max ) {
if( toupper( *s ) != toupper( *t ))
break;
if( *s == '\0' )
return( 0 );
}
return( toupper( *s ) - toupper( *t ));
}
int32_t Stricmp( const char *s, const char *t )
{
for(; toupper( *s ) == toupper( *t ); ++s, ++t ) {
if( *s == '\0' )
return( 0 );
}
return( toupper( *s ) - toupper( *t ));
}
/*************************************************************************
*
* FUNCTION NAME: getPnBits
*
* PURPOSE:
*
* Generate iBits pseudo-random bits using *pL_PNSeed as the
* pn-generators seed.
*
* INPUTS:
*
* iBits - integer indicating how many random bits to return.
* range [0,15], 0 yields 1 bit output
*
* *pL_PNSeed - 32 bit seed (changed by function)
*
* OUTPUTS:
*
* *pL_PNSeed - 32 bit seed, modified.
*
* RETURN VALUE:
*
* random bits in iBits LSB's.
*
*
* IMPLEMENTATION:
*
* implementation of x**31 + x**3 + 1 == PN_XOR_REG | PN_XOR_ADD a
* PN sequence generator using int32_ts generating a 2**31 -1
* length pn-sequence.
*
*************************************************************************/
static int16_t getPnBits(int16_t iBits, int32_t *pL_PNSeed){
#define PN_XOR_REG (int32_t)0x00000005L
#define PN_XOR_ADD (int32_t)0x40000000L
int16_t swPnBits=0;
int32_t L_Taps,L_FeedBack;
int16_t i;
for (i=0; i < iBits; i++){
/* update the state */
/********************/
L_Taps = *pL_PNSeed & PN_XOR_REG;
L_FeedBack = L_Taps; /* Xor tap bits to yield feedback bit */
L_Taps = L_shr(L_Taps,1);
while(L_Taps){
L_FeedBack = L_FeedBack ^ L_Taps;
L_Taps = L_shr(L_Taps,1);
}
/* LSB of L_FeedBack is next MSB of PN register */
*pL_PNSeed = L_shr(*pL_PNSeed,1);
if (L_FeedBack & 1)
*pL_PNSeed = *pL_PNSeed | PN_XOR_ADD;
/* State update complete.
Get the output bit from the state, add/or it into output */
swPnBits = shl(swPnBits,1);
swPnBits = swPnBits | (*pL_PNSeed & 1);
}
return(swPnBits);
}
/***************************************************************************
*
* FUNCTION NAME: L_shl
*
* PURPOSE:
*
* Arithmetic shift left (or right).
* Arithmetically shift the input left by var2. If var2 is
* negative then an arithmetic shift right (L_shr) of L_var1 by
* -var2 is performed.
*
* INPUTS:
*
* var2
* 16 bit short signed integer (int16_t) whose value
* falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
* L_var1
* 32 bit long signed integer (int32_t) whose value
* falls in the range
* 0x8000 0000 <= L_var1 <= 0x7fff ffff.
* OUTPUTS:
*
* none
*
* RETURN VALUE:
*
* L_Out
* 32 bit long signed integer (int32_t) whose value
* falls in the range
* 0x8000 0000 <= L_var1 <= 0x7fff ffff.
*
*
* IMPLEMENTATION:
*
* Arithmetically shift the 32 bit input left by var2. This
* operation maintains the sign of the input number. If var2 is
* negative then an arithmetic shift right (L_shr) of L_var1 by
* -var2 is performed. See description of L_shr for details.
*
* Equivalent to the Full-Rate GSM ">> n" operation. Note that
* ANSI-C does not guarantee operation of the C ">>" or "<<"
* operator for negative numbers.
*
* KEYWORDS: shift, arithmetic shift left,
*
*************************************************************************/
int32_t L_shl(int32_t L_var1, int16_t var2)
{
int32_t L_Mask,
L_Out;
int i,
iOverflow = 0;
if (var2 == 0 || L_var1 == 0)
{
L_Out = L_var1;
}
else if (var2 < 0)
{
if (var2 <= -31)
{
if (L_var1 > 0)
L_Out = 0;
else
L_Out = 0xffffffffL;
}
else
L_Out = L_shr(L_var1, -var2);
}
else
{
if (var2 >= 31)
iOverflow = 1;
else
{
if (L_var1 < 0)
L_Mask = LW_SIGN; /* sign bit mask */
else
L_Mask = 0x0;
L_Out = L_var1;
for (i = 0; i < var2 && !iOverflow; i++)
{
/* check the sign bit */
L_Out = (L_Out & 0x7fffffffL) << 1;
if ((L_Mask ^ L_Out) & LW_SIGN)
iOverflow = 1;
}
}
if (iOverflow)
{
/* saturate */
if (L_var1 > 0)
L_Out = LW_MAX;
else
L_Out = LW_MIN;
}
}
return (L_Out);
}
/***************************************************************************
*
* FUNCTION NAME: L_shr
*
* PURPOSE:
*
* Arithmetic shift right (or left).
* Arithmetically shift the input right by var2. If var2 is
* negative then an arithmetic shift left (shl) of var1 by
* -var2 is performed.
*
* INPUTS:
*
* var2
* 16 bit short signed integer (int16_t) whose value
* falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
* L_var1
* 32 bit long signed integer (int32_t) whose value
* falls in the range
* 0x8000 0000 <= L_var1 <= 0x7fff ffff.
* OUTPUTS:
*
* none
*
* RETURN VALUE:
*
* L_Out
* 32 bit long signed integer (int32_t) whose value
* falls in the range
* 0x8000 0000 <= L_var1 <= 0x7fff ffff.
*
*
* IMPLEMENTATION:
*
* Arithmetically shift the input right by var2. This
* operation maintains the sign of the input number. If var2 is
* negative then an arithmetic shift left (shl) of L_var1 by
* -var2 is performed. See description of L_shl for details.
*
* The input is a 32 bit number, as is the output.
*
* Equivalent to the Full-Rate GSM ">> n" operation. Note that
* ANSI-C does not guarantee operation of the C ">>" or "<<"
* operator for negative numbers.
*
* KEYWORDS: shift, arithmetic shift right,
*
*************************************************************************/
int32_t L_shr(int32_t L_var1, int16_t var2)
{
int32_t L_Mask,
L_Out;
if (var2 == 0 || L_var1 == 0)
{
L_Out = L_var1;
}
else if (var2 < 0)
{
/* perform a left shift */
/*----------------------*/
if (var2 <= -31)
{
/* saturate */
if (L_var1 > 0)
L_Out = LW_MAX;
else
L_Out = LW_MIN;
}
else
L_Out = L_shl(L_var1, -var2);
}
else
{
if (var2 >= 31)
{
if (L_var1 > 0)
L_Out = 0;
else
L_Out = 0xffffffffL;
}
else
{
L_Mask = 0;
if (L_var1 < 0)
{
L_Mask = ~L_Mask << (32 - var2);
}
L_var1 >>= var2;
L_Out = L_Mask | L_var1;
}
}
return (L_Out);
}
/***************************************************************************
*
* FUNCTION NAME: shl
*
* PURPOSE:
*
* Arithmetically shift the input left by var2.
*
*
* INPUTS:
*
* var1
* 16 bit short signed integer (int16_t) whose value
* falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
* var2
* 16 bit short signed integer (int16_t) whose value
* falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
*
* OUTPUTS:
*
* none
*
* RETURN VALUE:
*
* swOut
* 16 bit short signed integer (int16_t) whose value
* falls in the range
* 0xffff 8000 <= swOut <= 0x0000 7fff.
*
* IMPLEMENTATION:
*
* If Arithmetically shift the input left by var2. If var2 is
* negative then an arithmetic shift right (shr) of var1 by
* -var2 is performed. See description of shr for details.
* When an arithmetic shift left is performed the var2 LS bits
* are zero filled.
*
* The only exception is if the left shift causes an overflow
* or underflow. In this case the LS bits are not modified.
* The number returned is 0x8000 in the case of an underflow or
* 0x7fff in the case of an overflow.
*
* The shl is equivalent to the Full-Rate GSM "<< n" operation.
* Note that ANSI-C does not guarantee operation of the C ">>"
* or "<<" operator for negative numbers - it is not specified
* whether this shift is an arithmetic or logical shift.
*
* KEYWORDS: asl, arithmetic shift left, shift
*
*************************************************************************/
int16_t shl(int16_t var1, int16_t var2)
{
int16_t swOut;
int32_t L_Out;
if (var2 == 0 || var1 == 0)
{
swOut = var1;
}
else if (var2 < 0)
{
/* perform a right shift */
/*-----------------------*/
if (var2 <= -15)
{
if (var1 < 0)
swOut = (int16_t) 0xffff;
else
swOut = 0x0;
}
else
swOut = shr(var1, -var2);
}
else
{
/* var2 > 0 */
if (var2 >= 15)
{
/* saturate */
if (var1 > 0)
swOut = SW_MAX;
else
swOut = SW_MIN;
}
else
{
L_Out = (int32_t) var1 *(1 << var2);
swOut = (int16_t) L_Out; /* copy low portion to swOut,
* overflow could have hpnd */
if (swOut != L_Out)
{
/* overflow */
if (var1 > 0)
swOut = SW_MAX; /* saturate */
else
swOut = SW_MIN; /* saturate */
}
}
}
return (swOut);
}
/***************************************************************************
*
* FUNCTION NAME: shr
*
* PURPOSE:
*
* Arithmetic shift right (or left).
* Arithmetically shift the input right by var2. If var2 is
* negative then an arithmetic shift left (shl) of var1 by
* -var2 is performed.
*
* INPUTS:
*
* var1
* 16 bit short signed integer (int16_t) whose value
* falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
* var2
* 16 bit short signed integer (int16_t) whose value
* falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
*
* OUTPUTS:
*
* none
*
* RETURN VALUE:
*
* swOut
* 16 bit short signed integer (int16_t) whose value
* falls in the range
* 0xffff 8000 <= swOut <= 0x0000 7fff.
*
* IMPLEMENTATION:
*
* Arithmetically shift the input right by var2. This
* operation maintains the sign of the input number. If var2 is
* negative then an arithmetic shift left (shl) of var1 by
* -var2 is performed. See description of shl for details.
*
* Equivalent to the Full-Rate GSM ">> n" operation. Note that
* ANSI-C does not guarantee operation of the C ">>" or "<<"
* operator for negative numbers.
*
* KEYWORDS: shift, arithmetic shift right,
*
*************************************************************************/
int16_t shr(int16_t var1, int16_t var2)
{
int16_t swMask,
swOut;
if (var2 == 0 || var1 == 0)
swOut = var1;
else if (var2 < 0)
{
/* perform an arithmetic left shift */
/*----------------------------------*/
if (var2 <= -15)
{
/* saturate */
if (var1 > 0)
swOut = SW_MAX;
else
swOut = SW_MIN;
}
else
swOut = shl(var1, -var2);
}
else
{
/* positive shift count */
/*----------------------*/
if (var2 >= 15)
{
if (var1 < 0)
swOut = (int16_t) 0xffff;
else
swOut = 0x0;
}
else
{
/* take care of sign extension */
/*-----------------------------*/
swMask = 0;
if (var1 < 0)
{
swMask = ~swMask << (16 - var2);
}
var1 >>= var2;
swOut = swMask | var1;
}
}
return (swOut);
}
/*___________________________________________________________________________
| |
| This subroutine calculates the 'SID flag' |
| |
| Input: pswParameters[18] |
| input parameters of the speech decoder |
| |
| pswErrorFlag[3] |
| error flags, generated by channel decoder |
| |
| Return Value: |
| 0: speech frame detected |
| 1: most likely SID frame received |
| 2: SID frame detected |
| |
|___________________________________________________________________________|
| |
| History: |
| |
| 12-Oct-1994: Bug removed: error corrected in case of a mode (unvoiced/|
| voiced) mismatch, if a SID frame was received as an |
| unvoiced frame |
|___________________________________________________________________________|
*/
static int16_t swSidDetection(int16_t pswParameters[],
int16_t pswErrorFlag[])
{
static int16_t ppswIBit[2][18] = {
5, 11,9,8, 1, 2, 7,7,5, 7,7,5, 7,7,5, 7,7,5, /* unvoiced */
5, 11,9,8, 1, 2, 8,9,5, 4,9,5, 4,9,5, 4,9,5}; /* voiced */
static int16_t ppswCL1pCL2[2][18] = {
0x0001, /* R0 */ /* unvoiced */
0x00ef, /* LPC1 */
0x003e, /* LPC2 */
0x007f, /* LPC3 */
0x0001, /* INT LPC */
0x0003, /* Mode */
0x001f, /* Code1_1 */
0x0072, /* Code2_1 */
0x0012, /* GSP0_1 */
0x003f, /* Code1_2 */
0x007f, /* Code2_2 */
0x0008, /* GSP0_2 */
0x007f, /* Code1_3 */
0x007f, /* Code2_3 */
0x0008, /* GSP0_3 */
0x007f, /* Code1_4 */
0x007f, /* Code2_4 */
0x000c, /* GSP0_4 */
0x0000, /* R0 */ /* voiced */
0x0000, /* LPC1 */
0x0000, /* LPC2 */
0x0000, /* LPC3 */
0x0001, /* INT LPC */
0x0003, /* Mode */
0x00ff, /* Lag_1 */
0x01ff, /* Code_1 */
0x001f, /* GSP0_1 */
0x000f, /* Lag_2 */
0x01ff, /* Code_2 */
0x001f, /* GSP0_2 */
0x000f, /* Lag_3 */
0x01ff, /* Code_3 */
0x001f, /* GSP0_3 */
0x000f, /* Lag_4 */
0x01ff, /* Code_4 */
0x001f}; /* GSP0_4 */
static int16_t ppswCL2[2][18] = {
0x0000, /* R0 */ /* unvoiced */
0x0000, /* LPC1 */
0x0000, /* LPC2 */
0x0000, /* LPC3 */
0x0000, /* INT LPC */
0x0000, /* Mode */
0x0000, /* Code1_1 */
0x0000, /* Code2_1 */
0x0000, /* GSP0_1 */
0x0000, /* Code1_2 */
0x0000, /* Code2_2 */
0x0000, /* GSP0_2 */
0x0000, /* Code1_3 */
0x0007, /* Code2_3 */ /* 3 bits */
0x0000, /* GSP0_3 */
0x007f, /* Code1_4 */ /* 7 bits */
0x007f, /* Code2_4 */ /* 7 bits */
0x0000, /* GSP0_4 */
0x0000, /* R0 */ /* voiced */
0x0000, /* LPC1 */
0x0000, /* LPC2 */
0x0000, /* LPC3 */
0x0000, /* INT LPC */
0x0000, /* Mode */
0x0000, /* Lag_1 */
0x0000, /* Code_1 */
0x0000, /* GSP0_1 */
0x0000, /* Lag_2 */
0x0000, /* Code_2 */
0x0000, /* GSP0_2 */
0x0000, /* Lag_3 */
0x00ff, /* Code_3 */ /* 8 bits */
0x0000, /* GSP0_3 */
0x0000, /* Lag_4 */
0x01ff, /* Code_4 */ /* 9 bits */
0x0000}; /* GSP0_4 */
static int first = 1;
int16_t swMode, swBitMask;
int16_t swSidN1, swSidN2, swSidN1pN2;
int16_t swSid ;
short siI, siII;
if (first)
{
/* Force Sid codewords to be represented */
/* internally in PC byte order */
/* ------------------------------------- */
SwapBytes(ppswCL1pCL2[0], 18);
SwapBytes(ppswCL1pCL2[1], 18);
SwapBytes(ppswCL2[0], 18);
SwapBytes(ppswCL2[1], 18);
first = 0;
}
/* count transmission errors within the SID codeword */
/* count number of bits equal '0' within the SID codeword */
/* ------------------------------------------------------ */
if (pswParameters[5] == 0)
swMode = 0;
else
swMode = 1;
swSidN1pN2 = 0; /* N1 + N2 */
swSidN2 = 0;
swSidN1 = 0;
for (siI = 0; siI < 18; siI++) {
swBitMask = 0x0001;
SwapBytes(&swBitMask, 1); /* force swBitMask to PC byte order */
for (siII = 0; siII < ppswIBit[swMode][siI]; siII++) {
if ( (pswParameters[siI] & swBitMask) == 0 ) {
if ( (ppswCL1pCL2[swMode][siI] & swBitMask) != 0 ) swSidN1pN2++;
if ( (ppswCL2[swMode][siI] & swBitMask) != 0 ) swSidN2++;
}
SwapBytes(&swBitMask, 1); /* return swBitMask to native byte order */
swBitMask = swBitMask << 1;
SwapBytes(&swBitMask, 1); /* force swBitMask to PC byte order */
}
}
swSidN1 = swSidN1pN2 - swSidN2;
/* frame classification */
/* -------------------- */
if (pswErrorFlag[2]) {
if (swSidN1 < 3)
swSid = 2;
else if (swSidN1pN2 < 16)
swSid = 1;
else
swSid = 0;
if ( (swSidN1pN2 >= 16) && (swSidN1pN2 <= 25) ) {
pswErrorFlag[0] = 1;
}
}
else {
if (swSidN1 < 3)
swSid = 2;
else if (swSidN1pN2 < 11)
swSid = 1;
else
swSid = 0;
}
/* in case of a mode mismatch */
/*----------------------------*/
if ( (swSid == 2) && (swMode == 0) ) swSid = 1;
return(swSid);
}
/*___________________________________________________________________________
| |
| This subroutine sets the 18 speech parameters to random values |
| |
| Input: pswParameters[18] |
| input parameters of the speech decoder |
| |
|___________________________________________________________________________|
*/
static void RandomParameters(int16_t pswParameters[])
{
static int16_t ppswIBit[2][18] = {
5, 11,9,8, 1, 2, 7,7,5, 7,7,5, 7,7,5, 7,7,5, /* unvoiced */
5, 11,9,8, 1, 2, 8,9,5, 4,9,5, 4,9,5, 4,9,5}; /* voiced */
static int32_t L_PNSeed=(int32_t)0x1091988L;
int16_t i,ind;
/* Determine mode bit */
/* ------------------ */
pswParameters[5] = getPnBits(2, &L_PNSeed);
/* Switch bit allocation accordingly */
/* --------------------------------- */
ind = 0;
if (pswParameters[5] > 0) ind = 1;
for (i=0; i < 5; i++){
pswParameters[i] = getPnBits(ppswIBit[ind][i], &L_PNSeed);
}
for (i=6; i < 18; i++){
pswParameters[i] = getPnBits(ppswIBit[ind][i], &L_PNSeed);
}
/* force random parameters to PC byte order */
/* ---------------------------------------- */
SwapBytes(pswParameters, 18);
}
/*___________________________________________________________________________
| |
| Main - Program |
| |
|___________________________________________________________________________|
*/
int main( int argc, char *argv[] )
{
FILE *infile, *outfile;
int16_t errpat, i = 0;
if( argc < 4 || argc > 4 ) {
fprintf( stderr, "\tUsage: REID input output EPx \n" );
fprintf( stderr, "\tEPx: EP0\n" );
fprintf( stderr, "\t EP1 (not implemented)\n" );
fprintf( stderr, "\t EP2 (not implemented)\n" );
fprintf( stderr, "\t EP3 (not implemented)\n" );
return( 1 );
}
if( !Strincmp( argv[3], "ep", 2 ))
errpat = atoi( &argv[3][2] );
printf( " _____________________________________________\n" );
printf( " | |\n" );
printf( " | Residual Error Insertion Device |\n" );
printf( " | for |\n" );
printf( " | GSM Half-Rate Codec Simulation |\n" );
printf( " | |\n" );
printf( " |_____________________________________________|\n\n" );
printf( " Input File : %s\n", argv[1] );
printf( " Output File : %s\n", argv[2] );
if( errpat ){
printf( " Error Pattern : EP%d (not implemented)\n", errpat);
return (1);
}
else
printf( " Error Pattern : EP%d (error free)\n", errpat );
printf( "\n" );
infile = OpenBinfile( argv[1], "r" );
outfile = OpenBinfile( argv[2], "w" );
if (errpat == 0) {
for (i=0;i<6000;i++)
if( error_free( infile, outfile)) break;
}
/*else
for (i=0;i<6000;i++)
if( residual_error_pattern( infile, outfile)) break;
EP1-3 not implemented */
fclose( infile );
fclose( outfile );
printf( " %d Frame%s processed \n\n", i,( i != 1 ) ? "s" : "" );
return( 0 );
}