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