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 }