1use crate::prelude::*;
4use half::prelude::HalfFloatSliceExt;
5
6
7#[derive(Copy, Clone, Debug)]
9pub enum Sample {
10
11 F16(f16),
13
14 F32(f32),
16
17 U32(u32)
19}
20
21impl Sample {
22
23 pub fn f32(f32: f32) -> Self { Sample::F32(f32) }
25
26 pub fn f16(f16: f16) -> Self { Sample::F16(f16) }
28
29 pub fn u32(u32: u32) -> Self { Sample::U32(u32) }
31
32 #[inline]
35 pub fn to_f16(self) -> f16 {
36 match self {
37 Sample::F16(sample) => sample,
38 Sample::F32(sample) => f16::from_f32(sample),
39 Sample::U32(sample) => f16::from_f32(sample as f32),
40 }
41 }
42
43 #[inline]
46 pub fn to_f32(self) -> f32 {
47 match self {
48 Sample::F32(sample) => sample,
49 Sample::F16(sample) => sample.to_f32(),
50 Sample::U32(sample) => sample as f32,
51 }
52 }
53
54 #[inline]
56 pub fn to_u32(self) -> u32 {
57 match self {
58 Sample::F16(sample) => sample.to_f32() as u32,
59 Sample::F32(sample) => sample as u32,
60 Sample::U32(sample) => sample,
61 }
62 }
63
64 #[inline]
66 pub fn is_nan(self) -> bool {
67 match self {
68 Sample::F16(value) => value.is_nan(),
69 Sample::F32(value) => value.is_nan(),
70 Sample::U32(_) => false,
71 }
72 }
73
74 #[inline]
76 pub fn is_zero(&self) -> bool {
77 match *self {
78 Sample::F16(value) => value == f16::ZERO || value == f16::NEG_ZERO,
79 Sample::F32(value) => value == 0.0,
80 Sample::U32(value) => value == 0,
81 }
82 }
83}
84
85impl PartialEq for Sample {
86 fn eq(&self, other: &Self) -> bool {
87 match *self {
88 Sample::F16(num) => num == other.to_f16(),
89 Sample::F32(num) => num == other.to_f32(),
90 Sample::U32(num) => num == other.to_u32(),
91 }
92 }
93}
94
95impl Default for Sample {
97 fn default() -> Self { Sample::F32(0.0) }
98}
99
100impl From<f16> for Sample { #[inline] fn from(f: f16) -> Self { Sample::F16(f) } }
101impl From<f32> for Sample { #[inline] fn from(f: f32) -> Self { Sample::F32(f) } }
102impl From<u32> for Sample { #[inline] fn from(f: u32) -> Self { Sample::U32(f) } }
103
104impl<T> From<Option<T>> for Sample where T: Into<Sample> + Default {
105 #[inline] fn from(num: Option<T>) -> Self { num.unwrap_or_default().into() }
106}
107
108
109impl From<Sample> for f16 { #[inline] fn from(s: Sample) -> Self { s.to_f16() } }
110impl From<Sample> for f32 { #[inline] fn from(s: Sample) -> Self { s.to_f32() } }
111impl From<Sample> for u32 { #[inline] fn from(s: Sample) -> Self { s.to_u32() } }
112
113
114pub trait FromNativeSample: Sized + Copy + Default + 'static {
118
119 fn from_f16(value: f16) -> Self;
121
122 fn from_f32(value: f32) -> Self;
124
125 fn from_u32(value: u32) -> Self;
127
128 #[inline]
134 fn from_f16s(from: &[f16], to: &mut [Self]) {
135 assert_eq!(from.len(), to.len(), "slices must have the same length");
136 for (from, to) in from.iter().zip(to.iter_mut()) {
137 *to = Self::from_f16(*from);
138 }
139 }
140
141 #[inline]
145 fn from_f32s(from: &[f32], to: &mut [Self]) {
146 assert_eq!(from.len(), to.len(), "slices must have the same length");
147 for (from, to) in from.iter().zip(to.iter_mut()) {
148 *to = Self::from_f32(*from);
149 }
150 }
151
152 #[inline]
159 fn from_u32s(from: &[u32], to: &mut [Self]) {
160 assert_eq!(from.len(), to.len(), "slices must have the same length");
161 for (from, to) in from.iter().zip(to.iter_mut()) {
162 *to = Self::from_u32(*from);
163 }
164 }
165}
166
167impl FromNativeSample for f32 {
169 #[inline] fn from_f16(value: f16) -> Self { value.to_f32() }
170 #[inline] fn from_f32(value: f32) -> Self { value }
171 #[inline] fn from_u32(value: u32) -> Self { value as f32 }
172
173 #[inline]
177 fn from_f16s(from: &[f16], to: &mut [Self]) {
178 from.convert_to_f32_slice(to);
179 }
180}
181
182impl FromNativeSample for u32 {
183 #[inline] fn from_f16(value: f16) -> Self { value.to_f32() as u32 }
184 #[inline] fn from_f32(value: f32) -> Self { value as u32 }
185 #[inline] fn from_u32(value: u32) -> Self { value }
186}
187
188impl FromNativeSample for f16 {
189 #[inline] fn from_f16(value: f16) -> Self { value }
190 #[inline] fn from_f32(value: f32) -> Self { f16::from_f32(value) }
191 #[inline] fn from_u32(value: u32) -> Self { f16::from_f32(value as f32) }
192
193 #[inline]
197 fn from_f32s(from: &[f32], to: &mut [Self]) {
198 to.convert_from_f32_slice(from)
199 }
200}
201
202impl FromNativeSample for Sample {
203 #[inline] fn from_f16(value: f16) -> Self { Self::from(value) }
204 #[inline] fn from_f32(value: f32) -> Self { Self::from(value) }
205 #[inline] fn from_u32(value: u32) -> Self { Self::from(value) }
206}
207
208
209pub trait IntoNativeSample: Copy + Default + Sync + 'static {
212
213 fn to_f16(&self) -> f16;
215
216 fn to_f32(&self) -> f32;
218
219 fn to_u32(&self) -> u32;
221}
222
223impl IntoNativeSample for f16 {
224 fn to_f16(&self) -> f16 { f16::from_f16(*self) }
225 fn to_f32(&self) -> f32 { f32::from_f16(*self) }
226 fn to_u32(&self) -> u32 { u32::from_f16(*self) }
227}
228
229impl IntoNativeSample for f32 {
230 fn to_f16(&self) -> f16 { f16::from_f32(*self) }
231 fn to_f32(&self) -> f32 { f32::from_f32(*self) }
232 fn to_u32(&self) -> u32 { u32::from_f32(*self) }
233}
234
235impl IntoNativeSample for u32 {
236 fn to_f16(&self) -> f16 { f16::from_u32(*self) }
237 fn to_f32(&self) -> f32 { f32::from_u32(*self) }
238 fn to_u32(&self) -> u32 { u32::from_u32(*self) }
239}
240
241impl IntoNativeSample for Sample {
242 fn to_f16(&self) -> f16 { Sample::to_f16(*self) }
243 fn to_f32(&self) -> f32 { Sample::to_f32(*self) }
244 fn to_u32(&self) -> u32 { Sample::to_u32(*self) }
245}
246
247
248