From f6f2822caad3cda4e8512a50ee0b4607257e7d06 Mon Sep 17 00:00:00 2001 From: Buschel Date: Mon, 15 Feb 2010 13:00:02 +0000 Subject: [PATCH] Work on atrac Joint Stereo mode. Correct calculation in getChannelWeights(), introduce lookup table and remove obsolete code. Optimize interpolation macro. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@24665 a1c6a512-1295-4272-9138-f99709370657 --- apps/codecs/libatrac/atrac3.c | 31 +++++++++++++++++------- apps/codecs/libatrac/atrac3data_fixed.h | 12 +++++++++ apps/codecs/libatrac/fixp_math.h | 43 --------------------------------- 3 files changed, 34 insertions(+), 52 deletions(-) diff --git a/apps/codecs/libatrac/atrac3.c b/apps/codecs/libatrac/atrac3.c index 467f42f16..5ff3a8587 100644 --- a/apps/codecs/libatrac/atrac3.c +++ b/apps/codecs/libatrac/atrac3.c @@ -628,8 +628,21 @@ static int addTonalComponents (int32_t *pSpectrum, int numComponents, tonal_comp return lastPos; } - -#define INTERPOLATE(old,new,nsample) ((old*ONE_16) + fixmul16(((nsample*ONE_16)>>3), (((new) - (old))*ONE_16))) +/** + * Linear equidistant interpolation between two points x and y. 7 interpolation + * points can be calculated. Result is scaled by <<16. + * Result for s=0 is x*ONE_16 + * Result for s=8 is y*ONE_16 + * + * @param x first input point + * @param y second input point + * @param s index of interpolation point (0..7) + */ + +/* +#define INTERPOLATE(x, y, s) ((x*ONE_16) + fixmul16(((s*ONE_16)>>3), (((x) - (y))*ONE_16))) +*/ +#define INTERPOLATE(x, y, s) ((((x)<<3) + s*((y)-(x)))<<13) static void reverseMatrixing(int32_t *su1, int32_t *su2, int *pPrevCode, int *pCurrCode) { @@ -695,14 +708,14 @@ static void reverseMatrixing(int32_t *su1, int32_t *su2, int *pPrevCode, int *pC } static void getChannelWeights (int indx, int flag, int32_t ch[2]){ - if (indx == 7) { - ch[0] = ONE_16; - ch[1] = ONE_16; + /* Read channel weights from table */ + if (flag) { + /* Swap channel weights */ + ch[1] = channelWeights0[indx&7]; + ch[0] = channelWeights1[indx&7]; } else { - ch[0] = fixdiv16(((indx & 7)*ONE_16), 7*ONE_16); - ch[1] = fastSqrt((ONE_16 << 1) - fixmul16(ch[0], ch[0])); - if(flag) - FFSWAP(int32_t, ch[0], ch[1]); + ch[0] = channelWeights0[indx&7]; + ch[1] = channelWeights1[indx&7]; } } diff --git a/apps/codecs/libatrac/atrac3data_fixed.h b/apps/codecs/libatrac/atrac3data_fixed.h index f0924a519..d73ded35f 100644 --- a/apps/codecs/libatrac/atrac3data_fixed.h +++ b/apps/codecs/libatrac/atrac3data_fixed.h @@ -80,3 +80,15 @@ static const int32_t matrixCoeffs_fix[8] ICONST_ATTR = { 0x00000000, 0x00000000, 0x00010000, 0x00010000, }; +/* channelWeights0[i] = ONE_16 * ((i & 7)/7) */ +static const int32_t channelWeights0[8] ICONST_ATTR = { + 0x00000000, 0x00002492, 0x00004925, 0x00006DB7, + 0x00009249, 0x0000B6DB, 0x0000DB6D, 0x00010000, +}; + +/* channelWeights1[i] = ONE_16 * sqrt(2-channelWeights0^2) */ +static const int32_t channelWeights1[8] ICONST_ATTR = { + 0x00016A0A, 0x00016830, 0x00016293, 0x00015904, + 0x00014B2B, 0x00013877, 0x00011FF7, 0x00010000, +}; + diff --git a/apps/codecs/libatrac/fixp_math.h b/apps/codecs/libatrac/fixp_math.h index 5174cc7cc..29d47a9e5 100644 --- a/apps/codecs/libatrac/fixp_math.h +++ b/apps/codecs/libatrac/fixp_math.h @@ -91,46 +91,3 @@ return (int32_t)temp; } #endif - -static inline int32_t fixdiv16(int32_t x, int32_t y) -{ - int64_t temp; - temp = x << 16; - temp /= y; - - return (int32_t)temp; -} - -/* - * Fast integer square root adapted from algorithm, - * Martin Guy @ UKC, June 1985. - * Originally from a book on programming abaci by Mr C. Woo. - * This is taken from : - * http://wiki.forum.nokia.com/index.php/How_to_use_fixed_point_maths#How_to_get_square_root_for_integers - * with a added shift up of the result by 8 bits to return result in 16.16 fixed-point representation. - */ -static inline int32_t fastSqrt(int32_t n) -{ - /* - * Logically, these are unsigned. - * We need the sign bit to test - * whether (op - res - one) underflowed. - */ - int32_t op, res, one; - op = n; - res = 0; - /* "one" starts at the highest power of four <= than the argument. */ - one = 1 << 30; /* second-to-top bit set */ - while (one > op) one >>= 2; - while (one != 0) - { - if (op >= res + one) - { - op = op - (res + one); - res = res + (one<<1); - } - res >>= 1; - one >>= 2; - } - return(res << 8); -} -- 2.11.4.GIT