Commit 7a87148a authored by Raymond Toy's avatar Raymond Toy Committed by Commit Bot

cancelScheduledValues removes setValueCurveAtTime

If the time requested in cancelScheduledValues overlaps the time of a
setValueCurveAtTime, then the setValueCurveAtTime is also removed.

Bug: 1063502
Change-Id: I6e8bd4bf802cd76f26b46f60905f977ab76d5b5b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2121353Reviewed-by: default avatarHongchan Choi <hongchan@chromium.org>
Commit-Queue: Raymond Toy <rtoy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#754612}
parent 6a7f0221
...@@ -694,7 +694,7 @@ bool AudioParamTimeline::HasValues(size_t current_frame, ...@@ -694,7 +694,7 @@ bool AudioParamTimeline::HasValues(size_t current_frame,
} }
void AudioParamTimeline::CancelScheduledValues( void AudioParamTimeline::CancelScheduledValues(
double start_time, double cancel_time,
ExceptionState& exception_state) { ExceptionState& exception_state) {
DCHECK(IsMainThread()); DCHECK(IsMainThread());
...@@ -702,7 +702,21 @@ void AudioParamTimeline::CancelScheduledValues( ...@@ -702,7 +702,21 @@ void AudioParamTimeline::CancelScheduledValues(
// Remove all events starting at startTime. // Remove all events starting at startTime.
for (wtf_size_t i = 0; i < events_.size(); ++i) { for (wtf_size_t i = 0; i < events_.size(); ++i) {
if (events_[i]->Time() >= start_time) { // Removal all events whose event time (start) is greater than or
// equal to the cancel time. And also handle the special case
// where the cancel time lies in the middle of a setValueCurve
// event.
//
// This critically depends on the fact that no event can be
// scheduled in the middle of the curve or at the same start time.
// Then removing the setValueCurve doesn't remove any events that
// shouldn't have been.
double start_time = events_[i]->Time();
if (start_time >= cancel_time ||
((events_[i]->GetType() == ParamEvent::kSetValueCurve) &&
start_time <= cancel_time &&
(start_time + events_[i]->Duration() > cancel_time))) {
RemoveCancelledEvents(i); RemoveCancelledEvents(i);
break; break;
} }
......
<!doctype html>
<html>
<head>
<title>
cancelScheduledValues
</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/webaudio/resources/audit-util.js"></script>
<script src="/webaudio/resources/audit.js"></script>
</head>
<body>
<script>
let sampleRate = 8000;
let renderFrames = 8000;
let audit = Audit.createTaskRunner();
audit.define(
{label: 'cancel1', description: 'cancel setValueCurve'},
(task, should) => {
let context = new OfflineAudioContext({
numberOfChannels: 1,
length: renderFrames,
sampleRate: sampleRate
});
let src = new ConstantSourceNode(context);
let gain = new GainNode(context);
src.connect(gain).connect(context.destination);
// Initial time and value for first automation (setValue)
let time0 = 0;
let value0 = 0.5;
// Time and duration of the setValueCurve. We'll also schedule a
// setValue at the same time.
let value1 = 1.5;
let curveStartTime = 0.25;
let curveDuration = 0.25;
// Time at which to cancel events
let cancelTime = 0.3;
// Time and value for event added after cancelScheduledValues has
// been called.
let time2 = curveStartTime + curveDuration / 2;
let value2 = 3;
// Self-consistency checks for the test.
should(cancelTime, 'cancelTime is after curve start')
.beGreaterThan(curveStartTime);
should(cancelTime, 'cancelTime is before curve ends')
.beLessThan(curveStartTime + curveDuration);
// These assertions are just to show what's happening
should(
() => gain.gain.setValueAtTime(value0, time0),
`gain.gain.setValueAtTime(${value0}, ${time0})`)
.notThrow();
// setValue at the sime time as the curve, to test that this event
// wasn't rmeoved.
should(
() => gain.gain.setValueAtTime(value1, curveStartTime),
`gain.gain.setValueAtTime(${value1}, ${curveStartTime})`)
.notThrow();
should(
() => gain.gain.setValueCurveAtTime(
[1, -1], curveStartTime, curveDuration),
`gain.gain.setValueCurveAtTime(..., ${curveStartTime}, ${
curveDuration})`)
.notThrow();
// An event after the curve to verify this is removed.
should(
() => gain.gain.setValueAtTime(
99, curveStartTime + curveDuration),
`gain.gain.setValueAtTime(99, ${
curveStartTime + curveDuration})`)
.notThrow();
// Cancel events now.
should(
() => gain.gain.cancelScheduledValues(cancelTime),
`gain.gain.cancelScheduledValues(${cancelTime})`)
.notThrow();
// Simple check that the setValueCurve is gone, by scheduling
// something in the middle of the (now deleted) event
should(
() => gain.gain.setValueAtTime(value2, time2),
`gain.gain.setValueAtTime(${value2}, ${time2})`)
.notThrow();
src.start();
context.startRendering()
.then(buffer => {
let audio = buffer.getChannelData(0);
// After canceling events, verify that the outputs have the
// desired values.
let curveFrame = curveStartTime * context.sampleRate;
should(
audio.slice(0, curveFrame), `output[0:${curveFrame - 1}]`)
.beConstantValueOf(value0);
let time2Frame = time2 * context.sampleRate;
should(
audio.slice(curveFrame, time2Frame),
`output[${curveFrame}:${time2Frame - 1}]`)
.beConstantValueOf(value1);
should(audio.slice(time2Frame), `output[${time2Frame}:]`)
.beConstantValueOf(value2);
})
.then(() => task.done());
});
audit.run();
</script>
</body>
</html>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment