diff options
author | Michael Giacomelli <giac2000@hotmail.com> | 2010-03-05 21:49:40 +0000 |
---|---|---|
committer | Michael Giacomelli <giac2000@hotmail.com> | 2010-03-05 21:49:40 +0000 |
commit | 6fc422e94019ccb0f5aa4cdee8cc010b64592961 (patch) | |
tree | 2af11391be706f9124a4ad40ebc28230a086a030 | |
parent | 4e797175f1b8954b60b8f1d8a7514c7c03a6d4a1 (diff) | |
download | rockbox-6fc422e94019ccb0f5aa4cdee8cc010b64592961.tar.gz rockbox-6fc422e94019ccb0f5aa4cdee8cc010b64592961.zip |
Fix red by moving fsincos back to libwma
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25036 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | apps/codecs/libwma/wmafixed.c | 101 | ||||
-rw-r--r-- | apps/codecs/libwma/wmafixed.h | 3 |
2 files changed, 103 insertions, 1 deletions
diff --git a/apps/codecs/libwma/wmafixed.c b/apps/codecs/libwma/wmafixed.c index 1472ed081c..649025b53a 100644 --- a/apps/codecs/libwma/wmafixed.c +++ b/apps/codecs/libwma/wmafixed.c | |||
@@ -250,3 +250,104 @@ fixed64 fixdiv64(fixed64 x, fixed64 y) | |||
250 | 250 | ||
251 | return (fixed32)(r << (PRECISION / 2)); | 251 | return (fixed32)(r << (PRECISION / 2)); |
252 | } | 252 | } |
253 | |||
254 | |||
255 | static const long cordic_circular_gain = 0xb2458939; /* 0.607252929 */ | ||
256 | |||
257 | /* Table of values of atan(2^-i) in 0.32 format fractions of pi where pi = 0xffffffff / 2 */ | ||
258 | static const unsigned long atan_table[] = { | ||
259 | 0x1fffffff, /* +0.785398163 (or pi/4) */ | ||
260 | 0x12e4051d, /* +0.463647609 */ | ||
261 | 0x09fb385b, /* +0.244978663 */ | ||
262 | 0x051111d4, /* +0.124354995 */ | ||
263 | 0x028b0d43, /* +0.062418810 */ | ||
264 | 0x0145d7e1, /* +0.031239833 */ | ||
265 | 0x00a2f61e, /* +0.015623729 */ | ||
266 | 0x00517c55, /* +0.007812341 */ | ||
267 | 0x0028be53, /* +0.003906230 */ | ||
268 | 0x00145f2e, /* +0.001953123 */ | ||
269 | 0x000a2f98, /* +0.000976562 */ | ||
270 | 0x000517cc, /* +0.000488281 */ | ||
271 | 0x00028be6, /* +0.000244141 */ | ||
272 | 0x000145f3, /* +0.000122070 */ | ||
273 | 0x0000a2f9, /* +0.000061035 */ | ||
274 | 0x0000517c, /* +0.000030518 */ | ||
275 | 0x000028be, /* +0.000015259 */ | ||
276 | 0x0000145f, /* +0.000007629 */ | ||
277 | 0x00000a2f, /* +0.000003815 */ | ||
278 | 0x00000517, /* +0.000001907 */ | ||
279 | 0x0000028b, /* +0.000000954 */ | ||
280 | 0x00000145, /* +0.000000477 */ | ||
281 | 0x000000a2, /* +0.000000238 */ | ||
282 | 0x00000051, /* +0.000000119 */ | ||
283 | 0x00000028, /* +0.000000060 */ | ||
284 | 0x00000014, /* +0.000000030 */ | ||
285 | 0x0000000a, /* +0.000000015 */ | ||
286 | 0x00000005, /* +0.000000007 */ | ||
287 | 0x00000002, /* +0.000000004 */ | ||
288 | 0x00000001, /* +0.000000002 */ | ||
289 | 0x00000000, /* +0.000000001 */ | ||
290 | 0x00000000, /* +0.000000000 */ | ||
291 | }; | ||
292 | |||
293 | /** | ||
294 | * Implements sin and cos using CORDIC rotation. | ||
295 | * | ||
296 | * @param phase has range from 0 to 0xffffffff, representing 0 and | ||
297 | * 2*pi respectively. | ||
298 | * @param cos return address for cos | ||
299 | * @return sin of phase, value is a signed value from LONG_MIN to LONG_MAX, | ||
300 | * representing -1 and 1 respectively. | ||
301 | * | ||
302 | * Gives at least 24 bits precision (last 2-8 bits or so are probably off) | ||
303 | */ | ||
304 | |||
305 | long fsincos(unsigned long phase, fixed32 *cos) | ||
306 | { | ||
307 | int32_t x, x1, y, y1; | ||
308 | unsigned long z, z1; | ||
309 | int i; | ||
310 | |||
311 | /* Setup initial vector */ | ||
312 | x = cordic_circular_gain; | ||
313 | y = 0; | ||
314 | z = phase; | ||
315 | |||
316 | /* The phase has to be somewhere between 0..pi for this to work right */ | ||
317 | if (z < 0xffffffff / 4) { | ||
318 | /* z in first quadrant, z += pi/2 to correct */ | ||
319 | x = -x; | ||
320 | z += 0xffffffff / 4; | ||
321 | } else if (z < 3 * (0xffffffff / 4)) { | ||
322 | /* z in third quadrant, z -= pi/2 to correct */ | ||
323 | z -= 0xffffffff / 4; | ||
324 | } else { | ||
325 | /* z in fourth quadrant, z -= 3pi/2 to correct */ | ||
326 | x = -x; | ||
327 | z -= 3 * (0xffffffff / 4); | ||
328 | } | ||
329 | |||
330 | /* Each iteration adds roughly 1-bit of extra precision */ | ||
331 | for (i = 0; i < 31; i++) { | ||
332 | x1 = x >> i; | ||
333 | y1 = y >> i; | ||
334 | z1 = atan_table[i]; | ||
335 | |||
336 | /* Decided which direction to rotate vector. Pivot point is pi/2 */ | ||
337 | if (z >= 0xffffffff / 4) { | ||
338 | x -= y1; | ||
339 | y += x1; | ||
340 | z -= z1; | ||
341 | } else { | ||
342 | x += y1; | ||
343 | y -= x1; | ||
344 | z += z1; | ||
345 | } | ||
346 | } | ||
347 | |||
348 | if (cos) | ||
349 | *cos = x; | ||
350 | |||
351 | return y; | ||
352 | } | ||
353 | \ No newline at end of file | ||
diff --git a/apps/codecs/libwma/wmafixed.h b/apps/codecs/libwma/wmafixed.h index 0ecdc5cfbc..d07acb3c6c 100644 --- a/apps/codecs/libwma/wmafixed.h +++ b/apps/codecs/libwma/wmafixed.h | |||
@@ -107,4 +107,5 @@ static inline fixed32 fixmul32(fixed32 x, fixed32 y) | |||
107 | #endif | 107 | #endif |
108 | 108 | ||
109 | 109 | ||
110 | /* get fixmul32b from codeclib */ | 110 | /* Inverse gain of circular cordic rotation in s0.31 format. */ |
111 | long fsincos(unsigned long phase, fixed32 *cos); | ||