summaryrefslogtreecommitdiff
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
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
-rw-r--r--apps/codecs/libfaad/common.c140
-rw-r--r--apps/codecs/libfaad/common.h4
-rw-r--r--apps/codecs/libfaad/fixed.h25
3 files changed, 105 insertions, 64 deletions
diff --git a/apps/codecs/libfaad/common.c b/apps/codecs/libfaad/common.c
index e8340d318d..025c8f8c5b 100644
--- a/apps/codecs/libfaad/common.c
+++ b/apps/codecs/libfaad/common.c
@@ -248,33 +248,78 @@ uint32_t random_int(void)
248#define TABLE_BITS 6 248#define TABLE_BITS 6
249/* just take the maximum number of bits for interpolation */ 249/* just take the maximum number of bits for interpolation */
250#define INTERP_BITS (REAL_BITS-TABLE_BITS) 250#define INTERP_BITS (REAL_BITS-TABLE_BITS)
251 251/* precision of values in pow2_tab */
252static const real_t pow2_tab[] = { 252#define POWTBL_BITS (31-(INTERP_BITS))
253 REAL_CONST(1.000000000000000), REAL_CONST(1.010889286051701), REAL_CONST(1.021897148654117), 253#define POWTBL_PRECIS (1U<<(POWTBL_BITS))
254 REAL_CONST(1.033024879021228), REAL_CONST(1.044273782427414), REAL_CONST(1.055645178360557), 254static const uint32_t pow2_tab[] ICONST_ATTR = {
255 REAL_CONST(1.067140400676824), REAL_CONST(1.078760797757120), REAL_CONST(1.090507732665258), 255 UFIX_CONST(1.000000000000000,POWTBL_PRECIS),
256 REAL_CONST(1.102382583307841), REAL_CONST(1.114386742595892), REAL_CONST(1.126521618608242), 256 UFIX_CONST(1.010889286051701,POWTBL_PRECIS),
257 REAL_CONST(1.138788634756692), REAL_CONST(1.151189229952983), REAL_CONST(1.163724858777578), 257 UFIX_CONST(1.021897148654117,POWTBL_PRECIS),
258 REAL_CONST(1.176396991650281), REAL_CONST(1.189207115002721), REAL_CONST(1.202156731452703), 258 UFIX_CONST(1.033024879021228,POWTBL_PRECIS),
259 REAL_CONST(1.215247359980469), REAL_CONST(1.228480536106870), REAL_CONST(1.241857812073484), 259 UFIX_CONST(1.044273782427414,POWTBL_PRECIS),
260 REAL_CONST(1.255380757024691), REAL_CONST(1.269050957191733), REAL_CONST(1.282870016078778), 260 UFIX_CONST(1.055645178360557,POWTBL_PRECIS),
261 REAL_CONST(1.296839554651010), REAL_CONST(1.310961211524764), REAL_CONST(1.325236643159741), 261 UFIX_CONST(1.067140400676824,POWTBL_PRECIS),
262 REAL_CONST(1.339667524053303), REAL_CONST(1.354255546936893), REAL_CONST(1.369002422974591), 262 UFIX_CONST(1.078760797757120,POWTBL_PRECIS),
263 REAL_CONST(1.383909881963832), REAL_CONST(1.398979672538311), REAL_CONST(1.414213562373095), 263 UFIX_CONST(1.090507732665258,POWTBL_PRECIS),
264 REAL_CONST(1.429613338391970), REAL_CONST(1.445180806977047), REAL_CONST(1.460917794180647), 264 UFIX_CONST(1.102382583307841,POWTBL_PRECIS),
265 REAL_CONST(1.476826145939499), REAL_CONST(1.492907728291265), REAL_CONST(1.509164427593423), 265 UFIX_CONST(1.114386742595892,POWTBL_PRECIS),
266 REAL_CONST(1.525598150744538), REAL_CONST(1.542210825407941), REAL_CONST(1.559004400237837), 266 UFIX_CONST(1.126521618608242,POWTBL_PRECIS),
267 REAL_CONST(1.575980845107887), REAL_CONST(1.593142151342267), REAL_CONST(1.610490331949254), 267 UFIX_CONST(1.138788634756692,POWTBL_PRECIS),
268 REAL_CONST(1.628027421857348), REAL_CONST(1.645755478153965), REAL_CONST(1.663676580326736), 268 UFIX_CONST(1.151189229952983,POWTBL_PRECIS),
269 REAL_CONST(1.681792830507429), REAL_CONST(1.700106353718524), REAL_CONST(1.718619298122478), 269 UFIX_CONST(1.163724858777578,POWTBL_PRECIS),
270 REAL_CONST(1.737333835273706), REAL_CONST(1.756252160373300), REAL_CONST(1.775376492526521), 270 UFIX_CONST(1.176396991650281,POWTBL_PRECIS),
271 REAL_CONST(1.794709075003107), REAL_CONST(1.814252175500399), REAL_CONST(1.834008086409342), 271 UFIX_CONST(1.189207115002721,POWTBL_PRECIS),
272 REAL_CONST(1.853979125083386), REAL_CONST(1.874167634110300), REAL_CONST(1.894575981586966), 272 UFIX_CONST(1.202156731452703,POWTBL_PRECIS),
273 REAL_CONST(1.915206561397147), REAL_CONST(1.936061793492294), REAL_CONST(1.957144124175400), 273 UFIX_CONST(1.215247359980469,POWTBL_PRECIS),
274 REAL_CONST(1.978456026387951), REAL_CONST(2.000000000000000) 274 UFIX_CONST(1.228480536106870,POWTBL_PRECIS),
275 UFIX_CONST(1.241857812073484,POWTBL_PRECIS),
276 UFIX_CONST(1.255380757024691,POWTBL_PRECIS),
277 UFIX_CONST(1.269050957191733,POWTBL_PRECIS),
278 UFIX_CONST(1.282870016078778,POWTBL_PRECIS),
279 UFIX_CONST(1.296839554651010,POWTBL_PRECIS),
280 UFIX_CONST(1.310961211524764,POWTBL_PRECIS),
281 UFIX_CONST(1.325236643159741,POWTBL_PRECIS),
282 UFIX_CONST(1.339667524053303,POWTBL_PRECIS),
283 UFIX_CONST(1.354255546936893,POWTBL_PRECIS),
284 UFIX_CONST(1.369002422974591,POWTBL_PRECIS),
285 UFIX_CONST(1.383909881963832,POWTBL_PRECIS),
286 UFIX_CONST(1.398979672538311,POWTBL_PRECIS),
287 UFIX_CONST(1.414213562373095,POWTBL_PRECIS),
288 UFIX_CONST(1.429613338391970,POWTBL_PRECIS),
289 UFIX_CONST(1.445180806977047,POWTBL_PRECIS),
290 UFIX_CONST(1.460917794180647,POWTBL_PRECIS),
291 UFIX_CONST(1.476826145939499,POWTBL_PRECIS),
292 UFIX_CONST(1.492907728291265,POWTBL_PRECIS),
293 UFIX_CONST(1.509164427593423,POWTBL_PRECIS),
294 UFIX_CONST(1.525598150744538,POWTBL_PRECIS),
295 UFIX_CONST(1.542210825407941,POWTBL_PRECIS),
296 UFIX_CONST(1.559004400237837,POWTBL_PRECIS),
297 UFIX_CONST(1.575980845107887,POWTBL_PRECIS),
298 UFIX_CONST(1.593142151342267,POWTBL_PRECIS),
299 UFIX_CONST(1.610490331949254,POWTBL_PRECIS),
300 UFIX_CONST(1.628027421857348,POWTBL_PRECIS),
301 UFIX_CONST(1.645755478153965,POWTBL_PRECIS),
302 UFIX_CONST(1.663676580326736,POWTBL_PRECIS),
303 UFIX_CONST(1.681792830507429,POWTBL_PRECIS),
304 UFIX_CONST(1.700106353718524,POWTBL_PRECIS),
305 UFIX_CONST(1.718619298122478,POWTBL_PRECIS),
306 UFIX_CONST(1.737333835273706,POWTBL_PRECIS),
307 UFIX_CONST(1.756252160373300,POWTBL_PRECIS),
308 UFIX_CONST(1.775376492526521,POWTBL_PRECIS),
309 UFIX_CONST(1.794709075003107,POWTBL_PRECIS),
310 UFIX_CONST(1.814252175500399,POWTBL_PRECIS),
311 UFIX_CONST(1.834008086409342,POWTBL_PRECIS),
312 UFIX_CONST(1.853979125083386,POWTBL_PRECIS),
313 UFIX_CONST(1.874167634110300,POWTBL_PRECIS),
314 UFIX_CONST(1.894575981586966,POWTBL_PRECIS),
315 UFIX_CONST(1.915206561397147,POWTBL_PRECIS),
316 UFIX_CONST(1.936061793492294,POWTBL_PRECIS),
317 UFIX_CONST(1.957144124175400,POWTBL_PRECIS),
318 UFIX_CONST(1.978456026387951,POWTBL_PRECIS),
319 UFIX_CONST(2.000000000000000,POWTBL_PRECIS)
275}; 320};
276 321
277static const real_t log2_tab[] = { 322static const real_t log2_tab[] ICONST_ATTR = {
278 REAL_CONST(0.000000000000000), REAL_CONST(0.022367813028455), REAL_CONST(0.044394119358453), 323 REAL_CONST(0.000000000000000), REAL_CONST(0.022367813028455), REAL_CONST(0.044394119358453),
279 REAL_CONST(0.066089190457772), REAL_CONST(0.087462841250339), REAL_CONST(0.108524456778169), 324 REAL_CONST(0.066089190457772), REAL_CONST(0.087462841250339), REAL_CONST(0.108524456778169),
280 REAL_CONST(0.129283016944966), REAL_CONST(0.149747119504682), REAL_CONST(0.169925001442312), 325 REAL_CONST(0.129283016944966), REAL_CONST(0.149747119504682), REAL_CONST(0.169925001442312),
@@ -299,12 +344,12 @@ static const real_t log2_tab[] = {
299 REAL_CONST(0.988684686772166), REAL_CONST(1.000000000000000) 344 REAL_CONST(0.988684686772166), REAL_CONST(1.000000000000000)
300}; 345};
301 346
302real_t pow2_fix(real_t val) 347uint32_t pow2_fix(real_t val)
303{ 348{
304 uint32_t x1, x2; 349 uint32_t x1, x2;
305 uint32_t errcorr; 350 uint32_t errcorr;
306 uint32_t index_frac; 351 uint32_t index_frac;
307 real_t retval; 352 uint32_t retval;
308 int32_t whole = (val >> REAL_BITS); 353 int32_t whole = (val >> REAL_BITS);
309 354
310 /* rest = [0..1] */ 355 /* rest = [0..1] */
@@ -313,41 +358,27 @@ real_t pow2_fix(real_t val)
313 /* index into pow2_tab */ 358 /* index into pow2_tab */
314 int32_t index = rest >> (REAL_BITS-TABLE_BITS); 359 int32_t index = rest >> (REAL_BITS-TABLE_BITS);
315 360
316
317 if (val == 0)
318 return (1<<REAL_BITS);
319
320 /* leave INTERP_BITS bits */ 361 /* leave INTERP_BITS bits */
321 index_frac = rest >> (REAL_BITS-TABLE_BITS-INTERP_BITS); 362 index_frac = rest >> (REAL_BITS-TABLE_BITS-INTERP_BITS);
322 index_frac = index_frac & ((1<<INTERP_BITS)-1); 363 index_frac = index_frac & ((1<<INTERP_BITS)-1);
323 364
324 if (whole > 0)
325 {
326 retval = 1 << whole;
327 } else {
328 retval = REAL_CONST(1) >> -whole;
329 }
330
331 x1 = pow2_tab[index & ((1<<TABLE_BITS)-1)]; 365 x1 = pow2_tab[index & ((1<<TABLE_BITS)-1)];
332 x2 = pow2_tab[(index & ((1<<TABLE_BITS)-1)) + 1]; 366 x2 = pow2_tab[(index & ((1<<TABLE_BITS)-1)) + 1];
333 errcorr = ( (index_frac*(x2-x1))) >> INTERP_BITS; 367 errcorr = ( (index_frac*(x2-x1)));
334 368
335 if (whole > 0) 369 retval = errcorr + (x1<<INTERP_BITS);
336 { 370
337 retval = retval * (errcorr + x1); 371 retval = DESCALE_SHIFT(retval, whole, POWTBL_BITS + INTERP_BITS - REAL_BITS);
338 } else {
339 retval = MUL_R(retval, (errcorr + x1));
340 }
341 372
342 return retval; 373 return retval;
343} 374}
344 375
345int32_t pow2_int(real_t val) 376uint32_t pow2_int(real_t val)
346{ 377{
347 uint32_t x1, x2; 378 uint32_t x1, x2;
348 uint32_t errcorr; 379 uint32_t errcorr;
349 uint32_t index_frac; 380 uint32_t index_frac;
350 real_t retval; 381 uint32_t retval;
351 int32_t whole = (val >> REAL_BITS); 382 int32_t whole = (val >> REAL_BITS);
352 383
353 /* rest = [0..1] */ 384 /* rest = [0..1] */
@@ -356,24 +387,17 @@ int32_t pow2_int(real_t val)
356 /* index into pow2_tab */ 387 /* index into pow2_tab */
357 int32_t index = rest >> (REAL_BITS-TABLE_BITS); 388 int32_t index = rest >> (REAL_BITS-TABLE_BITS);
358 389
359
360 if (val == 0)
361 return 1;
362
363 /* leave INTERP_BITS bits */ 390 /* leave INTERP_BITS bits */
364 index_frac = rest >> (REAL_BITS-TABLE_BITS-INTERP_BITS); 391 index_frac = rest >> (REAL_BITS-TABLE_BITS-INTERP_BITS);
365 index_frac = index_frac & ((1<<INTERP_BITS)-1); 392 index_frac = index_frac & ((1<<INTERP_BITS)-1);
366 393
367 if (whole > 0)
368 retval = 1 << whole;
369 else
370 retval = 0;
371
372 x1 = pow2_tab[index & ((1<<TABLE_BITS)-1)]; 394 x1 = pow2_tab[index & ((1<<TABLE_BITS)-1)];
373 x2 = pow2_tab[(index & ((1<<TABLE_BITS)-1)) + 1]; 395 x2 = pow2_tab[(index & ((1<<TABLE_BITS)-1)) + 1];
374 errcorr = ( (index_frac*(x2-x1))) >> INTERP_BITS; 396 errcorr = ( (index_frac*(x2-x1)));
397
398 retval = errcorr + (x1<<INTERP_BITS);
375 399
376 retval = MUL_R(retval, (errcorr + x1)); 400 retval = DESCALE_SHIFT(retval, whole, POWTBL_BITS + INTERP_BITS);
377 401
378 return retval; 402 return retval;
379} 403}
diff --git a/apps/codecs/libfaad/common.h b/apps/codecs/libfaad/common.h
index fe0d02b228..658e92f23f 100644
--- a/apps/codecs/libfaad/common.h
+++ b/apps/codecs/libfaad/common.h
@@ -404,8 +404,8 @@ uint32_t random_int(void);
404#define LOG2_MIN_INF REAL_CONST(-10000) 404#define LOG2_MIN_INF REAL_CONST(-10000)
405int32_t log2_int(uint32_t val); 405int32_t log2_int(uint32_t val);
406int32_t log2_fix(uint32_t val); 406int32_t log2_fix(uint32_t val);
407int32_t pow2_int(real_t val); 407uint32_t pow2_int(real_t val);
408real_t pow2_fix(real_t val); 408uint32_t pow2_fix(real_t val);
409#endif 409#endif
410uint8_t get_sr_index(const uint32_t samplerate); 410uint8_t get_sr_index(const uint32_t samplerate);
411uint8_t max_pred_sfb(const uint8_t sr_index); 411uint8_t max_pred_sfb(const uint8_t sr_index);
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,