File tree Expand file tree Collapse file tree 3 files changed +47
-1
lines changed Expand file tree Collapse file tree 3 files changed +47
-1
lines changed Original file line number Diff line number Diff line change @@ -25,6 +25,7 @@ hound = "3.5"
2525hrtf = " 0.8.1"
2626llq = " 0.1.1"
2727log = " 0.4"
28+ no_denormals = " 0.1.2"
2829num-complex = " 0.4"
2930realfft = " 3.3"
3031rubato = " 0.14"
Original file line number Diff line number Diff line change @@ -399,10 +399,21 @@ impl Graph {
399399 let params = AudioParamValues :: from ( & * nodes) ;
400400 scope. node_id . set ( * index) ;
401401 let ( success, tail_time) = {
402+ // for x64 and aarch, process with denormal floats disabled (for performance, #194)
403+ #[ cfg( any( target_arch = "x86" , target_arch = "x86_64" , target_arch = "aarch64" ) ) ]
404+ let process_fn = || no_denormals:: no_denormals ( || node. process ( params, scope) ) ;
405+ #[ cfg( not( any(
406+ target_arch = "x86" ,
407+ target_arch = "x86_64" ,
408+ target_arch = "aarch64"
409+ ) ) ) ]
410+ let process_fn = node. process ( params, scope) ;
411+
402412 // We are abusing AssertUnwindSafe here, we cannot guarantee it upholds.
403413 // This may lead to logic bugs later on, but it is the best that we can do.
404414 // The alternative is to crash and reboot the render thread.
405- let catch_me = AssertUnwindSafe ( || node. process ( params, scope) ) ;
415+ let catch_me = AssertUnwindSafe ( process_fn) ;
416+
406417 match panic:: catch_unwind ( catch_me) {
407418 Ok ( tail_time) => ( true , tail_time) ,
408419 Err ( e) => {
Original file line number Diff line number Diff line change 1+ use web_audio_api:: context:: { BaseAudioContext , OfflineAudioContext } ;
2+ use web_audio_api:: node:: { AudioNode , AudioScheduledSourceNode } ;
3+
4+ #[ test]
5+ fn test_flush_denormals ( ) {
6+ let context = OfflineAudioContext :: new ( 1 , 128 , 48000. ) ;
7+
8+ let mut signal = context. create_constant_source ( ) ;
9+ signal. start ( ) ;
10+
11+ let gain1 = context. create_gain ( ) ;
12+ gain1. gain ( ) . set_value ( 0.001 ) ;
13+ signal. connect ( & gain1) ;
14+
15+ let gain2 = context. create_gain ( ) ;
16+ gain2. gain ( ) . set_value ( f32:: MIN_POSITIVE ) ;
17+ gain1. connect ( & gain2) ;
18+
19+ let gain2 = context. create_gain ( ) ;
20+ gain2. gain ( ) . set_value ( f32:: MIN_POSITIVE ) ;
21+ gain1. connect ( & gain2) ;
22+
23+ let gain3 = context. create_gain ( ) ;
24+ gain3. gain ( ) . set_value ( f32:: MAX ) ;
25+ gain2. connect ( & gain3) ;
26+
27+ gain3. connect ( & context. destination ( ) ) ;
28+
29+ let output = context. start_rendering_sync ( ) ;
30+
31+ // When denormals are flushed, we expect the output to be exactly 0.0
32+ // If not, the output will be ~0.004
33+ assert_eq ! ( output. get_channel_data( 0 ) , & [ 0. ; 128 ] [ ..] ) ;
34+ }
You can’t perform that action at this time.
0 commit comments