#![allow(unsafe_code)]
#[cfg(any(target_arch = "aarch64", target_arch = "x86", target_arch = "x86_64"))]
use super::arch;
use super::scalar;
#[cfg(target_arch = "aarch64")]
#[cfg_attr(not(tarpaulin), inline(always))]
pub(super) fn neon_available() -> bool {
if cfg!(firered_vad_force_scalar) {
return false;
}
std::arch::is_aarch64_feature_detected!("neon")
}
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
#[cfg_attr(not(tarpaulin), inline(always))]
pub(super) fn avx512_available() -> bool {
if cfg!(firered_vad_force_scalar) || cfg!(firered_vad_disable_avx512) {
return false;
}
std::arch::is_x86_feature_detected!("avx512f")
}
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
#[cfg_attr(not(tarpaulin), inline(always))]
pub(super) fn avx2_available() -> bool {
if cfg!(firered_vad_force_scalar) || cfg!(firered_vad_disable_avx2) {
return false;
}
std::arch::is_x86_feature_detected!("avx2") && std::arch::is_x86_feature_detected!("fma")
}
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
#[cfg_attr(not(tarpaulin), inline(always))]
pub(super) fn sse41_available() -> bool {
if cfg!(firered_vad_force_scalar) {
return false;
}
std::arch::is_x86_feature_detected!("sse4.1")
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub(super) fn pcm_scale_extend(pcm: &[f32], out: &mut [f32]) {
scalar::pcm_scale_extend(pcm, out);
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub(super) fn dc_remove(window: &[f32], out: &mut [f32]) {
#[cfg(target_arch = "aarch64")]
{
if neon_available() {
unsafe { arch::neon::dc_remove(window, out) };
return;
}
}
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
{
if avx512_available() {
unsafe { arch::x86_avx512::dc_remove(window, out) };
return;
}
if avx2_available() {
unsafe { arch::x86_avx2::dc_remove(window, out) };
return;
}
if sse41_available() {
unsafe { arch::x86_sse41::dc_remove(window, out) };
return;
}
}
scalar::dc_remove(window, out);
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub(super) fn pre_emphasis(samples: &mut [f32]) {
scalar::pre_emphasis(samples);
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub(super) fn window_apply(samples: &mut [f32], window: &[f32]) {
#[cfg(target_arch = "aarch64")]
{
if neon_available() {
unsafe { arch::neon::window_apply(samples, window) };
return;
}
}
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
{
if avx512_available() {
unsafe { arch::x86_avx512::window_apply(samples, window) };
return;
}
if avx2_available() {
unsafe { arch::x86_avx2::window_apply(samples, window) };
return;
}
if sse41_available() {
unsafe { arch::x86_sse41::window_apply(samples, window) };
return;
}
}
scalar::window_apply(samples, window);
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub(super) fn power_spectrum(complex: &[rustfft::num_complex::Complex<f32>], out: &mut [f32]) {
#[cfg(target_arch = "aarch64")]
{
if neon_available() {
unsafe { arch::neon::power_spectrum(complex, out) };
return;
}
}
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
{
if avx512_available() {
unsafe { arch::x86_avx512::power_spectrum(complex, out) };
return;
}
if avx2_available() {
unsafe { arch::x86_avx2::power_spectrum(complex, out) };
return;
}
if sse41_available() {
unsafe { arch::x86_sse41::power_spectrum(complex, out) };
return;
}
}
scalar::power_spectrum(complex, out);
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub(super) fn cmvn_apply(feature: &mut [f32], means: &[f32], istd: &[f32]) {
#[cfg(target_arch = "aarch64")]
{
if neon_available() {
unsafe { arch::neon::cmvn_apply(feature, means, istd) };
return;
}
}
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
{
if avx512_available() {
unsafe { arch::x86_avx512::cmvn_apply(feature, means, istd) };
return;
}
if avx2_available() {
unsafe { arch::x86_avx2::cmvn_apply(feature, means, istd) };
return;
}
if sse41_available() {
unsafe { arch::x86_sse41::cmvn_apply(feature, means, istd) };
return;
}
}
scalar::cmvn_apply(feature, means, istd);
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub(super) fn mel_dot_log(power_slice: &[f32], weights: &[f32]) -> f32 {
#[cfg(target_arch = "aarch64")]
{
if neon_available() {
return unsafe { arch::neon::mel_dot_log(power_slice, weights) };
}
}
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
{
if avx512_available() {
return unsafe { arch::x86_avx512::mel_dot_log(power_slice, weights) };
}
if avx2_available() {
return unsafe { arch::x86_avx2::mel_dot_log(power_slice, weights) };
}
if sse41_available() {
return unsafe { arch::x86_sse41::mel_dot_log(power_slice, weights) };
}
}
scalar::mel_dot_log(power_slice, weights)
}