@@ -197,24 +197,14 @@ impl DelayNode {
197197 "NotSupportedError - maxDelayTime MUST be greater than zero and less than three minutes" ,
198198 ) ;
199199
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 ;
215205 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 ) ;
218208
219209 let shared_ring_buffer = Rc :: new ( RefCell :: new ( ring_buffer) ) ;
220210 let shared_ring_buffer_clone = Rc :: clone ( & shared_ring_buffer) ;
@@ -707,60 +697,59 @@ mod tests {
707697 }
708698
709699 #[ 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) ;
715704
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 ( ) ) ;
719708
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 ) ;
722711
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. ) ;
727716
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 ) ;
730719
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 ;
734723
735- assert_float_eq ! ( channel[ ..] , expected[ ..] , abs_all <= 0.00001 ) ;
736- }
724+ assert_float_eq ! ( channel[ ..] , expected[ ..] , abs_all <= 0.00001 ) ;
725+ }
737726
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) ;
742732
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 ( ) ) ;
746736
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 ) ;
749739
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. ) ;
754744
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 ) ;
757747
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 ;
761751
762- assert_float_eq ! ( channel[ ..] , expected[ ..] , abs_all <= 1e-5 ) ;
763- }
752+ assert_float_eq ! ( channel[ ..] , expected[ ..] , abs_all <= 1e-5 ) ;
764753 }
765754
766755 #[ test]
@@ -935,6 +924,60 @@ mod tests {
935924 assert_float_eq ! ( channel[ ..] , expected[ ..] , abs_all <= 0. ) ;
936925 }
937926
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+
938981 #[ test]
939982 fn test_max_delay_smaller_than_quantum_size ( ) {
940983 // regression test that even if the declared max_delay_time is smaller than
@@ -975,64 +1018,65 @@ mod tests {
9751018 }
9761019 }
9771020
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
9781026 #[ 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 ( ) {
9851028 // 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) ;
9891031
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 ( ) ) ;
9931036
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 ) ;
9961039
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. ) ;
10011044
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 ) ;
10041047
1005- let mut expected = vec ! [ 0. ; 256 ] ;
1006- expected[ 128 ] = 1. ;
1048+ let mut expected = vec ! [ 0. ; 256 ] ;
1049+ expected[ 128 ] = 1. ;
10071050
1008- assert_float_eq ! ( channel[ ..] , expected[ ..] , abs_all <= 1e-5 ) ;
1009- }
1051+ assert_float_eq ! ( channel[ ..] , expected[ ..] , abs_all <= 1e-5 ) ;
1052+ }
10101053
1054+ #[ test]
1055+ fn test_max_delay_multiple_of_quantum_size_2 ( ) {
10111056 // 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) ;
10151059
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 ( ) ) ;
10191064
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 ) ;
10221067
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. ) ;
10271072
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 ) ;
10301075
1031- let mut expected = vec ! [ 0. ; 3 * 128 ] ;
1032- expected[ 256 ] = 1. ;
1076+ let mut expected = vec ! [ 0. ; 3 * 128 ] ;
1077+ expected[ 256 ] = 1. ;
10331078
1034- assert_float_eq ! ( channel[ ..] , expected[ ..] , abs_all <= 1e-5 ) ;
1035- }
1079+ assert_float_eq ! ( channel[ ..] , expected[ ..] , abs_all <= 1e-5 ) ;
10361080 }
10371081
10381082 #[ test]
0 commit comments