From 935603076de10f599383c62e92a18e7c427d55c5 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 1 Sep 2006 18:07:41 +0000 Subject: [PATCH] Fixed broken audio conversions between float and unsigned datatypes. --- src/audio/SDL_audiotypecvt.c | 26 ++++++++++----------- src/audio/sdlgenaudiocvt.pl | 44 ++++++++++++++++-------------------- 2 files changed, 32 insertions(+), 38 deletions(-) diff --git a/src/audio/SDL_audiotypecvt.c b/src/audio/SDL_audiotypecvt.c index 264854221..0dd2bd041 100644 --- a/src/audio/SDL_audiotypecvt.c +++ b/src/audio/SDL_audiotypecvt.c @@ -28,9 +28,7 @@ /* *INDENT-OFF* */ #define DIVBY127 0.0078740157480315f -#define DIVBY255 0.00392156862745098f #define DIVBY32767 3.05185094759972e-05f -#define DIVBY65535 1.52590218966964e-05f #define DIVBY2147483647 4.6566128752458e-10f static void SDLCALL @@ -221,7 +219,7 @@ SDL_Convert_U8_to_F32LSB(SDL_AudioCVT * cvt, SDL_AudioFormat format) src = (const Uint8 *) (cvt->buf + cvt->len_cvt); dst = (float *) (cvt->buf + cvt->len_cvt * 4); for (i = cvt->len_cvt / sizeof (Uint8); i; --i, --src, --dst) { - const float val = (((float) *src) * DIVBY255); + const float val = ((((float) *src) * DIVBY127) - 1.0f); *dst = SDL_SwapFloatLE(val); } @@ -246,7 +244,7 @@ SDL_Convert_U8_to_F32MSB(SDL_AudioCVT * cvt, SDL_AudioFormat format) src = (const Uint8 *) (cvt->buf + cvt->len_cvt); dst = (float *) (cvt->buf + cvt->len_cvt * 4); for (i = cvt->len_cvt / sizeof (Uint8); i; --i, --src, --dst) { - const float val = (((float) *src) * DIVBY255); + const float val = ((((float) *src) * DIVBY127) - 1.0f); *dst = SDL_SwapFloatBE(val); } @@ -667,7 +665,7 @@ SDL_Convert_U16LSB_to_F32LSB(SDL_AudioCVT * cvt, SDL_AudioFormat format) src = (const Uint16 *) (cvt->buf + cvt->len_cvt); dst = (float *) (cvt->buf + cvt->len_cvt * 2); for (i = cvt->len_cvt / sizeof (Uint16); i; --i, --src, --dst) { - const float val = (((float) SDL_SwapLE16(*src)) * DIVBY65535); + const float val = ((((float) SDL_SwapLE16(*src)) * DIVBY32767) - 1.0f); *dst = SDL_SwapFloatLE(val); } @@ -692,7 +690,7 @@ SDL_Convert_U16LSB_to_F32MSB(SDL_AudioCVT * cvt, SDL_AudioFormat format) src = (const Uint16 *) (cvt->buf + cvt->len_cvt); dst = (float *) (cvt->buf + cvt->len_cvt * 2); for (i = cvt->len_cvt / sizeof (Uint16); i; --i, --src, --dst) { - const float val = (((float) SDL_SwapLE16(*src)) * DIVBY65535); + const float val = ((((float) SDL_SwapLE16(*src)) * DIVBY32767) - 1.0f); *dst = SDL_SwapFloatBE(val); } @@ -1111,7 +1109,7 @@ SDL_Convert_U16MSB_to_F32LSB(SDL_AudioCVT * cvt, SDL_AudioFormat format) src = (const Uint16 *) (cvt->buf + cvt->len_cvt); dst = (float *) (cvt->buf + cvt->len_cvt * 2); for (i = cvt->len_cvt / sizeof (Uint16); i; --i, --src, --dst) { - const float val = (((float) SDL_SwapBE16(*src)) * DIVBY65535); + const float val = ((((float) SDL_SwapBE16(*src)) * DIVBY32767) - 1.0f); *dst = SDL_SwapFloatLE(val); } @@ -1136,7 +1134,7 @@ SDL_Convert_U16MSB_to_F32MSB(SDL_AudioCVT * cvt, SDL_AudioFormat format) src = (const Uint16 *) (cvt->buf + cvt->len_cvt); dst = (float *) (cvt->buf + cvt->len_cvt * 2); for (i = cvt->len_cvt / sizeof (Uint16); i; --i, --src, --dst) { - const float val = (((float) SDL_SwapBE16(*src)) * DIVBY65535); + const float val = ((((float) SDL_SwapBE16(*src)) * DIVBY32767) - 1.0f); *dst = SDL_SwapFloatBE(val); } @@ -1827,7 +1825,7 @@ SDL_Convert_F32LSB_to_U8(SDL_AudioCVT * cvt, SDL_AudioFormat format) src = (const float *) cvt->buf; dst = (Uint8 *) cvt->buf; for (i = cvt->len_cvt / sizeof (float); i; --i, ++src, ++dst) { - const Uint8 val = ((Uint8) (SDL_SwapFloatLE(*src) * 255.0f)); + const Uint8 val = ((Uint8) ((SDL_SwapFloatLE(*src) + 1.0f) * 127.0f)); *dst = val; } @@ -1877,7 +1875,7 @@ SDL_Convert_F32LSB_to_U16LSB(SDL_AudioCVT * cvt, SDL_AudioFormat format) src = (const float *) cvt->buf; dst = (Uint16 *) cvt->buf; for (i = cvt->len_cvt / sizeof (float); i; --i, ++src, ++dst) { - const Uint16 val = ((Uint16) (SDL_SwapFloatLE(*src) * 65535.0f)); + const Uint16 val = ((Uint16) ((SDL_SwapFloatLE(*src) + 1.0f) * 32767.0f)); *dst = SDL_SwapLE16(val); } @@ -1927,7 +1925,7 @@ SDL_Convert_F32LSB_to_U16MSB(SDL_AudioCVT * cvt, SDL_AudioFormat format) src = (const float *) cvt->buf; dst = (Uint16 *) cvt->buf; for (i = cvt->len_cvt / sizeof (float); i; --i, ++src, ++dst) { - const Uint16 val = ((Uint16) (SDL_SwapFloatLE(*src) * 65535.0f)); + const Uint16 val = ((Uint16) ((SDL_SwapFloatLE(*src) + 1.0f) * 32767.0f)); *dst = SDL_SwapBE16(val); } @@ -2049,7 +2047,7 @@ SDL_Convert_F32MSB_to_U8(SDL_AudioCVT * cvt, SDL_AudioFormat format) src = (const float *) cvt->buf; dst = (Uint8 *) cvt->buf; for (i = cvt->len_cvt / sizeof (float); i; --i, ++src, ++dst) { - const Uint8 val = ((Uint8) (SDL_SwapFloatBE(*src) * 255.0f)); + const Uint8 val = ((Uint8) ((SDL_SwapFloatBE(*src) + 1.0f) * 127.0f)); *dst = val; } @@ -2099,7 +2097,7 @@ SDL_Convert_F32MSB_to_U16LSB(SDL_AudioCVT * cvt, SDL_AudioFormat format) src = (const float *) cvt->buf; dst = (Uint16 *) cvt->buf; for (i = cvt->len_cvt / sizeof (float); i; --i, ++src, ++dst) { - const Uint16 val = ((Uint16) (SDL_SwapFloatBE(*src) * 65535.0f)); + const Uint16 val = ((Uint16) ((SDL_SwapFloatBE(*src) + 1.0f) * 32767.0f)); *dst = SDL_SwapLE16(val); } @@ -2149,7 +2147,7 @@ SDL_Convert_F32MSB_to_U16MSB(SDL_AudioCVT * cvt, SDL_AudioFormat format) src = (const float *) cvt->buf; dst = (Uint16 *) cvt->buf; for (i = cvt->len_cvt / sizeof (float); i; --i, ++src, ++dst) { - const Uint16 val = ((Uint16) (SDL_SwapFloatBE(*src) * 65535.0f)); + const Uint16 val = ((Uint16) ((SDL_SwapFloatBE(*src) + 1.0f) * 32767.0f)); *dst = SDL_SwapBE16(val); } diff --git a/src/audio/sdlgenaudiocvt.pl b/src/audio/sdlgenaudiocvt.pl index 047ffb0df..e36bb1037 100755 --- a/src/audio/sdlgenaudiocvt.pl +++ b/src/audio/sdlgenaudiocvt.pl @@ -54,7 +54,7 @@ sub outputHeader { EOF - my @vals = ( 127, 255, 32767, 65535, 2147483647 ); + my @vals = ( 127, 32767, 2147483647 ); foreach (@vals) { my $val = $_; my $fval = 1.0 / $val; @@ -113,38 +113,28 @@ sub getSwapFunc { sub maxIntVal { - my ($signed, $size) = @_; - if ($signed) { - if ($size == 8) { - return 0x7F; - } elsif ($size == 16) { - return 0x7FFF; - } elsif ($size == 32) { - return 0x7FFFFFFF; - } - } else { - if ($size == 8) { - return 0xFF; - } elsif ($size == 16) { - return 0xFFFF; - } elsif ($size == 32) { - return 0xFFFFFFFF; - } + my $size = shift; + if ($size == 8) { + return 0x7F; + } elsif ($size == 16) { + return 0x7FFF; + } elsif ($size == 32) { + return 0x7FFFFFFF; } die("bug in script.\n"); } sub getFloatToIntMult { - my ($signed, $size) = @_; - my $val = maxIntVal($signed, $size) . '.0'; + my $size = shift; + my $val = maxIntVal($size) . '.0'; $val .= 'f' if ($size < 32); return $val; } sub getIntToFloatDivBy { - my ($signed, $size) = @_; - return 'DIVBY' . maxIntVal($signed, $size); + my $size = shift; + return 'DIVBY' . maxIntVal($size); } sub getSignFlipVal { @@ -215,13 +205,19 @@ sub buildCvtFunc { my $code = getSwapFunc($fsize, $fsigned, $ffloat, $fendian, '*src'); if ($ffloat != $tfloat) { if ($ffloat) { - my $mult = getFloatToIntMult($tsigned, $tsize); + my $mult = getFloatToIntMult($tsize); + if (!$tsigned) { # bump from -1.0f/1.0f to 0.0f/2.0f + $code = "($code + 1.0f)"; + } $code = "(($tctype) ($code * $mult))"; } else { # $divby will be the reciprocal, to avoid pipeline stalls # from floating point division...so multiply it. - my $divby = getIntToFloatDivBy($fsigned, $fsize); + my $divby = getIntToFloatDivBy($fsize); $code = "(((float) $code) * $divby)"; + if (!$fsigned) { # bump from 0.0f/2.0f to -1.0f/1.0f. + $code = "($code - 1.0f)"; + } } } else { # All integer conversions here.