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"
25
25
hrtf = " 0.8.1"
26
26
llq = " 0.1.1"
27
27
log = " 0.4"
28
+ no_denormals = " 0.1.2"
28
29
num-complex = " 0.4"
29
30
realfft = " 3.3"
30
31
rubato = " 0.14"
Original file line number Diff line number Diff line change @@ -399,10 +399,21 @@ impl Graph {
399
399
let params = AudioParamValues :: from ( & * nodes) ;
400
400
scope. node_id . set ( * index) ;
401
401
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
+
402
412
// We are abusing AssertUnwindSafe here, we cannot guarantee it upholds.
403
413
// This may lead to logic bugs later on, but it is the best that we can do.
404
414
// 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
+
406
417
match panic:: catch_unwind ( catch_me) {
407
418
Ok ( tail_time) => ( true , tail_time) ,
408
419
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