From feb069a48e14ec9d2e3d9e1ba20cb99f5d75459e Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Fri, 9 Aug 2019 18:50:35 +0200 Subject: [PATCH 1/2] Remove shift of signed int in src_float_to_short_array Scale by -SHORT_MIN Clip if float is outside range of short Otherwise round and truncate (guaranteed to fit to short) Uses float instead of double as float can fit all 16 bit values --- src/samplerate.c | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/src/samplerate.c b/src/samplerate.c index 5ced68b1..890acd7d 100644 --- a/src/samplerate.c +++ b/src/samplerate.c @@ -495,24 +495,18 @@ src_short_to_float_array (const short *in, float *out, int len) void src_float_to_short_array (const float *in, short *out, int len) -{ double scaled_value ; - +{ while (len) - { len -- ; - - scaled_value = in [len] * (8.0 * 0x10000000) ; - if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF)) - { out [len] = 32767 ; - continue ; - } ; - if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000)) - { out [len] = -32768 ; - continue ; - } ; - - out [len] = (short) (lrint (scaled_value) >> 16) ; - } ; - + { float scaled_value ; + len -- ; + scaled_value = in [len] * 32768.f ; + if (scaled_value >= 32767.f) + out [len] = 32767 ; + else if (scaled_value <= -32768.f) + out [len] = -32768 ; + else + out [len] = (short) (lrintf (scaled_value)) ; + } } /* src_float_to_short_array */ void From ed155a139a89d1fe13abe3df187534209d59d9a8 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Fri, 9 Aug 2019 19:05:24 +0200 Subject: [PATCH 2/2] Add corner cases to tests --- tests/float_short_test.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/float_short_test.c b/tests/float_short_test.c index 16cf6822..dbf57794 100644 --- a/tests/float_short_test.c +++ b/tests/float_short_test.c @@ -45,10 +45,14 @@ static void float_to_short_test (void) { static float fpos [] = - { 0.95, 0.99, 1.0, 1.01, 1.1, 2.0, 11.1, 111.1, 2222.2, 33333.3 + { 0.95, 0.99, 1.0, 1.01, 1.1, 2.0, 11.1, 111.1, 2222.2, 33333.3, + // Some "almost 1" as corner cases + 32767./32768., (32767. + 0.4)/32768., (32767. + 0.5)/32768., (32767. + 0.6)/32768., (32767. + 0.9)/32768., } ; static float fneg [] = - { -0.95, -0.99, -1.0, -1.01, -1.1, -2.0, -11.1, -111.1, -2222.2, -33333.3 + { -0.95, -0.99, -1.0, -1.01, -1.1, -2.0, -11.1, -111.1, -2222.2, -33333.3, + // Some "almost 1" as corner cases + -32767./32768., -(32767. + 0.4)/32768., -(32767. + 0.5)/32768., -(32767. + 0.6)/32768., -(32767. + 0.9)/32768., } ; static short out [MAX (ARRAY_LEN (fpos), ARRAY_LEN (fneg))] ;