Convert float samples to integer using a power-of-2 multiple
This commit is contained in:
parent
355a8898cf
commit
90c005bbec
22
Alc/ALu.c
22
Alc/ALu.c
@ -1306,34 +1306,30 @@ static void UpdateContextSources(ALCcontext *ctx, const struct ALeffectslotArray
|
||||
}
|
||||
|
||||
|
||||
/* Specialized function to clamp to [-1, +1] with only one branch. This also
|
||||
* converts NaN to 0. */
|
||||
static inline ALfloat aluClampf(ALfloat val)
|
||||
{
|
||||
if(fabsf(val) <= 1.0f) return val;
|
||||
return (ALfloat)((0.0f < val) - (val < 0.0f));
|
||||
}
|
||||
|
||||
static inline ALfloat aluF2F(ALfloat val)
|
||||
{ return val; }
|
||||
|
||||
#define S25_MAX_NORM (16777215.0f/16777216.0f)
|
||||
static inline ALint aluF2I(ALfloat val)
|
||||
{
|
||||
/* Floats only have a 24-bit mantissa, so [-16777215, +16777215] is the max
|
||||
* integer range normalized floats can be safely converted to.
|
||||
/* Floats only have a 24-bit mantissa, so [-16777216, +16777216] is the max
|
||||
* integer range normalized floats can be safely converted to (a bit of the
|
||||
* exponent helps out, effectively giving 25 bits).
|
||||
*/
|
||||
return fastf2i(aluClampf(val)*16777215.0f)<<7;
|
||||
return fastf2i(clampf(val, -1.0f, S25_MAX_NORM)*16777216.0f)<<7;
|
||||
}
|
||||
static inline ALuint aluF2UI(ALfloat val)
|
||||
{ return aluF2I(val)+2147483648u; }
|
||||
|
||||
#define S16_MAX_NORM (32767.0f/32768.0f)
|
||||
static inline ALshort aluF2S(ALfloat val)
|
||||
{ return fastf2i(aluClampf(val)*32767.0f); }
|
||||
{ return fastf2i(clampf(val, -1.0f, S16_MAX_NORM)*32768.0f); }
|
||||
static inline ALushort aluF2US(ALfloat val)
|
||||
{ return aluF2S(val)+32768; }
|
||||
|
||||
#define S8_MAX_NORM (127.0f/128.0f)
|
||||
static inline ALbyte aluF2B(ALfloat val)
|
||||
{ return fastf2i(aluClampf(val)*127.0f); }
|
||||
{ return fastf2i(clampf(val, -1.0f, S8_MAX_NORM)*128.0f); }
|
||||
static inline ALubyte aluF2UB(ALfloat val)
|
||||
{ return aluF2B(val)+128; }
|
||||
|
||||
|
@ -574,9 +574,10 @@ static inline ALfloat Conv_ALfloat_ALuint(ALuint val)
|
||||
#define DECL_TEMPLATE(FT, T, smin, smax) \
|
||||
static inline AL##T Conv_AL##T##_##FT(FT val) \
|
||||
{ \
|
||||
if(val > 1.0f) return smax; \
|
||||
if(val < -1.0f) return smin; \
|
||||
return (AL##T)(val * (FT)smax); \
|
||||
val *= (FT)smax + 1; \
|
||||
if(val >= (FT)smax) return smax; \
|
||||
if(val <= (FT)smin) return smin; \
|
||||
return (AL##T)val; \
|
||||
} \
|
||||
static inline ALu##T Conv_ALu##T##_##FT(FT val) \
|
||||
{ return Conv_ALu##T##_AL##T(Conv_AL##T##_##FT(val)); }
|
||||
@ -590,9 +591,10 @@ DECL_TEMPLATE(ALdouble, int, -2147483647-1, 2147483647)
|
||||
/* Special handling for float32 to int32, since it would overflow. */
|
||||
static inline ALint Conv_ALint_ALfloat(ALfloat val)
|
||||
{
|
||||
if(val > 1.0f) return 2147483647;
|
||||
if(val < -1.0f) return -2147483647-1;
|
||||
return (ALint)(val * 16777215.0f) << 7;
|
||||
val *= 16777216.0f;
|
||||
if(val >= 16777215.0f) return 0x7fffff80/*16777215 << 7*/;
|
||||
if(val <= -16777216.0f) return 0x80000000/*-16777216 << 7*/;
|
||||
return (ALint)val << 7;
|
||||
}
|
||||
static inline ALuint Conv_ALuint_ALfloat(ALfloat val)
|
||||
{ return Conv_ALuint_ALint(Conv_ALint_ALfloat(val)); }
|
||||
|
Loading…
Reference in New Issue
Block a user