mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
audioconvert: introduce s25_32 type, f32<->s25 cast is lossless
The largest integer that 32-bit floating point can exactly represent is actually `(2^24)-1`, not`(2^23)-1` like the code assumes. This means, whenever we use s24 as an intermediate step to go between f32 and s32, we lose a bit of precision. s25_32 is really a i32 with highest byte always being a sign byte. Printing was done by adding ``` for(int e = 0; e != 13; ++e) fprintf(stderr, "%16.32e,", ((float*)m1)[e]); ``` to `compare_mem`. I don't like how these tests work. https://godbolt.org/z/abe94sedT
This commit is contained in:
parent
7b4c0dd5ec
commit
2a035ac49e
2 changed files with 131 additions and 9 deletions
|
|
@ -88,6 +88,18 @@
|
|||
|
||||
#define U32_TO_U24_32(v) (((uint32_t)(v)) >> 8)
|
||||
|
||||
#define S25_MIN -16777216
|
||||
#define S25_MAX 16777215
|
||||
#define S25_SCALE 16777216.0f
|
||||
#define S25_32_TO_F32(v) ITOF(int32_t, v, S25_SCALE, 0.0f)
|
||||
#define S25_32S_TO_F32(v) S25_32_TO_F32(bswap_32(v))
|
||||
#define F32_TO_S25_32_D(v,d) FTOI(int32_t, v, S25_SCALE, 0.0f, d, S25_MIN, S25_MAX)
|
||||
#define F32_TO_S25_32(v) F32_TO_S25_32_D(v, 0.0f)
|
||||
#define F32_TO_S25_32S(v) bswap_32(F32_TO_S25_32(v))
|
||||
#define F32_TO_S25_32S_D(v,d) bswap_32(F32_TO_S25_32_D(v,d))
|
||||
#define S25_32_TO_S32(v) ((int32_t)(((uint32_t)(v)) << 7))
|
||||
#define S32_TO_S25_32(v) (((int32_t)(v)) >> 7)
|
||||
|
||||
#define U32_MIN 0u
|
||||
#define U32_MAX 4294967295u
|
||||
#define U32_SCALE 2147483648.f
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue