1use crate::mode::{Float32Complex, Int16Complex, Packed4Bit};
19use alloc::vec::Vec;
20
21#[cfg(feature = "simd")]
22use super::simd;
23
24pub trait Convert<S>: Sized {
28 fn convert(src: S) -> Self;
30}
31
32#[cfg(feature = "simd")]
37pub fn try_simd_convert<S, D>(src: &[S]) -> Option<Vec<D>>
38where
39 D: Convert<S> + 'static,
40 S: 'static,
41{
42 use core::any::TypeId;
43
44 if TypeId::of::<D>() != TypeId::of::<f32>() {
46 return None;
47 }
48
49 let result_f32: Vec<f32> = if TypeId::of::<S>() == TypeId::of::<i8>() {
51 simd::convert_i8_to_f32_simd(unsafe { core::slice::from_raw_parts(src.as_ptr() as *const i8, src.len()) })
52 } else if TypeId::of::<S>() == TypeId::of::<i16>() {
53 simd::convert_i16_to_f32_simd(unsafe { core::slice::from_raw_parts(src.as_ptr() as *const i16, src.len()) })
54 } else if TypeId::of::<S>() == TypeId::of::<u16>() {
55 simd::convert_u16_to_f32_simd(unsafe { core::slice::from_raw_parts(src.as_ptr() as *const u16, src.len()) })
56 } else if TypeId::of::<S>() == TypeId::of::<u8>() {
57 simd::convert_u8_to_f32_simd(unsafe { core::slice::from_raw_parts(src.as_ptr() as *const u8, src.len()) })
58 } else {
59 return None;
60 };
61
62 Some(unsafe { core::mem::transmute::<Vec<f32>, Vec<D>>(result_f32) })
65}
66
67#[cfg(not(feature = "simd"))]
69pub fn try_simd_convert<S, D: Convert<S>>(_src: &[S]) -> Option<Vec<D>> {
70 None
71}
72
73#[cfg(feature = "simd")]
78pub fn try_simd_convert_reverse<S, D>(src: &[S]) -> Option<Vec<D>>
79where
80 S: 'static,
81 D: Convert<S> + 'static,
82{
83 use core::any::TypeId;
84
85 if TypeId::of::<S>() != TypeId::of::<f32>() {
87 return None;
88 }
89
90 let _src_f32: &[f32] = unsafe { core::slice::from_raw_parts(src.as_ptr() as *const f32, src.len()) };
91
92 None
96}
97
98#[cfg(not(feature = "simd"))]
100pub fn try_simd_convert_reverse<S, D: Convert<S>>(_src: &[S]) -> Option<Vec<D>> {
101 None
102}
103
104impl Convert<i8> for f32 {
107 #[inline]
108 fn convert(src: i8) -> Self {
109 src as f32
110 }
111}
112
113#[cfg(feature = "simd")]
115pub fn convert_i8_slice_to_f32(src: &[i8]) -> Vec<f32> {
116 simd::convert_i8_to_f32_simd(src)
117}
118
119#[cfg(not(feature = "simd"))]
121pub fn convert_i8_slice_to_f32(src: &[i8]) -> Vec<f32> {
122 src.iter().map(|&x| x as f32).collect()
123}
124
125#[cfg(feature = "simd")]
127pub fn convert_i16_slice_to_f32(src: &[i16]) -> Vec<f32> {
128 simd::convert_i16_to_f32_simd(src)
129}
130
131#[cfg(not(feature = "simd"))]
133pub fn convert_i16_slice_to_f32(src: &[i16]) -> Vec<f32> {
134 src.iter().map(|&x| x as f32).collect()
135}
136
137#[cfg(feature = "simd")]
139pub fn convert_u16_slice_to_f32(src: &[u16]) -> Vec<f32> {
140 simd::convert_u16_to_f32_simd(src)
141}
142
143#[cfg(not(feature = "simd"))]
145pub fn convert_u16_slice_to_f32(src: &[u16]) -> Vec<f32> {
146 src.iter().map(|&x| x as f32).collect()
147}
148
149#[cfg(feature = "simd")]
151pub fn convert_u8_slice_to_f32(src: &[u8]) -> Vec<f32> {
152 simd::convert_u8_to_f32_simd(src)
153}
154
155#[cfg(not(feature = "simd"))]
157pub fn convert_u8_slice_to_f32(src: &[u8]) -> Vec<f32> {
158 src.iter().map(|&x| x as f32).collect()
159}
160
161#[cfg(feature = "f16")]
163pub fn convert_f16_slice_to_f32(src: &[f16]) -> Vec<f32> {
164 src.iter().map(|&x| x as f32).collect()
168}
169
170#[cfg(feature = "f16")]
172pub fn convert_f32_slice_to_f16(src: &[f32]) -> Vec<f16> {
173 src.iter().map(|&x| x as f16).collect()
174}
175
176impl Convert<u8> for f32 {
177 #[inline]
178 fn convert(src: u8) -> Self {
179 src as f32
180 }
181}
182
183impl Convert<i16> for f32 {
184 #[inline]
185 fn convert(src: i16) -> Self {
186 src as f32
187 }
188}
189
190impl Convert<u16> for f32 {
191 #[inline]
192 fn convert(src: u16) -> Self {
193 src as f32
194 }
195}
196
197#[cfg(feature = "f16")]
198impl Convert<f16> for f32 {
199 #[inline]
200 fn convert(src: f16) -> Self {
201 src as f32
202 }
203}
204
205impl Convert<f32> for f32 {
206 #[inline]
207 fn convert(src: f32) -> Self {
208 src
209 }
210}
211
212impl Convert<f32> for i8 {
215 #[inline]
216 fn convert(src: f32) -> Self {
217 src.clamp(i8::MIN as f32, i8::MAX as f32) as i8
218 }
219}
220
221impl Convert<f32> for u8 {
222 #[inline]
223 fn convert(src: f32) -> Self {
224 src.clamp(u8::MIN as f32, u8::MAX as f32) as u8
225 }
226}
227
228impl Convert<f32> for i16 {
229 #[inline]
230 fn convert(src: f32) -> Self {
231 src.clamp(i16::MIN as f32, i16::MAX as f32) as i16
232 }
233}
234
235impl Convert<f32> for u16 {
236 #[inline]
237 fn convert(src: f32) -> Self {
238 src.clamp(u16::MIN as f32, u16::MAX as f32) as u16
239 }
240}
241
242#[cfg(feature = "f16")]
243impl Convert<f32> for f16 {
244 #[inline]
245 fn convert(src: f32) -> Self {
246 src as f16
247 }
248}
249
250impl Convert<i8> for i8 {
253 #[inline]
254 fn convert(src: i8) -> Self {
255 src
256 }
257}
258
259impl Convert<i16> for i16 {
260 #[inline]
261 fn convert(src: i16) -> Self {
262 src
263 }
264}
265
266impl Convert<u16> for u16 {
267 #[inline]
268 fn convert(src: u16) -> Self {
269 src
270 }
271}
272
273impl Convert<Int16Complex> for Float32Complex {
276 #[inline]
277 fn convert(src: Int16Complex) -> Self {
278 Self {
279 real: src.real as f32,
280 imag: src.imag as f32,
281 }
282 }
283}
284
285impl Convert<Float32Complex> for Int16Complex {
286 #[inline]
287 fn convert(src: Float32Complex) -> Self {
288 Self {
289 real: src.real.clamp(i16::MIN as f32, i16::MAX as f32) as i16,
290 imag: src.imag.clamp(i16::MIN as f32, i16::MAX as f32) as i16,
291 }
292 }
293}
294
295impl Convert<Int16Complex> for Int16Complex {
296 #[inline]
297 fn convert(src: Int16Complex) -> Self {
298 src
299 }
300}
301
302impl Convert<Float32Complex> for Float32Complex {
303 #[inline]
304 fn convert(src: Float32Complex) -> Self {
305 src
306 }
307}
308
309impl Convert<i8> for i16 {
312 #[inline]
313 fn convert(src: i8) -> Self {
314 src as i16
315 }
316}
317
318impl Convert<i16> for i8 {
319 #[inline]
320 fn convert(src: i16) -> Self {
321 src.clamp(i8::MIN as i16, i8::MAX as i16) as i8
322 }
323}
324
325impl Convert<u8> for i16 {
326 #[inline]
327 fn convert(src: u8) -> Self {
328 src as i16
329 }
330}
331
332impl Convert<i16> for u8 {
333 #[inline]
334 fn convert(src: i16) -> Self {
335 src.clamp(u8::MIN as i16, u8::MAX as i16) as u8
336 }
337}
338
339impl Convert<u8> for u16 {
340 #[inline]
341 fn convert(src: u8) -> Self {
342 src as u16
343 }
344}
345
346impl Convert<u16> for u8 {
347 #[inline]
348 fn convert(src: u16) -> Self {
349 src.clamp(u8::MIN as u16, u8::MAX as u16) as u8
350 }
351}
352
353impl Convert<i8> for u16 {
354 #[inline]
355 fn convert(src: i8) -> Self {
356 src.max(0) as u16
357 }
358}
359
360impl Convert<u16> for i8 {
361 #[inline]
362 fn convert(src: u16) -> Self {
363 (src as i16).clamp(i8::MIN as i16, i8::MAX as i16) as i8
364 }
365}
366
367impl Convert<i16> for u16 {
368 #[inline]
369 fn convert(src: i16) -> Self {
370 src.max(0) as u16
371 }
372}
373
374impl Convert<u16> for i16 {
375 #[inline]
376 fn convert(src: u16) -> Self {
377 src.min(i16::MAX as u16) as i16
378 }
379}
380
381impl Convert<Packed4Bit> for u8 {
384 #[inline]
385 fn convert(src: Packed4Bit) -> Self {
386 src.first()
387 }
388}
389
390impl Convert<Packed4Bit> for i8 {
391 #[inline]
392 fn convert(src: Packed4Bit) -> Self {
393 let val = src.first();
395 if val & 0x08 != 0 {
396 (val | 0xF0) as i8 } else {
398 val as i8
399 }
400 }
401}
402
403impl Convert<Packed4Bit> for f32 {
404 #[inline]
405 fn convert(src: Packed4Bit) -> Self {
406 src.first() as f32
408 }
409}
410
411impl Convert<u8> for u8 {
414 #[inline]
415 fn convert(src: u8) -> Self {
416 src
417 }
418}