From db36090a987c50bc6dff501f7ad804175181cbb1 Mon Sep 17 00:00:00 2001 From: dmitrykos Date: Sun, 26 Dec 2010 15:58:30 +0000 Subject: [PATCH] corrected Int24_To_Int16_Dither and implemented Int24_To_Int8_Dither, Float32_To_Int24 to use all 'double' types for optimal code generation (not mixing double with floats) --- src/common/pa_converters.c | 72 ++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 30 deletions(-) diff --git a/src/common/pa_converters.c b/src/common/pa_converters.c index dbdb14c..97e1274 100644 --- a/src/common/pa_converters.c +++ b/src/common/pa_converters.c @@ -459,7 +459,7 @@ static void Float32_To_Int24( while( count-- ) { /* convert to 32 bit and drop the low 8 bits */ - double scaled = *src * 0x7FFFFFFF; + double scaled = (double)(*src) * 2147483647.0; temp = (PaInt32) scaled; #if defined(PA_LITTLE_ENDIAN) @@ -1163,39 +1163,33 @@ static void Int24_To_Int16_Dither( void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { - #define _PA_CNV_RESCALE(__max_from,__max_to,g) ((1.0f/(float)(__max_from/2+1))*((float)((__max_to/2+1)+g))) -#ifndef PA_BIG_ENDIAN - #define _PA_INT24_TO_INT32(v) ((int)(((int)v[2] << 24)|((int)v[1] << 16)|((int)v[0] << 8)) >> 8) -#else - #define _PA_INT24_TO_INT32(v) ((int)(((int)v[0] << 24)|((int)v[1] << 16)|((int)v[2] << 8)) >> 8) -#endif - #define _PA_INT24_TO_FLOAT(v,g) ((float)(_PA_INT24_TO_INT32(v)) * _PA_CNV_RESCALE(0xffffff,0xffff,g)) + unsigned char *src = (unsigned char*)sourceBuffer; + PaInt16 *dest = (PaInt16*)destinationBuffer; - unsigned char *src = (unsigned char *)sourceBuffer; - PaInt16 *dest = (PaInt16 *)destinationBuffer; - float dither, dithered; + PaInt32 temp, dither; while( count-- ) { - dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); - - /* downscale 24-bit int to 16-bit int placed into 32-bit float container, - 16-bit scaler is decreased by 2 to leave space for dither in order not to overflow - */ - dithered = _PA_INT24_TO_FLOAT(src, -2.0f) + dither; -#ifdef PA_USE_C99_LRINTF - *dest = lrintf(dithered-0.5f); -#else - *dest = (PaInt16) dithered; +#if defined(PA_LITTLE_ENDIAN) + temp = (((PaInt32)src[0]) << 8); + temp = temp | (((PaInt32)src[1]) << 16); + temp = temp | (((PaInt32)src[2]) << 24); +#elif defined(PA_BIG_ENDIAN) + temp = (((PaInt32)src[0]) << 24); + temp = temp | (((PaInt32)src[1]) << 16); + temp = temp | (((PaInt32)src[2]) << 8); #endif - src += sourceStride * 3; + /* REVIEW */ + dither = PaUtil_Generate16BitTriangularDither( ditherGenerator ); + *dest = (PaInt16) (((temp >> 1) + dither) >> 15); + + src += sourceStride * 3; dest += destinationStride; } } - /* -------------------------------------------------------------------------- */ static void Int24_To_Int8( @@ -1233,13 +1227,31 @@ static void Int24_To_Int8_Dither( void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { - (void) destinationBuffer; /* unused parameters */ - (void) destinationStride; /* unused parameters */ - (void) sourceBuffer; /* unused parameters */ - (void) sourceStride; /* unused parameters */ - (void) count; /* unused parameters */ - (void) ditherGenerator; /* unused parameters */ - /* IMPLEMENT ME */ + unsigned char *src = (unsigned char*)sourceBuffer; + signed char *dest = (signed char*)destinationBuffer; + + PaInt32 temp, dither; + + while( count-- ) + { + +#if defined(PA_LITTLE_ENDIAN) + temp = (((PaInt32)src[0]) << 8); + temp = temp | (((PaInt32)src[1]) << 16); + temp = temp | (((PaInt32)src[2]) << 24); +#elif defined(PA_BIG_ENDIAN) + temp = (((PaInt32)src[0]) << 24); + temp = temp | (((PaInt32)src[1]) << 16); + temp = temp | (((PaInt32)src[2]) << 8); +#endif + + /* REVIEW */ + dither = PaUtil_Generate16BitTriangularDither( ditherGenerator ); + *dest = (signed char) (((temp >> 1) + dither) >> 23); + + src += sourceStride * 3; + dest += destinationStride; + } } /* -------------------------------------------------------------------------- */ -- 2.43.0