Commit 383cca0d authored by Raymond Toy's avatar Raymond Toy Committed by Commit Bot

Remove SetTarget events when finished

If the last event in the timeline is SetTarget, and the current value
is close enough to the final value, and if enough time has elapsed
since the beginning of the event, we can remove the SetTarget event
from the timeline.

Doing so allows all nodes to use the fast path because the AudioParam
is a constant over the rendering quantum.

Bug: 794712
Test: 
Change-Id: I7274f9ba10b4a31728c6329c0fca3394cb557e7f
Reviewed-on: https://chromium-review.googlesource.com/826124
Commit-Queue: Raymond Toy <rtoy@chromium.org>
Reviewed-by: default avatarHongchan Choi <hongchan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#527127}
parent 6c528868
......@@ -1123,6 +1123,14 @@ void AudioParamTimeline::ClampNewEventsToCurrentTime(double current_time) {
new_events_.clear();
}
// Test that for a SetTarget event, the current value is close enough
// to the target value that we can consider the event to have
// converged to the target.
static bool HasSetTargetConverged(float value, float target) {
return fabs(value - target) < kSetTargetThreshold * fabs(target) ||
(target == 0 && fabs(value) < kSetTargetZeroThreshold);
}
bool AudioParamTimeline::HandleAllEventsInThePast(double current_time,
double sample_rate,
float default_value,
......@@ -1139,9 +1147,22 @@ bool AudioParamTimeline::HandleAllEventsInThePast(double current_time,
// the curve, so we don't need to worry that SetValueCurve time is a
// start time, not an end time.
if (last_event_time +
1.5 * AudioUtilities::kRenderQuantumFrames / sample_rate <
current_time &&
last_event_type != ParamEvent::kSetTarget) {
1.5 * AudioUtilities::kRenderQuantumFrames / sample_rate <
current_time) {
// If the last event is SetTarget, make sure we've converged and, that
// we're at least 5 time constants past the start of the event. If not, we
// have to continue processing it.
if (last_event_type == ParamEvent::kSetTarget) {
if (HasSetTargetConverged(default_value, last_event->Value()) &&
current_time > last_event_time + 5 * last_event->TimeConstant()) {
// We've converged. Slam the default value with the target value.
default_value = last_event->Value();
} else {
// Not converged, so give up; we can't remove this event yet.
return false;
}
}
// |events_| is being mutated. |new_events_| better be empty because there
// are raw pointers there.
DCHECK_EQ(new_events_.size(), 0U);
......@@ -1499,8 +1520,7 @@ std::tuple<size_t, float, unsigned> AudioParamTimeline::ProcessSetTarget(
// If the value is close enough to the target, just fill in the data
// with the target value.
if (fabs(value - target) < kSetTargetThreshold * fabs(target) ||
(!target && fabs(value) < kSetTargetZeroThreshold)) {
if (HasSetTargetConverged(value, target)) {
for (; write_index < fill_to_frame; ++write_index)
values[write_index] = target;
} else {
......
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