[pulseaudio-discuss] [PATCH 2/3] WIP sconv: deal with PulseAudio's misguided sample-to-float conversion

Peter Meerwald pmeerw at pmeerw.net
Fri Oct 26 04:04:46 PDT 2012


From: Peter Meerwald <p.meerwald at bct-electronic.com>

PulseAudio does the following for s16<->float conversion

flt = s16 / (float) 0x7fff

this has the following problems:

(1) flt_to_s16(s16_to_flt(x)) != x for x == -32768
(2) x / (float) 0x7fff != x * (1.0f / 0x7fff)
on the other hand
x / (float) (1<<15) == x * (1.0f / (1<<15))
and the 2nd form would allow to avoid division in favour of
multiplication of the inverse
(3) saturation instruction cannot be directly used
PA clips at -32767, but the any (?) sane (?) CPU would saturate to -32768 :)

this patch makes the sconv NEON code follow PA's conversion semantics, it hurts!

I think signed int<->float conversion should be reworked in PulseAudio

Signed-off-by: Peter Meerwald <p.meerwald at bct-electronic.com>
---
 src/pulsecore/sconv_neon.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/pulsecore/sconv_neon.c b/src/pulsecore/sconv_neon.c
index cbca232..fd45965 100644
--- a/src/pulsecore/sconv_neon.c
+++ b/src/pulsecore/sconv_neon.c
@@ -39,9 +39,11 @@ static void pa_sconv_s16le_from_f32ne_neon(unsigned n, const float *src, int16_t
         "vdup.f32   q2, %[two23]            \n\t"
         "vdup.f32   q3, %[scale]            \n\t"
         "vdup.u32   q4, %[mask]             \n\t"
+        "vdup.f32   q5, %[mone]             \n\t"
 
         "1:                                 \n\t"
         "vld1.32    {q0}, [%[src]]!         \n\t" /* load x */
+        "vmaxq.f32  q0, q0, q5              \n\t" /* clip at -1.0 */
         "vmul.f32   q0, q0, q3              \n\t" /* scale */
         "vand.u32   q1, q0, q4              \n\t" /* get sign bit */
         "vorr.u32   q1, q1, q2              \n\t" /* put sign on 2^23 */
@@ -56,8 +58,8 @@ static void pa_sconv_s16le_from_f32ne_neon(unsigned n, const float *src, int16_t
         "2:                                 \n\t"
 
         : [dst] "+r" (dst), [src] "+r" (src), [n] "+r" (n) /* output operands (or input operands that get modified) */
-        : [scale] "r" (32767.0f), [two23] "r" (8.3886080000e+06f), [mask] "r" (0x80000000) /* input operands */
-        : "memory", "cc", "q0", "q1", "q2", "q3", "q4" /* clobber list */
+        : [scale] "r" (32767.0f), [two23] "r" (8.3886080000e+06f), [mask] "r" (0x80000000), [mone] "r" (-1.0f) /* input operands */
+        : "memory", "cc", "q0", "q1", "q2", "q3", "q4", "q5" /* clobber list */
     );
 
     /* leftovers */
-- 
1.7.9.5



More information about the pulseaudio-discuss mailing list