Code clean up: Move fixed point functions into their own files. Move various lookup tables into header files.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13784 a1c6a512-1295-4272-9138-f99709370657
diff --git a/apps/codecs/libwma/SOURCES b/apps/codecs/libwma/SOURCES
index 3351bb2..190e3a7 100644
--- a/apps/codecs/libwma/SOURCES
+++ b/apps/codecs/libwma/SOURCES
@@ -1,2 +1,3 @@
wmadeci.c
common.c
+wmafixed.c
\ No newline at end of file
diff --git a/apps/codecs/libwma/wmadata.h b/apps/codecs/libwma/wmadata.h
index ee17207..ae4844e 100644
--- a/apps/codecs/libwma/wmadata.h
+++ b/apps/codecs/libwma/wmadata.h
@@ -1389,24 +1389,118 @@
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
};
-
+
static const CoefVLCTable coef_vlcs[6] = {
- {
+ {
sizeof(coef0_huffbits), coef0_huffcodes, coef0_huffbits, levels0,
},
- {
+ {
sizeof(coef1_huffbits), coef1_huffcodes, coef1_huffbits, levels1,
},
- {
+ {
sizeof(coef2_huffbits), coef2_huffcodes, coef2_huffbits, levels2,
},
- {
+ {
sizeof(coef3_huffbits), coef3_huffcodes, coef3_huffbits, levels3,
},
- {
+ {
sizeof(coef4_huffbits), coef4_huffcodes, coef4_huffbits, levels4,
},
- {
+ {
sizeof(coef5_huffbits), coef5_huffcodes, coef5_huffbits, levels5,
},
};
+
+
+const fixed64 pow_table[] =
+ {
+ 0x10000LL,0x11f3dLL,0x14249LL,0x1699cLL,0x195bcLL,0x1c73dLL,0x1fec9LL,0x23d1dLL,0x2830bLL,0x2d182LL,
+ 0x3298bLL,0x38c53LL,0x3fb28LL,0x47783LL,0x5030aLL,0x59f98LL,0x64f40LL,0x71457LL,0x7f17bLL,0x8e99aLL,
+ 0xa0000LL,0xb385eLL,0xc96d9LL,0xe2019LL,0xfd954LL,0x11c865LL,0x13f3dfLL,0x166320LL,0x191e6eLL,0x1c2f10LL,
+ 0x1f9f6eLL,0x237b39LL,0x27cf8bLL,0x2cab1aLL,0x321e65LL,0x383bf0LL,0x3f1882LL,0x46cb6aLL,0x4f6eceLL,0x592006LL,
+ 0x640000LL,0x7033acLL,0x7de47eLL,0x8d40f6LL,0x9e7d44LL,0xb1d3f4LL,0xc786b7LL,0xdfdf43LL,0xfb304bLL,0x119d69aLL,
+ 0x13c3a4eLL,0x162d03aLL,0x18e1b70LL,0x1beaf00LL,0x1f52feeLL,0x2325760LL,0x276f514LL,0x2c3f220LL,0x31a5408LL,
+ 0x37b403cLL,0x3e80000LL,0x46204b8LL,0x4eaece8LL,0x58489a0LL,0x630e4a8LL,0x6f24788LL,0x7cb4328LL,0x8beb8a0LL,
+ 0x9cfe2f0LL,0xb026200LL,0xc5a4710LL,0xddc2240LL,0xf8d1260LL,0x1172d600LL,0x1393df60LL,0x15f769c0LL,0x18a592c0LL,
+ 0x1ba77540LL,0x1f074840LL,0x22d08280LL,0x27100000LL,0x2bd42f40LL,0x312d4100LL,0x372d6000LL,0x3de8ee80LL,
+ 0x4576cb80LL,0x4df09f80LL,0x57733600LL,0x621edd80LL,0x6e17d480LL,0x7b86c700LL,0x8a995700LL,0x9b82b800LL,
+ 0xae7c5c00LL,0xc3c6b900LL,0xdbaa2200LL,0xf677bc00LL,0x1148a9400LL,0x13648d200LL,0x15c251800LL,0x186a00000LL,
+ 0x1b649d800LL,0x1ebc48a00LL,0x227c5c000LL,0x26b195000LL,0x2b6a3f000LL,0x30b663c00LL,0x36a801c00LL,0x3d534a400LL,
+ 0x44cee4800LL,0x4d343c800LL,0x569fd6000LL,0x6131b2800LL,0x6d0db9800LL,0x7a5c33800LL,0x894a55000LL,0x9a0ad6000LL,
+ 0xacd69d000LL,0xc1ed84000LL,0xd9972f000LL,0xf42400000LL,0x111ee28000LL,0x1335ad6000LL,0x158db98000LL,0x182efd4000LL,
+ 0x1b22676000LL,0x1e71fe6000LL,0x2229014000LL,0x26540e8000LL,0x2b014f0000LL,0x3040a5c000LL,0x3623e60000LL,0x3cbf0fc000LL,
+ 0x4428940000LL,0x4c79a08000LL,0x55ce758000LL,0x6046c58000LL,0x6c06220000LL,0x7934728000LL,0x87fe7d0000LL,0x9896800000LL,
+ 0xab34d90000LL,0xc018c60000LL,0xd7893f0000LL,0xf1d5e40000LL,0x10f580a0000LL,0x13073f00000LL,0x1559a0c0000LL,0x17f48900000LL,
+ 0x1ae0d160000LL,0x1e286780000LL,0x21d66fc0000LL,0x25f769c0000LL,0x2a995c80000LL,0x2fcc0440000LL,0x35a10940000LL,
+ 0x3c2c3b80000LL,0x4383d500000LL,0x4bc0c780000LL,0x54ff0e80000LL,0x5f5e1000000LL,0x6b010780000LL,0x780f7c00000LL,
+ 0x86b5c800000LL,0x9725ae00000LL,0xa9970600000LL,0xbe487500000LL,0xd5804700000LL,0xef8d5a00000LL,0x10cc82e00000LL,
+ 0x12d940c00000LL,0x152605c00000LL,0x17baa2200000LL,0x1a9fd9c00000LL,0x1ddf82a00000LL,0x2184a5c00000LL,0x259ba5400000LL,
+ 0x2a3265400000LL,0x2f587cc00000LL,0x351f69000000LL,0x3b9aca000000LL,0x42e0a4800000LL,0x4b09ad800000LL,
+ 0x54319d000000LL,0x5e778d000000LL,0x69fe64000000LL,0x76ed49800000LL,0x85702c000000LL,0x95b858000000LL,
+ 0xa7fd1c000000LL,0xbc7c87000000LL,0xd37c3a000000LL,0xed4a55000000LL,0x10a3e82000000LL,0x12abb1a000000LL,
+ 0x14f2e7a000000LL,0x1781474000000LL,0x1a5f7f4000000LL,0x1d974de000000LL,0x2133a18000000LL
+ };
+
+const fixed32 pow_10_to_yover16[] ICONST_ATTR=
+{
+0x10000,0x127a0,0x15562,0x18a39,0x1c73d,0x20db4,0x25f12,0x2bd09,0x3298b,0x3a6d9,0x4378b,0x4dea3,
+0x59f98,0x67e6b,0x77fbb,0x8a8de,0xa0000,0xb8c3e,0xd55d1,0xf6636,0x11c865,0x148906,0x17b6b8,0x1b625b,
+0x1f9f6e,0x248475,0x2a2b6e,0x30b25f,0x383bf0,0x40f02c,0x4afd4b,0x5698b0,0x640000,0x737a6b,0x855a26,
+0x99fe1f,0xb1d3f4,0xcd5a3e,0xed232b,0x111d78a,0x13c3a4e,0x16d2c94,0x1a5b24e,0x1e6f7b0,0x2325760,
+0x28961b4,0x2ede4ec,0x361f6dc,0x3e80000,0x482c830,0x5358580,0x603ed30,0x6f24788,0x8058670,0x9435fb0,
+0xab26b70,0xc5a4710,0xe43bdc0,0x1078f700,0x1305ace0,0x15f769c0,0x195dd100,0x1d4af120
+};
+
+const fixed32 pow_a_table[] =
+{
+0x1004,0x1008,0x100c,0x1010,0x1014,0x1018,0x101c,0x1021,0x1025,0x1029,0x102d,0x1031,0x1036,0x103a,
+0x103e,0x1043,0x1047,0x104b,0x1050,0x1054,0x1059,0x105d,0x1062,0x1066,0x106b,0x106f,0x1074,0x1078,
+0x107d,0x1082,0x1086,0x108b,0x1090,0x1095,0x1099,0x109e,0x10a3,0x10a8,0x10ad,0x10b2,0x10b7,0x10bc,
+0x10c1,0x10c6,0x10cb,0x10d0,0x10d5,0x10da,0x10df,0x10e5,0x10ea,0x10ef,0x10f5,0x10fa,0x10ff,0x1105,
+0x110a,0x1110,0x1115,0x111b,0x1120,0x1126,0x112c,0x1131,0x1137,0x113d,0x1143,0x1149,0x114f,0x1155,
+0x115a,0x1161,0x1167,0x116d,0x1173,0x1179,0x117f,0x1186,0x118c,0x1192,0x1199,0x119f,0x11a6,0x11ac,
+0x11b3,0x11b9,0x11c0,0x11c7,0x11ce,0x11d4,0x11db,0x11e2,0x11e9,0x11f0,0x11f8,0x11ff,0x1206,0x120d,
+0x1215,0x121c,0x1223,0x122b,0x1233,0x123a,0x1242,0x124a,0x1251,0x1259,0x1261,0x1269,0x1271,0x127a,
+0x1282,0x128a,0x1293,0x129b,0x12a4,0x12ac,0x12b5,0x12be,0x12c7,0x12d0,0x12d9,0x12e2,0x12eb,0x12f4,
+0x12fe,0x1307
+};
+
+const fixed64 lsp_pow_e_table[] =
+{
+ 0xf333f9deLL, 0xf0518db9LL, 0x0LL, 0x7e656b4fLL, 0x7999fcefLL, 0xf828c6dcLL, 0x0LL,
+ 0x3f32b5a7LL, 0x3cccfe78LL, 0xfc14636eLL, 0x0LL, 0x9f995ad4LL, 0x9e667f3cLL, 0xfe0a31b7LL,
+ 0x0LL, 0x4fccad6aLL, 0x4f333f9eLL, 0x7f0518dcLL, 0x0LL, 0x27e656b5LL, 0x27999fcfLL,
+ 0xbf828c6eLL, 0x0LL, 0x13f32b5aLL, 0x13cccfe7LL, 0xdfc14637LL, 0x0LL, 0x89f995adLL,
+ 0x9e667f4LL, 0x6fe0a31bLL, 0x0LL, 0x44fccad7LL, 0x4f333faLL, 0x37f0518eLL, 0x0LL,
+ 0xa27e656bLL, 0x827999fdLL, 0x1bf828c7LL, 0x0LL, 0xd13f32b6LL, 0x413cccfeLL, 0xdfc1463LL,
+ 0x0LL, 0xe89f995bLL, 0xa09e667fLL, 0x6fe0a32LL, 0x0LL, 0x744fccadLL, 0x504f3340LL,
+ 0x837f0519LL, 0x0LL, 0xba27e657LL, 0xa82799a0LL, 0xc1bf828cLL, 0x0LL, 0x5d13f32bLL,
+ 0xd413ccd0LL, 0x60dfc146LL, 0x0LL, 0xae89f996LL, 0x6a09e668LL, 0x306fe0a3LL, 0x0LL,
+ 0xd744fccbLL, 0xb504f334LL, 0x9837f052LL, 0x80000000LL, 0x6ba27e65LL, 0x5a82799aLL,
+ 0x4c1bf829LL, 0x40000000LL, 0x35d13f33LL, 0x2d413ccdLL, 0x260dfc14LL, 0x20000000LL,
+ 0x1ae89f99LL, 0x16a09e66LL, 0x1306fe0aLL, 0x10000000LL, 0xd744fcdLL, 0xb504f33LL,
+ 0x9837f05LL, 0x8000000LL, 0x6ba27e6LL, 0x5a8279aLL, 0x4c1bf83LL, 0x4000000LL,
+ 0x35d13f3LL, 0x2d413cdLL, 0x260dfc1LL, 0x2000000LL, 0x1ae89faLL, 0x16a09e6LL,
+ 0x1306fe1LL, 0x1000000LL, 0xd744fdLL, 0xb504f3LL, 0x9837f0LL, 0x800000LL,
+ 0x6ba27eLL, 0x5a827aLL, 0x4c1bf8LL, 0x400000LL, 0x35d13fLL, 0x2d413dLL,
+ 0x260dfcLL, 0x200000LL, 0x1ae8a0LL, 0x16a09eLL, 0x1306feLL, 0x100000LL,
+ 0xd7450LL, 0xb504fLL, 0x9837fLL, 0x80000LL, 0x6ba28LL, 0x5a828LL, 0x4c1c0LL,
+ 0x40000LL, 0x35d14LL, 0x2d414LL, 0x260e0LL, 0x20000LL, 0x1ae8aLL, 0x16a0aLL,
+ 0x13070LL, 0x10000LL, 0xd745LL, 0xb505LL, 0x9838LL, 0x8000LL, 0x6ba2LL,
+ 0x5a82LL, 0x4c1cLL, 0x4000LL, 0x35d1LL, 0x2d41LL, 0x260eLL, 0x2000LL,
+ 0x1ae9LL, 0x16a1LL, 0x1307LL, 0x1000LL, 0xd74LL, 0xb50LL, 0x983LL, 0x800LL,
+ 0x6baLL, 0x5a8LL, 0x4c2LL, 0x400LL, 0x35dLL, 0x2d4LL, 0x261LL, 0x200LL, 0x1afLL,
+ 0x16aLL, 0x130LL, 0x100LL, 0xd7LL, 0xb5LL, 0x98LL, 0x80LL, 0x6cLL, 0x5bLL,
+ 0x4cLL, 0x40LL, 0x36LL, 0x2dLL, 0x26LL, 0x20LL, 0x1bLL, 0x17LL, 0x13LL,
+ 0x10LL, 0xdLL, 0xbLL, 0xaLL, 0x8LL, 0x7LL, 0x6LL, 0x5LL, 0x4LL, 0x3LL,
+ 0x3LL, 0x2LL, 0x2LL, 0x2LL, 0x1LL, 0x1LL, 0x1LL, 0x1LL, 0x1LL, 0x1LL,
+ 0x1LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL,
+ 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL,
+ 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL,
+ 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL,
+ 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL,
+ 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL,
+ 0x0LL, 0x0LL
+};
+
+
diff --git a/apps/codecs/libwma/wmadeci.c b/apps/codecs/libwma/wmadeci.c
index c064bf0..6647ed4 100644
--- a/apps/codecs/libwma/wmadeci.c
+++ b/apps/codecs/libwma/wmadeci.c
@@ -26,409 +26,9 @@
#include <codecs/lib/codeclib.h>
#include "asf.h"
#include "wmadec.h"
-
-/* These are for development and debugging and should not be changed unless
-you REALLY know what you are doing ;) */
-//#define IGNORE_OVERFLOW
-#define FAST_FILTERS
-#define PRECISION 16
-#define PRECISION64 16
-
-static fixed64 IntTo64(int x)
-{
- fixed64 res = 0;
- unsigned char *p = (unsigned char *)&res;
-
-#ifdef ROCKBOX_BIG_ENDIAN
- p[5] = x & 0xff;
- p[4] = (x & 0xff00)>>8;
- p[3] = (x & 0xff0000)>>16;
- p[2] = (x & 0xff000000)>>24;
-#else
- p[2] = x & 0xff;
- p[3] = (x & 0xff00)>>8;
- p[4] = (x & 0xff0000)>>16;
- p[5] = (x & 0xff000000)>>24;
-#endif
- return res;
-}
-
-static int IntFrom64(fixed64 x)
-{
- int res = 0;
- unsigned char *p = (unsigned char *)&x;
-
-#ifdef ROCKBOX_BIG_ENDIAN
- res = p[5] | (p[4]<<8) | (p[3]<<16) | (p[2]<<24);
-#else
- res = p[2] | (p[3]<<8) | (p[4]<<16) | (p[5]<<24);
-#endif
- return res;
-}
-
-static fixed32 Fixed32From64(fixed64 x)
-{
- return x & 0xFFFFFFFF;
-}
-
-static fixed64 Fixed32To64(fixed32 x)
-{
- return (fixed64)x;
-}
-#define fixtof64(x) (float)((float)(x) / (float)(1 << PRECISION64)) //does not work on int64_t!
-#define ftofix32(x) ((fixed32)((x) * (float)(1 << PRECISION) + ((x) < 0 ? -0.5 : 0.5)))
-#define itofix64(x) (IntTo64(x))
-#define itofix32(x) ((x) << PRECISION)
-#define fixtoi32(x) ((x) >> PRECISION)
-#define fixtoi64(x) (IntFrom64(x))
-
-#ifdef CPU_ARM
-#define fixmul32(x, y) \
- ({ int32_t __hi; \
- uint32_t __lo; \
- int32_t __result; \
- asm ("smull %0, %1, %3, %4\n\t" \
- "movs %0, %0, lsr %5\n\t" \
- "adc %2, %0, %1, lsl %6" \
- : "=&r" (__lo), "=&r" (__hi), "=r" (__result) \
- : "%r" (x), "r" (y), \
- "M" (PRECISION), "M" (32 - PRECISION) \
- : "cc"); \
- __result; \
- })
-#elif defined(CPU_COLDFIRE)
-static inline int32_t fixmul32(int32_t x, int32_t y)
-{
-#if PRECISION != 16
-#warning Coldfire fixmul32() only works for PRECISION == 16
-#endif
- int32_t t1;
- asm (
- "mac.l %[x], %[y], %%acc0 \n" /* multiply */
- "mulu.l %[y], %[x] \n" /* get lower half, avoid emac stall */
- "movclr.l %%acc0, %[t1] \n" /* get higher half */
- "lsr.l #1, %[t1] \n"
- "move.w %[t1], %[x] \n"
- "swap %[x] \n"
- : /* outputs */
- [t1]"=&d"(t1),
- [x] "+d" (x)
- : /* inputs */
- [y] "d" (y)
- );
- return x;
-}
-#else
-fixed32 fixmul32(fixed32 x, fixed32 y)
-{
- fixed64 temp;
- float lol;
- // int filehandle = rb->open("/mul.txt", O_WRONLY|O_CREAT|O_APPEND);
- lol= fixtof64(x) * fixtof64(y);
-
- temp = x;
- temp *= y;
-
- temp >>= PRECISION;
-
- //rb->fdprintf(filehandle,"%d\n", (fixed32)temp);
- //rb->close(filehandle);
-
- return (fixed32)temp;
-}
-
-#endif
-//thanks MAD!
+#include "wmafixed.c"
-//mgg: special fixmul32 that does a 16.16 x 1.31 multiply that returns a 16.16 value.
-//this is needed because the fft constants are all normalized to be less then 1 and can't fit into a 16 bit number
-#ifdef CPU_ARM
-
-# define fixmul32b(x, y) \
- ({ int32_t __hi; \
- uint32_t __lo; \
- int32_t __result; \
- asm ("smull %0, %1, %3, %4\n\t" \
- "movs %0, %0, lsr %5\n\t" \
- "adc %2, %0, %1, lsl %6" \
- : "=&r" (__lo), "=&r" (__hi), "=r" (__result) \
- : "%r" (x), "r" (y), \
- "M" (31), "M" (1) \
- : "cc"); \
- __result; \
- })
-#elif !defined(CPU_COLDFIRE)
-static fixed32 fixmul32b(fixed32 x, fixed32 y)
-{
- fixed64 temp;
-
- temp = x;
- temp *= y;
-
- temp >>= 31; //16+31-16 = 31 bits
-
- return (fixed32)temp;
-}
-
-#endif
-
-
-
-
-static fixed64 fixmul64byfixed(fixed64 x, fixed32 y)
-{
-
- //return x * y;
- return (x * y);
- // return (fixed64) fixmul32(Fixed32From64(x),y);
-}
-
-
-fixed32 fixdiv32(fixed32 x, fixed32 y)
-{
- fixed64 temp;
-
- if(x == 0)
- return 0;
- if(y == 0)
- return 0x7fffffff;
- temp = x;
- temp <<= PRECISION;
- return (fixed32)(temp / y);
-}
-
-
-static fixed64 fixdiv64(fixed64 x, fixed64 y)
-{
- fixed64 temp;
-
- if(x == 0)
- return 0;
- if(y == 0)
- return 0x07ffffffffffffffLL;
- temp = x;
- temp <<= PRECISION64;
- return (fixed64)(temp / y);
-}
-
-static fixed32 fixsqrt32(fixed32 x)
-{
-
- unsigned long r = 0, s, v = (unsigned long)x;
-
-#define STEP(k) s = r + (1 << k * 2); r >>= 1; \
- if (s <= v) { v -= s; r |= (1 << k * 2); }
-
- STEP(15);
- STEP(14);
- STEP(13);
- STEP(12);
- STEP(11);
- STEP(10);
- STEP(9);
- STEP(8);
- STEP(7);
- STEP(6);
- STEP(5);
- STEP(4);
- STEP(3);
- STEP(2);
- STEP(1);
- STEP(0);
-
- return (fixed32)(r << (PRECISION / 2));
-}
-
-
-__inline fixed32 fixsin32(fixed32 x)
-{
-
- fixed64 x2, temp;
- int sign = 1;
-
- if(x < 0)
- {
- sign = -1;
- x = -x;
- }
- while (x > 0x19220)
- {
- x -= M_PI_F;
- sign = -sign;
- }
- if (x > 0x19220)
- {
- x = M_PI_F - x;
- }
- x2 = (fixed64)x * x;
- x2 >>= PRECISION;
- if(sign != 1)
- {
- x = -x;
- }
- /**
- temp = ftofix32(-.0000000239f) * x2;
- temp >>= PRECISION;
- **/
- temp = 0; // PJJ
- //temp = (temp + 0x0) * x2; //MGG: this can't possibly do anything?
- //temp >>= PRECISION;
- temp = (temp - 0xd) * x2;
- temp >>= PRECISION;
- temp = (temp + 0x222) * x2;
- temp >>= PRECISION;
- temp = (temp - 0x2aab) * x2;
- temp >>= PRECISION;
- temp += 0x10000;
- temp = temp * x;
- temp >>= PRECISION;
-
- return (fixed32)(temp);
-}
-
-__inline fixed32 fixcos32(fixed32 x)
-{
- return fixsin32(x - (M_PI_F>>1))*-1;
-}
-
-
-/* Inverse gain of circular cordic rotation in s0.31 format. */
-static const long cordic_circular_gain = 0xb2458939; /* 0.607252929 */
-
-/* Table of values of atan(2^-i) in 0.32 format fractions of pi where pi = 0xffffffff / 2 */
-static const unsigned long atan_table[] = {
- 0x1fffffff, /* +0.785398163 (or pi/4) */
- 0x12e4051d, /* +0.463647609 */
- 0x09fb385b, /* +0.244978663 */
- 0x051111d4, /* +0.124354995 */
- 0x028b0d43, /* +0.062418810 */
- 0x0145d7e1, /* +0.031239833 */
- 0x00a2f61e, /* +0.015623729 */
- 0x00517c55, /* +0.007812341 */
- 0x0028be53, /* +0.003906230 */
- 0x00145f2e, /* +0.001953123 */
- 0x000a2f98, /* +0.000976562 */
- 0x000517cc, /* +0.000488281 */
- 0x00028be6, /* +0.000244141 */
- 0x000145f3, /* +0.000122070 */
- 0x0000a2f9, /* +0.000061035 */
- 0x0000517c, /* +0.000030518 */
- 0x000028be, /* +0.000015259 */
- 0x0000145f, /* +0.000007629 */
- 0x00000a2f, /* +0.000003815 */
- 0x00000517, /* +0.000001907 */
- 0x0000028b, /* +0.000000954 */
- 0x00000145, /* +0.000000477 */
- 0x000000a2, /* +0.000000238 */
- 0x00000051, /* +0.000000119 */
- 0x00000028, /* +0.000000060 */
- 0x00000014, /* +0.000000030 */
- 0x0000000a, /* +0.000000015 */
- 0x00000005, /* +0.000000007 */
- 0x00000002, /* +0.000000004 */
- 0x00000001, /* +0.000000002 */
- 0x00000000, /* +0.000000001 */
- 0x00000000, /* +0.000000000 */
-};
-
-/**
- * Implements sin and cos using CORDIC rotation.
- *
- * @param phase has range from 0 to 0xffffffff, representing 0 and
- * 2*pi respectively.
- * @param cos return address for cos
- * @return sin of phase, value is a signed value from LONG_MIN to LONG_MAX,
- * representing -1 and 1 respectively.
- *
- * Gives at least 24 bits precision (last 2-8 bits or so are probably off)
- */
-static long fsincos(unsigned long phase, fixed32 *cos)
-{
- int32_t x, x1, y, y1;
- unsigned long z, z1;
- int i;
-
- /* Setup initial vector */
- x = cordic_circular_gain;
- y = 0;
- z = phase;
-
- /* The phase has to be somewhere between 0..pi for this to work right */
- if (z < 0xffffffff / 4) {
- /* z in first quadrant, z += pi/2 to correct */
- x = -x;
- z += 0xffffffff / 4;
- } else if (z < 3 * (0xffffffff / 4)) {
- /* z in third quadrant, z -= pi/2 to correct */
- z -= 0xffffffff / 4;
- } else {
- /* z in fourth quadrant, z -= 3pi/2 to correct */
- x = -x;
- z -= 3 * (0xffffffff / 4);
- }
-
- /* Each iteration adds roughly 1-bit of extra precision */
- for (i = 0; i < 31; i++) {
- x1 = x >> i;
- y1 = y >> i;
- z1 = atan_table[i];
-
- /* Decided which direction to rotate vector. Pivot point is pi/2 */
- if (z >= 0xffffffff / 4) {
- x -= y1;
- y += x1;
- z -= z1;
- } else {
- x += y1;
- y -= x1;
- z += z1;
- }
- }
-
- if (cos)
- *cos = x;
-
- return y;
-}
-
-
-
-/*
-__inline fixed32 fixasin32(fixed32 x)
-{
- fixed64 temp;
- int sign = 1;
-
- if(x > 0x10000 || x < 0xffff0000)
- {
- return 0;
- }
- if(x < 0)
- {
- sign = -1;
- x = -x;
- }
- temp = 0xffffffad * (fixed64)x;
- temp >>= PRECISION;
- temp = (temp + 0x1b5) * x;
- temp >>= PRECISION;
- temp = (temp - 0x460) * x;
- temp >>= PRECISION;
- temp = (temp + 0x7e9) * x;
- temp >>= PRECISION;
- temp = (temp - 0xcd8) * x;
- temp >>= PRECISION;
- temp = (temp + 0x16c7) * x;
- temp >>= PRECISION;
- temp = (temp - 0x36f0) * x;
- temp >>= PRECISION;
- temp = (temp + 0x19220) * fixsqrt32(0x10000 - x);
- temp >>= PRECISION;
-
- return sign * ((M_PI_F>>1) - (fixed32)temp);
-}
-*/
#define ALT_BITSTREAM_READER
@@ -528,98 +128,8 @@
static VLC_TYPE vlcbuf2[3584][2];
static VLC_TYPE vlcbuf3[1536][2] IBSS_ATTR; //small so lets try iram
-//fixed32 window[BLOCK_MAX_SIZE * 2];
-const fixed64 pow_table[] =
- {
- 0x10000LL,0x11f3dLL,0x14249LL,0x1699cLL,0x195bcLL,0x1c73dLL,0x1fec9LL,0x23d1dLL,0x2830bLL,0x2d182LL,
- 0x3298bLL,0x38c53LL,0x3fb28LL,0x47783LL,0x5030aLL,0x59f98LL,0x64f40LL,0x71457LL,0x7f17bLL,0x8e99aLL,
- 0xa0000LL,0xb385eLL,0xc96d9LL,0xe2019LL,0xfd954LL,0x11c865LL,0x13f3dfLL,0x166320LL,0x191e6eLL,0x1c2f10LL,
- 0x1f9f6eLL,0x237b39LL,0x27cf8bLL,0x2cab1aLL,0x321e65LL,0x383bf0LL,0x3f1882LL,0x46cb6aLL,0x4f6eceLL,0x592006LL,
- 0x640000LL,0x7033acLL,0x7de47eLL,0x8d40f6LL,0x9e7d44LL,0xb1d3f4LL,0xc786b7LL,0xdfdf43LL,0xfb304bLL,0x119d69aLL,
- 0x13c3a4eLL,0x162d03aLL,0x18e1b70LL,0x1beaf00LL,0x1f52feeLL,0x2325760LL,0x276f514LL,0x2c3f220LL,0x31a5408LL,
- 0x37b403cLL,0x3e80000LL,0x46204b8LL,0x4eaece8LL,0x58489a0LL,0x630e4a8LL,0x6f24788LL,0x7cb4328LL,0x8beb8a0LL,
- 0x9cfe2f0LL,0xb026200LL,0xc5a4710LL,0xddc2240LL,0xf8d1260LL,0x1172d600LL,0x1393df60LL,0x15f769c0LL,0x18a592c0LL,
- 0x1ba77540LL,0x1f074840LL,0x22d08280LL,0x27100000LL,0x2bd42f40LL,0x312d4100LL,0x372d6000LL,0x3de8ee80LL,
- 0x4576cb80LL,0x4df09f80LL,0x57733600LL,0x621edd80LL,0x6e17d480LL,0x7b86c700LL,0x8a995700LL,0x9b82b800LL,
- 0xae7c5c00LL,0xc3c6b900LL,0xdbaa2200LL,0xf677bc00LL,0x1148a9400LL,0x13648d200LL,0x15c251800LL,0x186a00000LL,
- 0x1b649d800LL,0x1ebc48a00LL,0x227c5c000LL,0x26b195000LL,0x2b6a3f000LL,0x30b663c00LL,0x36a801c00LL,0x3d534a400LL,
- 0x44cee4800LL,0x4d343c800LL,0x569fd6000LL,0x6131b2800LL,0x6d0db9800LL,0x7a5c33800LL,0x894a55000LL,0x9a0ad6000LL,
- 0xacd69d000LL,0xc1ed84000LL,0xd9972f000LL,0xf42400000LL,0x111ee28000LL,0x1335ad6000LL,0x158db98000LL,0x182efd4000LL,
- 0x1b22676000LL,0x1e71fe6000LL,0x2229014000LL,0x26540e8000LL,0x2b014f0000LL,0x3040a5c000LL,0x3623e60000LL,0x3cbf0fc000LL,
- 0x4428940000LL,0x4c79a08000LL,0x55ce758000LL,0x6046c58000LL,0x6c06220000LL,0x7934728000LL,0x87fe7d0000LL,0x9896800000LL,
- 0xab34d90000LL,0xc018c60000LL,0xd7893f0000LL,0xf1d5e40000LL,0x10f580a0000LL,0x13073f00000LL,0x1559a0c0000LL,0x17f48900000LL,
- 0x1ae0d160000LL,0x1e286780000LL,0x21d66fc0000LL,0x25f769c0000LL,0x2a995c80000LL,0x2fcc0440000LL,0x35a10940000LL,
- 0x3c2c3b80000LL,0x4383d500000LL,0x4bc0c780000LL,0x54ff0e80000LL,0x5f5e1000000LL,0x6b010780000LL,0x780f7c00000LL,
- 0x86b5c800000LL,0x9725ae00000LL,0xa9970600000LL,0xbe487500000LL,0xd5804700000LL,0xef8d5a00000LL,0x10cc82e00000LL,
- 0x12d940c00000LL,0x152605c00000LL,0x17baa2200000LL,0x1a9fd9c00000LL,0x1ddf82a00000LL,0x2184a5c00000LL,0x259ba5400000LL,
- 0x2a3265400000LL,0x2f587cc00000LL,0x351f69000000LL,0x3b9aca000000LL,0x42e0a4800000LL,0x4b09ad800000LL,
- 0x54319d000000LL,0x5e778d000000LL,0x69fe64000000LL,0x76ed49800000LL,0x85702c000000LL,0x95b858000000LL,
- 0xa7fd1c000000LL,0xbc7c87000000LL,0xd37c3a000000LL,0xed4a55000000LL,0x10a3e82000000LL,0x12abb1a000000LL,
- 0x14f2e7a000000LL,0x1781474000000LL,0x1a5f7f4000000LL,0x1d974de000000LL,0x2133a18000000LL
- };
-const fixed32 pow_10_to_yover16[] ICONST_ATTR=
-{
-0x10000,0x127a0,0x15562,0x18a39,0x1c73d,0x20db4,0x25f12,0x2bd09,0x3298b,0x3a6d9,0x4378b,0x4dea3,
-0x59f98,0x67e6b,0x77fbb,0x8a8de,0xa0000,0xb8c3e,0xd55d1,0xf6636,0x11c865,0x148906,0x17b6b8,0x1b625b,
-0x1f9f6e,0x248475,0x2a2b6e,0x30b25f,0x383bf0,0x40f02c,0x4afd4b,0x5698b0,0x640000,0x737a6b,0x855a26,
-0x99fe1f,0xb1d3f4,0xcd5a3e,0xed232b,0x111d78a,0x13c3a4e,0x16d2c94,0x1a5b24e,0x1e6f7b0,0x2325760,
-0x28961b4,0x2ede4ec,0x361f6dc,0x3e80000,0x482c830,0x5358580,0x603ed30,0x6f24788,0x8058670,0x9435fb0,
-0xab26b70,0xc5a4710,0xe43bdc0,0x1078f700,0x1305ace0,0x15f769c0,0x195dd100,0x1d4af120
-};
-
-const fixed32 pow_a_table[] =
-{
-0x1004,0x1008,0x100c,0x1010,0x1014,0x1018,0x101c,0x1021,0x1025,0x1029,0x102d,0x1031,0x1036,0x103a,
-0x103e,0x1043,0x1047,0x104b,0x1050,0x1054,0x1059,0x105d,0x1062,0x1066,0x106b,0x106f,0x1074,0x1078,
-0x107d,0x1082,0x1086,0x108b,0x1090,0x1095,0x1099,0x109e,0x10a3,0x10a8,0x10ad,0x10b2,0x10b7,0x10bc,
-0x10c1,0x10c6,0x10cb,0x10d0,0x10d5,0x10da,0x10df,0x10e5,0x10ea,0x10ef,0x10f5,0x10fa,0x10ff,0x1105,
-0x110a,0x1110,0x1115,0x111b,0x1120,0x1126,0x112c,0x1131,0x1137,0x113d,0x1143,0x1149,0x114f,0x1155,
-0x115a,0x1161,0x1167,0x116d,0x1173,0x1179,0x117f,0x1186,0x118c,0x1192,0x1199,0x119f,0x11a6,0x11ac,
-0x11b3,0x11b9,0x11c0,0x11c7,0x11ce,0x11d4,0x11db,0x11e2,0x11e9,0x11f0,0x11f8,0x11ff,0x1206,0x120d,
-0x1215,0x121c,0x1223,0x122b,0x1233,0x123a,0x1242,0x124a,0x1251,0x1259,0x1261,0x1269,0x1271,0x127a,
-0x1282,0x128a,0x1293,0x129b,0x12a4,0x12ac,0x12b5,0x12be,0x12c7,0x12d0,0x12d9,0x12e2,0x12eb,0x12f4,
-0x12fe,0x1307
-};
-
-const fixed64 lsp_pow_e_table[] =
-{
- 0xf333f9deLL, 0xf0518db9LL, 0x0LL, 0x7e656b4fLL, 0x7999fcefLL, 0xf828c6dcLL, 0x0LL,
- 0x3f32b5a7LL, 0x3cccfe78LL, 0xfc14636eLL, 0x0LL, 0x9f995ad4LL, 0x9e667f3cLL, 0xfe0a31b7LL,
- 0x0LL, 0x4fccad6aLL, 0x4f333f9eLL, 0x7f0518dcLL, 0x0LL, 0x27e656b5LL, 0x27999fcfLL,
- 0xbf828c6eLL, 0x0LL, 0x13f32b5aLL, 0x13cccfe7LL, 0xdfc14637LL, 0x0LL, 0x89f995adLL,
- 0x9e667f4LL, 0x6fe0a31bLL, 0x0LL, 0x44fccad7LL, 0x4f333faLL, 0x37f0518eLL, 0x0LL,
- 0xa27e656bLL, 0x827999fdLL, 0x1bf828c7LL, 0x0LL, 0xd13f32b6LL, 0x413cccfeLL, 0xdfc1463LL,
- 0x0LL, 0xe89f995bLL, 0xa09e667fLL, 0x6fe0a32LL, 0x0LL, 0x744fccadLL, 0x504f3340LL,
- 0x837f0519LL, 0x0LL, 0xba27e657LL, 0xa82799a0LL, 0xc1bf828cLL, 0x0LL, 0x5d13f32bLL,
- 0xd413ccd0LL, 0x60dfc146LL, 0x0LL, 0xae89f996LL, 0x6a09e668LL, 0x306fe0a3LL, 0x0LL,
- 0xd744fccbLL, 0xb504f334LL, 0x9837f052LL, 0x80000000LL, 0x6ba27e65LL, 0x5a82799aLL,
- 0x4c1bf829LL, 0x40000000LL, 0x35d13f33LL, 0x2d413ccdLL, 0x260dfc14LL, 0x20000000LL,
- 0x1ae89f99LL, 0x16a09e66LL, 0x1306fe0aLL, 0x10000000LL, 0xd744fcdLL, 0xb504f33LL,
- 0x9837f05LL, 0x8000000LL, 0x6ba27e6LL, 0x5a8279aLL, 0x4c1bf83LL, 0x4000000LL,
- 0x35d13f3LL, 0x2d413cdLL, 0x260dfc1LL, 0x2000000LL, 0x1ae89faLL, 0x16a09e6LL,
- 0x1306fe1LL, 0x1000000LL, 0xd744fdLL, 0xb504f3LL, 0x9837f0LL, 0x800000LL,
- 0x6ba27eLL, 0x5a827aLL, 0x4c1bf8LL, 0x400000LL, 0x35d13fLL, 0x2d413dLL,
- 0x260dfcLL, 0x200000LL, 0x1ae8a0LL, 0x16a09eLL, 0x1306feLL, 0x100000LL,
- 0xd7450LL, 0xb504fLL, 0x9837fLL, 0x80000LL, 0x6ba28LL, 0x5a828LL, 0x4c1c0LL,
- 0x40000LL, 0x35d14LL, 0x2d414LL, 0x260e0LL, 0x20000LL, 0x1ae8aLL, 0x16a0aLL,
- 0x13070LL, 0x10000LL, 0xd745LL, 0xb505LL, 0x9838LL, 0x8000LL, 0x6ba2LL,
- 0x5a82LL, 0x4c1cLL, 0x4000LL, 0x35d1LL, 0x2d41LL, 0x260eLL, 0x2000LL,
- 0x1ae9LL, 0x16a1LL, 0x1307LL, 0x1000LL, 0xd74LL, 0xb50LL, 0x983LL, 0x800LL,
- 0x6baLL, 0x5a8LL, 0x4c2LL, 0x400LL, 0x35dLL, 0x2d4LL, 0x261LL, 0x200LL, 0x1afLL,
- 0x16aLL, 0x130LL, 0x100LL, 0xd7LL, 0xb5LL, 0x98LL, 0x80LL, 0x6cLL, 0x5bLL,
- 0x4cLL, 0x40LL, 0x36LL, 0x2dLL, 0x26LL, 0x20LL, 0x1bLL, 0x17LL, 0x13LL,
- 0x10LL, 0xdLL, 0xbLL, 0xaLL, 0x8LL, 0x7LL, 0x6LL, 0x5LL, 0x4LL, 0x3LL,
- 0x3LL, 0x2LL, 0x2LL, 0x2LL, 0x1LL, 0x1LL, 0x1LL, 0x1LL, 0x1LL, 0x1LL,
- 0x1LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL,
- 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL,
- 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL,
- 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL,
- 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL,
- 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL, 0x0LL,
- 0x0LL, 0x0LL
-};
#include "wmadata.h" // PJJ
@@ -630,12 +140,11 @@
int fft_inits(FFTContext *s, int nbits, int inverse)
{
int i, j, m, n;
- fixed32 alpha, c1, s1, ct, st;
+ fixed32 c1, s1;
int s2;
s->nbits = nbits;
n = 1 << nbits;
-
//s->exptab = exparray[10-nbits]; //not needed
//s->exptab = av_malloc((n >> 1) * sizeof(FFTComplex));
@@ -666,9 +175,9 @@
fixed32 nfix = itofix32(n);
fixed32 res = fixdiv32(ifix,nfix); //this is really bad here since nfix can be as large as 1024 !
//also, make this a shift, since its a fucking power of two divide
- alpha = fixmul32(TWO_M_PI_F, res);
- ct = fixcos32(alpha); //need to correct alpha for 0->2pi scale
- st = fixsin32(alpha);// * s2;
+ //alpha = fixmul32(TWO_M_PI_F, res);
+ //ct = fixcos32(alpha); //need to correct alpha for 0->2pi scale
+ //st = fixsin32(alpha);// * s2;
s1 = fsincos(res<<16, &c1); //does sin and cos in one pass!
@@ -718,10 +227,6 @@
qim = (by - ay);\
}
-//this goddamn butterfly could overflow and i'd neve rknow it...
-//holy shit it was the fucking butterfly oh god this is the worst thing ever
-
-
int fft_calc_unscaled(FFTContext *s, FFTComplex *z)
{
@@ -1612,18 +1117,6 @@
init_coef_vlc(&s->coef_vlc[1], &s->run_table[1], &s->level_table[1],
&coef_vlcs[coef_vlc_table * 2 + 1], 1);
- //filehandle = rb->open("/log.txt", O_WRONLY|O_CREAT|O_APPEND);
-
-
-
- //rb->fdprintf(filehandle,"In init:\n\nsample rate %d\nbit_rate %d\n version %d\n", s->sample_rate, s->bit_rate, s->version );
- //rb->fdprintf(filehandle,"use_noise_coding %d \nframe_len %d\nframe_len_bits %d\n", s->use_noise_coding, s->frame_len, s->frame_len_bits);
- //rb->fdprintf(filehandle,"use_bit_reservoir %d\n use_variable_block_len %d\n use_exp_vlc %d\n",s->use_bit_reservoir, s->use_variable_block_len, s->use_exp_vlc);
- //rb->fdprintf(filehandle,"use_noise_coding %d\n byte_offset_bits %d\n use_exp_vlc %d\n",s->use_noise_coding, s->byte_offset_bits, s->use_exp_vlc);
- //rb->close(filehandle);
-
-
-
return 0;
}
diff --git a/apps/codecs/libwma/wmafixed.c b/apps/codecs/libwma/wmafixed.c
new file mode 100644
index 0000000..6cb3d3c
--- /dev/null
+++ b/apps/codecs/libwma/wmafixed.c
@@ -0,0 +1,350 @@
+//#include "asf.h"
+#include "wmadec.h"
+#include "wmafixed.h"
+#include <codecs.h>
+
+fixed64 IntTo64(int x){
+ fixed64 res = 0;
+ unsigned char *p = (unsigned char *)&res;
+
+#ifdef ROCKBOX_BIG_ENDIAN
+ p[5] = x & 0xff;
+ p[4] = (x & 0xff00)>>8;
+ p[3] = (x & 0xff0000)>>16;
+ p[2] = (x & 0xff000000)>>24;
+#else
+ p[2] = x & 0xff;
+ p[3] = (x & 0xff00)>>8;
+ p[4] = (x & 0xff0000)>>16;
+ p[5] = (x & 0xff000000)>>24;
+#endif
+ return res;
+}
+
+int IntFrom64(fixed64 x)
+{
+ int res = 0;
+ unsigned char *p = (unsigned char *)&x;
+
+#ifdef ROCKBOX_BIG_ENDIAN
+ res = p[5] | (p[4]<<8) | (p[3]<<16) | (p[2]<<24);
+#else
+ res = p[2] | (p[3]<<8) | (p[4]<<16) | (p[5]<<24);
+#endif
+ return res;
+}
+
+fixed32 Fixed32From64(fixed64 x)
+{
+ return x & 0xFFFFFFFF;
+}
+
+fixed64 Fixed32To64(fixed32 x)
+{
+ return (fixed64)x;
+}
+
+
+/*
+ Fixed precision multiply code.
+
+*/
+
+/*Sign-15.16 format */
+#ifdef CPU_ARM
+/* these are defines in wmafixed.h*/
+
+
+#elif defined(CPU_COLDFIRE)
+static inline int32_t fixmul32(int32_t x, int32_t y)
+{
+#if PRECISION != 16
+#warning Coldfire fixmul32() only works for PRECISION == 16
+#endif
+ int32_t t1;
+ asm (
+ "mac.l %[x], %[y], %%acc0 \n" /* multiply */
+ "mulu.l %[y], %[x] \n" /* get lower half, avoid emac stall */
+ "movclr.l %%acc0, %[t1] \n" /* get higher half */
+ "lsr.l #1, %[t1] \n"
+ "move.w %[t1], %[x] \n"
+ "swap %[x] \n"
+ : /* outputs */
+ [t1]"=&d"(t1),
+ [x] "+d" (x)
+ : /* inputs */
+ [y] "d" (y)
+ );
+ return x;
+}
+#else
+
+fixed32 fixmul32(fixed32 x, fixed32 y)
+{
+ fixed64 temp;
+ temp = x;
+ temp *= y;
+
+ temp >>= PRECISION;
+
+ return (fixed32)temp;
+}
+
+
+
+/*
+ Special fixmul32 that does a 16.16 x 1.31 multiply that returns a 16.16 value.
+ this is needed because the fft constants are all normalized to be less then 1
+ and can't fit into a 16 bit number without excessive rounding
+
+
+*/
+
+fixed32 fixmul32b(fixed32 x, fixed32 y)
+{
+ fixed64 temp;
+
+ temp = x;
+ temp *= y;
+
+ temp >>= 31; //16+31-16 = 31 bits
+
+ return (fixed32)temp;
+}
+
+#endif
+
+
+/*
+ Not performance senstitive code here
+
+*/
+
+
+fixed64 fixmul64byfixed(fixed64 x, fixed32 y)
+{
+
+ //return x * y;
+ return (x * y);
+ // return (fixed64) fixmul32(Fixed32From64(x),y);
+}
+
+
+fixed32 fixdiv32(fixed32 x, fixed32 y)
+{
+ fixed64 temp;
+
+ if(x == 0)
+ return 0;
+ if(y == 0)
+ return 0x7fffffff;
+ temp = x;
+ temp <<= PRECISION;
+ return (fixed32)(temp / y);
+}
+
+fixed64 fixdiv64(fixed64 x, fixed64 y)
+{
+ fixed64 temp;
+
+ if(x == 0)
+ return 0;
+ if(y == 0)
+ return 0x07ffffffffffffffLL;
+ temp = x;
+ temp <<= PRECISION64;
+ return (fixed64)(temp / y);
+}
+
+ fixed32 fixsqrt32(fixed32 x)
+{
+
+ unsigned long r = 0, s, v = (unsigned long)x;
+
+#define STEP(k) s = r + (1 << k * 2); r >>= 1; \
+ if (s <= v) { v -= s; r |= (1 << k * 2); }
+
+ STEP(15);
+ STEP(14);
+ STEP(13);
+ STEP(12);
+ STEP(11);
+ STEP(10);
+ STEP(9);
+ STEP(8);
+ STEP(7);
+ STEP(6);
+ STEP(5);
+ STEP(4);
+ STEP(3);
+ STEP(2);
+ STEP(1);
+ STEP(0);
+
+ return (fixed32)(r << (PRECISION / 2));
+}
+
+
+
+/* Inverse gain of circular cordic rotation in s0.31 format. */
+static const long cordic_circular_gain = 0xb2458939; /* 0.607252929 */
+
+/* Table of values of atan(2^-i) in 0.32 format fractions of pi where pi = 0xffffffff / 2 */
+static const unsigned long atan_table[] = {
+ 0x1fffffff, /* +0.785398163 (or pi/4) */
+ 0x12e4051d, /* +0.463647609 */
+ 0x09fb385b, /* +0.244978663 */
+ 0x051111d4, /* +0.124354995 */
+ 0x028b0d43, /* +0.062418810 */
+ 0x0145d7e1, /* +0.031239833 */
+ 0x00a2f61e, /* +0.015623729 */
+ 0x00517c55, /* +0.007812341 */
+ 0x0028be53, /* +0.003906230 */
+ 0x00145f2e, /* +0.001953123 */
+ 0x000a2f98, /* +0.000976562 */
+ 0x000517cc, /* +0.000488281 */
+ 0x00028be6, /* +0.000244141 */
+ 0x000145f3, /* +0.000122070 */
+ 0x0000a2f9, /* +0.000061035 */
+ 0x0000517c, /* +0.000030518 */
+ 0x000028be, /* +0.000015259 */
+ 0x0000145f, /* +0.000007629 */
+ 0x00000a2f, /* +0.000003815 */
+ 0x00000517, /* +0.000001907 */
+ 0x0000028b, /* +0.000000954 */
+ 0x00000145, /* +0.000000477 */
+ 0x000000a2, /* +0.000000238 */
+ 0x00000051, /* +0.000000119 */
+ 0x00000028, /* +0.000000060 */
+ 0x00000014, /* +0.000000030 */
+ 0x0000000a, /* +0.000000015 */
+ 0x00000005, /* +0.000000007 */
+ 0x00000002, /* +0.000000004 */
+ 0x00000001, /* +0.000000002 */
+ 0x00000000, /* +0.000000001 */
+ 0x00000000, /* +0.000000000 */
+};
+
+
+/*
+
+ Below here functions do not use standard fixed precision!
+*/
+
+
+/**
+ * Implements sin and cos using CORDIC rotation.
+ *
+ * @param phase has range from 0 to 0xffffffff, representing 0 and
+ * 2*pi respectively.
+ * @param cos return address for cos
+ * @return sin of phase, value is a signed value from LONG_MIN to LONG_MAX,
+ * representing -1 and 1 respectively.
+ *
+ * Gives at least 24 bits precision (last 2-8 bits or so are probably off)
+ */
+long fsincos(unsigned long phase, fixed32 *cos)
+{
+ int32_t x, x1, y, y1;
+ unsigned long z, z1;
+ int i;
+
+ /* Setup initial vector */
+ x = cordic_circular_gain;
+ y = 0;
+ z = phase;
+
+ /* The phase has to be somewhere between 0..pi for this to work right */
+ if (z < 0xffffffff / 4) {
+ /* z in first quadrant, z += pi/2 to correct */
+ x = -x;
+ z += 0xffffffff / 4;
+ } else if (z < 3 * (0xffffffff / 4)) {
+ /* z in third quadrant, z -= pi/2 to correct */
+ z -= 0xffffffff / 4;
+ } else {
+ /* z in fourth quadrant, z -= 3pi/2 to correct */
+ x = -x;
+ z -= 3 * (0xffffffff / 4);
+ }
+
+ /* Each iteration adds roughly 1-bit of extra precision */
+ for (i = 0; i < 31; i++) {
+ x1 = x >> i;
+ y1 = y >> i;
+ z1 = atan_table[i];
+
+ /* Decided which direction to rotate vector. Pivot point is pi/2 */
+ if (z >= 0xffffffff / 4) {
+ x -= y1;
+ y += x1;
+ z -= z1;
+ } else {
+ x += y1;
+ y -= x1;
+ z += z1;
+ }
+ }
+
+ if (cos)
+ *cos = x;
+
+ return y;
+}
+
+
+/*
+ Old trig functions. Still used in 1 place each.
+
+*/
+
+fixed32 fixsin32(fixed32 x)
+{
+
+ fixed64 x2, temp;
+ int sign = 1;
+
+ if(x < 0)
+ {
+ sign = -1;
+ x = -x;
+ }
+ while (x > 0x19220)
+ {
+ x -= M_PI_F;
+ sign = -sign;
+ }
+ if (x > 0x19220)
+ {
+ x = M_PI_F - x;
+ }
+ x2 = (fixed64)x * x;
+ x2 >>= PRECISION;
+ if(sign != 1)
+ {
+ x = -x;
+ }
+ /**
+ temp = ftofix32(-.0000000239f) * x2;
+ temp >>= PRECISION;
+ **/
+ temp = 0; // PJJ
+ //temp = (temp + 0x0) * x2; //MGG: this can't possibly do anything?
+ //temp >>= PRECISION;
+ temp = (temp - 0xd) * x2;
+ temp >>= PRECISION;
+ temp = (temp + 0x222) * x2;
+ temp >>= PRECISION;
+ temp = (temp - 0x2aab) * x2;
+ temp >>= PRECISION;
+ temp += 0x10000;
+ temp = temp * x;
+ temp >>= PRECISION;
+
+ return (fixed32)(temp);
+}
+
+fixed32 fixcos32(fixed32 x)
+{
+ return fixsin32(x - (M_PI_F>>1))*-1;
+}
diff --git a/apps/codecs/libwma/wmafixed.h b/apps/codecs/libwma/wmafixed.h
new file mode 100644
index 0000000..878601d
--- /dev/null
+++ b/apps/codecs/libwma/wmafixed.h
@@ -0,0 +1,92 @@
+/* fixed precision code. We use a combination of Sign 15.16 and Sign.31
+ precision here.
+
+ The WMA decoder does not always follow this convention, and occasionally
+ renormalizes values to other formats in order to maximize precision.
+ However, only the two precisions above are provided in this file.
+
+*/
+
+
+#define PRECISION 16
+#define PRECISION64 16
+
+
+#define fixtof64(x) (float)((float)(x) / (float)(1 << PRECISION64)) //does not work on int64_t!
+#define ftofix32(x) ((fixed32)((x) * (float)(1 << PRECISION) + ((x) < 0 ? -0.5 : 0.5)))
+#define itofix64(x) (IntTo64(x))
+#define itofix32(x) ((x) << PRECISION)
+#define fixtoi32(x) ((x) >> PRECISION)
+#define fixtoi64(x) (IntFrom64(x))
+
+
+/*fixed functions*/
+
+fixed64 IntTo64(int x);
+int IntFrom64(fixed64 x);
+fixed32 Fixed32From64(fixed64 x);
+fixed64 Fixed32To64(fixed32 x);
+fixed64 fixmul64byfixed(fixed64 x, fixed32 y);
+fixed32 fixdiv32(fixed32 x, fixed32 y);
+fixed64 fixdiv64(fixed64 x, fixed64 y);
+fixed32 fixsqrt32(fixed32 x);
+fixed32 fixsin32(fixed32 x);
+fixed32 fixcos32(fixed32 x);
+long fsincos(unsigned long phase, fixed32 *cos);
+
+
+
+
+
+#ifdef CPU_ARM
+
+/*
+ Fixed precision multiply code ASM.
+
+*/
+
+/*Sign-15.16 format */
+
+#define fixmul32(x, y) \
+ ({ int32_t __hi; \
+ uint32_t __lo; \
+ int32_t __result; \
+ asm ("smull %0, %1, %3, %4\n\t" \
+ "movs %0, %0, lsr %5\n\t" \
+ "adc %2, %0, %1, lsl %6" \
+ : "=&r" (__lo), "=&r" (__hi), "=r" (__result) \
+ : "%r" (x), "r" (y), \
+ "M" (PRECISION), "M" (32 - PRECISION) \
+ : "cc"); \
+ __result; \
+ })
+
+/*
+ Special fixmul32 that does a 16.16 x 1.31 multiply that returns a 16.16 value.
+ this is needed because the fft constants are all normalized to be less then 1
+ and can't fit into a 16 bit number without excessive rounding
+
+
+*/
+
+
+# define fixmul32b(x, y) \
+ ({ int32_t __hi; \
+ uint32_t __lo; \
+ int32_t __result; \
+ asm ("smull %0, %1, %3, %4\n\t" \
+ "movs %0, %0, lsr %5\n\t" \
+ "adc %2, %0, %1, lsl %6" \
+ : "=&r" (__lo), "=&r" (__hi), "=r" (__result) \
+ : "%r" (x), "r" (y), \
+ "M" (31), "M" (1) \
+ : "cc"); \
+ __result; \
+ })
+
+
+#else
+fixed32 fixmul32(fixed32 x, fixed32 y);
+fixed32 fixmul32b(fixed32 x, fixed32 y);
+#endif
+