Mercurial > hg > audiostuff
comparison intercom/gsm/add.c @ 2:13be24d74cd2
import intercom-0.4.1
author | Peter Meerwald <pmeerw@cosy.sbg.ac.at> |
---|---|
date | Fri, 25 Jun 2010 09:57:52 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
1:9cadc470e3da | 2:13be24d74cd2 |
---|---|
1 /* | |
2 * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische | |
3 * Universitaet Berlin. See the accompanying file "COPYRIGHT" for | |
4 * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. | |
5 */ | |
6 | |
7 /* $Header: /home/kbs/jutta/src/gsm/gsm-1.0/src/RCS/add.c,v 1.2 1993/01/29 18:23:15 jutta Exp $ */ | |
8 | |
9 /* | |
10 * See private.h for the more commonly used macro versions. | |
11 */ | |
12 | |
13 #include <stdio.h> | |
14 #include <assert.h> | |
15 | |
16 #include "private.h" | |
17 #include "gsm.h" | |
18 #include "proto.h" | |
19 | |
20 #define saturate(x) \ | |
21 ((x) < MIN_WORD ? MIN_WORD : (x) > MAX_WORD ? MAX_WORD: (x)) | |
22 | |
23 word gsm_add P2((a, b), word a, word b) | |
24 { | |
25 longword sum = (longword) a + (longword) b; | |
26 return saturate(sum); | |
27 } | |
28 | |
29 word gsm_sub P2((a, b), word a, word b) | |
30 { | |
31 longword diff = (longword) a - (longword) b; | |
32 return saturate(diff); | |
33 } | |
34 | |
35 word gsm_mult P2((a, b), word a, word b) | |
36 { | |
37 if (a == MIN_WORD && b == MIN_WORD) | |
38 return MAX_WORD; | |
39 else | |
40 return (word) (SASR((longword) a * (longword) b, 15)); | |
41 } | |
42 | |
43 word gsm_mult_r P2((a, b), word a, word b) | |
44 { | |
45 if (b == MIN_WORD && a == MIN_WORD) | |
46 return MAX_WORD; | |
47 else { | |
48 longword prod = (longword) a * (longword) b + 16384; | |
49 prod >>= 15; | |
50 return prod & 0xFFFF; | |
51 } | |
52 } | |
53 | |
54 word gsm_abs P1((a), word a) | |
55 { | |
56 return a < 0 ? (a == MIN_WORD ? MAX_WORD : -a) : a; | |
57 } | |
58 | |
59 longword gsm_L_mult P2((a, b), word a, word b) | |
60 { | |
61 assert(a != MIN_WORD || b != MIN_WORD); | |
62 return ((longword) a * (longword) b) << 1; | |
63 } | |
64 | |
65 longword gsm_L_add P2((a, b), longword a, longword b) | |
66 { | |
67 if (a < 0) { | |
68 if (b >= 0) | |
69 return a + b; | |
70 else { | |
71 ulongword A = (ulongword) - (a + 1) + (ulongword) - (b + 1); | |
72 return A >= | |
73 (ulongword) MAX_LONGWORD ? MIN_LONGWORD : -(longword) A - 2; | |
74 } | |
75 } else if (b <= 0) | |
76 return a + b; | |
77 else { | |
78 ulongword A = (ulongword) a + (ulongword) b; | |
79 return A > (ulongword) MAX_LONGWORD ? MAX_LONGWORD : A; | |
80 } | |
81 } | |
82 | |
83 longword gsm_L_sub P2((a, b), longword a, longword b) | |
84 { | |
85 if (a >= 0) { | |
86 if (b >= 0) | |
87 return a - b; | |
88 else { | |
89 /* a>=0, b<0 */ | |
90 | |
91 ulongword A = (ulongword) a + -(b + 1); | |
92 return A >= (ulongword) MAX_LONGWORD ? MAX_LONGWORD : (A + 1); | |
93 } | |
94 } else if (b <= 0) | |
95 return a - b; | |
96 else { | |
97 /* a<0, b>0 */ | |
98 | |
99 ulongword A = (ulongword) - (a + 1) + b; | |
100 return A >= (ulongword) MAX_LONGWORD ? MIN_LONGWORD : -A - 1; | |
101 } | |
102 } | |
103 | |
104 static unsigned char bitoff[256] = { | |
105 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, | |
106 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, | |
107 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |
108 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |
109 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
110 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
111 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
112 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
113 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
114 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
115 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
116 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
117 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
118 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
119 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
120 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 | |
121 }; | |
122 | |
123 word gsm_norm P1((a), longword a) | |
124 /* | |
125 * the number of left shifts needed to normalize the 32 bit | |
126 * variable L_var1 for positive values on the interval | |
127 * | |
128 * with minimum of | |
129 * minimum of 1073741824 (01000000000000000000000000000000) and | |
130 * maximum of 2147483647 (01111111111111111111111111111111) | |
131 * | |
132 * | |
133 * and for negative values on the interval with | |
134 * minimum of -2147483648 (-10000000000000000000000000000000) and | |
135 * maximum of -1073741824 ( -1000000000000000000000000000000). | |
136 * | |
137 * in order to normalize the result, the following | |
138 * operation must be done: L_norm_var1 = L_var1 << norm( L_var1 ); | |
139 * | |
140 * (That's 'ffs', only from the left, not the right..) | |
141 */ | |
142 { | |
143 assert(a != 0); | |
144 | |
145 if (a < 0) { | |
146 if (a <= (longword) - 1073741824) | |
147 return 0; | |
148 a = ~a; | |
149 } | |
150 | |
151 return a & 0xffff0000 | |
152 ? (a & 0xff000000 ? -1 + bitoff[(unsigned char) (0xFF & (a >> 24))] | |
153 : 7 + bitoff[(unsigned char) (0xFF & (a >> 16))]) | |
154 : (a & 0xff00 ? 15 + bitoff[(unsigned char) (0xFF & (a >> 8))] | |
155 : 23 + bitoff[(unsigned char) (0xFF & a)]); | |
156 } | |
157 | |
158 longword gsm_L_asl P2((a, n), longword a, int n) | |
159 { | |
160 if (n >= 32) | |
161 return 0; | |
162 if (n <= -32) | |
163 return -(a < 0); | |
164 if (n < 0) | |
165 return gsm_asr(a, -n); | |
166 return a << n; | |
167 } | |
168 | |
169 word gsm_asl P2((a, n), word a, int n) | |
170 { | |
171 if (n >= 16) | |
172 return 0; | |
173 if (n <= -16) | |
174 return -(a < 0); | |
175 if (n < 0) | |
176 return gsm_asr(a, -n); | |
177 return a << n; | |
178 } | |
179 | |
180 longword gsm_L_asr P2((a, n), longword a, int n) | |
181 { | |
182 if (n >= 32) | |
183 return -(a < 0); | |
184 if (n <= -32) | |
185 return 0; | |
186 if (n < 0) | |
187 return a << -n; | |
188 | |
189 # ifdef SASR | |
190 return a >> n; | |
191 # else | |
192 if (a >= 0) | |
193 return a >> n; | |
194 else | |
195 return -(longword) (-(ulongword) a >> n); | |
196 # endif | |
197 } | |
198 | |
199 word gsm_asr P2((a, n), word a, int n) | |
200 { | |
201 if (n >= 16) | |
202 return -(a < 0); | |
203 if (n <= -16) | |
204 return 0; | |
205 if (n < 0) | |
206 return a << -n; | |
207 | |
208 # ifdef SASR | |
209 return a >> n; | |
210 # else | |
211 if (a >= 0) | |
212 return a >> n; | |
213 else | |
214 return -(word) (-(uword) a >> n); | |
215 # endif | |
216 } | |
217 | |
218 /* | |
219 * (From p. 46, end of section 4.2.5) | |
220 * | |
221 * NOTE: The following lines gives [sic] one correct implementation | |
222 * of the div(num, denum) arithmetic operation. Compute div | |
223 * which is the integer division of num by denum: with denum | |
224 * >= num > 0 | |
225 */ | |
226 | |
227 word gsm_div P2((num, denum), word num, word denum) | |
228 { | |
229 longword L_num = num; | |
230 longword L_denum = denum; | |
231 word div = 0; | |
232 int k = 15; | |
233 | |
234 /* The parameter num sometimes becomes zero. | |
235 * Although this is explicitly guarded against in 4.2.5, | |
236 * we assume that the result should then be zero as well. | |
237 */ | |
238 | |
239 /* assert(num != 0); */ | |
240 | |
241 assert(num >= 0 && denum >= num); | |
242 if (num == 0) | |
243 return 0; | |
244 | |
245 while (k--) { | |
246 div <<= 1; | |
247 L_num <<= 1; | |
248 | |
249 if (L_num >= L_denum) { | |
250 L_num -= L_denum; | |
251 div++; | |
252 } | |
253 } | |
254 | |
255 return div; | |
256 } |