rnd-20040822-4-src
[rocksndiamonds.git] / src / game_em / ulaw_generate.c
1 /* 2000-08-10T04:29:10Z
2  *
3  * generate ulaw<->linear conversion tables to be included
4  * directly in emerald mine source
5  */
6
7 #include "game_em.h"
8
9
10 #if defined(TARGET_X11)
11
12 #if defined(PLATFORM_LINUX) || defined(PLATFORM_BSD)
13
14 #include <stdio.h>
15
16 int calc_ulaw_to_linear(unsigned char);
17 unsigned char calc_linear_to_ulaw(int);
18
19 int buffer[65536];
20
21 /* convert from 8 bit ulaw to signed 16 bit linear */
22 short ulaw_to_linear[256];
23
24 /* convert from signed 16 bit linear to 8 bit ulaw */
25 unsigned char linear_to_ulaw[65536];
26
27 void ulaw_generate()
28 {
29   int i;
30
31   for(i = 0; i < 256; i++)
32     ulaw_to_linear[i] = calc_ulaw_to_linear(i);
33
34   for(i = -32768; i < 32768; i++)
35     linear_to_ulaw[i + 32768] = calc_linear_to_ulaw(i);
36 }
37
38 /*
39 ** This routine converts from ulaw to 16 bit linear.
40 **
41 ** Craig Reese: IDA/Supercomputing Research Center
42 ** 29 September 1989
43 **
44 ** References:
45 ** 1) CCITT Recommendation G.711  (very difficult to follow)
46 ** 2) MIL-STD-188-113,"Interoperability and Performance Standards
47 **     for Analog-to_Digital Conversion Techniques,"
48 **     17 February 1987
49 **
50 ** Input: 8 bit ulaw sample
51 ** Output: signed 16 bit linear sample
52 */
53
54 int calc_ulaw_to_linear(unsigned char ulawbyte)
55 {
56   static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
57   int sign, exponent, mantissa, sample;
58
59   ulawbyte = ~ ulawbyte;
60   sign = ( ulawbyte & 0x80 );
61   exponent = ( ulawbyte >> 4 ) & 0x07;
62   mantissa = ulawbyte & 0x0F;
63   sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
64   if (sign != 0)
65     sample = -sample;
66
67   return(sample);
68 }
69
70 /*
71 ** This routine converts from linear to ulaw.
72 **
73 ** Craig Reese: IDA/Supercomputing Research Center
74 ** Joe Campbell: Department of Defense
75 ** 29 September 1989
76 **
77 ** References:
78 ** 1) CCITT Recommendation G.711  (very difficult to follow)
79 ** 2) "A New Digital Technique for Implementation of Any
80 **     Continuous PCM Companding Law," Villeret, Michel,
81 **     et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
82 **     1973, pg. 11.12-11.17
83 ** 3) MIL-STD-188-113,"Interoperability and Performance Standards
84 **     for Analog-to_Digital Conversion Techniques,"
85 **     17 February 1987
86 **
87 ** Input: Signed 16 bit linear sample
88 ** Output: 8 bit ulaw sample
89 */
90
91 #define ZEROTRAP    /* turn on the trap as per the MIL-STD */
92 #define BIAS 0x84   /* define the add-in bias for 16 bit samples */
93 #define CLIP 32635
94
95 unsigned char calc_linear_to_ulaw(int sample)
96 {
97   static int exp_lut[256] =
98   {
99     0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
100     4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
101     5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
102     5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
103     6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
104     6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
105     6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
106     6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
107     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
108     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
109     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
110     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
111     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
112     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
113     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
114     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
115   };
116
117   int sign, exponent, mantissa;
118   unsigned char ulawbyte;
119
120 /* Get the sample into sign-magnitude. */
121   sign = (sample >> 8) & 0x80; /* set aside the sign */
122   if (sign != 0)
123     sample = -sample; /* get magnitude */
124   if (sample > CLIP)
125     sample = CLIP; /* clip the magnitude */
126
127 /* Convert from 16 bit linear to ulaw. */
128   sample = sample + BIAS;
129   exponent = exp_lut[( sample >> 7 ) & 0xFF];
130   mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
131   ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
132 #ifdef ZEROTRAP
133   if (ulawbyte == 0)
134     ulawbyte = 0x02; /* optional CCITT trap */
135 #endif
136
137   return(ulawbyte);
138 }
139
140 #endif /* defined(PLATFORM_LINUX) || defined(PLATFORM_BSD) */
141
142 #endif