Commit graph

30 commits

Author SHA1 Message Date
Roman Lebedev
7c40cafa7c
audioconvert: avoid even more precision loss in F32 to S32 conversion
This is somewhat similar to the S32->F32 conversion improvements,
but here things a bit more tricky...

The main consideration is that the limits to which we clamp
must be valid 32-bit signed integers, but not all such integers
are exactly losslessly representable in `float32_t`.

For example it we'd clamp to `2147483647`,
that is actually a `2147483648.0f`,
and `2147483648` is not a valid 32-bit signed integer,
so the post-clamp conversion would basically be UB.
We don't have this problem for negative bound, though.

But as we know, any 25-bit signed integer is losslessly
round-trippable through float32_t, and since multiplying by 2
only changes the float's exponent, we can clamp to `2147483520`!
The algorithm of selection of the pre-clamping scale is unaffected.

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 is finally zero.

Without going through `float`->`double`->`int`,
i'm not sure if the `float`->`int` conversion
can be improved further.
2024-06-27 19:41:20 +03:00
Roman Lebedev
f4c89b1b40
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.
2024-06-27 19:41:20 +03:00
Roman Lebedev
c517865864
audioconvert: somewhat avoid precision loss in S32 to F32 conversion
At the very least, we should go through s25_32 intermediate
instead of s24_32, to avoid needlessly loosing 1 LSB precision bit.

That being said, i suspect it's still not doing the right thing.
Why are we silently dropping those 7 LSB bits?
Is that really the way to do it?
2024-06-27 19:41:20 +03:00
Roman Lebedev
175d533b56
audioconvert: somewhat avoid precision loss in F32 to S32 conversion
At the very least, we should go through s25_32 intermediate
instead of s24_32, to avoid needlessly loosing 1 LSB precision bit.

FIXME: the noise codepath is not covered with tests.
2024-06-27 19:41:20 +03:00
Wim Taymans
16ad067cc9 audioconvert: use spa_write_unaligned
Use a macro to write out unaligned data to avoid ASAN errors.

See #3572
2023-10-16 12:21:33 +02:00
Wim Taymans
cc109843e5 audioconvert: avoid unaligned writes and left shift of neagtives
See #3572
2023-10-15 21:12:23 +02:00
Wim Taymans
b2c24f3435 audioconvert: fix unaligned writes
Avoid some optimizations that cause unaligned writes.

See #3572
2023-10-15 20:52:54 +02:00
Wim Taymans
bdd577c360 Revert "audioconvert: fix unaligned address"
This reverts commit ae3798abaa.
2023-10-15 20:49:31 +02:00
Wim Taymans
ae3798abaa audioconvert: fix unaligned address
See #3572
2023-10-15 20:40:30 +02:00
Barnabás Pőcze
8c17a6626d treewide: mark some functions static
These were found by enabling the "missing-declarations" warning.
2023-07-03 19:40:31 +02:00
Barnabás Pőcze
934ab3036e treewide: use SPDX tags to specify copyright information
SPDX tags make the licensing information easy to understand and clear,
and they are machine parseable.

See https://spdx.dev for more information.
2023-02-16 10:54:48 +00:00
Sefa Eyeoglu
b927063b89
audioconvert: fix distorted audio on AVX2
Closes pipewire/pipewire#2885

Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
2022-12-11 20:16:03 +01:00
Wim Taymans
177479dfd1 audioconvert: improve some more AVX2 code 2022-12-05 09:37:29 +01:00
Wim Taymans
4e4d76ccd0 audioconvert: use gather in AVX2 code 2022-12-04 20:38:35 +01:00
Wim Taymans
38b3d027ec audioconvert: remove S32_SCALE
We don't use it, we use S24_SCALE and then shift. Also adjust the
S32_MIN and S32_MAX values, based on S24 values.
2022-07-20 17:45:34 +02:00
Wim Taymans
0ba3e7c5db audioconvert: round instead of truncate, to reduce distortion
See #2543
2022-07-13 20:56:13 +02:00
Wim Taymans
6a8fd7024e audioconvert: add and use AVX2 clamp macros 2022-07-12 10:45:41 +02:00
Wim Taymans
b8a4bf880f audioconvert: use 24 bits for 32 formats
The float only preserves 24 bits so use this. Otherwise we get overflows
and errors in clang.
2022-07-07 18:38:32 +02:00
Wim Taymans
22317da685 audioconvert: tweak conversion constants
Tweak the conversion constants a bit so that they handle the
extreme ranges a bit better.
Align the C and vector instructions.
Reactivate the unit test asserts when a conversion fails.
2022-07-05 12:20:02 +02:00
Wim Taymans
817d5bd7a4 audioconvert: simplify 24 bits handling
Make a new uint42_t and int24_t type and use that to handle 24 bits
samples. This makes it easier because we can iterate and copy the
structs like other types.
2022-07-01 12:25:58 +02:00
Wim Taymans
938f2b123e audioconvert: improve format conversion
Make dither noise as a value between -0.5 and 0.5 and add this
to the scaled samples.
For this, we first need to do the scaling and then the CLAMP to
the target depth. This optimizes to the same code but allows us
to avoid under and overflows when we add the dither noise.

Add more dithering methods.

Expose a dither.method property on audioconvert. Disable dither when
the target depth > 16.
2022-06-29 14:10:15 +02:00
Wim Taymans
d23b96b033 audioconvert: fix some compiler warnings 2022-06-29 14:08:30 +02:00
raghu447
af263187ea Reverting redundant changes 2020-06-04 10:36:39 +02:00
raghu447
9024cc4444 Integrating libcamera 2020-06-04 10:36:39 +02:00
Martin Koch
fefdc26f84 plugin: workaround for AVX intrinsic: "_mm256_setr_m128()" missing in GCC
Signed-off-by: Martin Koch <martin.koch@ese.de>
2020-05-13 08:53:43 +00:00
Wim Taymans
b8a1ea1d3a fmt-ops: fix 32 bit compilation
_mm256_extract_epi64 is only for 64 bits, add workaround for 32
bits.

Fixes #220
2020-03-23 14:18:10 +01:00
Wim Taymans
57f84ae5ae fmt-ops: use gather to read samples 2020-03-18 11:41:14 +01:00
Wim Taymans
55633ebf9a fmt-ops: move AVX 2020-03-18 10:06:54 +01:00
Wim Taymans
949dba7bfc fmt-ops: flesh out avx optimizations 2020-03-17 17:27:47 +01:00
Wim Taymans
3a911dfe3b fmt-ops: add avx2 optimized version
Only one optimized version but the sse2 version are compiled with
the avx2 flags so that they get optimized better.
2020-03-16 16:11:29 +01:00