@@ -1222,6 +1222,42 @@ mod tests {
12221222 assert_float_eq ! ( channel[ ..] , expected[ ..] , abs_all <= 1e-6 ) ;
12231223 }
12241224
1225+ #[ test]
1226+ fn test_negative_playback_rate ( ) {
1227+ let sample_rate = 44_100 ;
1228+ let mut context = OfflineAudioContext :: new ( 1 , sample_rate, sample_rate as f32 ) ;
1229+
1230+ let mut buffer = context. create_buffer ( 1 , sample_rate, sample_rate as f32 ) ;
1231+ let mut sine = vec ! [ ] ;
1232+
1233+ // 1 Hz sine
1234+ for i in 0 ..sample_rate {
1235+ let phase = i as f32 / sample_rate as f32 * 2. * PI ;
1236+ let sample = phase. sin ( ) ;
1237+ sine. push ( sample) ;
1238+ }
1239+
1240+ buffer. copy_to_channel ( & sine[ ..] , 0 ) ;
1241+
1242+ let mut src = context. create_buffer_source ( ) ;
1243+ src. connect ( & context. destination ( ) ) ;
1244+ src. set_buffer ( buffer. clone ( ) ) ;
1245+ src. playback_rate . set_value ( -1. ) ;
1246+ src. start_at_with_offset ( context. current_time ( ) , buffer. duration ( ) ) ;
1247+
1248+ let result = context. start_rendering_sync ( ) ;
1249+ let channel = result. get_channel_data ( 0 ) ;
1250+
1251+ // -1 Hz sine
1252+ let mut expected: Vec < f32 > = sine. into_iter ( ) . rev ( ) . collect ( ) ;
1253+ // offset is at duration (after last sample), then result will start
1254+ // with a zero value
1255+ expected. pop ( ) ;
1256+ expected. insert ( 0 , 0. ) ;
1257+
1258+ assert_float_eq ! ( channel[ ..] , expected[ ..] , abs_all <= 1e-6 ) ;
1259+ }
1260+
12251261 #[ test]
12261262 fn test_detune ( ) {
12271263 let sample_rate = 44_100 ;
0 commit comments