@@ -197,24 +197,14 @@ impl DelayNode {
197
197
"NotSupportedError - maxDelayTime MUST be greater than zero and less than three minutes" ,
198
198
) ;
199
199
200
- // we internally clamp max delay to quantum duration because the current
201
- // implementation doesn't allow sub-quantum delays. Later, this will
202
- // ensure that even if the declared max_delay_time and max_delay are smaller
203
- // than quantum duration, the node, if found in a loop, will gracefully
204
- // fallback to the clamped behavior. (e.g. we ensure that ring buffer size
205
- // is always >= 2)
206
- let quantum_duration = 1. / sample_rate * RENDER_QUANTUM_SIZE as f64 ;
207
- let max_delay_time = options. max_delay_time . max ( quantum_duration) ;
208
-
209
- // allocate large enough buffer to store all delayed samples
210
- //
211
- // we add 1 here so that in edge cases where num_samples is a multiple of
212
- // RENDER_QUANTUM_SIZE and delay_time == max_delay_time we are sure to
213
- // enough room for history. (see. test_max_delay_multiple_of_quantum_size)
214
- let num_samples = max_delay_time * sample_rate + 1. ;
200
+ // Allocate large enough ring buffer to store all delayed samples.
201
+ // We add one extra slot in the ring buffer so that reader never reads the
202
+ // same entry in history as the writer, even if `delay_time == max_delay_time`
203
+ // of if `max_delay_time < quantum duration`
204
+ let max_delay_time = options. max_delay_time ;
215
205
let num_quanta =
216
- ( num_samples . ceil ( ) as usize + RENDER_QUANTUM_SIZE - 1 ) / RENDER_QUANTUM_SIZE ;
217
- let ring_buffer = Vec :: with_capacity ( num_quanta) ;
206
+ ( max_delay_time * sample_rate / RENDER_QUANTUM_SIZE as f64 ) . ceil ( ) as usize ;
207
+ let ring_buffer = Vec :: with_capacity ( num_quanta + 1 ) ;
218
208
219
209
let shared_ring_buffer = Rc :: new ( RefCell :: new ( ring_buffer) ) ;
220
210
let shared_ring_buffer_clone = Rc :: clone ( & shared_ring_buffer) ;
@@ -707,60 +697,59 @@ mod tests {
707
697
}
708
698
709
699
#[ test]
710
- fn test_sub_sample_accurate ( ) {
711
- {
712
- let delay_in_samples = 128.5 ;
713
- let sample_rate = 48_000. ;
714
- let mut context = OfflineAudioContext :: new ( 1 , 256 , sample_rate) ;
700
+ fn test_sub_sample_accurate_1 ( ) {
701
+ let delay_in_samples = 128.5 ;
702
+ let sample_rate = 48_000. ;
703
+ let mut context = OfflineAudioContext :: new ( 1 , 256 , sample_rate) ;
715
704
716
- let delay = context. create_delay ( 2. ) ;
717
- delay. delay_time . set_value ( delay_in_samples / sample_rate) ;
718
- delay. connect ( & context. destination ( ) ) ;
705
+ let delay = context. create_delay ( 2. ) ;
706
+ delay. delay_time . set_value ( delay_in_samples / sample_rate) ;
707
+ delay. connect ( & context. destination ( ) ) ;
719
708
720
- let mut dirac = context. create_buffer ( 1 , 1 , sample_rate) ;
721
- dirac. copy_to_channel ( & [ 1. ] , 0 ) ;
709
+ let mut dirac = context. create_buffer ( 1 , 1 , sample_rate) ;
710
+ dirac. copy_to_channel ( & [ 1. ] , 0 ) ;
722
711
723
- let mut src = context. create_buffer_source ( ) ;
724
- src. connect ( & delay) ;
725
- src. set_buffer ( dirac) ;
726
- src. start_at ( 0. ) ;
712
+ let mut src = context. create_buffer_source ( ) ;
713
+ src. connect ( & delay) ;
714
+ src. set_buffer ( dirac) ;
715
+ src. start_at ( 0. ) ;
727
716
728
- let result = context. start_rendering_sync ( ) ;
729
- let channel = result. get_channel_data ( 0 ) ;
717
+ let result = context. start_rendering_sync ( ) ;
718
+ let channel = result. get_channel_data ( 0 ) ;
730
719
731
- let mut expected = vec ! [ 0. ; 256 ] ;
732
- expected[ 128 ] = 0.5 ;
733
- expected[ 129 ] = 0.5 ;
720
+ let mut expected = vec ! [ 0. ; 256 ] ;
721
+ expected[ 128 ] = 0.5 ;
722
+ expected[ 129 ] = 0.5 ;
734
723
735
- assert_float_eq ! ( channel[ ..] , expected[ ..] , abs_all <= 0.00001 ) ;
736
- }
724
+ assert_float_eq ! ( channel[ ..] , expected[ ..] , abs_all <= 0.00001 ) ;
725
+ }
737
726
738
- {
739
- let delay_in_samples = 128.8 ;
740
- let sample_rate = 48_000. ;
741
- let mut context = OfflineAudioContext :: new ( 1 , 256 , sample_rate) ;
727
+ #[ test]
728
+ fn test_sub_sample_accurate_2 ( ) {
729
+ let delay_in_samples = 128.8 ;
730
+ let sample_rate = 48_000. ;
731
+ let mut context = OfflineAudioContext :: new ( 1 , 256 , sample_rate) ;
742
732
743
- let delay = context. create_delay ( 2. ) ;
744
- delay. delay_time . set_value ( delay_in_samples / sample_rate) ;
745
- delay. connect ( & context. destination ( ) ) ;
733
+ let delay = context. create_delay ( 2. ) ;
734
+ delay. delay_time . set_value ( delay_in_samples / sample_rate) ;
735
+ delay. connect ( & context. destination ( ) ) ;
746
736
747
- let mut dirac = context. create_buffer ( 1 , 1 , sample_rate) ;
748
- dirac. copy_to_channel ( & [ 1. ] , 0 ) ;
737
+ let mut dirac = context. create_buffer ( 1 , 1 , sample_rate) ;
738
+ dirac. copy_to_channel ( & [ 1. ] , 0 ) ;
749
739
750
- let mut src = context. create_buffer_source ( ) ;
751
- src. connect ( & delay) ;
752
- src. set_buffer ( dirac) ;
753
- src. start_at ( 0. ) ;
740
+ let mut src = context. create_buffer_source ( ) ;
741
+ src. connect ( & delay) ;
742
+ src. set_buffer ( dirac) ;
743
+ src. start_at ( 0. ) ;
754
744
755
- let result = context. start_rendering_sync ( ) ;
756
- let channel = result. get_channel_data ( 0 ) ;
745
+ let result = context. start_rendering_sync ( ) ;
746
+ let channel = result. get_channel_data ( 0 ) ;
757
747
758
- let mut expected = vec ! [ 0. ; 256 ] ;
759
- expected[ 128 ] = 0.2 ;
760
- expected[ 129 ] = 0.8 ;
748
+ let mut expected = vec ! [ 0. ; 256 ] ;
749
+ expected[ 128 ] = 0.2 ;
750
+ expected[ 129 ] = 0.8 ;
761
751
762
- assert_float_eq ! ( channel[ ..] , expected[ ..] , abs_all <= 1e-5 ) ;
763
- }
752
+ assert_float_eq ! ( channel[ ..] , expected[ ..] , abs_all <= 1e-5 ) ;
764
753
}
765
754
766
755
#[ test]
@@ -935,6 +924,60 @@ mod tests {
935
924
assert_float_eq ! ( channel[ ..] , expected[ ..] , abs_all <= 0. ) ;
936
925
}
937
926
927
+ // reproduce wpt tests from
928
+ // - the-delaynode-interface/delaynode-max-default-delay.html
929
+ // - the-delaynode-interface/delaynode-max-nondefault-delay.html
930
+ #[ test]
931
+ fn test_max_delay ( ) {
932
+ use std:: f32:: consts:: PI ;
933
+
934
+ for & delay_time_seconds in [ 1. , 1.5 ] . iter ( ) {
935
+ let sample_rate = 44100.0 ;
936
+ let render_length = 4 * sample_rate as usize ;
937
+
938
+ let mut context = OfflineAudioContext :: new ( 1 , render_length, sample_rate) ;
939
+
940
+ // create 2 seconds tone buffer at 20Hz
941
+ let tone_frequency = 20. ;
942
+ let tone_length_seconds = 2. ;
943
+ let tone_length = tone_length_seconds as usize * sample_rate as usize ;
944
+ let mut tone_buffer = context. create_buffer ( 1 , tone_length, sample_rate) ;
945
+ let tone_data = tone_buffer. get_channel_data_mut ( 0 ) ;
946
+
947
+ for ( i, s) in tone_data. iter_mut ( ) . enumerate ( ) {
948
+ * s = ( tone_frequency * 2.0 * PI * i as f32 / sample_rate) . sin ( ) ;
949
+ }
950
+
951
+ let mut buffer_source = context. create_buffer_source ( ) ;
952
+ buffer_source. set_buffer ( tone_buffer. clone ( ) ) ;
953
+
954
+ let delay = context. create_delay ( delay_time_seconds) ; // max delay defaults to 1 second
955
+ delay. delay_time . set_value ( delay_time_seconds as f32 ) ;
956
+
957
+ buffer_source. connect ( & delay) ;
958
+ delay. connect ( & context. destination ( ) ) ;
959
+ buffer_source. start_at ( 0. ) ;
960
+
961
+ let output = context. start_rendering_sync ( ) ;
962
+ let source = tone_buffer. get_channel_data ( 0 ) ;
963
+ let rendered = output. get_channel_data ( 0 ) ;
964
+
965
+ let delay_time_frames = ( delay_time_seconds * sample_rate as f64 ) as usize ;
966
+ let tone_length_frames = ( tone_length_seconds * sample_rate as f64 ) as usize ;
967
+
968
+ for ( i, s) in rendered. iter ( ) . enumerate ( ) {
969
+ if i < delay_time_frames {
970
+ assert_eq ! ( * s, 0. ) ;
971
+ } else if i >= delay_time_frames && i < delay_time_frames + tone_length_frames {
972
+ let j = i - delay_time_frames;
973
+ assert_eq ! ( * s, source[ j] ) ;
974
+ } else {
975
+ assert_eq ! ( * s, 0. ) ;
976
+ }
977
+ }
978
+ }
979
+ }
980
+
938
981
#[ test]
939
982
fn test_max_delay_smaller_than_quantum_size ( ) {
940
983
// regression test that even if the declared max_delay_time is smaller than
@@ -975,64 +1018,65 @@ mod tests {
975
1018
}
976
1019
}
977
1020
1021
+ // test_max_delay_multiple_of_quantum_size_x
1022
+ // are regression test that delay node has always enough internal buffer size
1023
+ // when max_delay is a multiple of quantum size and delay == max_delay.
1024
+ // This bug only occurs when the Writer is called before than the Reader,
1025
+ // which is the case when not in a loop
978
1026
#[ test]
979
- fn test_max_delay_multiple_of_quantum_size ( ) {
980
- // regression test that delay node has always enough internal buffer size
981
- // when max_delay is a multiple of quantum size and delay == max_delay.
982
- // This bug only occurs when the Writer is called before than the Reader,
983
- // which is the case when not in a loop
984
-
1027
+ fn test_max_delay_multiple_of_quantum_size_1 ( ) {
985
1028
// set delay and max delay time exactly 1 render quantum
986
- {
987
- let sample_rate = 48_000. ;
988
- let mut context = OfflineAudioContext :: new ( 1 , 256 , sample_rate) ;
1029
+ let sample_rate = 48_000. ;
1030
+ let mut context = OfflineAudioContext :: new ( 1 , 256 , sample_rate) ;
989
1031
990
- let delay = context. create_delay ( 1. ) ;
991
- delay. delay_time . set_value ( 128. / sample_rate) ;
992
- delay. connect ( & context. destination ( ) ) ;
1032
+ let max_delay = 128. / sample_rate;
1033
+ let delay = context. create_delay ( max_delay. into ( ) ) ;
1034
+ delay. delay_time . set_value ( max_delay) ;
1035
+ delay. connect ( & context. destination ( ) ) ;
993
1036
994
- let mut dirac = context. create_buffer ( 1 , 1 , sample_rate) ;
995
- dirac. copy_to_channel ( & [ 1. ] , 0 ) ;
1037
+ let mut dirac = context. create_buffer ( 1 , 1 , sample_rate) ;
1038
+ dirac. copy_to_channel ( & [ 1. ] , 0 ) ;
996
1039
997
- let mut src = context. create_buffer_source ( ) ;
998
- src. connect ( & delay) ;
999
- src. set_buffer ( dirac) ;
1000
- src. start_at ( 0. ) ;
1040
+ let mut src = context. create_buffer_source ( ) ;
1041
+ src. connect ( & delay) ;
1042
+ src. set_buffer ( dirac) ;
1043
+ src. start_at ( 0. ) ;
1001
1044
1002
- let result = context. start_rendering_sync ( ) ;
1003
- let channel = result. get_channel_data ( 0 ) ;
1045
+ let result = context. start_rendering_sync ( ) ;
1046
+ let channel = result. get_channel_data ( 0 ) ;
1004
1047
1005
- let mut expected = vec ! [ 0. ; 256 ] ;
1006
- expected[ 128 ] = 1. ;
1048
+ let mut expected = vec ! [ 0. ; 256 ] ;
1049
+ expected[ 128 ] = 1. ;
1007
1050
1008
- assert_float_eq ! ( channel[ ..] , expected[ ..] , abs_all <= 1e-5 ) ;
1009
- }
1051
+ assert_float_eq ! ( channel[ ..] , expected[ ..] , abs_all <= 1e-5 ) ;
1052
+ }
1010
1053
1054
+ #[ test]
1055
+ fn test_max_delay_multiple_of_quantum_size_2 ( ) {
1011
1056
// set delay and max delay time exactly 2 render quantum
1012
- {
1013
- let sample_rate = 48_000. ;
1014
- let mut context = OfflineAudioContext :: new ( 1 , 3 * 128 , sample_rate) ;
1057
+ let sample_rate = 48_000. ;
1058
+ let mut context = OfflineAudioContext :: new ( 1 , 3 * 128 , sample_rate) ;
1015
1059
1016
- let delay = context. create_delay ( 2. ) ;
1017
- delay. delay_time . set_value ( 128. * 2. / sample_rate) ;
1018
- delay. connect ( & context. destination ( ) ) ;
1060
+ let max_delay = 128. * 2. / sample_rate;
1061
+ let delay = context. create_delay ( max_delay. into ( ) ) ;
1062
+ delay. delay_time . set_value ( max_delay) ;
1063
+ delay. connect ( & context. destination ( ) ) ;
1019
1064
1020
- let mut dirac = context. create_buffer ( 1 , 1 , sample_rate) ;
1021
- dirac. copy_to_channel ( & [ 1. ] , 0 ) ;
1065
+ let mut dirac = context. create_buffer ( 1 , 1 , sample_rate) ;
1066
+ dirac. copy_to_channel ( & [ 1. ] , 0 ) ;
1022
1067
1023
- let mut src = context. create_buffer_source ( ) ;
1024
- src. connect ( & delay) ;
1025
- src. set_buffer ( dirac) ;
1026
- src. start_at ( 0. ) ;
1068
+ let mut src = context. create_buffer_source ( ) ;
1069
+ src. connect ( & delay) ;
1070
+ src. set_buffer ( dirac) ;
1071
+ src. start_at ( 0. ) ;
1027
1072
1028
- let result = context. start_rendering_sync ( ) ;
1029
- let channel = result. get_channel_data ( 0 ) ;
1073
+ let result = context. start_rendering_sync ( ) ;
1074
+ let channel = result. get_channel_data ( 0 ) ;
1030
1075
1031
- let mut expected = vec ! [ 0. ; 3 * 128 ] ;
1032
- expected[ 256 ] = 1. ;
1076
+ let mut expected = vec ! [ 0. ; 3 * 128 ] ;
1077
+ expected[ 256 ] = 1. ;
1033
1078
1034
- assert_float_eq ! ( channel[ ..] , expected[ ..] , abs_all <= 1e-5 ) ;
1035
- }
1079
+ assert_float_eq ! ( channel[ ..] , expected[ ..] , abs_all <= 1e-5 ) ;
1036
1080
}
1037
1081
1038
1082
#[ test]
0 commit comments