FreeCalypso > hg > gsmhr-codec-ref
comparison reid.c @ 5:59fc7fc126d0
mv utils.c reid.c
In the original GSM 06.06 code drop, reid.c resides in the "utilities"
collection (Dir_UTIL.zip), but there is also a copy of reid.c named
utils.c in the "C" collection (Dir_C.zip), even though it is never
compiled or linked as such.
When I originally created the present Hg repository, I did not intend
to include REID, only the main body of the codec - but I overlooked
that utils.c copy, so it got imported. In the present time, however,
it has become useful to have REID code in Hg for easier public study
and discussion - so let's have it under its proper name.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Mon, 22 Jul 2024 18:43:12 +0000 |
parents | utils.c@9008dbc8ca74 |
children |
comparison
equal
deleted
inserted
replaced
4:a2529fec5442 | 5:59fc7fc126d0 |
---|---|
1 /*___________________________________________________________________________ | |
2 | | | |
3 | | | |
4 | Residual Error Insertion Device | | |
5 | | | |
6 | | | |
7 | File : REID.C | | |
8 | | | |
9 | Date : February 03, 1995 | | |
10 | | | |
11 | Version: 4.1 | | |
12 | | | |
13 | | | |
14 | Description: | | |
15 | ------------ | | |
16 | This routine transforms the output file format of the GSM Half | | |
17 | Rate Encoder module consisting of: | | |
18 | * 18 speech parameters (see GSM TS 06.20) | | |
19 | * 1 speech flag SP (see GSM TS 06.41) | | |
20 | * 1 voice activity flag VAD (see GSM TS 06.42) | | |
21 | | | |
22 | to the input file format of the GSM Half Rate Decoder module | | |
23 | requiring: | | |
24 | * 18 speech parameters (see GSM TS 06.20) | | |
25 | * 1 channel condition flag BFI (see GSM TS 06.21, 05.05) | | |
26 | * 1 channel condition flag UFI (see GSM TS 06.21, 05.05) | | |
27 | * 1 SID flag (2 bits) (see GSM TS 06.41, 05.05) | | |
28 | * 1 time alignment flag TAF (see GSM TS 06.41) | | |
29 | | | |
30 | Between SID updates the speech parameters are replaced by random | | |
31 | values simulating an interrupted transmission on the air interface | | |
32 | | | |
33 | The actual implementation only supports error free transmission (EP0)| | |
34 | | | |
35 | The shell for the future use of error patterns (residual error | | |
36 | pattern insertion) is already included. If necessary, byte swapping | | |
37 | is performed on the input speech parameters so that they are always | | |
38 | represented internally in PC byte order (assuming that the byte | | |
39 | order of the input file is compatible with the machine on which the | | |
40 | program is run). However, byte swapping is not done on the flag | | |
41 | words (input: SP and VAD, output: BFI, UFI, SID, and TAF). Thus, | | |
42 | the residual error pattern insertion code may be written to handle | | |
43 | the speech parameter words on a byte basis, but the flag words must | | |
44 | always be handled on a word basis. | | |
45 |___________________________________________________________________________| | |
46 */ | |
47 /*___________________________________________________________________________ | |
48 | | | |
49 | Creation: 19.12.94 | | |
50 | | | |
51 | Changes: | | |
52 | 22.12.94: Removal of BCI flag, instead: determination of SID flag | | |
53 | 12.01.95: SID update period = 12 (instead of 24) | | |
54 | 13.01.95: When in CNI mode, the parameters between SID updates are | | |
55 | random values. This simulates the interrupted transmission| | |
56 | 03.02.95: Longword main( Longword...) replaced by int main(int ...),| | |
57 | initial value of swTAFCnt set to 1 | | |
58 |___________________________________________________________________________| | |
59 */ | |
60 | |
61 /*___________________________________________________________________________ | |
62 | | | |
63 | Include-Files | | |
64 |___________________________________________________________________________| | |
65 */ | |
66 #include <stdlib.h> | |
67 #include <stdio.h> | |
68 #include <string.h> | |
69 #include <ctype.h> | |
70 | |
71 #ifdef VAX | |
72 # define OPEN_WI "wb","mrs=512","rfm=fix","ctx=stm" | |
73 # define OPEN_RI "rb","mrs=512","rfm=fix","ctx=stm" | |
74 # define OPEN_WB "wb","mrs=512","rfm=fix","ctx=stm" | |
75 # define OPEN_RB "rb","mrs=2","rfm=fix","ctx=stm" | |
76 # define OPEN_WT "w","mrs=256","rat=cr","rfm=var" | |
77 # define OPEN_RT "r","mrs=256","rat=cr","rfm=var" | |
78 #else | |
79 # define OPEN_WB "wb" | |
80 # define OPEN_RB "rb" | |
81 # define OPEN_WI "wb" | |
82 # define OPEN_RI "rb" | |
83 # define OPEN_WT "wt" | |
84 # define OPEN_RT "rt" | |
85 #endif | |
86 | |
87 #define LW_SIGN (long)0x80000000 /* sign bit */ | |
88 #define LW_MIN (long)0x80000000 | |
89 #define LW_MAX (long)0x7fffffff | |
90 #define SW_MIN (short)0x8000 /* smallest Ram */ | |
91 #define SW_MAX (short)0x7fff /* largest Ram */ | |
92 | |
93 typedef char Byte; | |
94 typedef long int Longword; /* 32 bit "accumulator" (L_*) */ | |
95 typedef short int Shortword; /* 16 bit "register" (sw*) */ | |
96 | |
97 /*___________________________________________________________________________ | |
98 | | | |
99 | local Functions | | |
100 |___________________________________________________________________________| | |
101 */ | |
102 static Longword error_free( FILE *infile, FILE *outfile); | |
103 static void SwapBytes( Shortword buffer[], Longword len ); | |
104 static Longword ByteOrder( void ); | |
105 static size_t ReadInputFile( Shortword buffer[], FILE *fp ); | |
106 static size_t WriteOutputFile( Shortword buffer[], FILE *fp ); | |
107 static Longword EncoderInterface( FILE *infile, Shortword swInPara[] ); | |
108 static Shortword swSidDetection(Shortword pswParameters[], | |
109 Shortword pswErrorFlag[]); | |
110 static void RandomParameters(Shortword pswParameters[]); | |
111 static Shortword getPnBits(Shortword iBits, Longword *pL_PNSeed); | |
112 FILE *OpenBinfile( char *name, char *mode ); | |
113 Longword Strincmp( const char *s, const char *t, size_t max ); | |
114 Longword Stricmp( const char *s, const char *t ); | |
115 | |
116 Longword L_shr(Longword L_var1, Shortword var2); /* 2 ops */ | |
117 Longword L_shl(Longword L_var1, Shortword var2); /* 2 ops */ | |
118 Shortword shr(Shortword var1, Shortword var2); /* 1 ops */ | |
119 Shortword shl(Shortword var1, Shortword var2); /* 1 ops */ | |
120 | |
121 /*___________________________________________________________________________ | |
122 | | | |
123 | Subroutines | | |
124 |___________________________________________________________________________| | |
125 */ | |
126 static Longword error_free( FILE *infile, FILE *outfile) | |
127 { | |
128 | |
129 #define SPEECH 1 | |
130 #define CNIFIRSTSID 2 | |
131 #define CNICONT 3 | |
132 #define VALIDSID 11 | |
133 #define GOODSPEECH 33 | |
134 | |
135 static Shortword swDecoMode = {SPEECH}; | |
136 static Shortword swTAFCnt = {1}; | |
137 Shortword swInPara[20], i, swFrameType; | |
138 Shortword swOutPara[22],pswErrorFlag[3]; | |
139 | |
140 if( EncoderInterface( infile, swInPara )) return( 1 ); | |
141 | |
142 /* Copy input parameters to output parameters (error free transmission) */ | |
143 /* -------------------------------------------------------------------- */ | |
144 for (i=0;i<18;i++) | |
145 swOutPara[i] = swInPara[i]; | |
146 | |
147 /* Set channel status flags (error free transmission) */ | |
148 /* -------------------------------------------------- */ | |
149 swOutPara[18] = 0; /* BFI flag */ | |
150 swOutPara[19] = 0; /* UFI flag */ | |
151 | |
152 /* Evaluate SID flag */ | |
153 /* ----------------- */ | |
154 pswErrorFlag[0] = 0; /* BFI flag */ | |
155 pswErrorFlag[1] = 0; /* UFI flag */ | |
156 pswErrorFlag[2] = 0; /* BCI flag */ | |
157 swOutPara[20] = swSidDetection(swOutPara, pswErrorFlag); | |
158 | |
159 | |
160 /* Evaluate TAF flag */ | |
161 /* ----------------- */ | |
162 if (swTAFCnt == 0) swOutPara[21] = 1; | |
163 else swOutPara[21] = 0; | |
164 swTAFCnt = (swTAFCnt + 1) % 12; | |
165 | |
166 | |
167 /* Frame classification: */ | |
168 /* Since the transmission is error free, the received frames are either */ | |
169 /* valid speech or valid SID frames */ | |
170 /* -------------------------------------------------------------------- */ | |
171 if ( swOutPara[20] == 2) swFrameType = VALIDSID; | |
172 else if ( swOutPara[20] == 0) swFrameType = GOODSPEECH; | |
173 else { | |
174 printf( "Error in SID detection\n" ); | |
175 return( 1 ); | |
176 } | |
177 | |
178 /* Update of decoder state */ | |
179 /* ----------------------- */ | |
180 if (swDecoMode == SPEECH) { | |
181 if (swFrameType == VALIDSID) swDecoMode = CNIFIRSTSID; | |
182 else if (swFrameType == GOODSPEECH) swDecoMode = SPEECH; | |
183 } | |
184 else { /* comfort noise insertion mode */ | |
185 if (swFrameType == VALIDSID) swDecoMode = CNICONT; | |
186 else if (swFrameType == GOODSPEECH) swDecoMode = SPEECH; | |
187 } | |
188 | |
189 | |
190 /* Replace parameters by random data if in CNICONT-mode and TAF=0 */ | |
191 /* -------------------------------------------------------------- */ | |
192 if ((swDecoMode == CNICONT) && (swOutPara[21] == 0)){ | |
193 RandomParameters(swOutPara); | |
194 /* Set flags such, that an "unusable frame" is produced */ | |
195 swOutPara[18] = 1; /* BFI flag */ | |
196 swOutPara[19] = 1; /* UFI flag */ | |
197 swOutPara[20] = 0; /* SID flag */ | |
198 } | |
199 | |
200 | |
201 | |
202 if( outfile ) { | |
203 if( WriteOutputFile( swOutPara, outfile )) { | |
204 printf( "Error writing File\n" ); | |
205 return( 1 ); | |
206 } | |
207 } | |
208 return( 0 ); | |
209 } | |
210 | |
211 static Longword EncoderInterface( FILE *infile, Shortword swInPara[] ) | |
212 { | |
213 size_t i = 0; | |
214 | |
215 i = ReadInputFile( swInPara, infile ); | |
216 | |
217 return(( i == 0 ) ? 1 : 0 ); | |
218 } | |
219 | |
220 static size_t ReadInputFile( Shortword buffer[], FILE *fp ) | |
221 { | |
222 size_t i; | |
223 | |
224 i = fread( buffer, sizeof( Shortword ), 20, fp ); | |
225 SwapBytes( buffer, 18 ); | |
226 return( i ); | |
227 } | |
228 | |
229 static size_t WriteOutputFile( Shortword buffer[], FILE *fp ) | |
230 { | |
231 size_t i; | |
232 | |
233 SwapBytes( buffer, 18 ); | |
234 i = fwrite( buffer, sizeof( Shortword ), 22, fp ); | |
235 return( ( i == 22 ) ? 0 : 1 ); | |
236 } | |
237 | |
238 | |
239 static void SwapBytes( Shortword buffer[], Longword len ) | |
240 { | |
241 Byte *pc, tmp; | |
242 Longword i; | |
243 | |
244 if( !ByteOrder()) | |
245 return; | |
246 pc = (Byte *)buffer; | |
247 for( i = 0; i < len; i++ ) { | |
248 tmp = pc[0]; | |
249 pc[0] = pc[1]; | |
250 pc[1] = tmp; | |
251 pc += 2; | |
252 } | |
253 } | |
254 | |
255 static Longword ByteOrder( void ) | |
256 { | |
257 Shortword si; | |
258 Byte *pc; | |
259 | |
260 si = 0x1234; | |
261 pc = (Byte *)&si; | |
262 if (pc[1] == 0x12 && pc[0] == 0x34 ) | |
263 return( 0 ); | |
264 if (pc[0] == 0x12 && pc[1] == 0x34 ) | |
265 return( 1 ); | |
266 printf( "Error in ByteOrder: %X, %X\n", (int)pc[0], (int)pc[1] ); | |
267 exit( 1 ); | |
268 return( 2 ); | |
269 } | |
270 | |
271 FILE *OpenBinfile( char *name, char *mode ) | |
272 { | |
273 FILE *fp; | |
274 | |
275 if( toupper( *mode ) == 'W' ) { /* Write access */ | |
276 if(( fp = fopen( name, OPEN_WB )) == NULL ) { | |
277 printf( "Can't open output file '%s'\n", name ); | |
278 exit( 1 ); | |
279 } | |
280 } else { /* Read access */ | |
281 if(( fp = fopen( name, OPEN_RB )) == NULL ) { | |
282 printf( "Can't open file '%s'\n", name ); | |
283 exit( 1 ); | |
284 } | |
285 } | |
286 return( fp ); | |
287 } | |
288 | |
289 Longword Strincmp( const char *s, const char *t, size_t max ) | |
290 { | |
291 for( ; max > 1; ++s, ++t, --max ) { | |
292 if( toupper( *s ) != toupper( *t )) | |
293 break; | |
294 if( *s == '\0' ) | |
295 return( 0 ); | |
296 } | |
297 return( toupper( *s ) - toupper( *t )); | |
298 } | |
299 | |
300 Longword Stricmp( const char *s, const char *t ) | |
301 { | |
302 for(; toupper( *s ) == toupper( *t ); ++s, ++t ) { | |
303 if( *s == '\0' ) | |
304 return( 0 ); | |
305 } | |
306 return( toupper( *s ) - toupper( *t )); | |
307 } | |
308 | |
309 /************************************************************************* | |
310 * | |
311 * FUNCTION NAME: getPnBits | |
312 * | |
313 * PURPOSE: | |
314 * | |
315 * Generate iBits pseudo-random bits using *pL_PNSeed as the | |
316 * pn-generators seed. | |
317 * | |
318 * INPUTS: | |
319 * | |
320 * iBits - integer indicating how many random bits to return. | |
321 * range [0,15], 0 yields 1 bit output | |
322 * | |
323 * *pL_PNSeed - 32 bit seed (changed by function) | |
324 * | |
325 * OUTPUTS: | |
326 * | |
327 * *pL_PNSeed - 32 bit seed, modified. | |
328 * | |
329 * RETURN VALUE: | |
330 * | |
331 * random bits in iBits LSB's. | |
332 * | |
333 * | |
334 * IMPLEMENTATION: | |
335 * | |
336 * implementation of x**31 + x**3 + 1 == PN_XOR_REG | PN_XOR_ADD a | |
337 * PN sequence generator using Longwords generating a 2**31 -1 | |
338 * length pn-sequence. | |
339 * | |
340 *************************************************************************/ | |
341 | |
342 static Shortword getPnBits(Shortword iBits, Longword *pL_PNSeed){ | |
343 | |
344 #define PN_XOR_REG (Longword)0x00000005L | |
345 #define PN_XOR_ADD (Longword)0x40000000L | |
346 | |
347 Shortword swPnBits=0; | |
348 Longword L_Taps,L_FeedBack; | |
349 Shortword i; | |
350 | |
351 for (i=0; i < iBits; i++){ | |
352 | |
353 /* update the state */ | |
354 /********************/ | |
355 | |
356 L_Taps = *pL_PNSeed & PN_XOR_REG; | |
357 L_FeedBack = L_Taps; /* Xor tap bits to yield feedback bit */ | |
358 L_Taps = L_shr(L_Taps,1); | |
359 | |
360 while(L_Taps){ | |
361 L_FeedBack = L_FeedBack ^ L_Taps; | |
362 L_Taps = L_shr(L_Taps,1); | |
363 } | |
364 | |
365 /* LSB of L_FeedBack is next MSB of PN register */ | |
366 | |
367 *pL_PNSeed = L_shr(*pL_PNSeed,1); | |
368 if (L_FeedBack & 1) | |
369 *pL_PNSeed = *pL_PNSeed | PN_XOR_ADD; | |
370 | |
371 /* State update complete. | |
372 Get the output bit from the state, add/or it into output */ | |
373 | |
374 swPnBits = shl(swPnBits,1); | |
375 swPnBits = swPnBits | (*pL_PNSeed & 1); | |
376 | |
377 } | |
378 return(swPnBits); | |
379 } | |
380 | |
381 | |
382 /*************************************************************************** | |
383 * | |
384 * FUNCTION NAME: L_shl | |
385 * | |
386 * PURPOSE: | |
387 * | |
388 * Arithmetic shift left (or right). | |
389 * Arithmetically shift the input left by var2. If var2 is | |
390 * negative then an arithmetic shift right (L_shr) of L_var1 by | |
391 * -var2 is performed. | |
392 * | |
393 * INPUTS: | |
394 * | |
395 * var2 | |
396 * 16 bit short signed integer (Shortword) whose value | |
397 * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. | |
398 * L_var1 | |
399 * 32 bit long signed integer (Longword) whose value | |
400 * falls in the range | |
401 * 0x8000 0000 <= L_var1 <= 0x7fff ffff. | |
402 * OUTPUTS: | |
403 * | |
404 * none | |
405 * | |
406 * RETURN VALUE: | |
407 * | |
408 * L_Out | |
409 * 32 bit long signed integer (Longword) whose value | |
410 * falls in the range | |
411 * 0x8000 0000 <= L_var1 <= 0x7fff ffff. | |
412 * | |
413 * | |
414 * IMPLEMENTATION: | |
415 * | |
416 * Arithmetically shift the 32 bit input left by var2. This | |
417 * operation maintains the sign of the input number. If var2 is | |
418 * negative then an arithmetic shift right (L_shr) of L_var1 by | |
419 * -var2 is performed. See description of L_shr for details. | |
420 * | |
421 * Equivalent to the Full-Rate GSM ">> n" operation. Note that | |
422 * ANSI-C does not guarantee operation of the C ">>" or "<<" | |
423 * operator for negative numbers. | |
424 * | |
425 * KEYWORDS: shift, arithmetic shift left, | |
426 * | |
427 *************************************************************************/ | |
428 | |
429 Longword L_shl(Longword L_var1, Shortword var2) | |
430 { | |
431 | |
432 Longword L_Mask, | |
433 L_Out; | |
434 int i, | |
435 iOverflow = 0; | |
436 | |
437 if (var2 == 0 || L_var1 == 0) | |
438 { | |
439 L_Out = L_var1; | |
440 } | |
441 else if (var2 < 0) | |
442 { | |
443 if (var2 <= -31) | |
444 { | |
445 if (L_var1 > 0) | |
446 L_Out = 0; | |
447 else | |
448 L_Out = 0xffffffffL; | |
449 } | |
450 else | |
451 L_Out = L_shr(L_var1, -var2); | |
452 } | |
453 else | |
454 { | |
455 | |
456 if (var2 >= 31) | |
457 iOverflow = 1; | |
458 | |
459 else | |
460 { | |
461 | |
462 if (L_var1 < 0) | |
463 L_Mask = LW_SIGN; /* sign bit mask */ | |
464 else | |
465 L_Mask = 0x0; | |
466 L_Out = L_var1; | |
467 for (i = 0; i < var2 && !iOverflow; i++) | |
468 { | |
469 /* check the sign bit */ | |
470 L_Out = (L_Out & 0x7fffffffL) << 1; | |
471 if ((L_Mask ^ L_Out) & LW_SIGN) | |
472 iOverflow = 1; | |
473 } | |
474 } | |
475 | |
476 if (iOverflow) | |
477 { | |
478 /* saturate */ | |
479 if (L_var1 > 0) | |
480 L_Out = LW_MAX; | |
481 else | |
482 L_Out = LW_MIN; | |
483 } | |
484 } | |
485 | |
486 return (L_Out); | |
487 } | |
488 | |
489 /*************************************************************************** | |
490 * | |
491 * FUNCTION NAME: L_shr | |
492 * | |
493 * PURPOSE: | |
494 * | |
495 * Arithmetic shift right (or left). | |
496 * Arithmetically shift the input right by var2. If var2 is | |
497 * negative then an arithmetic shift left (shl) of var1 by | |
498 * -var2 is performed. | |
499 * | |
500 * INPUTS: | |
501 * | |
502 * var2 | |
503 * 16 bit short signed integer (Shortword) whose value | |
504 * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. | |
505 * L_var1 | |
506 * 32 bit long signed integer (Longword) whose value | |
507 * falls in the range | |
508 * 0x8000 0000 <= L_var1 <= 0x7fff ffff. | |
509 * OUTPUTS: | |
510 * | |
511 * none | |
512 * | |
513 * RETURN VALUE: | |
514 * | |
515 * L_Out | |
516 * 32 bit long signed integer (Longword) whose value | |
517 * falls in the range | |
518 * 0x8000 0000 <= L_var1 <= 0x7fff ffff. | |
519 * | |
520 * | |
521 * IMPLEMENTATION: | |
522 * | |
523 * Arithmetically shift the input right by var2. This | |
524 * operation maintains the sign of the input number. If var2 is | |
525 * negative then an arithmetic shift left (shl) of L_var1 by | |
526 * -var2 is performed. See description of L_shl for details. | |
527 * | |
528 * The input is a 32 bit number, as is the output. | |
529 * | |
530 * Equivalent to the Full-Rate GSM ">> n" operation. Note that | |
531 * ANSI-C does not guarantee operation of the C ">>" or "<<" | |
532 * operator for negative numbers. | |
533 * | |
534 * KEYWORDS: shift, arithmetic shift right, | |
535 * | |
536 *************************************************************************/ | |
537 | |
538 Longword L_shr(Longword L_var1, Shortword var2) | |
539 { | |
540 | |
541 Longword L_Mask, | |
542 L_Out; | |
543 | |
544 if (var2 == 0 || L_var1 == 0) | |
545 { | |
546 L_Out = L_var1; | |
547 } | |
548 else if (var2 < 0) | |
549 { | |
550 /* perform a left shift */ | |
551 /*----------------------*/ | |
552 if (var2 <= -31) | |
553 { | |
554 /* saturate */ | |
555 if (L_var1 > 0) | |
556 L_Out = LW_MAX; | |
557 else | |
558 L_Out = LW_MIN; | |
559 } | |
560 else | |
561 L_Out = L_shl(L_var1, -var2); | |
562 } | |
563 else | |
564 { | |
565 | |
566 if (var2 >= 31) | |
567 { | |
568 if (L_var1 > 0) | |
569 L_Out = 0; | |
570 else | |
571 L_Out = 0xffffffffL; | |
572 } | |
573 else | |
574 { | |
575 L_Mask = 0; | |
576 | |
577 if (L_var1 < 0) | |
578 { | |
579 L_Mask = ~L_Mask << (32 - var2); | |
580 } | |
581 | |
582 L_var1 >>= var2; | |
583 L_Out = L_Mask | L_var1; | |
584 } | |
585 } | |
586 return (L_Out); | |
587 } | |
588 | |
589 | |
590 /*************************************************************************** | |
591 * | |
592 * FUNCTION NAME: shl | |
593 * | |
594 * PURPOSE: | |
595 * | |
596 * Arithmetically shift the input left by var2. | |
597 * | |
598 * | |
599 * INPUTS: | |
600 * | |
601 * var1 | |
602 * 16 bit short signed integer (Shortword) whose value | |
603 * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. | |
604 * var2 | |
605 * 16 bit short signed integer (Shortword) whose value | |
606 * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. | |
607 * | |
608 * OUTPUTS: | |
609 * | |
610 * none | |
611 * | |
612 * RETURN VALUE: | |
613 * | |
614 * swOut | |
615 * 16 bit short signed integer (Shortword) whose value | |
616 * falls in the range | |
617 * 0xffff 8000 <= swOut <= 0x0000 7fff. | |
618 * | |
619 * IMPLEMENTATION: | |
620 * | |
621 * If Arithmetically shift the input left by var2. If var2 is | |
622 * negative then an arithmetic shift right (shr) of var1 by | |
623 * -var2 is performed. See description of shr for details. | |
624 * When an arithmetic shift left is performed the var2 LS bits | |
625 * are zero filled. | |
626 * | |
627 * The only exception is if the left shift causes an overflow | |
628 * or underflow. In this case the LS bits are not modified. | |
629 * The number returned is 0x8000 in the case of an underflow or | |
630 * 0x7fff in the case of an overflow. | |
631 * | |
632 * The shl is equivalent to the Full-Rate GSM "<< n" operation. | |
633 * Note that ANSI-C does not guarantee operation of the C ">>" | |
634 * or "<<" operator for negative numbers - it is not specified | |
635 * whether this shift is an arithmetic or logical shift. | |
636 * | |
637 * KEYWORDS: asl, arithmetic shift left, shift | |
638 * | |
639 *************************************************************************/ | |
640 | |
641 Shortword shl(Shortword var1, Shortword var2) | |
642 { | |
643 Shortword swOut; | |
644 Longword L_Out; | |
645 | |
646 if (var2 == 0 || var1 == 0) | |
647 { | |
648 swOut = var1; | |
649 } | |
650 else if (var2 < 0) | |
651 { | |
652 | |
653 /* perform a right shift */ | |
654 /*-----------------------*/ | |
655 | |
656 if (var2 <= -15) | |
657 { | |
658 if (var1 < 0) | |
659 swOut = (Shortword) 0xffff; | |
660 else | |
661 swOut = 0x0; | |
662 } | |
663 else | |
664 swOut = shr(var1, -var2); | |
665 | |
666 } | |
667 else | |
668 { | |
669 /* var2 > 0 */ | |
670 if (var2 >= 15) | |
671 { | |
672 /* saturate */ | |
673 if (var1 > 0) | |
674 swOut = SW_MAX; | |
675 else | |
676 swOut = SW_MIN; | |
677 } | |
678 else | |
679 { | |
680 | |
681 L_Out = (Longword) var1 *(1 << var2); | |
682 | |
683 swOut = (Shortword) L_Out; /* copy low portion to swOut, | |
684 * overflow could have hpnd */ | |
685 if (swOut != L_Out) | |
686 { | |
687 /* overflow */ | |
688 if (var1 > 0) | |
689 swOut = SW_MAX; /* saturate */ | |
690 else | |
691 swOut = SW_MIN; /* saturate */ | |
692 } | |
693 } | |
694 } | |
695 return (swOut); | |
696 } | |
697 | |
698 /*************************************************************************** | |
699 * | |
700 * FUNCTION NAME: shr | |
701 * | |
702 * PURPOSE: | |
703 * | |
704 * Arithmetic shift right (or left). | |
705 * Arithmetically shift the input right by var2. If var2 is | |
706 * negative then an arithmetic shift left (shl) of var1 by | |
707 * -var2 is performed. | |
708 * | |
709 * INPUTS: | |
710 * | |
711 * var1 | |
712 * 16 bit short signed integer (Shortword) whose value | |
713 * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. | |
714 * var2 | |
715 * 16 bit short signed integer (Shortword) whose value | |
716 * falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff. | |
717 * | |
718 * OUTPUTS: | |
719 * | |
720 * none | |
721 * | |
722 * RETURN VALUE: | |
723 * | |
724 * swOut | |
725 * 16 bit short signed integer (Shortword) whose value | |
726 * falls in the range | |
727 * 0xffff 8000 <= swOut <= 0x0000 7fff. | |
728 * | |
729 * IMPLEMENTATION: | |
730 * | |
731 * Arithmetically shift the input right by var2. This | |
732 * operation maintains the sign of the input number. If var2 is | |
733 * negative then an arithmetic shift left (shl) of var1 by | |
734 * -var2 is performed. See description of shl for details. | |
735 * | |
736 * Equivalent to the Full-Rate GSM ">> n" operation. Note that | |
737 * ANSI-C does not guarantee operation of the C ">>" or "<<" | |
738 * operator for negative numbers. | |
739 * | |
740 * KEYWORDS: shift, arithmetic shift right, | |
741 * | |
742 *************************************************************************/ | |
743 | |
744 Shortword shr(Shortword var1, Shortword var2) | |
745 { | |
746 | |
747 Shortword swMask, | |
748 swOut; | |
749 | |
750 if (var2 == 0 || var1 == 0) | |
751 swOut = var1; | |
752 | |
753 else if (var2 < 0) | |
754 { | |
755 /* perform an arithmetic left shift */ | |
756 /*----------------------------------*/ | |
757 if (var2 <= -15) | |
758 { | |
759 /* saturate */ | |
760 if (var1 > 0) | |
761 swOut = SW_MAX; | |
762 else | |
763 swOut = SW_MIN; | |
764 } | |
765 else | |
766 swOut = shl(var1, -var2); | |
767 } | |
768 | |
769 else | |
770 { | |
771 | |
772 /* positive shift count */ | |
773 /*----------------------*/ | |
774 | |
775 if (var2 >= 15) | |
776 { | |
777 if (var1 < 0) | |
778 swOut = (Shortword) 0xffff; | |
779 else | |
780 swOut = 0x0; | |
781 } | |
782 else | |
783 { | |
784 /* take care of sign extension */ | |
785 /*-----------------------------*/ | |
786 | |
787 swMask = 0; | |
788 if (var1 < 0) | |
789 { | |
790 swMask = ~swMask << (16 - var2); | |
791 } | |
792 | |
793 var1 >>= var2; | |
794 swOut = swMask | var1; | |
795 | |
796 } | |
797 } | |
798 return (swOut); | |
799 } | |
800 | |
801 /*___________________________________________________________________________ | |
802 | | | |
803 | This subroutine calculates the 'SID flag' | | |
804 | | | |
805 | Input: pswParameters[18] | | |
806 | input parameters of the speech decoder | | |
807 | | | |
808 | pswErrorFlag[3] | | |
809 | error flags, generated by channel decoder | | |
810 | | | |
811 | Return Value: | | |
812 | 0: speech frame detected | | |
813 | 1: most likely SID frame received | | |
814 | 2: SID frame detected | | |
815 | | | |
816 |___________________________________________________________________________| | |
817 | | | |
818 | History: | | |
819 | | | |
820 | 12-Oct-1994: Bug removed: error corrected in case of a mode (unvoiced/| | |
821 | voiced) mismatch, if a SID frame was received as an | | |
822 | unvoiced frame | | |
823 |___________________________________________________________________________| | |
824 */ | |
825 | |
826 static Shortword swSidDetection(Shortword pswParameters[], | |
827 Shortword pswErrorFlag[]) | |
828 { | |
829 static Shortword ppswIBit[2][18] = { | |
830 5, 11,9,8, 1, 2, 7,7,5, 7,7,5, 7,7,5, 7,7,5, /* unvoiced */ | |
831 5, 11,9,8, 1, 2, 8,9,5, 4,9,5, 4,9,5, 4,9,5}; /* voiced */ | |
832 | |
833 static Shortword ppswCL1pCL2[2][18] = { | |
834 0x0001, /* R0 */ /* unvoiced */ | |
835 0x00ef, /* LPC1 */ | |
836 0x003e, /* LPC2 */ | |
837 0x007f, /* LPC3 */ | |
838 0x0001, /* INT LPC */ | |
839 0x0003, /* Mode */ | |
840 0x001f, /* Code1_1 */ | |
841 0x0072, /* Code2_1 */ | |
842 0x0012, /* GSP0_1 */ | |
843 0x003f, /* Code1_2 */ | |
844 0x007f, /* Code2_2 */ | |
845 0x0008, /* GSP0_2 */ | |
846 0x007f, /* Code1_3 */ | |
847 0x007f, /* Code2_3 */ | |
848 0x0008, /* GSP0_3 */ | |
849 0x007f, /* Code1_4 */ | |
850 0x007f, /* Code2_4 */ | |
851 0x000c, /* GSP0_4 */ | |
852 | |
853 0x0000, /* R0 */ /* voiced */ | |
854 0x0000, /* LPC1 */ | |
855 0x0000, /* LPC2 */ | |
856 0x0000, /* LPC3 */ | |
857 0x0001, /* INT LPC */ | |
858 0x0003, /* Mode */ | |
859 0x00ff, /* Lag_1 */ | |
860 0x01ff, /* Code_1 */ | |
861 0x001f, /* GSP0_1 */ | |
862 0x000f, /* Lag_2 */ | |
863 0x01ff, /* Code_2 */ | |
864 0x001f, /* GSP0_2 */ | |
865 0x000f, /* Lag_3 */ | |
866 0x01ff, /* Code_3 */ | |
867 0x001f, /* GSP0_3 */ | |
868 0x000f, /* Lag_4 */ | |
869 0x01ff, /* Code_4 */ | |
870 0x001f}; /* GSP0_4 */ | |
871 | |
872 static Shortword ppswCL2[2][18] = { | |
873 0x0000, /* R0 */ /* unvoiced */ | |
874 0x0000, /* LPC1 */ | |
875 0x0000, /* LPC2 */ | |
876 0x0000, /* LPC3 */ | |
877 0x0000, /* INT LPC */ | |
878 0x0000, /* Mode */ | |
879 0x0000, /* Code1_1 */ | |
880 0x0000, /* Code2_1 */ | |
881 0x0000, /* GSP0_1 */ | |
882 0x0000, /* Code1_2 */ | |
883 0x0000, /* Code2_2 */ | |
884 0x0000, /* GSP0_2 */ | |
885 0x0000, /* Code1_3 */ | |
886 0x0007, /* Code2_3 */ /* 3 bits */ | |
887 0x0000, /* GSP0_3 */ | |
888 0x007f, /* Code1_4 */ /* 7 bits */ | |
889 0x007f, /* Code2_4 */ /* 7 bits */ | |
890 0x0000, /* GSP0_4 */ | |
891 | |
892 0x0000, /* R0 */ /* voiced */ | |
893 0x0000, /* LPC1 */ | |
894 0x0000, /* LPC2 */ | |
895 0x0000, /* LPC3 */ | |
896 0x0000, /* INT LPC */ | |
897 0x0000, /* Mode */ | |
898 0x0000, /* Lag_1 */ | |
899 0x0000, /* Code_1 */ | |
900 0x0000, /* GSP0_1 */ | |
901 0x0000, /* Lag_2 */ | |
902 0x0000, /* Code_2 */ | |
903 0x0000, /* GSP0_2 */ | |
904 0x0000, /* Lag_3 */ | |
905 0x00ff, /* Code_3 */ /* 8 bits */ | |
906 0x0000, /* GSP0_3 */ | |
907 0x0000, /* Lag_4 */ | |
908 0x01ff, /* Code_4 */ /* 9 bits */ | |
909 0x0000}; /* GSP0_4 */ | |
910 | |
911 static int first = 1; | |
912 | |
913 Shortword swMode, swBitMask; | |
914 Shortword swSidN1, swSidN2, swSidN1pN2; | |
915 Shortword swSid ; | |
916 | |
917 short siI, siII; | |
918 | |
919 | |
920 if (first) | |
921 { | |
922 /* Force Sid codewords to be represented */ | |
923 /* internally in PC byte order */ | |
924 /* ------------------------------------- */ | |
925 | |
926 SwapBytes(ppswCL1pCL2[0], 18); | |
927 SwapBytes(ppswCL1pCL2[1], 18); | |
928 SwapBytes(ppswCL2[0], 18); | |
929 SwapBytes(ppswCL2[1], 18); | |
930 | |
931 first = 0; | |
932 } | |
933 | |
934 | |
935 /* count transmission errors within the SID codeword */ | |
936 /* count number of bits equal '0' within the SID codeword */ | |
937 /* ------------------------------------------------------ */ | |
938 | |
939 if (pswParameters[5] == 0) | |
940 swMode = 0; | |
941 else | |
942 swMode = 1; | |
943 | |
944 | |
945 swSidN1pN2 = 0; /* N1 + N2 */ | |
946 swSidN2 = 0; | |
947 swSidN1 = 0; | |
948 | |
949 for (siI = 0; siI < 18; siI++) { | |
950 swBitMask = 0x0001; | |
951 SwapBytes(&swBitMask, 1); /* force swBitMask to PC byte order */ | |
952 for (siII = 0; siII < ppswIBit[swMode][siI]; siII++) { | |
953 if ( (pswParameters[siI] & swBitMask) == 0 ) { | |
954 if ( (ppswCL1pCL2[swMode][siI] & swBitMask) != 0 ) swSidN1pN2++; | |
955 if ( (ppswCL2[swMode][siI] & swBitMask) != 0 ) swSidN2++; | |
956 } | |
957 SwapBytes(&swBitMask, 1); /* return swBitMask to native byte order */ | |
958 swBitMask = swBitMask << 1; | |
959 SwapBytes(&swBitMask, 1); /* force swBitMask to PC byte order */ | |
960 } | |
961 } | |
962 | |
963 swSidN1 = swSidN1pN2 - swSidN2; | |
964 | |
965 | |
966 /* frame classification */ | |
967 /* -------------------- */ | |
968 | |
969 if (pswErrorFlag[2]) { | |
970 | |
971 if (swSidN1 < 3) | |
972 swSid = 2; | |
973 else if (swSidN1pN2 < 16) | |
974 swSid = 1; | |
975 else | |
976 swSid = 0; | |
977 | |
978 if ( (swSidN1pN2 >= 16) && (swSidN1pN2 <= 25) ) { | |
979 pswErrorFlag[0] = 1; | |
980 } | |
981 | |
982 } | |
983 else { | |
984 | |
985 if (swSidN1 < 3) | |
986 swSid = 2; | |
987 else if (swSidN1pN2 < 11) | |
988 swSid = 1; | |
989 else | |
990 swSid = 0; | |
991 | |
992 } | |
993 | |
994 | |
995 /* in case of a mode mismatch */ | |
996 /*----------------------------*/ | |
997 | |
998 if ( (swSid == 2) && (swMode == 0) ) swSid = 1; | |
999 | |
1000 return(swSid); | |
1001 | |
1002 } | |
1003 | |
1004 | |
1005 /*___________________________________________________________________________ | |
1006 | | | |
1007 | This subroutine sets the 18 speech parameters to random values | | |
1008 | | | |
1009 | Input: pswParameters[18] | | |
1010 | input parameters of the speech decoder | | |
1011 | | | |
1012 |___________________________________________________________________________| | |
1013 */ | |
1014 | |
1015 static void RandomParameters(Shortword pswParameters[]) | |
1016 { | |
1017 static Shortword ppswIBit[2][18] = { | |
1018 5, 11,9,8, 1, 2, 7,7,5, 7,7,5, 7,7,5, 7,7,5, /* unvoiced */ | |
1019 5, 11,9,8, 1, 2, 8,9,5, 4,9,5, 4,9,5, 4,9,5}; /* voiced */ | |
1020 | |
1021 static Longword L_PNSeed=(Longword)0x1091988L; | |
1022 Shortword i,ind; | |
1023 | |
1024 /* Determine mode bit */ | |
1025 /* ------------------ */ | |
1026 pswParameters[5] = getPnBits(2, &L_PNSeed); | |
1027 | |
1028 /* Switch bit allocation accordingly */ | |
1029 /* --------------------------------- */ | |
1030 ind = 0; | |
1031 if (pswParameters[5] > 0) ind = 1; | |
1032 | |
1033 for (i=0; i < 5; i++){ | |
1034 pswParameters[i] = getPnBits(ppswIBit[ind][i], &L_PNSeed); | |
1035 } | |
1036 for (i=6; i < 18; i++){ | |
1037 pswParameters[i] = getPnBits(ppswIBit[ind][i], &L_PNSeed); | |
1038 } | |
1039 | |
1040 /* force random parameters to PC byte order */ | |
1041 /* ---------------------------------------- */ | |
1042 | |
1043 SwapBytes(pswParameters, 18); | |
1044 } | |
1045 | |
1046 /*___________________________________________________________________________ | |
1047 | | | |
1048 | Main - Program | | |
1049 | | | |
1050 |___________________________________________________________________________| | |
1051 */ | |
1052 int main( int argc, char *argv[] ) | |
1053 { | |
1054 FILE *infile, *outfile; | |
1055 Shortword errpat, i = 0; | |
1056 | |
1057 if( argc < 4 || argc > 4 ) { | |
1058 fprintf( stderr, "\tUsage: REID input output EPx \n" ); | |
1059 fprintf( stderr, "\tEPx: EP0\n" ); | |
1060 fprintf( stderr, "\t EP1 (not implemented)\n" ); | |
1061 fprintf( stderr, "\t EP2 (not implemented)\n" ); | |
1062 fprintf( stderr, "\t EP3 (not implemented)\n" ); | |
1063 return( 1 ); | |
1064 } | |
1065 | |
1066 | |
1067 if( !Strincmp( argv[3], "ep", 2 )) | |
1068 errpat = atoi( &argv[3][2] ); | |
1069 | |
1070 printf( " _____________________________________________\n" ); | |
1071 printf( " | |\n" ); | |
1072 printf( " | Residual Error Insertion Device |\n" ); | |
1073 printf( " | for |\n" ); | |
1074 printf( " | GSM Half-Rate Codec Simulation |\n" ); | |
1075 printf( " | |\n" ); | |
1076 printf( " |_____________________________________________|\n\n" ); | |
1077 | |
1078 printf( " Input File : %s\n", argv[1] ); | |
1079 printf( " Output File : %s\n", argv[2] ); | |
1080 if( errpat ){ | |
1081 printf( " Error Pattern : EP%d (not implemented)\n", errpat); | |
1082 return (1); | |
1083 } | |
1084 else | |
1085 printf( " Error Pattern : EP%d (error free)\n", errpat ); | |
1086 printf( "\n" ); | |
1087 | |
1088 infile = OpenBinfile( argv[1], "r" ); | |
1089 outfile = OpenBinfile( argv[2], "w" ); | |
1090 | |
1091 | |
1092 if (errpat == 0) { | |
1093 for (i=0;i<6000;i++) | |
1094 if( error_free( infile, outfile)) break; | |
1095 } | |
1096 /*else | |
1097 for (i=0;i<6000;i++) | |
1098 if( residual_error_pattern( infile, outfile)) break; | |
1099 EP1-3 not implemented */ | |
1100 | |
1101 fclose( infile ); | |
1102 fclose( outfile ); | |
1103 | |
1104 printf( " %d Frame%s processed \n\n", i,( i != 1 ) ? "s" : "" ); | |
1105 return( 0 ); | |
1106 } |