--- a/dom/media/webaudio/AudioEventTimeline.cpp
+++ b/dom/media/webaudio/AudioEventTimeline.cpp
@@ -40,18 +40,22 @@ namespace mozilla {
namespace dom {
template <class ErrorResult> bool
AudioEventTimeline::ValidateEvent(AudioTimelineEvent& aEvent,
ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread());
+ auto TimeOf = [](const AudioTimelineEvent& aEvent) -> double {
+ return aEvent.template Time<double>();
+ };
+
// Validate the event itself
- if (!WebAudioUtils::IsTimeValid(aEvent.template Time<double>()) ||
+ if (!WebAudioUtils::IsTimeValid(TimeOf(aEvent)) ||
!WebAudioUtils::IsTimeValid(aEvent.mTimeConstant)) {
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
return false;
}
if (aEvent.mType == AudioTimelineEvent::SetValueCurve) {
if (!aEvent.mCurve || !aEvent.mCurveLength) {
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
@@ -78,48 +82,48 @@ AudioEventTimeline::ValidateEvent(AudioT
return false;
}
// 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 == AudioTimelineEvent::SetValueCurve &&
!(aEvent.mType == AudioTimelineEvent::SetValueCurve &&
- aEvent.template Time<double>() == mEvents[i].template Time<double>()) &&
- mEvents[i].template Time<double>() <= aEvent.template Time<double>() &&
- (mEvents[i].template Time<double>() + mEvents[i].mDuration) >= aEvent.template Time<double>()) {
+ TimeOf(aEvent) == TimeOf(mEvents[i])) &&
+ TimeOf(mEvents[i]) <= TimeOf(aEvent) &&
+ TimeOf(mEvents[i]) + mEvents[i].mDuration >= TimeOf(aEvent)) {
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
return false;
}
}
// Make sure that curve events don't fall in a range which includes other
// events.
if (aEvent.mType == AudioTimelineEvent::SetValueCurve) {
for (unsigned i = 0; i < mEvents.Length(); ++i) {
// In case we have two curve at the same time
if (mEvents[i].mType == AudioTimelineEvent::SetValueCurve &&
- mEvents[i].template Time<double>() == aEvent.template Time<double>()) {
+ TimeOf(mEvents[i]) == TimeOf(aEvent)) {
continue;
}
- if (mEvents[i].template Time<double>() > aEvent.template Time<double>() &&
- mEvents[i].template Time<double>() < (aEvent.template Time<double>() + aEvent.mDuration)) {
+ if (TimeOf(mEvents[i]) > TimeOf(aEvent) &&
+ TimeOf(mEvents[i]) < TimeOf(aEvent) + aEvent.mDuration) {
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
return false;
}
}
}
// Make sure that invalid values are not used for exponential curves
if (aEvent.mType == AudioTimelineEvent::ExponentialRamp) {
if (aEvent.mValue <= 0.f) {
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
return false;
}
- const AudioTimelineEvent* previousEvent = GetPreviousEvent(aEvent.template Time<double>());
+ const AudioTimelineEvent* previousEvent = GetPreviousEvent(TimeOf(aEvent));
if (previousEvent) {
if (previousEvent->mValue <= 0.f) {
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
return false;
}
} else {
if (mValue <= 0.f) {
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
@@ -136,73 +140,77 @@ AudioEventTimeline::ValidateEvent(AudioT
// This method computes the AudioParam value at a given time based on the event timeline
template<class TimeType> void
AudioEventTimeline::GetValuesAtTimeHelper(TimeType aTime, float* aBuffer,
const size_t aSize)
{
MOZ_ASSERT(aBuffer);
MOZ_ASSERT(aSize);
+ auto TimeOf = [](const AudioTimelineEvent& aEvent) -> TimeType {
+ return aEvent.template Time<TimeType>();
+ };
+
size_t eventIndex = 0;
const AudioTimelineEvent* previous = nullptr;
const AudioTimelineEvent* next = nullptr;
bool bailOut = false;
// Let's remove old events except the last one: we need it to calculate some curves.
while (mEvents.Length() > 1 &&
- aTime > mEvents[1].template Time<TimeType>()) {
+ aTime > TimeOf(mEvents[1])) {
mEvents.RemoveElementAt(0);
}
for (size_t bufferIndex = 0; bufferIndex < aSize; ++bufferIndex, ++aTime) {
for (; !bailOut && eventIndex < mEvents.Length(); ++eventIndex) {
#ifdef DEBUG
const AudioTimelineEvent* current = &mEvents[eventIndex];
MOZ_ASSERT(current->mType == AudioTimelineEvent::SetValueAtTime ||
current->mType == AudioTimelineEvent::SetTarget ||
current->mType == AudioTimelineEvent::LinearRamp ||
current->mType == AudioTimelineEvent::ExponentialRamp ||
current->mType == AudioTimelineEvent::SetValueCurve);
#endif
- if (TimesEqual(aTime, mEvents[eventIndex].template Time<TimeType>())) {
+ if (TimesEqual(aTime, TimeOf(mEvents[eventIndex]))) {
mLastComputedValue = mComputedValue;
// Find the last event with the same time
while (eventIndex < mEvents.Length() - 1 &&
- TimesEqual(aTime, mEvents[eventIndex + 1].template Time<TimeType>())) {
+ TimesEqual(aTime, TimeOf(mEvents[eventIndex + 1]))) {
++eventIndex;
}
break;
}
previous = next;
next = &mEvents[eventIndex];
- if (aTime < mEvents[eventIndex].template Time<TimeType>()) {
+ if (aTime < TimeOf(mEvents[eventIndex])) {
bailOut = true;
}
}
if (!bailOut && eventIndex < mEvents.Length()) {
// The time matches one of the events exactly.
- MOZ_ASSERT(TimesEqual(aTime, mEvents[eventIndex].template Time<TimeType>()));
+ MOZ_ASSERT(TimesEqual(aTime, TimeOf(mEvents[eventIndex])));
// SetTarget nodes can be handled no matter what their next node is (if they have one)
if (mEvents[eventIndex].mType == AudioTimelineEvent::SetTarget) {
// Follow the curve, without regard to the next event, starting at
// the last value of the last event.
- aBuffer[bufferIndex] = ExponentialApproach(mEvents[eventIndex].template Time<TimeType>(),
+ aBuffer[bufferIndex] = ExponentialApproach(TimeOf(mEvents[eventIndex]),
mLastComputedValue, mEvents[eventIndex].mValue,
mEvents[eventIndex].mTimeConstant, aTime);
continue;
}
// SetValueCurve events can be handled no matter what their event node is (if they have one)
if (mEvents[eventIndex].mType == AudioTimelineEvent::SetValueCurve) {
- aBuffer[bufferIndex] = ExtractValueFromCurve(mEvents[eventIndex].template Time<TimeType>(),
+ aBuffer[bufferIndex] = ExtractValueFromCurve(TimeOf(mEvents[eventIndex]),
mEvents[eventIndex].mCurve,
mEvents[eventIndex].mCurveLength,
mEvents[eventIndex].mDuration, aTime);
continue;
}
// For other event types
aBuffer[bufferIndex] = mEvents[eventIndex].mValue;
@@ -229,42 +237,46 @@ AudioEventTimeline::GetValuesAtTimeHelpe
const AudioTimelineEvent* aPrevious,
const AudioTimelineEvent* aNext)
{
// If the requested time is before all of the existing events
if (!aPrevious) {
return mValue;
}
+ auto TimeOf = [](const AudioTimelineEvent* aEvent) -> TimeType {
+ return aEvent->template Time<TimeType>();
+ };
+
// SetTarget nodes can be handled no matter what their next node is (if
// they have one)
if (aPrevious->mType == AudioTimelineEvent::SetTarget) {
- return ExponentialApproach(aPrevious->template Time<TimeType>(),
+ return ExponentialApproach(TimeOf(aPrevious),
mLastComputedValue, aPrevious->mValue,
aPrevious->mTimeConstant, aTime);
}
// SetValueCurve events can be handled no mattar what their next node is
// (if they have one)
if (aPrevious->mType == AudioTimelineEvent::SetValueCurve) {
- return ExtractValueFromCurve(aPrevious->template Time<TimeType>(),
+ return ExtractValueFromCurve(TimeOf(aPrevious),
aPrevious->mCurve, aPrevious->mCurveLength,
aPrevious->mDuration, aTime);
}
// If the requested time is after all of the existing events
if (!aNext) {
switch (aPrevious->mType) {
case AudioTimelineEvent::SetValueAtTime:
case AudioTimelineEvent::LinearRamp:
case AudioTimelineEvent::ExponentialRamp:
// The value will be constant after the last event
return aPrevious->mValue;
case AudioTimelineEvent::SetValueCurve:
- return ExtractValueFromCurve(aPrevious->template Time<TimeType>(),
+ return ExtractValueFromCurve(TimeOf(aPrevious),
aPrevious->mCurve, aPrevious->mCurveLength,
aPrevious->mDuration, aTime);
case AudioTimelineEvent::SetTarget:
MOZ_FALLTHROUGH_ASSERT("AudioTimelineEvent::SetTarget");
case AudioTimelineEvent::SetValue:
case AudioTimelineEvent::Cancel:
case AudioTimelineEvent::Stream:
MOZ_ASSERT(false, "Should have been handled earlier.");
@@ -272,25 +284,25 @@ AudioEventTimeline::GetValuesAtTimeHelpe
MOZ_ASSERT(false, "unreached");
}
// Finally, handle the case where we have both a previous and a next event
// First, handle the case where our range ends up in a ramp event
switch (aNext->mType) {
case AudioTimelineEvent::LinearRamp:
- return LinearInterpolate(aPrevious->template Time<TimeType>(),
+ return LinearInterpolate(TimeOf(aPrevious),
aPrevious->mValue,
- aNext->template Time<TimeType>(),
+ TimeOf(aNext),
aNext->mValue, aTime);
case AudioTimelineEvent::ExponentialRamp:
- return ExponentialInterpolate(aPrevious->template Time<TimeType>(),
+ return ExponentialInterpolate(TimeOf(aPrevious),
aPrevious->mValue,
- aNext->template Time<TimeType>(),
+ TimeOf(aNext),
aNext->mValue, aTime);
case AudioTimelineEvent::SetValueAtTime:
case AudioTimelineEvent::SetTarget:
case AudioTimelineEvent::SetValueCurve:
break;
case AudioTimelineEvent::SetValue:
case AudioTimelineEvent::Cancel:
@@ -302,17 +314,17 @@ AudioEventTimeline::GetValuesAtTimeHelpe
switch (aPrevious->mType) {
case AudioTimelineEvent::SetValueAtTime:
case AudioTimelineEvent::LinearRamp:
case AudioTimelineEvent::ExponentialRamp:
// If the next event type is neither linear or exponential ramp, the
// value is constant.
return aPrevious->mValue;
case AudioTimelineEvent::SetValueCurve:
- return ExtractValueFromCurve(aPrevious->template Time<TimeType>(),
+ return ExtractValueFromCurve(TimeOf(aPrevious),
aPrevious->mCurve, aPrevious->mCurveLength,
aPrevious->mDuration, aTime);
case AudioTimelineEvent::SetTarget:
MOZ_FALLTHROUGH_ASSERT("AudioTimelineEvent::SetTarget");
case AudioTimelineEvent::SetValue:
case AudioTimelineEvent::Cancel:
case AudioTimelineEvent::Stream:
MOZ_ASSERT(false, "Should have been handled earlier.");
@@ -331,35 +343,39 @@ AudioEventTimeline::GetValuesAtTimeHelpe
const AudioTimelineEvent* aNext);
const AudioTimelineEvent*
AudioEventTimeline::GetPreviousEvent(double aTime) const
{
const AudioTimelineEvent* previous = nullptr;
const AudioTimelineEvent* next = nullptr;
+ auto TimeOf = [](const AudioTimelineEvent& aEvent) -> double {
+ return aEvent.template Time<double>();
+ };
+
bool bailOut = false;
for (unsigned i = 0; !bailOut && i < mEvents.Length(); ++i) {
switch (mEvents[i].mType) {
case AudioTimelineEvent::SetValueAtTime:
case AudioTimelineEvent::SetTarget:
case AudioTimelineEvent::LinearRamp:
case AudioTimelineEvent::ExponentialRamp:
case AudioTimelineEvent::SetValueCurve:
- if (aTime == mEvents[i].template Time<double>()) {
+ if (aTime == TimeOf(mEvents[i])) {
// Find the last event with the same time
do {
++i;
} while (i < mEvents.Length() &&
- aTime == mEvents[i].template Time<double>());
+ aTime == TimeOf(mEvents[i]));
return &mEvents[i - 1];
}
previous = next;
next = &mEvents[i];
- if (aTime < mEvents[i].template Time<double>()) {
+ if (aTime < TimeOf(mEvents[i])) {
bailOut = true;
}
break;
default:
MOZ_ASSERT(false, "unreached");
}
}
// Handle the case where the time is past all of the events