1use crate::types::*;
4
5pub fn abs_f32(src: &[f32], dst: &mut [f32]) {
8 let len = src.len().min(dst.len());
9 for i in 0..len {
10 dst[i] = src[i].abs();
11 }
12}
13
14pub fn abs_f64(src: &[f64], dst: &mut [f64]) {
15 let len = src.len().min(dst.len());
16 for i in 0..len {
17 dst[i] = src[i].abs();
18 }
19}
20
21pub fn abs_q31(src: &[q31], dst: &mut [q31]) {
22 let len = src.len().min(dst.len());
23 for i in 0..len {
24 dst[i] = src[i].saturating_abs();
25 }
26}
27
28pub fn abs_q15(src: &[q15], dst: &mut [q15]) {
29 let len = src.len().min(dst.len());
30 for i in 0..len {
31 dst[i] = src[i].saturating_abs();
32 }
33}
34
35pub fn abs_q7(src: &[q7], dst: &mut [q7]) {
36 let len = src.len().min(dst.len());
37 for i in 0..len {
38 dst[i] = src[i].saturating_abs();
39 }
40}
41
42pub fn add_f32(src_a: &[f32], src_b: &[f32], dst: &mut [f32]) {
45 let len = src_a.len().min(src_b.len()).min(dst.len());
46 for i in 0..len {
47 dst[i] = src_a[i] + src_b[i];
48 }
49}
50
51pub fn add_f64(src_a: &[f64], src_b: &[f64], dst: &mut [f64]) {
52 let len = src_a.len().min(src_b.len()).min(dst.len());
53 for i in 0..len {
54 dst[i] = src_a[i] + src_b[i];
55 }
56}
57
58pub fn add_q31(src_a: &[q31], src_b: &[q31], dst: &mut [q31]) {
59 let len = src_a.len().min(src_b.len()).min(dst.len());
60 for i in 0..len {
61 dst[i] = src_a[i].saturating_add(src_b[i]);
62 }
63}
64
65pub fn add_q15(src_a: &[q15], src_b: &[q15], dst: &mut [q15]) {
66 crate::intrinsics::simd_add_q15(src_a, src_b, dst);
67}
68
69pub fn add_q7(src_a: &[q7], src_b: &[q7], dst: &mut [q7]) {
70 let len = src_a.len().min(src_b.len()).min(dst.len());
71 for i in 0..len {
72 dst[i] = src_a[i].saturating_add(src_b[i]);
73 }
74}
75
76pub fn sub_f32(src_a: &[f32], src_b: &[f32], dst: &mut [f32]) {
79 let len = src_a.len().min(src_b.len()).min(dst.len());
80 for i in 0..len {
81 dst[i] = src_a[i] - src_b[i];
82 }
83}
84
85pub fn sub_f64(src_a: &[f64], src_b: &[f64], dst: &mut [f64]) {
86 let len = src_a.len().min(src_b.len()).min(dst.len());
87 for i in 0..len {
88 dst[i] = src_a[i] - src_b[i];
89 }
90}
91
92pub fn sub_q31(src_a: &[q31], src_b: &[q31], dst: &mut [q31]) {
93 let len = src_a.len().min(src_b.len()).min(dst.len());
94 for i in 0..len {
95 dst[i] = src_a[i].saturating_sub(src_b[i]);
96 }
97}
98
99pub fn sub_q15(src_a: &[q15], src_b: &[q15], dst: &mut [q15]) {
100 crate::intrinsics::simd_sub_q15(src_a, src_b, dst);
101}
102
103pub fn sub_q7(src_a: &[q7], src_b: &[q7], dst: &mut [q7]) {
104 let len = src_a.len().min(src_b.len()).min(dst.len());
105 for i in 0..len {
106 dst[i] = src_a[i].saturating_sub(src_b[i]);
107 }
108}
109
110pub fn mult_f32(src_a: &[f32], src_b: &[f32], dst: &mut [f32]) {
113 let len = src_a.len().min(src_b.len()).min(dst.len());
114 for i in 0..len {
115 dst[i] = src_a[i] * src_b[i];
116 }
117}
118
119pub fn mult_f64(src_a: &[f64], src_b: &[f64], dst: &mut [f64]) {
120 let len = src_a.len().min(src_b.len()).min(dst.len());
121 for i in 0..len {
122 dst[i] = src_a[i] * src_b[i];
123 }
124}
125
126pub fn mult_q31(src_a: &[q31], src_b: &[q31], dst: &mut [q31]) {
127 let len = src_a.len().min(src_b.len()).min(dst.len());
128 for i in 0..len {
129 dst[i] = q31_mult(src_a[i], src_b[i]);
130 }
131}
132
133pub fn mult_q15(src_a: &[q15], src_b: &[q15], dst: &mut [q15]) {
134 crate::intrinsics::simd_mult_q15(src_a, src_b, dst);
135}
136
137pub fn mult_q7(src_a: &[q7], src_b: &[q7], dst: &mut [q7]) {
138 let len = src_a.len().min(src_b.len()).min(dst.len());
139 for i in 0..len {
140 dst[i] = q7_mult(src_a[i], src_b[i]);
141 }
142}
143
144pub fn negate_f32(src: &[f32], dst: &mut [f32]) {
147 let len = src.len().min(dst.len());
148 for i in 0..len {
149 dst[i] = -src[i];
150 }
151}
152
153pub fn negate_f64(src: &[f64], dst: &mut [f64]) {
154 let len = src.len().min(dst.len());
155 for i in 0..len {
156 dst[i] = -src[i];
157 }
158}
159
160pub fn negate_q31(src: &[q31], dst: &mut [q31]) {
161 let len = src.len().min(dst.len());
162 for i in 0..len {
163 dst[i] = src[i].saturating_neg();
164 }
165}
166
167pub fn negate_q15(src: &[q15], dst: &mut [q15]) {
168 let len = src.len().min(dst.len());
169 for i in 0..len {
170 dst[i] = src[i].saturating_neg();
171 }
172}
173
174pub fn negate_q7(src: &[q7], dst: &mut [q7]) {
175 let len = src.len().min(dst.len());
176 for i in 0..len {
177 dst[i] = src[i].saturating_neg();
178 }
179}
180
181pub fn offset_f32(src: &[f32], offset: f32, dst: &mut [f32]) {
184 let len = src.len().min(dst.len());
185 for i in 0..len {
186 dst[i] = src[i] + offset;
187 }
188}
189
190pub fn offset_f64(src: &[f64], offset: f64, dst: &mut [f64]) {
191 let len = src.len().min(dst.len());
192 for i in 0..len {
193 dst[i] = src[i] + offset;
194 }
195}
196
197pub fn offset_q31(src: &[q31], offset: q31, dst: &mut [q31]) {
198 let len = src.len().min(dst.len());
199 for i in 0..len {
200 dst[i] = src[i].saturating_add(offset);
201 }
202}
203
204pub fn offset_q15(src: &[q15], offset: q15, dst: &mut [q15]) {
205 let len = src.len().min(dst.len());
206 for i in 0..len {
207 dst[i] = src[i].saturating_add(offset);
208 }
209}
210
211pub fn offset_q7(src: &[q7], offset: q7, dst: &mut [q7]) {
212 let len = src.len().min(dst.len());
213 for i in 0..len {
214 dst[i] = src[i].saturating_add(offset);
215 }
216}
217
218pub fn scale_f32(src: &[f32], scale: f32, dst: &mut [f32]) {
221 let len = src.len().min(dst.len());
222 for i in 0..len {
223 dst[i] = src[i] * scale;
224 }
225}
226
227pub fn scale_f64(src: &[f64], scale: f64, dst: &mut [f64]) {
228 let len = src.len().min(dst.len());
229 for i in 0..len {
230 dst[i] = src[i] * scale;
231 }
232}
233
234pub fn scale_q31(src: &[q31], scale_fract: q31, shift: i8, dst: &mut [q31]) {
235 let len = src.len().min(dst.len());
236 let k_shift = 31 - shift;
237 for i in 0..len {
238 let mult = (src[i].to_bits() as i64 * scale_fract.to_bits() as i64)
239 >> if k_shift >= 0 { k_shift as u32 } else { 0 };
240 let val = if k_shift < 0 {
241 mult << (-k_shift as u32)
242 } else {
243 mult
244 };
245 dst[i] = q31::from_bits(val.clamp(i32::MIN as i64, i32::MAX as i64) as i32);
246 }
247}
248
249pub fn scale_q15(src: &[q15], scale_fract: q15, shift: i8, dst: &mut [q15]) {
250 let len = src.len().min(dst.len());
251 let k_shift = 15 - shift;
252 for i in 0..len {
253 let mult = (src[i].to_bits() as i32 * scale_fract.to_bits() as i32)
254 >> if k_shift >= 0 { k_shift as u32 } else { 0 };
255 let val = if k_shift < 0 {
256 mult << (-k_shift as u32)
257 } else {
258 mult
259 };
260 dst[i] = q15::from_bits(val.clamp(i16::MIN as i32, i16::MAX as i32) as i16);
261 }
262}
263
264pub fn scale_q7(src: &[q7], scale_fract: q7, shift: i8, dst: &mut [q7]) {
265 let len = src.len().min(dst.len());
266 let k_shift = 7 - shift;
267 for i in 0..len {
268 let mult = (src[i].to_bits() as i32 * scale_fract.to_bits() as i32)
269 >> if k_shift >= 0 { k_shift as u32 } else { 0 };
270 let val = if k_shift < 0 {
271 mult << (-k_shift as u32)
272 } else {
273 mult
274 };
275 dst[i] = q7::from_bits(val.clamp(i8::MIN as i32, i8::MAX as i32) as i8);
276 }
277}
278
279pub fn shift_q31(src: &[q31], shift_bits: i8, dst: &mut [q31]) {
282 let len = src.len().min(dst.len());
283 for i in 0..len {
284 if shift_bits >= 0 {
285 dst[i] = q31::from_bits(
286 ((src[i].to_bits() as i64) << shift_bits).clamp(i32::MIN as i64, i32::MAX as i64)
287 as i32,
288 );
289 } else {
290 dst[i] = q31::from_bits(src[i].to_bits() >> (-shift_bits));
291 }
292 }
293}
294
295pub fn shift_q15(src: &[q15], shift_bits: i8, dst: &mut [q15]) {
296 let len = src.len().min(dst.len());
297 for i in 0..len {
298 if shift_bits >= 0 {
299 dst[i] = q15::from_bits(
300 ((src[i].to_bits() as i32) << shift_bits).clamp(i16::MIN as i32, i16::MAX as i32)
301 as i16,
302 );
303 } else {
304 dst[i] = q15::from_bits(src[i].to_bits() >> (-shift_bits));
305 }
306 }
307}
308
309pub fn shift_q7(src: &[q7], shift_bits: i8, dst: &mut [q7]) {
310 let len = src.len().min(dst.len());
311 for i in 0..len {
312 if shift_bits >= 0 {
313 dst[i] = q7::from_bits(
314 ((src[i].to_bits() as i32) << shift_bits).clamp(i8::MIN as i32, i8::MAX as i32)
315 as i8,
316 );
317 } else {
318 dst[i] = q7::from_bits(src[i].to_bits() >> (-shift_bits));
319 }
320 }
321}
322
323pub fn dot_prod_f32(src_a: &[f32], src_b: &[f32]) -> f32 {
326 let len = src_a.len().min(src_b.len());
327 let mut sum = 0.0f32;
328 for i in 0..len {
329 sum += src_a[i] * src_b[i];
330 }
331 sum
332}
333
334pub fn dot_prod_f64(src_a: &[f64], src_b: &[f64]) -> f64 {
335 let len = src_a.len().min(src_b.len());
336 let mut sum = 0.0f64;
337 for i in 0..len {
338 sum += src_a[i] * src_b[i];
339 }
340 sum
341}
342
343pub fn dot_prod_q31(src_a: &[q31], src_b: &[q31]) -> q63 {
344 let len = src_a.len().min(src_b.len());
345 let mut sum: q63 = 0;
346 for i in 0..len {
347 sum += (src_a[i].to_bits() as i64 * src_b[i].to_bits() as i64) >> 14;
348 }
349 sum
350}
351
352pub fn dot_prod_q15(src_a: &[q15], src_b: &[q15]) -> q63 {
353 crate::intrinsics::simd_dot_prod_q15(src_a, src_b)
354}
355
356pub fn dot_prod_q7(src_a: &[q7], src_b: &[q7]) -> q31 {
357 let len = src_a.len().min(src_b.len());
358 let mut sum = q31::ZERO;
359 for i in 0..len {
360 sum += q31::from_bits(src_a[i].to_bits() as i32 * src_b[i].to_bits() as i32);
361 }
362 sum
363}
364
365pub fn clip_f32(src: &[f32], low: f32, high: f32, dst: &mut [f32]) {
368 let len = src.len().min(dst.len());
369 for i in 0..len {
370 dst[i] = src[i].clamp(low, high);
371 }
372}
373
374pub fn clip_q31(src: &[q31], low: q31, high: q31, dst: &mut [q31]) {
375 let len = src.len().min(dst.len());
376 for i in 0..len {
377 dst[i] = src[i].clamp(low, high);
378 }
379}
380
381pub fn clip_q15(src: &[q15], low: q15, high: q15, dst: &mut [q15]) {
382 let len = src.len().min(dst.len());
383 for i in 0..len {
384 dst[i] = src[i].clamp(low, high);
385 }
386}
387
388pub fn clip_q7(src: &[q7], low: q7, high: q7, dst: &mut [q7]) {
389 let len = src.len().min(dst.len());
390 for i in 0..len {
391 dst[i] = src[i].clamp(low, high);
392 }
393}
394
395pub fn and_u32(src_a: &[u32], src_b: &[u32], dst: &mut [u32]) {
398 let len = src_a.len().min(src_b.len()).min(dst.len());
399 for i in 0..len {
400 dst[i] = src_a[i] & src_b[i];
401 }
402}
403
404pub fn and_u16(src_a: &[u16], src_b: &[u16], dst: &mut [u16]) {
405 let len = src_a.len().min(src_b.len()).min(dst.len());
406 for i in 0..len {
407 dst[i] = src_a[i] & src_b[i];
408 }
409}
410
411pub fn and_u8(src_a: &[u8], src_b: &[u8], dst: &mut [u8]) {
412 let len = src_a.len().min(src_b.len()).min(dst.len());
413 for i in 0..len {
414 dst[i] = src_a[i] & src_b[i];
415 }
416}
417
418pub fn or_u32(src_a: &[u32], src_b: &[u32], dst: &mut [u32]) {
419 let len = src_a.len().min(src_b.len()).min(dst.len());
420 for i in 0..len {
421 dst[i] = src_a[i] | src_b[i];
422 }
423}
424
425pub fn or_u16(src_a: &[u16], src_b: &[u16], dst: &mut [u16]) {
426 let len = src_a.len().min(src_b.len()).min(dst.len());
427 for i in 0..len {
428 dst[i] = src_a[i] | src_b[i];
429 }
430}
431
432pub fn or_u8(src_a: &[u8], src_b: &[u8], dst: &mut [u8]) {
433 let len = src_a.len().min(src_b.len()).min(dst.len());
434 for i in 0..len {
435 dst[i] = src_a[i] | src_b[i];
436 }
437}
438
439pub fn not_u32(src: &[u32], dst: &mut [u32]) {
440 let len = src.len().min(dst.len());
441 for i in 0..len {
442 dst[i] = !src[i];
443 }
444}
445
446pub fn not_u16(src: &[u16], dst: &mut [u16]) {
447 let len = src.len().min(dst.len());
448 for i in 0..len {
449 dst[i] = !src[i];
450 }
451}
452
453pub fn not_u8(src: &[u8], dst: &mut [u8]) {
454 let len = src.len().min(dst.len());
455 for i in 0..len {
456 dst[i] = !src[i];
457 }
458}
459
460pub fn xor_u32(src_a: &[u32], src_b: &[u32], dst: &mut [u32]) {
461 let len = src_a.len().min(src_b.len()).min(dst.len());
462 for i in 0..len {
463 dst[i] = src_a[i] ^ src_b[i];
464 }
465}
466
467pub fn xor_u16(src_a: &[u16], src_b: &[u16], dst: &mut [u16]) {
468 let len = src_a.len().min(src_b.len()).min(dst.len());
469 for i in 0..len {
470 dst[i] = src_a[i] ^ src_b[i];
471 }
472}
473
474pub fn xor_u8(src_a: &[u8], src_b: &[u8], dst: &mut [u8]) {
475 let len = src_a.len().min(src_b.len()).min(dst.len());
476 for i in 0..len {
477 dst[i] = src_a[i] ^ src_b[i];
478 }
479}