Index: third_party/WebKit/Source/modules/webaudio/AudioParamTimeline.cpp |
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioParamTimeline.cpp b/third_party/WebKit/Source/modules/webaudio/AudioParamTimeline.cpp |
index 3954f121531c1dbed524d9ce6d377c7e4ed0e7f6..5402035431cc77970a891efffd4f6d3ad9811478 100644 |
--- a/third_party/WebKit/Source/modules/webaudio/AudioParamTimeline.cpp |
+++ b/third_party/WebKit/Source/modules/webaudio/AudioParamTimeline.cpp |
@@ -405,6 +405,19 @@ float AudioParamTimeline::valuesForFrameRangeImpl( |
continue; |
} |
+ ParamEvent::Type nextEventType = nextEvent ? static_cast<ParamEvent::Type>(nextEvent->type()) : ParamEvent::LastType /* unknown */; |
+ |
+ // If the current event is SetTarget and the next event is a LinearRampToValue or |
+ // ExponentialRampToValue, special handling is needed. In this case, the linear and |
+ // exponential ramp should start at wherever the SetTarget processing has reached. |
+ if (event.type() == ParamEvent::SetTarget |
+ && (nextEventType == ParamEvent::LinearRampToValue |
+ || nextEventType == ParamEvent::ExponentialRampToValue)) { |
+ // Replace the SetTarget with a SetValue to set the starting time and value for the ramp |
+ // using the current frame and value. |
+ m_events[i] = ParamEvent::createSetValueEvent(value, currentFrame / sampleRate); |
+ } |
+ |
float value1 = event.value(); |
double time1 = event.time(); |
@@ -426,7 +439,6 @@ float AudioParamTimeline::valuesForFrameRangeImpl( |
size_t fillToFrame = fillToEndFrame - startFrame; |
fillToFrame = std::min(fillToFrame, static_cast<size_t>(numberOfValues)); |
- ParamEvent::Type nextEventType = nextEvent ? static_cast<ParamEvent::Type>(nextEvent->type()) : ParamEvent::LastType /* unknown */; |
// First handle linear and exponential ramps which require looking ahead to the next event. |
if (nextEventType == ParamEvent::LinearRampToValue) { |
@@ -510,6 +522,10 @@ float AudioParamTimeline::valuesForFrameRangeImpl( |
value *= multiplier; |
++currentFrame; |
} |
+ // Due to roundoff it's possible that value exceeds value2. Clip value to value2 if |
+ // we are within 1/2 frame of time2. |
+ if (currentFrame > time2 * sampleRate - 0.5) |
+ value = value2; |
} |
} else { |
// Handle event types not requiring looking ahead to the next event. |