Skip to content

Commit 734f6f0

Browse files
committed
fix: review faulty test + fix wrong condition
1 parent 84f136b commit 734f6f0

File tree

1 file changed

+43
-32
lines changed

1 file changed

+43
-32
lines changed

src/node/audio_buffer_source.rs

Lines changed: 43 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -401,23 +401,24 @@ impl AudioBufferSourceRenderer {
401401
ControlMessage::LoopEnd(loop_end) => self.loop_state.end = *loop_end,
402402
}
403403

404+
// @todo -
404405
self.clamp_loop_boundaries();
405406
}
406407

407408
fn clamp_loop_boundaries(&mut self) {
408409
if let Some(buffer) = &self.buffer {
409410
let duration = buffer.duration();
410411

412+
// https://webaudio.github.io/web-audio-api/#dom-audiobuffersourcenode-loopstart
411413
if self.loop_state.start < 0. {
412414
self.loop_state.start = 0.;
413-
}
414-
415-
if self.loop_state.start > duration {
415+
} else if self.loop_state.start > duration {
416416
self.loop_state.start = duration;
417417
}
418418

419+
// https://webaudio.github.io/web-audio-api/#dom-audiobuffersourcenode-loopend
419420
if self.loop_state.end <= 0. || self.loop_state.end > duration {
420-
self.loop_state.end = 0.;
421+
self.loop_state.end = duration;
421422
}
422423
}
423424
}
@@ -469,8 +470,6 @@ impl AudioProcessor for AudioBufferSourceRenderer {
469470
end: loop_end,
470471
} = self.loop_state;
471472

472-
println!("infos: {loop_start}, {loop_end}");
473-
474473
// these will only be used if `loop_` is true, so no need for `Option`
475474
let mut actual_loop_start = 0.;
476475
let mut actual_loop_end = 0.;
@@ -526,9 +525,11 @@ impl AudioProcessor for AudioBufferSourceRenderer {
526525
// For now we just consider that we can go fast track if loop points are
527526
// bound to the buffer boundaries.
528527
//
529-
// by default loop_end is 0., see AudioBufferSourceOptions
530-
// but loop_start = 0 && loop_end = buffer.duration should go to fast track
531-
if loop_start != 0. || (loop_end != 0. && loop_end != self.duration) {
528+
// by default loop_end is equal to buffer_duration, so loop_start = 0 &&
529+
// loop_end = buffer.duration should go to fast track
530+
531+
// @todo - test loop_end against 0 too, semantics is loop_end as not been changed
532+
if loop_start != 0. || loop_end != buffer_duration {
532533
self.render_state.is_aligned = false;
533534
}
534535

@@ -556,9 +557,8 @@ impl AudioProcessor for AudioBufferSourceRenderer {
556557
buffer.length()
557558
};
558559

559-
// in case of a loop point in the middle of the block, this value
560-
// will be used to recompute `buffer_time` according
561-
// to the actual loop point.
560+
// In case of a loop point in the middle of the block, this value will
561+
// be used to recompute `buffer_time` according to the actual loop point.
562562
let mut loop_point_index: Option<usize> = None;
563563

564564
buffer
@@ -624,6 +624,7 @@ impl AudioProcessor for AudioBufferSourceRenderer {
624624
if is_looping {
625625
if loop_start >= 0. && loop_end > 0. && loop_start < loop_end {
626626
actual_loop_start = loop_start;
627+
// @todo - min is not required loop_end is already clamped
627628
actual_loop_end = loop_end.min(buffer_duration);
628629
} else {
629630
actual_loop_start = 0.;
@@ -740,25 +741,22 @@ impl AudioProcessor for AudioBufferSourceRenderer {
740741
}) => {
741742
// `prev_frame_index` cannot be out of bounds
742743
let prev_sample = buffer_channel[*prev_frame_index];
743-
744-
// @todo - stiching between loop points
745744
let next_sample = match buffer_channel.get(prev_frame_index + 1)
746745
{
747746
Some(val) => *val,
748747
None => {
749-
// @todo - this works only in "normal" case
750-
// - check invalid loop points
751-
// - playback_rate < 0.
748+
// @todo - handle playback_rate < 0.
752749
//
753750
// find first sample >= to start loop point
754751
if is_looping {
755-
let start_playhead = actual_loop_start * sample_rate;
756-
let start_index = if start_playhead.floor() == start_playhead {
757-
start_playhead as usize
758-
} else {
759-
start_playhead as usize + 1
760-
};
761-
println!("{actual_loop_start}, {actual_loop_end}");
752+
let start_playhead =
753+
actual_loop_start * sample_rate;
754+
let start_index =
755+
if start_playhead.floor() == start_playhead {
756+
start_playhead as usize
757+
} else {
758+
start_playhead as usize + 1
759+
};
762760

763761
buffer_channel[start_index]
764762
} else {
@@ -1426,7 +1424,7 @@ mod tests {
14261424
expected[i] = 1.;
14271425
}
14281426

1429-
assert_float_eq!(channel[..], expected[..], abs_all <= 0.);
1427+
assert_float_eq!(channel[..], expected[..], abs_all <= 1e-10);
14301428
}
14311429
}
14321430

@@ -1511,12 +1509,12 @@ mod tests {
15111509
assert_float_eq!(
15121510
result.get_channel_data(0)[..],
15131511
expected_left[..],
1514-
abs_all <= 0.
1512+
abs_all <= 1e-10
15151513
);
15161514
assert_float_eq!(
15171515
result.get_channel_data(1)[..],
15181516
expected_right[..],
1519-
abs_all <= 0.
1517+
abs_all <= 1e-10
15201518
);
15211519
}
15221520
}
@@ -1574,12 +1572,14 @@ mod tests {
15741572
}
15751573

15761574
#[test]
1577-
fn test_loop_hangs() {
1575+
// @todo - test all conditions
1576+
fn test_loop_out_of_bounds() {
15781577
let sample_rate = 48_000.;
15791578
let length = sample_rate as usize / 10;
15801579
let mut context = OfflineAudioContext::new(1, length, sample_rate);
15811580

1582-
let mut buffer = context.create_buffer(1, 500, sample_rate);
1581+
let buffer_size = 500;
1582+
let mut buffer = context.create_buffer(1, buffer_size, sample_rate);
15831583
let data = vec![1.; 1];
15841584
buffer.copy_to_channel(&data, 0);
15851585

@@ -1590,14 +1590,25 @@ mod tests {
15901590
src.set_loop(true);
15911591
src.set_loop_start(0.5); // outside of buffer duration
15921592
src.set_loop_end(1.5); // outside of buffer duration
1593-
15941593
src.start();
15951594

15961595
let result = context.start_rendering_sync(); // should terminate
15971596
let channel = result.get_channel_data(0);
15981597

1599-
assert_float_eq!(channel[0], 1.0, abs_all <= 0.);
1600-
assert_float_eq!(channel[1..], vec![0.; length - 1][..], abs_all <= 0.);
1598+
// Both loop points will be clamped to buffer duration due to rules defined at
1599+
// https://webaudio.github.io/web-audio-api/#dom-audiobuffersourcenode-loopstart
1600+
// https://webaudio.github.io/web-audio-api/#dom-audiobuffersourcenode-loopend
1601+
// Thus it violates the rule defined in
1602+
// https://webaudio.github.io/web-audio-api/#playback-AudioBufferSourceNode
1603+
// `loopStart >= 0 && loopEnd > 0 && loopStart < loopEnd`
1604+
// Hence the whole buffer should be looped
1605+
1606+
let mut expected = vec![0.; length];
1607+
for i in (0..length).step_by(buffer_size) {
1608+
expected[i] = 1.;
1609+
}
1610+
1611+
assert_float_eq!(channel[..], expected[..], abs_all <= 0.);
16011612
}
16021613

16031614
#[test]

0 commit comments

Comments
 (0)