Commit graph

70 commits

Author SHA1 Message Date
Wim Taymans
f7c3d37969 fmt-ops: allocate shaper memory dynamically
It is based on the number of channels so allocate it dynamically.
2025-10-24 12:46:38 +02:00
Wim Taymans
0817001728 audioconvert: add clear function
Sets all samples to 0 in the target format.
2025-07-02 10:27:26 +02:00
Wim Taymans
0c8f803d59 audioconvert: optimise f32d to/from s16s conversions
They are mostly used for sending and receiving RTP so it might be worth
to make them a bit faster.
2025-01-24 10:37:02 +01:00
Wim Taymans
84bd4b7ea9 spa: use static inline for interfaces instead of macro
It gives better typechecking and a path to make a library of functions.
2024-11-26 11:35:49 +01:00
sunyuechi
245adda985 fmt-ops: add RVV optimizations for s32_to_f32d 2024-09-29 11:17:42 +08:00
sunyuechi
79d41e183e fmt-ops: add RVV optimizations for f32d_to_s32 2024-09-26 00:55:49 +08:00
sunyuechi
74832445ba fmt-ops: add RVV optimizations for s16_to_f32d 2024-09-25 10:50:05 +00:00
sunyuechi
8a8843ba20 fmt-ops: add RVV optimizations for f32d_s16 2024-09-23 08:10:43 +00:00
sunyuechi
852de6c35c fmt-ops: add RVV optimizations for f32d_s16d 2024-09-23 08:10:43 +00:00
sunyuechi
d932e52d5b fmt-ops: add R-V V optimizations for f32_s16 2024-09-18 10:40:48 +00:00
David Coles
5d7624001d Add spa/utils/endian.h
This provides access to GNU C library-style endian and byteswap functions.

Windows doesn't provide pre-processor defines for endianness, but
all current Windows architectures (X32, X64, ARM) are little-endian.
2024-07-01 15:28:58 +00:00
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
Roman Lebedev
2a035ac49e
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
2024-06-27 19:41:20 +03:00
Barnabás Pőcze
80572a6fbc audioconvert: don't left shift negative values
See #3572
2023-10-15 21:00:01 +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
Wim Taymans
3e6f62875d audioconvert: make sure shifts are defined
Don't to signed left shifts, make macros to do the shifting on unsigned
ints when needed.

See !1505
2023-01-24 21:29:18 +01:00
Wim Taymans
d22feab92a spa: add macro to simplify array iterations some more
uint32_t i;
	for (i = 0; i < SPA_N_ELEMENTS(some_array); i++)
		.. stuff with some_array[i].foo ...

   becomes:

	SPA_FOR_EACH_ELEMENT_VAR(some_array, p)
		.. stuff with p->foo ..
2022-09-30 16:24:26 +02:00
Wim Taymans
a145c42ec4 audioconvert: make separate noise functions
So that we can reuse optimized versions in unoptimized noise
functions.
Do allocation a little different so that we can align everything
from the start.
2022-09-29 21:36:06 +02: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
5a8af97a40 audioconvert: use SPA_CLAMPF to clamp floats
It generates better assembler.
2022-07-19 17:59:14 +02:00
Wim Taymans
ada39f3048 audioconvert: improve noise bits
Make a new noise method called PATTERN and use it to add a slow (every
1024 samples) repeating pattern of -1, 0.
Only use this method when we don't already use triangular dither.

See #2540
2022-07-18 11:41:57 +02:00
Wim Taymans
57f63feb92 audioconvert: Fix Wannamaker name 2022-07-18 10:22:21 +02:00
Wim Taymans
a4db745a7e audioconvert: improve noise shaping
Reorganize things a little so we can add more noise shapers.
Add sloped triangular noise.
Add wanamaker3 noise shaping.
2022-07-15 12:36:15 +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
d18428f8bb audiconvert: make macros for conversions
Make a common macro for float to int and int to float so that we can
change the algorithms easily.
2022-07-13 18:10:25 +02:00
Wim Taymans
7745346292 audioconvert: add sse2 s16 dither functions 2022-07-12 10:34:13 +02:00
Wim Taymans
dd1d5960b4 audioconvert: implement f64s
Add swapping functions for f64s.
Fix the awkward interleave/deinterleave names for 32s.
2022-07-11 10:58:51 +02:00
Wim Taymans
3ffb9f4b26 audioconvert: improve s24_32 and u24_32 conversion
We should ignore the upper 8 bits, so first shift them out and then
use the s32/u32 conversion functions.
Add a test for this.
2022-07-09 18:07:49 +02:00
Wim Taymans
df40c9bf6a fmt-ops: express 32 bits formats in terms of 32_24 bits formats 2022-07-07 20:11:08 +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
Frédéric Danis
036bb13474 audioconvert: Fix s24/u24 byte swapping 2022-07-05 14:06:31 +00:00
Wim Taymans
c4cc13c094 audioconvert: use right scale value
Disable assert, it seems to fail on clang.
2022-07-05 16:02:24 +02:00
Wim Taymans
f62244d7a9 audioconvert: tweak more conversion constants
Tweak some more constants to make lossless conversions work.
Add some tests for lossless conversion.
Add some more tests.
2022-07-05 15:50:05 +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
e3951cc1f1 audioconvert: fix pack/unpack of s24/u24
Copy the values into the right place in the struct.
2022-07-05 12:18:57 +02:00
Wim Taymans
e0b3e06bea audioconvert: remove unused field 2022-07-01 12:40:19 +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
06b1cf8663 audioconvert: implement (de)interleave with existing functions 2022-06-30 18:24:05 +02:00
Wim Taymans
9b37142ef6 audioconvert: implement noise shaping
To compare the results:

  pw-cat -r test.wav --format=u8 -P '{ dither.method=none }'

vs:

  pw-cat -r test.wav --format=u8 -P '{ dither.method=shaped5 }'
2022-06-29 17:33:37 +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
6b49bded3a audioconvert: move dither and noise to fmt-ops
We need to do dithering and noise when converting f32 to the
target format. This is more natural because we can work in 32 bits
integers instead of floats.

This will also make it possible to actually calculate the error between
source and target values and implement some sort of feedback and
noise shaping later.
2022-06-28 16:55:50 +02:00
Lucas Holt
6a15a02ec2 Add support for MidnightBSD
Fix build issue

Fix build issue
2022-06-19 18:22:47 +00:00
Wim Taymans
734470f0cd audioconvert: add SSE (de)interleave_32(s) versions 2022-03-11 15:02:02 +01:00
Wim Taymans
92198e4d0d spa: clamp required alignment to cpu alignment
pipewire will allocate buffers aligned to the max alignment required for
the CPU. Take this into account and don't expect larger alignment.

Fixes a warning in mixer-dsp when the CPU max alignment is 16 but the
plugin requires 32 bytes alignment for the AVX2 path (that would never
be chosen on the CPU).

See #2074
2022-01-28 11:49:06 +01:00
Gleb Popov
44b18b86cd Fix build on FreeBSD by defining bswap_64. 2022-01-26 14:37:19 +03:00
Wim Taymans
9f5caa6358 audioconvert: add f64 conversion
See #1990
2022-01-10 13:04:31 +01:00
Wim Taymans
0ace131d72 audioconvert: add stereo deinterleave neon asm
This can take some shortcuts and convert twice as many samples in one
iteration as the strided stereo deinterleave one.
2021-10-28 11:30:04 +02:00