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