summaryrefslogtreecommitdiff
path: root/apps/codecs/libfaad/fixed.h
diff options
context:
space:
mode:
authorAndrew Mahone <andrew.mahone@gmail.com>2009-12-13 03:45:40 +0000
committerAndrew Mahone <andrew.mahone@gmail.com>2009-12-13 03:45:40 +0000
commitaf5bad46d883731728b9e4c797cae015e17f11f3 (patch)
tree21a6fd00a8c1c90dcb1501b27d8253ccea162e7c /apps/codecs/libfaad/fixed.h
parent7668e3fe51ed0d2bb00ba5580b45e289ae0e836b (diff)
downloadrockbox-af5bad46d883731728b9e4c797cae015e17f11f3.tar.gz
rockbox-af5bad46d883731728b9e4c797cae015e17f11f3.zip
Libfaad pow2/log2 improvements:
Correct pow2_* to calculate correct output for input < 0.0 or between 0.0 and 1.0 instead of returning 0. This will change output, but the float version of this codec uses pow(2.0,x) in place of these functions, so this behavior was probably a bug Replace 64-bit multiply in pow2_* with left or right shift by whole part of input, rounding if shifting right. An ARM-specific optimized version is provided as a C inline function, other targets use a C macro. Increase constant size of table for pow2 to improve accuracy, also avoid early truncation in linear interpolation of result. Move constant tables for pow2 and log2 to iram. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23967 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs/libfaad/fixed.h')
-rw-r--r--apps/codecs/libfaad/fixed.h25
1 files changed, 21 insertions, 4 deletions
diff --git a/apps/codecs/libfaad/fixed.h b/apps/codecs/libfaad/fixed.h
index da895e81bc..9781a846f7 100644
--- a/apps/codecs/libfaad/fixed.h
+++ b/apps/codecs/libfaad/fixed.h
@@ -49,10 +49,11 @@ extern "C" {
49 49
50typedef int32_t real_t; 50typedef int32_t real_t;
51 51
52 52#define UFIX_CONST(A,PRECISION) ((uint32_t)((A)*(PRECISION)+0.5))
53#define REAL_CONST(A) (((A) >= 0) ? ((real_t)((A)*(REAL_PRECISION)+0.5)) : ((real_t)((A)*(REAL_PRECISION)-0.5))) 53#define FIX_CONST(A,PRECISION) (((A) >= 0) ? ((real_t)((A)*(PRECISION)+0.5)) : ((real_t)((A)*(PRECISION)-0.5)))
54#define COEF_CONST(A) (((A) >= 0) ? ((real_t)((A)*(COEF_PRECISION)+0.5)) : ((real_t)((A)*(COEF_PRECISION)-0.5))) 54#define REAL_CONST(A) FIX_CONST((A),(REAL_PRECISION))
55#define FRAC_CONST(A) (((A) == 1.00) ? ((real_t)FRAC_MAX) : (((A) >= 0) ? ((real_t)((A)*(FRAC_PRECISION)+0.5)) : ((real_t)((A)*(FRAC_PRECISION)-0.5)))) 55#define COEF_CONST(A) FIX_CONST((A),(COEF_PRECISION))
56#define FRAC_CONST(A) (((A) == 1.00) ? ((real_t)FRAC_MAX) : FIX_CONST((A),(FRAC_PRECISION)))
56//#define FRAC_CONST(A) (((A) >= 0) ? ((real_t)((A)*(FRAC_PRECISION)+0.5)) : ((real_t)((A)*(FRAC_PRECISION)-0.5))) 57//#define FRAC_CONST(A) (((A) >= 0) ? ((real_t)((A)*(FRAC_PRECISION)+0.5)) : ((real_t)((A)*(FRAC_PRECISION)-0.5)))
57 58
58#define Q2_BITS 22 59#define Q2_BITS 22
@@ -128,6 +129,8 @@ static INLINE void ComplexMult(real_t *y1, real_t *y2,
128 #define MUL_Q2(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (Q2_BITS-1))) >> Q2_BITS) 129 #define MUL_Q2(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (Q2_BITS-1))) >> Q2_BITS)
129 #define MUL_SHIFT6(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (6-1))) >> 6) 130 #define MUL_SHIFT6(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (6-1))) >> 6)
130 #define MUL_SHIFT23(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (23-1))) >> 23) 131 #define MUL_SHIFT23(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (23-1))) >> 23)
132 #define DESCALE(A,S) ((S)>0?(((A)>>((S)-1))+1)>>1:(A)<<-(S))
133 #define DESCALE_SHIFT(A,SH,SC) DESCALE((A),(SC)-(SH)
131 134
132#elif defined(__GNUC__) && defined (__arm__) 135#elif defined(__GNUC__) && defined (__arm__)
133 136
@@ -205,6 +208,18 @@ static INLINE void ComplexMult(real_t *y1, real_t *y2,
205 *y2 = yt2 << (FRAC_SIZE-FRAC_BITS); 208 *y2 = yt2 << (FRAC_SIZE-FRAC_BITS);
206} 209}
207 210
211static inline real_t DESCALE_SHIFT(unsigned val, int shift, int scale)
212{
213 unsigned out;
214 if ((out = val >> (scale - shift - 1)))
215 {
216 out++;
217 out >>= 1;
218 } else
219 out = val << (shift - scale);
220 return out;
221}
222
208#else 223#else
209 224
210 /* multiply with real shift */ 225 /* multiply with real shift */
@@ -225,6 +240,8 @@ static INLINE void ComplexMult(real_t *y1, real_t *y2,
225 #define MUL_Q2(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (Q2_BITS-1))) >> Q2_BITS) 240 #define MUL_Q2(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (Q2_BITS-1))) >> Q2_BITS)
226 #define MUL_SHIFT6(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (6-1))) >> 6) 241 #define MUL_SHIFT6(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (6-1))) >> 6)
227 #define MUL_SHIFT23(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (23-1))) >> 23) 242 #define MUL_SHIFT23(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (23-1))) >> 23)
243 #define DESCALE(A,S) ((S)>0?(((A)>>((S)-1))+1)>>1:(A)<<-(S))
244 #define DESCALE_SHIFT(A,SH,SC) DESCALE((A),(SC)-(SH)
228 245
229/* Complex multiplication */ 246/* Complex multiplication */
230static INLINE void ComplexMult(real_t *y1, real_t *y2, 247static INLINE void ComplexMult(real_t *y1, real_t *y2,