changeset 33723:6c8743e5fa30

Audio format conversion from float to int is not checked for overflow. The float may be slightly off the [-1;1] range thus causing audible crackling noise. Add proper clipping using av_clip functions. Fixes bug 1919.
author iive
date Mon, 04 Jul 2011 22:24:52 +0000
parents 5e80ff193bc2
children c919fb3d2531
files libaf/af_format.c
diffstat 1 files changed, 14 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/libaf/af_format.c	Mon Jul 04 19:23:03 2011 +0000
+++ b/libaf/af_format.c	Mon Jul 04 22:24:52 2011 +0000
@@ -32,6 +32,8 @@
 #include "mpbswap.h"
 #include "libvo/fastmemcpy.h"
 
+#include "libavutil/avutil.h"
+
 /* Functions used by play to convert the input audio to the correct
    format */
 
@@ -474,23 +476,29 @@
 
 static void float2int(float* in, void* out, int len, int bps)
 {
+  float f;
   register int i;
   switch(bps){
   case(1):
     for(i=0;i<len;i++)
-      ((int8_t*)out)[i] = lrintf(127.0 * in[i]);
+      ((int8_t *)out)[i] = av_clip_int8(lrintf(128.0 * in[i]));
     break;
   case(2):
     for(i=0;i<len;i++)
-      ((int16_t*)out)[i] = lrintf(32767.0 * in[i]);
+      ((int16_t*)out)[i] = av_clip_int16(lrintf(32768.0 * in[i]));
     break;
   case(3):
-    for(i=0;i<len;i++)
-      store24bit(out, i, lrintf(2147483647.0 * in[i]));
+    for(i=0;i<len;i++){
+      f = ldexp(in[i], 23);
+      store24bit(out, i,   av_clip(lrintf(f), -1*(1<<23), (1<<23)-1) << 8);
+    }
     break;
   case(4):
-    for(i=0;i<len;i++)
-      ((int32_t*)out)[i] = lrintf(2147483647.0 * in[i]);
+    for(i=0;i<len;i++){
+      f = ldexp(in[i], 23);
+      //The mantissa is only 23 bit, that's all the precision there is.
+      ((int32_t*)out)[i] = av_clip(lrintf(f), -1*(1<<23), (1<<23)-1) << 8;
+    }
     break;
   }
 }