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