audioconvert: avoid even more precision loss in S32 to F32 conversion

There's really no point in doing that s25_32 intermediate step,
to be honest i don't have a clue why the original implementation
did that \_(ツ)_/¯.

Both `S25_SCALE` and `S32_SCALE` are powers of two,
and thus are both exactly representable as floats,
and reprocial of power-of-two is also exactly representable,
so it's not like that rescaling results in precision loss.

This additionally avoids right-shift, and thus is even faster.

As `test_lossless_s32_lossless_subset` shows,
if the integer is in the form of s25+shift,
the maximal absolute error became even lower,
but not zero, because F32->S32 still goes through S25 intermediate.
I think we could theoretically do better,
but then the clamping becomes pretty finicky,
so i don't feel like touching that here.
This commit is contained in:
Roman Lebedev 2024-06-14 06:05:18 +03:00
parent c517865864
commit f4c89b1b40
No known key found for this signature in database
GPG key ID: 083C3EBB4A1689E0
4 changed files with 26 additions and 37 deletions

View file

@ -119,9 +119,10 @@
#define S32_TO_S24_32(v) (((int32_t)(v)) >> 8)
#define S32_MIN (S24_MIN * 256)
#define S32_MAX (S24_MAX * 256)
#define S32_TO_F32(v) ITOF(int32_t, S32_TO_S25_32(v), S25_SCALE, 0.0f)
#define S32_MIN -2147483648
#define S32_MAX 2147483647
#define S32_SCALE 2147483648.0f
#define S32_TO_F32(v) ITOF(int32_t, v, S32_SCALE, 0.0f)
#define S32S_TO_F32(v) S32_TO_F32(bswap_32(v))
#define F32_TO_S32_D(v,d) S25_32_TO_S32(F32_TO_S25_32_D(v,d))
#define F32_TO_S32(v) F32_TO_S32_D(v, 0.0f)