Skip to content

Commit bb70ed1

Browse files
committed
AudioBufferSourceNode: move early exit up, deduplicate 'ended' path
1 parent 7c2e6d0 commit bb70ed1

File tree

1 file changed

+21
-41
lines changed

1 file changed

+21
-41
lines changed

src/node/audio_buffer_source.rs

Lines changed: 21 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -411,25 +411,15 @@ impl AudioProcessor for AudioBufferSourceRenderer {
411411
params: AudioParamValues<'_>,
412412
scope: &AudioWorkletGlobalScope,
413413
) -> bool {
414-
// single output node
414+
// Single output node
415415
let output = &mut outputs[0];
416416

417417
let sample_rate = scope.sample_rate as f64;
418418
let dt = 1. / sample_rate;
419419
let block_duration = dt * RENDER_QUANTUM_SIZE as f64;
420420
let next_block_time = scope.current_time + block_duration;
421421

422-
let LoopState {
423-
is_looping,
424-
start: loop_start,
425-
end: loop_end,
426-
} = self.loop_state;
427-
428-
// these will only be used if `loop_` is true, so no need for `Option`
429-
let mut actual_loop_start = 0.;
430-
let mut actual_loop_end = 0.;
431-
432-
// return early if start_time is beyond this block
422+
// Return early if start_time is beyond this block
433423
if self.start_time >= next_block_time {
434424
output.make_silent();
435425
return true;
@@ -444,6 +434,16 @@ impl AudioProcessor for AudioBufferSourceRenderer {
444434
Some(b) => b,
445435
};
446436

437+
let LoopState {
438+
is_looping,
439+
start: loop_start,
440+
end: loop_end,
441+
} = self.loop_state;
442+
443+
// these will only be used if `loop_` is true, so no need for `Option`
444+
let mut actual_loop_start = 0.;
445+
let mut actual_loop_end = 0.;
446+
447447
// compute compound parameter at k-rate, these parameters have constraints
448448
// https://webaudio.github.io/web-audio-api/#audioparam-automation-rate-constraints
449449
let detune = params.get(&self.detune)[0];
@@ -456,15 +456,20 @@ impl AudioProcessor for AudioBufferSourceRenderer {
456456
// we just linearly interpolate, thus favoring performance vs quality
457457
let sampling_ratio = buffer.sample_rate() as f64 / sample_rate;
458458

459-
// In addition, if the buffer has more than one channel, then the
460-
// AudioBufferSourceNode output must change to a single channel of silence
461-
// at the beginning of a render quantum after the time at which any one of
462-
// the following conditions holds:
459+
// Load the buffer time from the render state.
460+
// The render state has to be updated before leaving this method!
461+
let mut buffer_time = self.render_state.buffer_time.load(Ordering::Relaxed);
463462

463+
// The output must change to a single channel of silence at the beginning of a render
464+
// quantum after the time at which any one of the following conditions holds:
464465
// 1. the stop time has been reached.
465466
// 2. the duration has been reached.
467+
// 3. the end of the buffer has been reached.
466468
if scope.current_time >= self.stop_time
467469
|| self.render_state.buffer_time_elapsed >= self.duration
470+
|| !is_looping
471+
&& (computed_playback_rate > 0. && buffer_time >= buffer_duration
472+
|| computed_playback_rate < 0. && buffer_time < 0.)
468473
{
469474
output.make_silent(); // also converts to mono
470475

@@ -477,31 +482,6 @@ impl AudioProcessor for AudioBufferSourceRenderer {
477482
return false;
478483
}
479484

480-
// Load the buffer time from the render state.
481-
// The render state has to be updated before leaving this method!
482-
let mut buffer_time = self.render_state.buffer_time.load(Ordering::Relaxed);
483-
484-
// 3. the end of the buffer has been reached.
485-
if !is_looping {
486-
if computed_playback_rate > 0. && buffer_time >= buffer_duration {
487-
output.make_silent(); // also converts to mono
488-
if !self.ended_triggered {
489-
scope.send_ended_event();
490-
self.ended_triggered = true;
491-
}
492-
return false;
493-
}
494-
495-
if computed_playback_rate < 0. && buffer_time < 0. {
496-
output.make_silent(); // also converts to mono
497-
if !self.ended_triggered {
498-
scope.send_ended_event();
499-
self.ended_triggered = true;
500-
}
501-
return false;
502-
}
503-
}
504-
505485
output.set_number_of_channels(buffer.number_of_channels());
506486

507487
// go through the algorithm described in the spec

0 commit comments

Comments
 (0)