diff --git a/content/media/AudioEventTimeline.h b/content/media/AudioEventTimeline.h index a3c6354f651..579e45f48e2 100644 --- a/content/media/AudioEventTimeline.h +++ b/content/media/AudioEventTimeline.h @@ -18,6 +18,58 @@ namespace mozilla { namespace dom { +// This is an internal helper class and should not be used outside of this header. +struct AudioTimelineEvent { + enum Type MOZ_ENUM_TYPE(uint32_t) { + SetValue, + LinearRamp, + ExponentialRamp, + SetTarget, + SetValueCurve + }; + + AudioTimelineEvent(Type aType, double aTime, float aValue, double aTimeConstant = 0.0, + float aDuration = 0.0, float* aCurve = nullptr, uint32_t aCurveLength = 0) + : mType(aType) + , mTimeConstant(aTimeConstant) + , mDuration(aDuration) + { + if (aType == AudioTimelineEvent::SetValueCurve) { + mCurve = aCurve; + mCurveLength = aCurveLength; + } else { + mValue = aValue; + mTime = aTime; + } + } + + bool IsValid() const + { + return IsValid(mTime) && + IsValid(mValue) && + IsValid(mTimeConstant) && + IsValid(mDuration); + } + + Type mType; + union { + float mValue; + uint32_t mCurveLength; + }; + union { + double mTime; + float* mCurve; + }; + double mTimeConstant; + double mDuration; + +private: + static bool IsValid(double value) + { + return MOZ_DOUBLE_IS_FINITE(value); + } +}; + /** * This class will be instantiated with different template arguments for testing and * production code. @@ -28,58 +80,6 @@ namespace dom { template class AudioEventTimeline { -private: - struct Event { - enum Type MOZ_ENUM_TYPE(uint32_t) { - SetValue, - LinearRamp, - ExponentialRamp, - SetTarget, - SetValueCurve - }; - - Event(Type aType, double aTime, float aValue, double aTimeConstant = 0.0, - float aDuration = 0.0, float* aCurve = nullptr, uint32_t aCurveLength = 0) - : mType(aType) - , mTimeConstant(aTimeConstant) - , mDuration(aDuration) - { - if (aType == Event::SetValueCurve) { - mCurve = aCurve; - mCurveLength = aCurveLength; - } else { - mValue = aValue; - mTime = aTime; - } - } - - bool IsValid() const - { - return IsValid(mTime) && - IsValid(mValue) && - IsValid(mTimeConstant) && - IsValid(mDuration); - } - - Type mType; - union { - float mValue; - uint32_t mCurveLength; - }; - union { - double mTime; - float* mCurve; - }; - double mTimeConstant; - double mDuration; - - private: - static bool IsValid(double value) - { - return MOZ_DOUBLE_IS_FINITE(value); - } - }; - public: explicit AudioEventTimeline(float aDefaultValue) : mValue(aDefaultValue) @@ -108,29 +108,29 @@ public: void SetValueAtTime(float aValue, double aStartTime, ErrorResult& aRv) { - InsertEvent(Event(Event::SetValue, aStartTime, aValue), aRv); + InsertEvent(AudioTimelineEvent(AudioTimelineEvent::SetValue, aStartTime, aValue), aRv); } void LinearRampToValueAtTime(float aValue, double aEndTime, ErrorResult& aRv) { - InsertEvent(Event(Event::LinearRamp, aEndTime, aValue), aRv); + InsertEvent(AudioTimelineEvent(AudioTimelineEvent::LinearRamp, aEndTime, aValue), aRv); } void ExponentialRampToValueAtTime(float aValue, double aEndTime, ErrorResult& aRv) { - InsertEvent(Event(Event::ExponentialRamp, aEndTime, aValue), aRv); + InsertEvent(AudioTimelineEvent(AudioTimelineEvent::ExponentialRamp, aEndTime, aValue), aRv); } void SetTargetAtTime(float aTarget, double aStartTime, double aTimeConstant, ErrorResult& aRv) { - InsertEvent(Event(Event::SetTarget, aStartTime, aTarget, aTimeConstant), aRv); + InsertEvent(AudioTimelineEvent(AudioTimelineEvent::SetTarget, aStartTime, aTarget, aTimeConstant), aRv); } void SetValueCurveAtTime(const float* aValues, uint32_t aValuesLength, double aStartTime, double aDuration, ErrorResult& aRv) { // TODO: implement // Note that we will need to copy the buffer here. - // InsertEvent(Event(Event::SetValueCurve, aStartTime, 0.0f, 0.0f, aDuration, aValues, aValuesLength), aRv); + // InsertEvent(AudioTimelineEvent(AudioTimelineEvent::SetValueCurve, aStartTime, 0.0f, 0.0f, aDuration, aValues, aValuesLength), aRv); } void CancelScheduledValues(double aStartTime) @@ -153,16 +153,16 @@ public: // This method computes the AudioParam value at a given time based on the event timeline float GetValueAtTime(double aTime) const { - const Event* previous = nullptr; - const Event* next = nullptr; + const AudioTimelineEvent* previous = nullptr; + const AudioTimelineEvent* next = nullptr; bool bailOut = false; for (unsigned i = 0; !bailOut && i < mEvents.Length(); ++i) { switch (mEvents[i].mType) { - case Event::SetValue: - case Event::SetTarget: - case Event::LinearRamp: - case Event::ExponentialRamp: + case AudioTimelineEvent::SetValue: + case AudioTimelineEvent::SetTarget: + case AudioTimelineEvent::LinearRamp: + case AudioTimelineEvent::ExponentialRamp: if (aTime == mEvents[i].mTime) { // Find the last event with the same time do { @@ -177,7 +177,7 @@ public: bailOut = true; } break; - case Event::SetValueCurve: + case AudioTimelineEvent::SetValueCurve: // TODO: implement break; default: @@ -198,17 +198,17 @@ public: // If the requested time is before all of the existing events if (!previous) { switch (next->mType) { - case Event::SetValue: - case Event::SetTarget: + case AudioTimelineEvent::SetValue: + case AudioTimelineEvent::SetTarget: // The requested time is before the first event return mValue; - case Event::LinearRamp: + case AudioTimelineEvent::LinearRamp: // Use t=0 as T0 and v=defaultValue as V0 return LinearInterpolate(0.0, mValue, next->mTime, next->mValue, aTime); - case Event::ExponentialRamp: + case AudioTimelineEvent::ExponentialRamp: // Use t=0 as T0 and v=defaultValue as V0 return ExponentialInterpolate(0.0, mValue, next->mTime, next->mValue, aTime); - case Event::SetValueCurve: + case AudioTimelineEvent::SetValueCurve: // TODO: implement return 0.0f; } @@ -216,7 +216,7 @@ public: } // SetTarget nodes can be handled no matter what their next node is (if they have one) - if (previous->mType == Event::SetTarget) { + if (previous->mType == AudioTimelineEvent::SetTarget) { // Follow the curve, without regard to the next node return ExponentialApproach(previous->mTime, mValue, previous->mValue, previous->mTimeConstant, aTime); @@ -225,15 +225,15 @@ public: // If the requested time is after all of the existing events if (!next) { switch (previous->mType) { - case Event::SetValue: - case Event::LinearRamp: - case Event::ExponentialRamp: + case AudioTimelineEvent::SetValue: + case AudioTimelineEvent::LinearRamp: + case AudioTimelineEvent::ExponentialRamp: // The value will be constant after the last event return previous->mValue; - case Event::SetValueCurve: + case AudioTimelineEvent::SetValueCurve: // TODO: implement return 0.0f; - case Event::SetTarget: + case AudioTimelineEvent::SetTarget: MOZ_ASSERT(false, "unreached"); } MOZ_ASSERT(false, "unreached"); @@ -243,28 +243,28 @@ public: // First, handle the case where our range ends up in a ramp event switch (next->mType) { - case Event::LinearRamp: + case AudioTimelineEvent::LinearRamp: return LinearInterpolate(previous->mTime, previous->mValue, next->mTime, next->mValue, aTime); - case Event::ExponentialRamp: + case AudioTimelineEvent::ExponentialRamp: return ExponentialInterpolate(previous->mTime, previous->mValue, next->mTime, next->mValue, aTime); - case Event::SetValue: - case Event::SetTarget: - case Event::SetValueCurve: + case AudioTimelineEvent::SetValue: + case AudioTimelineEvent::SetTarget: + case AudioTimelineEvent::SetValueCurve: break; } // Now handle all other cases switch (previous->mType) { - case Event::SetValue: - case Event::LinearRamp: - case Event::ExponentialRamp: + case AudioTimelineEvent::SetValue: + case AudioTimelineEvent::LinearRamp: + case AudioTimelineEvent::ExponentialRamp: // If the next event type is neither linear or exponential ramp, the // value is constant. return previous->mValue; - case Event::SetValueCurve: + case AudioTimelineEvent::SetValueCurve: // TODO: implement return 0.0f; - case Event::SetTarget: + case AudioTimelineEvent::SetTarget: MOZ_ASSERT(false, "unreached"); } @@ -294,18 +294,18 @@ public: } private: - const Event* GetPreviousEvent(double aTime) const + const AudioTimelineEvent* GetPreviousEvent(double aTime) const { - const Event* previous = nullptr; - const Event* next = nullptr; + const AudioTimelineEvent* previous = nullptr; + const AudioTimelineEvent* next = nullptr; bool bailOut = false; for (unsigned i = 0; !bailOut && i < mEvents.Length(); ++i) { switch (mEvents[i].mType) { - case Event::SetValue: - case Event::SetTarget: - case Event::LinearRamp: - case Event::ExponentialRamp: + case AudioTimelineEvent::SetValue: + case AudioTimelineEvent::SetTarget: + case AudioTimelineEvent::LinearRamp: + case AudioTimelineEvent::ExponentialRamp: if (aTime == mEvents[i].mTime) { // Find the last event with the same time do { @@ -320,7 +320,7 @@ private: bailOut = true; } break; - case Event::SetValueCurve: + case AudioTimelineEvent::SetValueCurve: // TODO: implement break; default: @@ -335,7 +335,7 @@ private: return previous; } - void InsertEvent(const Event& aEvent, ErrorResult& aRv) + void InsertEvent(const AudioTimelineEvent& aEvent, ErrorResult& aRv) { if (!aEvent.IsValid()) { aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR); @@ -345,7 +345,7 @@ private: // Make sure that non-curve events don't fall within the duration of a // curve event. for (unsigned i = 0; i < mEvents.Length(); ++i) { - if (mEvents[i].mType == Event::SetValueCurve && + if (mEvents[i].mType == AudioTimelineEvent::SetValueCurve && mEvents[i].mTime <= aEvent.mTime && (mEvents[i].mTime + mEvents[i].mDuration) >= aEvent.mTime) { aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR); @@ -355,7 +355,7 @@ private: // Make sure that curve events don't fall in a range which includes other // events. - if (aEvent.mType == Event::SetValueCurve) { + if (aEvent.mType == AudioTimelineEvent::SetValueCurve) { for (unsigned i = 0; i < mEvents.Length(); ++i) { if (mEvents[i].mTime >= aEvent.mTime && mEvents[i].mTime <= (aEvent.mTime + aEvent.mDuration)) { @@ -366,12 +366,12 @@ private: } // Make sure that invalid values are not used for exponential curves - if (aEvent.mType == Event::ExponentialRamp) { + if (aEvent.mType == AudioTimelineEvent::ExponentialRamp) { if (aEvent.mValue <= 0.f) { aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR); return; } - const Event* previousEvent = GetPreviousEvent(aEvent.mTime); + const AudioTimelineEvent* previousEvent = GetPreviousEvent(aEvent.mTime); if (previousEvent) { if (previousEvent->mValue <= 0.f) { aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR); @@ -418,7 +418,7 @@ private: // and that is the reason why we're using a simple array as the data structure. // We can optimize this in the future if the performance of the array ends up // being a bottleneck. - nsTArray mEvents; + nsTArray mEvents; float mValue; };