core/soundcvt: clip output in f32->i32 conversion
authorKostya Shishkov <kostya.shishkov@gmail.com>
Wed, 23 Dec 2020 10:41:45 +0000 (11:41 +0100)
committerKostya Shishkov <kostya.shishkov@gmail.com>
Wed, 23 Dec 2020 10:41:45 +0000 (11:41 +0100)
nihav-core/src/soundcvt/mod.rs

index 154b59f22ee58e9e0130c50208dee93328c437d1..17d7709cf32468219198c28561db03d30a3e6023 100644 (file)
@@ -139,7 +139,16 @@ impl FromFmt<f32> for i16 {
     fn cvt_from(val: f32) -> i16 { (val * 32768.0).min(32767.0).max(-32768.0) as i16 }
 }
 impl FromFmt<f32> for i32 {
     fn cvt_from(val: f32) -> i16 { (val * 32768.0).min(32767.0).max(-32768.0) as i16 }
 }
 impl FromFmt<f32> for i32 {
-    fn cvt_from(val: f32) -> i32 { (val * 31.0f32.exp2()) as i32 }
+    fn cvt_from(val: f32) -> i32 {
+        if val >= 1.0 {
+            std::i32::MAX
+        } else if val <= -1.0 {
+            std::i32::MIN
+        } else {
+            let scale = (1u32 << 31) as f32;
+            (val * scale) as i32
+        }
+    }
 }
 impl FromFmt<f32> for f32 {
     fn cvt_from(val: f32) -> f32 { val }
 }
 impl FromFmt<f32> for f32 {
     fn cvt_from(val: f32) -> f32 { val }