From: Akihiko Odaki <[email protected]>

clip_*_uint32_t() returns 0 when v == 1.f because it computes the result
as (IN_T)((v * ((mixeng_real)IN_MAX / 2.f)) + HALF):

- (v * ((mixeng_real)IN_MAX / 2.f)) + HALF == 0x100000000.f, which does
  not fit in uint32_t.
- (v * ((mixeng_real)IN_MAX / 2.f)) == 0x80000000.f
- ((mixeng_real)IN_MAX / 2.f) == 0x80000000.f
- (mixeng_real)IN_MAX == 0x100000000.f because 0xffffffff cannot be
  represented exactly in float.
- HALF == 0x7fffffff, which is implicitly converted to 0x80000000.f.

Clamp the result to avoid the overflow.

Signed-off-by: Akihiko Odaki <[email protected]>
Acked-by: Marc-AndrĂ© Lureau <[email protected]>
Message-Id: <[email protected]>
---
 audio/mixeng_template.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/audio/mixeng_template.h b/audio/mixeng_template.h
index 881653c44bf..5b0014bdd9a 100644
--- a/audio/mixeng_template.h
+++ b/audio/mixeng_template.h
@@ -65,7 +65,9 @@ static inline IN_T glue (clip_, ET) (mixeng_real v)
 #ifdef SIGNED
     return ENDIAN_CONVERT((IN_T)(v * (((mixeng_real)IN_MAX - IN_MIN) / 2.f)));
 #else
-    return ENDIAN_CONVERT((IN_T)((v * ((mixeng_real)IN_MAX / 2.f)) + HALF));
+    return ENDIAN_CONVERT(MIN((int64_t)((v * ((mixeng_real)IN_MAX / 2.f)) +
+                                        HALF),
+                              IN_MAX));
 #endif
 }
 
-- 
2.54.0


Reply via email to