Mercurial > mplayer.hg
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; } }