@@ -8,8 +8,14 @@ use param::{Param, ParamType};
8
8
pub enum AudioBufferSourceNodeMessage {
9
9
/// Set the data block holding the audio sample data to be played.
10
10
SetBuffer ( Option < AudioBuffer > ) ,
11
+ /// Set loop parameter.
12
+ SetLoopEnabled ( bool ) ,
13
+ /// Set loop parameter.
14
+ SetLoopEnd ( f64 ) ,
15
+ /// Set loop parameter.
16
+ SetLoopStart ( f64 ) ,
11
17
/// Set start parameters (when, offset, duration).
12
- Start ( f64 , Option < f64 > , Option < f64 > ) ,
18
+ SetStartParams ( f64 , Option < f64 > , Option < f64 > ) ,
13
19
}
14
20
15
21
/// This specifies options for constructing an AudioBufferSourceNode.
@@ -81,7 +87,7 @@ pub(crate) struct AudioBufferSourceNode {
81
87
/// Duration parameter passed to Start().
82
88
start_duration : Option < f64 > ,
83
89
/// The same as start_at, but with subsample accuracy.
84
- /// FIXME: Maybe AudioScheduledSourceNode should use this as well?
90
+ /// FIXME: AudioScheduledSourceNode should use this as well.
85
91
start_when : f64 ,
86
92
/// Time at which the source should stop playing.
87
93
stop_at : Option < Tick > ,
@@ -116,7 +122,18 @@ impl AudioBufferSourceNode {
116
122
AudioBufferSourceNodeMessage :: SetBuffer ( buffer) => {
117
123
self . buffer = buffer;
118
124
}
119
- AudioBufferSourceNodeMessage :: Start ( when, offset, duration) => {
125
+ // XXX(collares): To fully support dynamically updating loop bounds,
126
+ // Must truncate self.buffer_pos if it is now outside the loop.
127
+ AudioBufferSourceNodeMessage :: SetLoopEnabled ( loop_enabled) => {
128
+ self . loop_enabled = loop_enabled
129
+ }
130
+ AudioBufferSourceNodeMessage :: SetLoopEnd ( loop_end) => {
131
+ self . loop_end = Some ( loop_end)
132
+ }
133
+ AudioBufferSourceNodeMessage :: SetLoopStart ( loop_start) => {
134
+ self . loop_start = Some ( loop_start)
135
+ }
136
+ AudioBufferSourceNodeMessage :: SetStartParams ( when, offset, duration) => {
120
137
self . start_when = when;
121
138
self . start_offset = offset;
122
139
self . start_duration = duration;
@@ -163,6 +180,7 @@ impl AudioNodeEngine for AudioBufferSourceNode {
163
180
}
164
181
}
165
182
183
+ // https://webaudio.github.io/web-audio-api/#computedplaybackrate
166
184
self . playback_rate . update ( info, Tick ( 0 ) ) ;
167
185
self . detune . update ( info, Tick ( 0 ) ) ;
168
186
// computed_playback_rate can be negative or zero.
@@ -189,9 +207,7 @@ impl AudioNodeEngine for AudioBufferSourceNode {
189
207
if forward && self . buffer_pos >= actual_loop_end {
190
208
self . buffer_pos = actual_loop_start;
191
209
}
192
- // XXX(collares): This is technically not in the spec, but it's the
193
- // only thing that makes sense. I suspect the spec was not fully
194
- // updated for negative playbackRates.
210
+ // https://github.com/WebAudio/web-audio-api/issues/2031
195
211
if !forward && self . buffer_pos < actual_loop_start {
196
212
self . buffer_pos = actual_loop_end;
197
213
}
@@ -374,6 +390,7 @@ impl AudioBuffer {
374
390
// XXX(collares): There are better fast interpolation algorithms.
375
391
// Firefox uses (via Speex's resampler) the algorithm described in
376
392
// https://ccrma.stanford.edu/~jos/resample/resample.pdf
393
+ // There are Rust bindings: https://github.com/rust-av/speexdsp-rs
377
394
pub fn interpolate ( & self , chan : u8 , pos : f64 ) -> f32 {
378
395
debug_assert ! ( pos >= 0. && pos < self . len( ) as f64 ) ;
379
396
0 commit comments