From: Peter Meerwald <p.meerwald@xxxxxxxxxxxxxxxxxx> 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