changeset 9179:4172c9ef331a libavcodec

AAC: IEEE-754 type punning for 16-bit floating point rounding.
author alexc
date Mon, 16 Mar 2009 16:11:27 +0000
parents c1e6aaea75f2
children 6fdc4c276ef1
files aac.c
diffstat 1 files changed, 14 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/aac.c	Mon Mar 16 12:47:43 2009 +0000
+++ b/aac.c	Mon Mar 16 16:11:27 2009 +0000
@@ -93,6 +93,8 @@
 #include <math.h>
 #include <string.h>
 
+union float754 { float f; uint32_t i; };
+
 static VLC vlc_scalefactors;
 static VLC vlc_spectral[11];
 
@@ -930,24 +932,24 @@
 }
 
 static av_always_inline float flt16_round(float pf) {
-    int exp;
-    pf = frexpf(pf, &exp);
-    pf = ldexpf(roundf(ldexpf(pf, 8)), exp-8);
-    return pf;
+    union float754 tmp;
+    tmp.f = pf;
+    tmp.i = (tmp.i + 0x00008000U) & 0xFFFF0000U;
+    return tmp.f;
 }
 
 static av_always_inline float flt16_even(float pf) {
-    int exp;
-    pf = frexpf(pf, &exp);
-    pf = ldexpf(rintf(ldexpf(pf, 8)), exp-8);
-    return pf;
+    union float754 tmp;
+    tmp.f = pf;
+    tmp.i = (tmp.i + 0x00007FFFU + (tmp.i & 0x00010000U>>16)) & 0xFFFF0000U;
+    return tmp.f;
 }
 
 static av_always_inline float flt16_trunc(float pf) {
-    int exp;
-    pf = frexpf(pf, &exp);
-    pf = ldexpf(truncf(ldexpf(pf, 8)), exp-8);
-    return pf;
+    union float754 pun;
+    pun.f = pf;
+    pun.i &= 0xFFFF0000U;
+    return pun.f;
 }
 
 static void predict(AACContext * ac, PredictorState * ps, float* coef, int output_enable) {