audio_engine_core/
runtime.rs1thread_local! {
2 static AUDIO_THREAD_FLOAT_MODE_INITIALIZED: std::cell::Cell<bool> =
3 const { std::cell::Cell::new(false) };
4}
5
6pub fn audio_thread_init() {
12 AUDIO_THREAD_FLOAT_MODE_INITIALIZED.with(|initialized| {
13 if initialized.get() {
14 return;
15 }
16 set_audio_thread_float_mode();
17 initialized.set(true);
18 });
19}
20
21#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
22fn set_audio_thread_float_mode() {
23 const DAZ_BIT: u32 = 1 << 6;
24 const FTZ_BIT: u32 = 1 << 15;
25
26 unsafe {
29 let mut mxcsr = read_mxcsr();
30 mxcsr |= DAZ_BIT | FTZ_BIT;
31 write_mxcsr(mxcsr);
32 }
33}
34
35#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
36unsafe fn read_mxcsr() -> u32 {
37 let mut mxcsr = 0u32;
38 unsafe {
41 std::arch::asm!("stmxcsr [{}]", in(reg) &mut mxcsr, options(nostack, preserves_flags));
42 }
43 mxcsr
44}
45
46#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
47unsafe fn write_mxcsr(mxcsr: u32) {
48 unsafe {
51 std::arch::asm!("ldmxcsr [{}]", in(reg) &mxcsr, options(nostack, preserves_flags));
52 }
53}
54
55#[cfg(target_arch = "aarch64")]
56fn set_audio_thread_float_mode() {
57 let mut fpcr: u64;
58 unsafe {
61 std::arch::asm!("mrs {fpcr}, fpcr", fpcr = out(reg) fpcr);
62 fpcr |= 1 << 24;
63 std::arch::asm!("msr fpcr, {fpcr}", fpcr = in(reg) fpcr);
64 }
65}
66
67#[cfg(not(any(target_arch = "x86", target_arch = "x86_64", target_arch = "aarch64")))]
68fn set_audio_thread_float_mode() {
69 log::warn!("Audio thread FTZ/DAZ mode is unsupported on this CPU architecture");
70}
71
72#[cfg(any(test, debug_assertions))]
73pub fn audio_thread_float_mode_is_enabled() -> bool {
74 audio_thread_init();
75 audio_thread_float_mode_is_enabled_unchecked()
76}
77
78#[cfg(all(
79 any(test, debug_assertions),
80 any(target_arch = "x86", target_arch = "x86_64")
81))]
82fn audio_thread_float_mode_is_enabled_unchecked() -> bool {
83 const DAZ_BIT: u32 = 1 << 6;
84 const FTZ_BIT: u32 = 1 << 15;
85
86 let csr = unsafe { read_mxcsr() };
88 csr & (DAZ_BIT | FTZ_BIT) == (DAZ_BIT | FTZ_BIT)
89}
90
91#[cfg(all(any(test, debug_assertions), target_arch = "aarch64"))]
92fn audio_thread_float_mode_is_enabled_unchecked() -> bool {
93 let fpcr: u64;
94 unsafe {
96 std::arch::asm!("mrs {fpcr}, fpcr", fpcr = out(reg) fpcr);
97 }
98 fpcr & (1 << 24) != 0
99}
100
101#[cfg(all(
102 any(test, debug_assertions),
103 not(any(target_arch = "x86", target_arch = "x86_64", target_arch = "aarch64"))
104))]
105fn audio_thread_float_mode_is_enabled_unchecked() -> bool {
106 false
107}
108
109#[inline(always)]
110pub fn flush_subnormal_sample(sample: f64) -> f64 {
111 #[cfg(any(target_arch = "x86", target_arch = "x86_64", target_arch = "aarch64"))]
112 {
113 sample
114 }
115
116 #[cfg(not(any(target_arch = "x86", target_arch = "x86_64", target_arch = "aarch64")))]
117 {
118 if sample != 0.0 && sample.abs() < f64::MIN_POSITIVE {
119 0.0
120 } else {
121 sample
122 }
123 }
124}