From a16d0f389e949881c9d12ecb7942c23d4a9dcc78 Mon Sep 17 00:00:00 2001 From: Michael Giacomelli Date: Wed, 4 Jul 2007 17:15:09 +0000 Subject: 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 --- apps/codecs/libwma/SOURCES | 1 + apps/codecs/libwma/wmadata.h | 108 ++++++++- apps/codecs/libwma/wmadeci.c | 521 +----------------------------------------- apps/codecs/libwma/wmafixed.c | 350 ++++++++++++++++++++++++++++ apps/codecs/libwma/wmafixed.h | 92 ++++++++ 5 files changed, 551 insertions(+), 521 deletions(-) create mode 100644 apps/codecs/libwma/wmafixed.c create mode 100644 apps/codecs/libwma/wmafixed.h (limited to 'apps') diff --git a/apps/codecs/libwma/SOURCES b/apps/codecs/libwma/SOURCES index 3351bb27b8..190e3a7ba3 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 ee17207102..ae4844e152 100644 --- a/apps/codecs/libwma/wmadata.h +++ b/apps/codecs/libwma/wmadata.h @@ -1389,24 +1389,118 @@ static const uint16_t levels5[40] = { 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 c064bf0e04..6647ed4b40 100644 --- a/apps/codecs/libwma/wmadeci.c +++ b/apps/codecs/libwma/wmadeci.c @@ -26,409 +26,9 @@ #include #include "asf.h" #include "wmadec.h" +#include "wmafixed.c" -/* 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! - - -//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 vlcbuf1[6144][2]; 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 @@ const fixed64 lsp_pow_e_table[] = 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 @@ int fft_inits(FFTContext *s, int nbits, int inverse) 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 @@ int fft_inits(FFTContext *s, int nbits, int inverse) 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 @@ int wma_decode_init(WMADecodeContext* s, asf_waveformatex_t *wfx) 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 0000000000..6cb3d3c4a6 --- /dev/null +++ b/apps/codecs/libwma/wmafixed.c @@ -0,0 +1,350 @@ +//#include "asf.h" +#include "wmadec.h" +#include "wmafixed.h" +#include + +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 0000000000..878601d799 --- /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 + -- cgit v1.2.3