Commit 4260025d authored by rtoy's avatar rtoy Committed by Commit bot

Implement cancelValuesAndHoldAtTime

cancelValuesAndHoldAtTime(time) should cancel all events after time |time|
and when the context current time reaches |time|, the automation value
that is current at that time is held as if setValueAtTime were called
with the appropriate value and time.

Spec: https://webaudio.github.io/web-audio-api/#widl-AudioParam-cancelAndHoldAtTime-AudioParam-double-cancelTime
Intent: https://groups.google.com/a/chromium.org/d/msg/blink-dev/IftXib6yFyw/CLoxngG9BgAJ

BUG=432934
TEST=audioparam-cancel-scheduled-values.html

Review-Url: https://codereview.chromium.org/1533103002
Cr-Commit-Position: refs/heads/master@{#442916}
parent 97501194
......@@ -149,6 +149,7 @@ interface AudioParam
getter minValue
getter value
method cancelScheduledValues
method cancelValuesAndHoldAtTime
method constructor
method exponentialRampToValueAtTime
method linearRampToValueAtTime
......
......@@ -149,6 +149,7 @@ interface AudioParam
getter minValue
getter value
method cancelScheduledValues
method cancelValuesAndHoldAtTime
method constructor
method exponentialRampToValueAtTime
method linearRampToValueAtTime
......
......@@ -149,6 +149,7 @@ interface AudioParam
getter minValue
getter value
method cancelScheduledValues
method cancelValuesAndHoldAtTime
method constructor
method exponentialRampToValueAtTime
method linearRampToValueAtTime
......
......@@ -214,6 +214,7 @@ interface AudioParam
getter minValue
getter value
method cancelScheduledValues
method cancelValuesAndHoldAtTime
method constructor
method exponentialRampToValueAtTime
method linearRampToValueAtTime
......
......@@ -517,4 +517,11 @@ AudioParam* AudioParam::cancelScheduledValues(double startTime,
return this;
}
AudioParam* AudioParam::cancelValuesAndHoldAtTime(
double startTime,
ExceptionState& exceptionState) {
handler().timeline().cancelValuesAndHoldAtTime(startTime, exceptionState);
return this;
}
} // namespace blink
......@@ -251,6 +251,7 @@ class AudioParam final : public GarbageCollectedFinalized<AudioParam>,
double duration,
ExceptionState&);
AudioParam* cancelScheduledValues(double startTime, ExceptionState&);
AudioParam* cancelValuesAndHoldAtTime(double startTime, ExceptionState&);
private:
AudioParam(BaseAudioContext&,
......
......@@ -50,4 +50,7 @@ interface AudioParam {
// Cancels all scheduled parameter changes with times greater than or equal to startTime.
[RaisesException, MeasureAs=AudioParamCancelScheduledValues] AudioParam cancelScheduledValues(double startTime);
// Cancel scheduled parameter changes and hold the last value
[RaisesException] AudioParam cancelValuesAndHoldAtTime(double startTime);
};
......@@ -64,6 +64,7 @@ class AudioParamTimeline {
double duration,
ExceptionState&);
void cancelScheduledValues(double startTime, ExceptionState&);
void cancelValuesAndHoldAtTime(double cancelTime, ExceptionState&);
// hasValue is set to true if a valid timeline value is returned.
// otherwise defaultValue is returned.
......@@ -105,27 +106,50 @@ class AudioParamTimeline {
ExponentialRampToValue,
SetTarget,
SetValueCurve,
// For cancelValuesAndHold
CancelValues,
LastType
};
static ParamEvent createLinearRampEvent(float value,
double time,
float initialValue,
double callTime);
static ParamEvent createExponentialRampEvent(float value,
double time,
float initialValue,
double callTime);
static ParamEvent createSetValueEvent(float value, double time);
static ParamEvent createSetTargetEvent(float value,
double time,
double timeConstant);
static ParamEvent createSetValueCurveEvent(const DOMFloat32Array* curve,
double time,
double duration);
static bool eventPreceeds(const ParamEvent& a, const ParamEvent& b) {
return a.time() < b.time();
static std::unique_ptr<ParamEvent> createLinearRampEvent(float value,
double time,
float initialValue,
double callTime);
static std::unique_ptr<ParamEvent> createExponentialRampEvent(
float value,
double time,
float initialValue,
double callTime);
static std::unique_ptr<ParamEvent> createSetValueEvent(float value,
double time);
static std::unique_ptr<ParamEvent>
createSetTargetEvent(float value, double time, double timeConstant);
static std::unique_ptr<ParamEvent> createSetValueCurveEvent(
const DOMFloat32Array* curve,
double time,
double duration);
static std::unique_ptr<ParamEvent> createCancelValuesEvent(
double time,
std::unique_ptr<ParamEvent> savedEvent);
// Needed for creating a saved event where we want to supply all
// the possible parameters because we're mostly copying an
// existing event.
static std::unique_ptr<ParamEvent> createGeneralEvent(
Type,
float value,
double time,
float initialValue,
double callTime,
double timeConstant,
double duration,
Vector<float>& curve,
double curvePointsPerSecond,
float curveEndValue,
std::unique_ptr<ParamEvent> savedEvent);
static bool eventPreceeds(const std::unique_ptr<ParamEvent>& a,
const std::unique_ptr<ParamEvent>& b) {
return a->time() < b->time();
}
Type getType() const { return m_type; }
......@@ -140,34 +164,104 @@ class AudioParamTimeline {
bool needsTimeClampCheck() const { return m_needsTimeClampCheck; }
void clearTimeClampCheck() { m_needsTimeClampCheck = false; }
double curvePointsPerSecond() const { return m_curvePointsPerSecond; }
float curveEndValue() const { return m_curveEndValue; }
// For CancelValues events. Not valid for any other event.
ParamEvent* savedEvent() const;
bool hasDefaultCancelledValue() const;
void setCancelledValue(float);
private:
// General event
ParamEvent(Type type,
float value,
double time,
float initialValue,
double callTime,
double timeConstant,
double duration,
Vector<float>& curve,
double curvePointsPerSecond,
float curveEndValue,
std::unique_ptr<ParamEvent> savedEvent);
// Create simplest event needing just a value and time, like
// setValueAtTime.
ParamEvent(Type, float value, double time);
// Create a linear or exponential ramp that requires an initial
// value and time in case there is no actual event that preceeds
// this event.
ParamEvent(Type,
float value,
double time,
float initialValue,
double callTime);
// Create an event needing a time constant (setTargetAtTime)
ParamEvent(Type, float value, double time, double timeConstant);
// Create a setValueCurve event
ParamEvent(Type,
double time,
double duration,
const DOMFloat32Array* curve,
float initialValue = 0,
double callTime = 0);
double curvePointsPerSecond,
float curveEndValue);
// Create CancelValues event
ParamEvent(Type, double time, std::unique_ptr<ParamEvent> savedEvent);
Type m_type;
// The value for the event. The interpretation of this depends on
// the event type. Not used for SetValueCurve. For CancelValues,
// it is the end value to use when cancelling a LinearRampToValue
// or ExponentialRampToValue event.
float m_value;
// The time for the event. The interpretation of this depends on
// the event type.
double m_time;
// Only used for SetTarget events
double m_timeConstant;
// Only used for SetValueCurve events.
double m_duration;
Vector<float> m_curve;
// Initial value and time to use for linear and exponential ramps that don't
// have a preceding event.
float m_initialValue;
double m_callTime;
// Only used for SetTarget events
double m_timeConstant;
// The following items are only used for SetValueCurve events.
//
// The duration of the curve.
double m_duration;
// The array of curve points.
Vector<float> m_curve;
// The number of curve points per second. it is used to compute
// the curve index step when running the automation.
double m_curvePointsPerSecond;
// The default value to use at the end of the curve. Normally
// it's the last entry in m_curve, but cancelling a SetValueCurve
// will set this to a new value.
float m_curveEndValue;
// For CancelValues. If CancelValues is in the middle of an event, this
// holds the event that is being cancelled, so that processing can
// continue as if the event still existed up until we reach the actual
// scheduled cancel time.
std::unique_ptr<ParamEvent> m_savedEvent;
// True if the start time needs to be checked against current time
// to implement clamping.
bool m_needsTimeClampCheck;
// True if a default value has been assigned to the CancelValues event.
bool m_hasDefaultCancelledValue;
};
void insertEvent(const ParamEvent&, ExceptionState&);
void insertEvent(std::unique_ptr<ParamEvent>, ExceptionState&);
float valuesForFrameRangeImpl(size_t startFrame,
size_t endFrame,
float defaultValue,
......@@ -178,7 +272,33 @@ class AudioParamTimeline {
// Produce a nice string describing the event in human-readable form.
String eventToString(const ParamEvent&);
Vector<ParamEvent> m_events;
// Automation functions that compute the vlaue of the specified
// automation at the specified time.
float linearRampAtTime(double t,
float value1,
double time1,
float value2,
double time2);
float exponentialRampAtTime(double t,
float value1,
double time1,
float value2,
double time2);
float targetValueAtTime(double t,
float value1,
double time1,
float value2,
float timeConstant);
float valueCurveAtTime(double t,
double time1,
double duration,
const float* curveData,
unsigned curveLength);
// Vector of all automation events for the AudioParam. Access must
// be locked via m_eventsLock.
Vector<std::unique_ptr<ParamEvent>> m_events;
mutable Mutex m_eventsLock;
......
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