Skip to main content

rescale_core/
convert.rs

1//! Modul untuk konversi format sampel audio antar representasi integer dan float.
2
3pub trait SampleConvert {
4    fn to_f32(self) -> f32;
5    fn from_f32(sample: f32) -> Self;
6}
7
8impl SampleConvert for i16 {
9    #[inline(always)]
10    fn to_f32(self) -> f32 {
11        if self < 0 {
12            self as f32 / 32768.0
13        } else {
14            self as f32 / 32767.0
15        }
16    }
17
18    #[inline(always)]
19    fn from_f32(sample: f32) -> Self {
20        let clamped = sample.clamp(-1.0, 1.0);
21        if clamped < 0.0 {
22            (clamped * 32768.0).round() as i16
23        } else {
24            (clamped * 32767.0).round() as i16
25        }
26    }
27}
28
29// Catatan: literal `2147483647.0` (dan `2147483648.0`) keduanya bulat ke nilai
30// f32 yang sama (2^31), karena f32 tidak dapat merepresentasikan 2147483647.
31// Karena itu pembagian/penggandaan memakai 2^31 untuk kedua tanda; untuk nilai
32// +1.0 hasil `as i32` saturasi ke i32::MAX (2147483647) secara otomatis.
33impl SampleConvert for i32 {
34    #[inline(always)]
35    fn to_f32(self) -> f32 {
36        self as f32 / 2147483648.0
37    }
38
39    #[inline(always)]
40    fn from_f32(sample: f32) -> Self {
41        (sample.clamp(-1.0, 1.0) * 2147483648.0).round() as i32
42    }
43}
44
45impl SampleConvert for f32 {
46    #[inline(always)]
47    fn to_f32(self) -> f32 {
48        self
49    }
50
51    #[inline(always)]
52    fn from_f32(sample: f32) -> Self {
53        sample
54    }
55}