pub mod mel;
pub mod peaks;
pub mod resample;
pub mod stft;
pub mod windows;
pub(crate) const DB_LOG2_FACTOR: f32 = 10.0 / core::f32::consts::LOG2_10;
#[inline]
pub(crate) fn power_to_db_wide(buf: &mut [f32], floor: f32) {
use wide::f32x8;
let n = buf.len();
let chunks = n / 8;
let tail_start = chunks * 8;
let floor_v = f32x8::splat(floor);
let factor_v = f32x8::splat(DB_LOG2_FACTOR);
for i in 0..chunks {
let off = i * 8;
let v = f32x8::new(
buf[off..off + 8]
.try_into()
.expect("buf chunk is exactly 8 elements: loop iterates n/8 complete chunks"),
);
let clamped = v.max(floor_v);
let db = factor_v * clamped.log2();
buf[off..off + 8].copy_from_slice(db.as_array());
}
for v in &mut buf[tail_start..] {
*v = DB_LOG2_FACTOR * v.max(floor).log2();
}
}
#[inline]
pub(crate) fn dot_wide(a: &[f32], b: &[f32]) -> f32 {
use wide::f32x8;
debug_assert_eq!(a.len(), b.len());
let n = a.len();
let chunks = n / 8;
let tail_start = chunks * 8;
let mut acc = f32x8::ZERO;
for i in 0..chunks {
let off = i * 8;
let va = f32x8::new(
a[off..off + 8]
.try_into()
.expect("a chunk is exactly 8 elements: loop iterates n/8 complete chunks"),
);
let vb = f32x8::new(
b[off..off + 8]
.try_into()
.expect("b chunk is exactly 8 elements: loop iterates n/8 complete chunks"),
);
acc = va.mul_add(vb, acc);
}
let mut sum = acc.reduce_add();
for i in tail_start..n {
sum += a[i] * b[i];
}
sum
}
#[inline]
pub(crate) fn dot_sq_wide(a: &[f32], b: &[f32]) -> f32 {
use wide::f32x8;
debug_assert_eq!(a.len(), b.len());
let n = a.len();
let chunks = n / 8;
let tail_start = chunks * 8;
let mut acc = f32x8::ZERO;
for i in 0..chunks {
let off = i * 8;
let va = f32x8::new(
a[off..off + 8]
.try_into()
.expect("a chunk is exactly 8 elements: loop iterates n/8 complete chunks"),
);
let vb = f32x8::new(
b[off..off + 8]
.try_into()
.expect("b chunk is exactly 8 elements: loop iterates n/8 complete chunks"),
);
let vb_sq = vb * vb;
acc = va.mul_add(vb_sq, acc);
}
let mut sum = acc.reduce_add();
for i in tail_start..n {
sum += a[i] * (b[i] * b[i]);
}
sum
}