/*
 * Copyright (C) 2011 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "modules/webaudio/AudioParamTimeline.h"
#include "bindings/core/v8/ExceptionState.h"
#include "core/dom/ExceptionCode.h"
#include "platform/audio/AudioUtilities.h"
#include "wtf/CPU.h"
#include "wtf/MathExtras.h"
#include "wtf/PtrUtil.h"
#include <algorithm>

#if CPU(X86) || CPU(X86_64)
#include <emmintrin.h>
#endif

namespace blink {

// For a SetTarget event, if the relative difference between the current value
// and the target value is less than this, consider them the same and just
// output the target value.  This value MUST be larger than the single precision
// epsilon of 5.960465e-8.  Due to round-off, this value is not achievable in
// general.  This value can vary across the platforms (CPU) and thus it is
// determined experimentally.
const float kSetTargetThreshold = 1.5e-6;

// For a SetTarget event, if the target value is 0, and the current value is
// less than this threshold, consider the curve to have converged to 0.  We need
// a separate case from kSetTargetThreshold because that uses relative error,
// which is never met if the target value is 0, a common case.  This value MUST
// be larger than least positive normalized single precision
// value (1.1754944e-38) because we normally operate with flush-to-zero enabled.
const float kSetTargetZeroThreshold = 1e-20;

static bool isNonNegativeAudioParamTime(double time,
                                        ExceptionState& exceptionState,
                                        String message = "Time") {
  if (time >= 0)
    return true;

  exceptionState.throwDOMException(
      InvalidAccessError, message + " must be a finite non-negative number: " +
                              String::number(time));
  return false;
}

static bool isPositiveAudioParamTime(double time,
                                     ExceptionState& exceptionState,
                                     String message) {
  if (time > 0)
    return true;

  exceptionState.throwDOMException(
      InvalidAccessError,
      message + " must be a finite positive number: " + String::number(time));
  return false;
}

String AudioParamTimeline::eventToString(const ParamEvent& event) {
  // The default arguments for most automation methods is the value and the
  // time.
  String args =
      String::number(event.value()) + ", " + String::number(event.time(), 16);

  // Get a nice printable name for the event and update the args if necessary.
  String s;
  switch (event.getType()) {
    case ParamEvent::SetValue:
      s = "setValueAtTime";
      break;
    case ParamEvent::LinearRampToValue:
      s = "linearRampToValueAtTime";
      break;
    case ParamEvent::ExponentialRampToValue:
      s = "exponentialRampToValue";
      break;
    case ParamEvent::SetTarget:
      s = "setTargetAtTime";
      // This has an extra time constant arg
      args = args + ", " + String::number(event.timeConstant(), 16);
      break;
    case ParamEvent::SetValueCurve:
      s = "setValueCurveAtTime";
      // Replace the default arg, using "..." to denote the curve argument.
      args = "..., " + String::number(event.time(), 16) + ", " +
             String::number(event.duration(), 16);
      break;
    case ParamEvent::CancelValues:
    // Fall through; we should never have to print out the internal
    // CancelValues event.
    case ParamEvent::LastType:
      ASSERT_NOT_REACHED();
      break;
  };

  return s + "(" + args + ")";
}

// Computes the value of a linear ramp event at time t with the given event
// parameters.
float AudioParamTimeline::linearRampAtTime(double t,
                                           float value1,
                                           double time1,
                                           float value2,
                                           double time2) {
  return value1 + (value2 - value1) * (t - time1) / (time2 - time1);
}

// Computes the value of an exponential ramp event at time t with the given
// event parameters.
float AudioParamTimeline::exponentialRampAtTime(double t,
                                                float value1,
                                                double time1,
                                                float value2,
                                                double time2) {
  return value1 * pow(value2 / value1, (t - time1) / (time2 - time1));
}

// Compute the value of a set target event at time t with the given event
// parameters.
float AudioParamTimeline::targetValueAtTime(double t,
                                            float value1,
                                            double time1,
                                            float value2,
                                            float timeConstant) {
  return value2 + (value1 - value2) * exp(-(t - time1) / timeConstant);
}

// Compute the value of a set curve event at time t with the given event
// parameters.
float AudioParamTimeline::valueCurveAtTime(double t,
                                           double time1,
                                           double duration,
                                           const float* curveData,
                                           unsigned curveLength) {
  double curveIndex = (curveLength - 1) / duration * (t - time1);
  unsigned k = std::min(static_cast<unsigned>(curveIndex), curveLength - 1);
  unsigned k1 = std::min(k + 1, curveLength - 1);
  float c0 = curveData[k];
  float c1 = curveData[k1];
  float delta = std::min(curveIndex - k, 1.0);

  return c0 + (c1 - c0) * delta;
}

std::unique_ptr<AudioParamTimeline::ParamEvent>
AudioParamTimeline::ParamEvent::createSetValueEvent(float value, double time) {
  return WTF::wrapUnique(new ParamEvent(ParamEvent::SetValue, value, time));
}

std::unique_ptr<AudioParamTimeline::ParamEvent>
AudioParamTimeline::ParamEvent::createLinearRampEvent(float value,
                                                      double time,
                                                      float initialValue,
                                                      double callTime) {
  return WTF::wrapUnique(new ParamEvent(ParamEvent::LinearRampToValue, value,
                                        time, initialValue, callTime));
}

std::unique_ptr<AudioParamTimeline::ParamEvent>
AudioParamTimeline::ParamEvent::createExponentialRampEvent(float value,
                                                           double time,
                                                           float initialValue,
                                                           double callTime) {
  return WTF::wrapUnique(new ParamEvent(ParamEvent::ExponentialRampToValue,
                                        value, time, initialValue, callTime));
}

std::unique_ptr<AudioParamTimeline::ParamEvent>
AudioParamTimeline::ParamEvent::createSetTargetEvent(float value,
                                                     double time,
                                                     double timeConstant) {
  // The time line code does not expect a timeConstant of 0. (IT
  // returns NaN or Infinity due to division by zero.  The caller
  // should have converted this to a SetValueEvent.
  DCHECK_NE(timeConstant, 0);
  return WTF::wrapUnique(
      new ParamEvent(ParamEvent::SetTarget, value, time, timeConstant));
}

std::unique_ptr<AudioParamTimeline::ParamEvent>
AudioParamTimeline::ParamEvent::createSetValueCurveEvent(
    const DOMFloat32Array* curve,
    double time,
    double duration) {
  double curvePoints = (curve->length() - 1) / duration;
  float endValue = curve->data()[curve->length() - 1];

  return WTF::wrapUnique(new ParamEvent(
      ParamEvent::SetValueCurve, time, duration, curve, curvePoints, endValue));
}

std::unique_ptr<AudioParamTimeline::ParamEvent>
AudioParamTimeline::ParamEvent::createCancelValuesEvent(
    double time,
    std::unique_ptr<ParamEvent> savedEvent) {
  if (savedEvent) {
    // The savedEvent can only have certain event types.  Verify that.
    ParamEvent::Type savedType = savedEvent->getType();

    DCHECK_NE(savedType, ParamEvent::LastType);
    DCHECK(savedType == ParamEvent::LinearRampToValue ||
           savedType == ParamEvent::ExponentialRampToValue ||
           savedType == ParamEvent::SetValueCurve);
  }

  return WTF::wrapUnique(
      new ParamEvent(ParamEvent::CancelValues, time, std::move(savedEvent)));
}

std::unique_ptr<AudioParamTimeline::ParamEvent>
AudioParamTimeline::ParamEvent::createGeneralEvent(
    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) {
  return WTF::wrapUnique(new ParamEvent(
      type, value, time, initialValue, callTime, timeConstant, duration, curve,
      curvePointsPerSecond, curveEndValue, std::move(savedEvent)));
}

AudioParamTimeline::ParamEvent* AudioParamTimeline::ParamEvent::savedEvent()
    const {
  DCHECK_EQ(getType(), ParamEvent::CancelValues);
  return m_savedEvent.get();
}

bool AudioParamTimeline::ParamEvent::hasDefaultCancelledValue() const {
  DCHECK_EQ(getType(), ParamEvent::CancelValues);
  return m_hasDefaultCancelledValue;
}

void AudioParamTimeline::ParamEvent::setCancelledValue(float value) {
  DCHECK_EQ(getType(), ParamEvent::CancelValues);
  m_value = value;
  m_hasDefaultCancelledValue = true;
}

// General event
AudioParamTimeline::ParamEvent::ParamEvent(
    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)
    : m_type(type),
      m_value(value),
      m_time(time),
      m_initialValue(initialValue),
      m_callTime(callTime),
      m_timeConstant(timeConstant),
      m_duration(duration),
      m_curvePointsPerSecond(curvePointsPerSecond),
      m_curveEndValue(curveEndValue),
      m_savedEvent(std::move(savedEvent)),
      m_needsTimeClampCheck(true),
      m_hasDefaultCancelledValue(false) {
  m_curve = curve;
}

// Create simplest event needing just a value and time, like setValueAtTime
AudioParamTimeline::ParamEvent::ParamEvent(ParamEvent::Type type,
                                           float value,
                                           double time)
    : m_type(type),
      m_value(value),
      m_time(time),
      m_initialValue(0),
      m_callTime(0),
      m_timeConstant(0),
      m_duration(0),
      m_curvePointsPerSecond(0),
      m_curveEndValue(0),
      m_savedEvent(nullptr),
      m_needsTimeClampCheck(true),
      m_hasDefaultCancelledValue(false) {
  DCHECK_EQ(type, ParamEvent::SetValue);
}

// Create a linear or exponential ramp that requires an initial value and
// time in case
// there is no actual event that preceeds this event.
AudioParamTimeline::ParamEvent::ParamEvent(ParamEvent::Type type,
                                           float value,
                                           double time,
                                           float initialValue,
                                           double callTime)
    : m_type(type),
      m_value(value),
      m_time(time),
      m_initialValue(initialValue),
      m_callTime(callTime),
      m_timeConstant(0),
      m_duration(0),
      m_curvePointsPerSecond(0),
      m_curveEndValue(0),
      m_savedEvent(nullptr),
      m_needsTimeClampCheck(true),
      m_hasDefaultCancelledValue(false) {
  DCHECK(type == ParamEvent::LinearRampToValue ||
         type == ParamEvent::ExponentialRampToValue);
}

// Create an event needing a time constant (setTargetAtTime)
AudioParamTimeline::ParamEvent::ParamEvent(ParamEvent::Type type,
                                           float value,
                                           double time,
                                           double timeConstant)
    : m_type(type),
      m_value(value),
      m_time(time),
      m_initialValue(0),
      m_callTime(0),
      m_timeConstant(timeConstant),
      m_duration(0),
      m_curvePointsPerSecond(0),
      m_curveEndValue(0),
      m_savedEvent(nullptr),
      m_needsTimeClampCheck(true),
      m_hasDefaultCancelledValue(false) {
  DCHECK_EQ(type, ParamEvent::SetTarget);
}

// Create a setValueCurve event
AudioParamTimeline::ParamEvent::ParamEvent(ParamEvent::Type type,
                                           double time,
                                           double duration,
                                           const DOMFloat32Array* curve,
                                           double curvePointsPerSecond,
                                           float curveEndValue)
    : m_type(type),
      m_value(0),
      m_time(time),
      m_initialValue(0),
      m_callTime(0),
      m_timeConstant(0),
      m_duration(duration),
      m_curvePointsPerSecond(curvePointsPerSecond),
      m_curveEndValue(curveEndValue),
      m_savedEvent(nullptr),
      m_needsTimeClampCheck(true),
      m_hasDefaultCancelledValue(false) {
  DCHECK_EQ(type, ParamEvent::SetValueCurve);
  if (curve) {
    unsigned curveLength = curve->length();
    m_curve.resize(curve->length());
    memcpy(m_curve.data(), curve->data(), curveLength * sizeof(float));
  }
}

// Create CancelValues event
AudioParamTimeline::ParamEvent::ParamEvent(
    ParamEvent::Type type,
    double time,
    std::unique_ptr<ParamEvent> savedEvent)
    : m_type(type),
      m_value(0),
      m_time(time),
      m_initialValue(0),
      m_callTime(0),
      m_timeConstant(0),
      m_duration(0),
      m_curvePointsPerSecond(0),
      m_curveEndValue(0),
      m_savedEvent(std::move(savedEvent)),
      m_needsTimeClampCheck(true),
      m_hasDefaultCancelledValue(false) {
  DCHECK_EQ(type, ParamEvent::CancelValues);
}

void AudioParamTimeline::setValueAtTime(float value,
                                        double time,
                                        ExceptionState& exceptionState) {
  DCHECK(isMainThread());

  if (!isNonNegativeAudioParamTime(time, exceptionState))
    return;

  MutexLocker locker(m_eventsLock);
  insertEvent(ParamEvent::createSetValueEvent(value, time), exceptionState);
}

void AudioParamTimeline::linearRampToValueAtTime(
    float value,
    double time,
    float initialValue,
    double callTime,
    ExceptionState& exceptionState) {
  DCHECK(isMainThread());

  if (!isNonNegativeAudioParamTime(time, exceptionState))
    return;

  MutexLocker locker(m_eventsLock);
  insertEvent(
      ParamEvent::createLinearRampEvent(value, time, initialValue, callTime),
      exceptionState);
}

void AudioParamTimeline::exponentialRampToValueAtTime(
    float value,
    double time,
    float initialValue,
    double callTime,
    ExceptionState& exceptionState) {
  DCHECK(isMainThread());

  if (!isNonNegativeAudioParamTime(time, exceptionState))
    return;

  if (!value) {
    exceptionState.throwDOMException(
        InvalidAccessError,
        "The float target value provided (" + String::number(value) +
            ") should not be in the range (" +
            String::number(-std::numeric_limits<float>::denorm_min()) + ", " +
            String::number(std::numeric_limits<float>::denorm_min()) + ").");
    return;
  }

  MutexLocker locker(m_eventsLock);
  insertEvent(ParamEvent::createExponentialRampEvent(value, time, initialValue,
                                                     callTime),
              exceptionState);
}

void AudioParamTimeline::setTargetAtTime(float target,
                                         double time,
                                         double timeConstant,
                                         ExceptionState& exceptionState) {
  DCHECK(isMainThread());

  if (!isNonNegativeAudioParamTime(time, exceptionState) ||
      !isNonNegativeAudioParamTime(timeConstant, exceptionState,
                                   "Time constant"))
    return;

  MutexLocker locker(m_eventsLock);

  // If timeConstant = 0, we instantly jump to the target value, so
  // insert a SetValueEvent instead of SetTargetEvent.
  if (timeConstant == 0) {
    insertEvent(ParamEvent::createSetValueEvent(target, time), exceptionState);
  } else {
    insertEvent(ParamEvent::createSetTargetEvent(target, time, timeConstant),
                exceptionState);
  }
}

void AudioParamTimeline::setValueCurveAtTime(DOMFloat32Array* curve,
                                             double time,
                                             double duration,
                                             ExceptionState& exceptionState) {
  DCHECK(isMainThread());
  DCHECK(curve);

  if (!isNonNegativeAudioParamTime(time, exceptionState) ||
      !isPositiveAudioParamTime(duration, exceptionState, "Duration"))
    return;

  if (curve->length() < 2) {
    exceptionState.throwDOMException(
        InvalidStateError, ExceptionMessages::indexExceedsMinimumBound(
                               "curve length", curve->length(), 2U));
    return;
  }

  MutexLocker locker(m_eventsLock);
  insertEvent(ParamEvent::createSetValueCurveEvent(curve, time, duration),
              exceptionState);

  // Insert a setValueAtTime event too to establish an event so that all
  // following events will process from the end of the curve instead of the
  // beginning.
  insertEvent(ParamEvent::createSetValueEvent(
                  curve->data()[curve->length() - 1], time + duration),
              exceptionState);
}

void AudioParamTimeline::insertEvent(std::unique_ptr<ParamEvent> event,
                                     ExceptionState& exceptionState) {
  DCHECK(isMainThread());

  // Sanity check the event. Be super careful we're not getting infected with
  // NaN or Inf. These should have been handled by the caller.
  bool isValid = event->getType() < ParamEvent::LastType &&
                 std::isfinite(event->value()) &&
                 std::isfinite(event->time()) &&
                 std::isfinite(event->timeConstant()) &&
                 std::isfinite(event->duration()) && event->duration() >= 0;

  DCHECK(isValid);
  if (!isValid)
    return;

  unsigned i = 0;
  double insertTime = event->time();

  if (!m_events.size() &&
      (event->getType() == ParamEvent::LinearRampToValue ||
       event->getType() == ParamEvent::ExponentialRampToValue)) {
    // There are no events preceding these ramps.  Insert a new setValueAtTime
    // event to set the starting point for these events.
    m_events.insert(0, AudioParamTimeline::ParamEvent::createSetValueEvent(
                           event->initialValue(), event->callTime()));
  }

  for (i = 0; i < m_events.size(); ++i) {
    if (event->getType() == ParamEvent::SetValueCurve) {
      // If this event is a SetValueCurve, make sure it doesn't overlap any
      // existing event. It's ok if the SetValueCurve starts at the same time as
      // the end of some other duration.
      double endTime = event->time() + event->duration();
      if (m_events[i]->time() > event->time() &&
          m_events[i]->time() < endTime) {
        exceptionState.throwDOMException(
            NotSupportedError,
            eventToString(*event) + " overlaps " + eventToString(*m_events[i]));
        return;
      }
    } else {
      // Otherwise, make sure this event doesn't overlap any existing
      // SetValueCurve event.
      if (m_events[i]->getType() == ParamEvent::SetValueCurve) {
        double endTime = m_events[i]->time() + m_events[i]->duration();
        if (event->time() >= m_events[i]->time() && event->time() < endTime) {
          exceptionState.throwDOMException(
              NotSupportedError, eventToString(*event) + " overlaps " +
                                     eventToString(*m_events[i]));
          return;
        }
      }
    }

    // Overwrite same event type and time.
    if (m_events[i]->time() == insertTime &&
        m_events[i]->getType() == event->getType()) {
      m_events[i] = std::move(event);
      return;
    }

    if (m_events[i]->time() > insertTime)
      break;
  }

  m_events.insert(i, std::move(event));
}

bool AudioParamTimeline::hasValues() const {
  MutexTryLocker tryLocker(m_eventsLock);

  if (tryLocker.locked())
    return m_events.size();

  // Can't get the lock so that means the main thread is trying to insert an
  // event.  Just return true then.  If the main thread releases the lock before
  // valueForContextTime or valuesForFrameRange runs, then the there will be an
  // event on the timeline, so everything is fine.  If the lock is held so that
  // neither valueForContextTime nor valuesForFrameRange can run, this is ok
  // too, because they have tryLocks to produce a default value.  The event will
  // then get processed in the next rendering quantum.
  //
  // Don't want to return false here because that would confuse the processing
  // of the timeline if previously we returned true and now suddenly return
  // false, only to return true on the next rendering quantum.  Currently, once
  // a timeline has been introduced it is always true forever because m_events
  // never shrinks.
  return true;
}

void AudioParamTimeline::cancelScheduledValues(double startTime,
                                               ExceptionState& exceptionState) {
  DCHECK(isMainThread());

  MutexLocker locker(m_eventsLock);

  // Remove all events starting at startTime.
  for (unsigned i = 0; i < m_events.size(); ++i) {
    if (m_events[i]->time() >= startTime) {
      m_events.remove(i, m_events.size() - i);
      break;
    }
  }
}

void AudioParamTimeline::cancelValuesAndHoldAtTime(
    double cancelTime,
    ExceptionState& exceptionState) {
  DCHECK(isMainThread());

  if (!isNonNegativeAudioParamTime(cancelTime, exceptionState))
    return;

  MutexLocker locker(m_eventsLock);

  unsigned i;
  // Find the first event at or just past cancelTime.
  for (i = 0; i < m_events.size(); ++i) {
    if (m_events[i]->time() > cancelTime) {
      break;
    }
  }

  // The event that is being cancelled.  This is the event just past
  // cancelTime, if any.
  unsigned cancelledEventIndex = i;

  // If the event just before cancelTime is a SetTarget or SetValueCurve
  // event, we need to handle that event specially instead of the event after.
  if (i > 0 && ((m_events[i - 1]->getType() == ParamEvent::SetTarget) ||
                (m_events[i - 1]->getType() == ParamEvent::SetValueCurve))) {
    cancelledEventIndex = i - 1;
  } else if (i >= m_events.size()) {
    // If there were no events occurring after |cancelTime| (and the
    // previous event is not SetTarget or SetValueCurve, we're done.
    return;
  }

  // cancelledEvent is the event that is being cancelled.
  ParamEvent* cancelledEvent = m_events[cancelledEventIndex].get();
  ParamEvent::Type eventType = cancelledEvent->getType();

  // New event to be inserted, if any, and a SetValueEvent if needed.
  std::unique_ptr<ParamEvent> newEvent = nullptr;
  std::unique_ptr<ParamEvent> newSetValueEvent = nullptr;

  switch (eventType) {
    case ParamEvent::LinearRampToValue:
    case ParamEvent::ExponentialRampToValue: {
      // For these events we need to remember the parameters of the event
      // for a CancelValues event so that we can properly cancel the event
      // and hold the value.
      std::unique_ptr<ParamEvent> savedEvent = ParamEvent::createGeneralEvent(
          eventType, cancelledEvent->value(), cancelledEvent->time(),
          cancelledEvent->initialValue(), cancelledEvent->callTime(),
          cancelledEvent->timeConstant(), cancelledEvent->duration(),
          cancelledEvent->curve(), cancelledEvent->curvePointsPerSecond(),
          cancelledEvent->curveEndValue(), nullptr);

      newEvent = ParamEvent::createCancelValuesEvent(cancelTime,
                                                     std::move(savedEvent));
    } break;
    case ParamEvent::SetTarget: {
      // Don't want to remove the SetTarget event, so bump the index.  But
      // we do want to insert a cancelEvent so that we stop this
      // automation and hold the value when we get there.
      ++cancelledEventIndex;

      newEvent = ParamEvent::createCancelValuesEvent(cancelTime, nullptr);
    } break;
    case ParamEvent::SetValueCurve: {
      double newDuration = cancelTime - cancelledEvent->time();

      if (cancelTime > cancelledEvent->time() + cancelledEvent->duration()) {
        // If the cancellation time is past the end of the curve,
        // there's nothing to do except remove the following events.
        ++cancelledEventIndex;
      } else {
        // Cancellation time is in the middle of the curve.  Therefore,
        // create a new SetValueCurve event with the appropriate new
        // parameters to cancel this event properly.  Since it's illegal
        // to insert any event within a SetValueCurve event, we can
        // compute the new end value now instead of doing when running
        // the timeline.
        float endValue = valueCurveAtTime(
            cancelTime, cancelledEvent->time(), cancelledEvent->duration(),
            cancelledEvent->curve().data(), cancelledEvent->curve().size());

        // Replace the existing SetValueCurve with this new one that is
        // identical except for the duration.
        newEvent = ParamEvent::createGeneralEvent(
            eventType, cancelledEvent->value(), cancelledEvent->time(),
            cancelledEvent->initialValue(), cancelledEvent->callTime(),
            cancelledEvent->timeConstant(), newDuration,
            cancelledEvent->curve(), cancelledEvent->curvePointsPerSecond(),
            endValue, nullptr);

        newSetValueEvent = ParamEvent::createSetValueEvent(
            endValue, cancelledEvent->time() + newDuration);
      }
    } break;
    case ParamEvent::SetValue:
    case ParamEvent::CancelValues:
      // Nothing needs to be done for a SetValue or CancelValues event.
      break;
    case ParamEvent::LastType:
      NOTREACHED();
      break;
  }

  // Now remove all the following events from the timeline.
  if (cancelledEventIndex < m_events.size())
    m_events.remove(cancelledEventIndex, m_events.size() - cancelledEventIndex);

  // Insert the new event, if any.
  if (newEvent) {
    insertEvent(std::move(newEvent), exceptionState);
    if (newSetValueEvent)
      insertEvent(std::move(newSetValueEvent), exceptionState);
  }
}

float AudioParamTimeline::valueForContextTime(
    AudioDestinationHandler& audioDestination,
    float defaultValue,
    bool& hasValue,
    float minValue,
    float maxValue) {
  {
    MutexTryLocker tryLocker(m_eventsLock);
    if (!tryLocker.locked() || !m_events.size() ||
        audioDestination.currentTime() < m_events[0]->time()) {
      hasValue = false;
      return defaultValue;
    }
  }

  // Ask for just a single value.
  float value;
  double sampleRate = audioDestination.sampleRate();
  size_t startFrame = audioDestination.currentSampleFrame();
  // One parameter change per render quantum.
  double controlRate = sampleRate / AudioUtilities::kRenderQuantumFrames;
  value = valuesForFrameRange(startFrame, startFrame + 1, defaultValue, &value,
                              1, sampleRate, controlRate, minValue, maxValue);

  hasValue = true;
  return value;
}

float AudioParamTimeline::valuesForFrameRange(size_t startFrame,
                                              size_t endFrame,
                                              float defaultValue,
                                              float* values,
                                              unsigned numberOfValues,
                                              double sampleRate,
                                              double controlRate,
                                              float minValue,
                                              float maxValue) {
  // We can't contend the lock in the realtime audio thread.
  MutexTryLocker tryLocker(m_eventsLock);
  if (!tryLocker.locked()) {
    if (values) {
      for (unsigned i = 0; i < numberOfValues; ++i)
        values[i] = defaultValue;
    }
    return defaultValue;
  }

  float lastValue =
      valuesForFrameRangeImpl(startFrame, endFrame, defaultValue, values,
                              numberOfValues, sampleRate, controlRate);

  // Clamp the values now to the nominal range
  for (unsigned k = 0; k < numberOfValues; ++k)
    values[k] = clampTo(values[k], minValue, maxValue);

  return lastValue;
}

float AudioParamTimeline::valuesForFrameRangeImpl(size_t startFrame,
                                                  size_t endFrame,
                                                  float defaultValue,
                                                  float* values,
                                                  unsigned numberOfValues,
                                                  double sampleRate,
                                                  double controlRate) {
  DCHECK(values);
  DCHECK_GE(numberOfValues, 1u);
  if (!values || !(numberOfValues >= 1))
    return defaultValue;

  // Return default value if there are no events matching the desired time
  // range.
  if (!m_events.size() || (endFrame / sampleRate <= m_events[0]->time())) {
    for (unsigned i = 0; i < numberOfValues; ++i)
      values[i] = defaultValue;
    return defaultValue;
  }

  int numberOfEvents = m_events.size();

  if (numberOfEvents > 0) {
    bool clampedSomeEventTime = false;
    double currentTime = startFrame / sampleRate;

    // Look at all the events in the timeline and check to see if any needs
    // to clamp the start time to the current time.
    for (int k = 0; k < numberOfEvents; ++k) {
      ParamEvent* event = m_events[k].get();

      // We're examining the event for the first time and the event time is
      // in the past so clamp the event time to the current time (start of
      // the rendering quantum).
      if (event->needsTimeClampCheck()) {
        if (event->time() < currentTime) {
          event->setTime(currentTime);
          clampedSomeEventTime = true;
        }

        // In all cases, we can clear the flag because the event is either
        // in the future, or we've already checked it (just now).
        event->clearTimeClampCheck();
      }
    }

    if (clampedSomeEventTime) {
      // If we clamped some event time to current time, we need to
      // sort the event list in time order again, but it must be
      // stable!
      std::stable_sort(m_events.begin(), m_events.end(),
                       ParamEvent::eventPreceeds);
    }

    // Optimize the case where the last event is in the past.
    ParamEvent* lastEvent = m_events[m_events.size() - 1].get();
    ParamEvent::Type lastEventType = lastEvent->getType();
    double lastEventTime = lastEvent->time();

    // If the last event is in the past and the event has ended, then we can
    // just propagate the same value.  Except for SetTarget which lasts
    // "forever".  SetValueCurve also has an explicit SetValue at the end of
    // the curve, so we don't need to worry that SetValueCurve time is a
    // start time, not an end time.
    //
    // Allow at least one render quantum to go by before handling this
    // to allow k-rate parameters to finish processing the event. See
    // crbug.com/672857. Due to possible roundoff, arbirtrarily wait
    // for 1.5 render quanta instead of 1.
    if (lastEventTime +
                1.5 * AudioUtilities::kRenderQuantumFrames / sampleRate <
            currentTime &&
        lastEventType != ParamEvent::SetTarget) {
      // The event has finished, so just copy the default value out.
      // Since all events are now also in the past, we can just remove all
      // timeline events too because |defaultValue| has the expected
      // value.
      for (unsigned i = 0; i < numberOfValues; ++i)
        values[i] = defaultValue;
      m_smoothedValue = defaultValue;
      m_events.clear();
      return defaultValue;
    }
  }

  // Maintain a running time (frame) and index for writing the values buffer.
  size_t currentFrame = startFrame;
  unsigned writeIndex = 0;

  // If first event is after startFrame then fill initial part of values buffer
  // with defaultValue until we reach the first event time.
  double firstEventTime = m_events[0]->time();
  if (firstEventTime > startFrame / sampleRate) {
    // |fillToFrame| is an exclusive upper bound, so use ceil() to compute the
    // bound from the firstEventTime.
    size_t fillToFrame = endFrame;
    double firstEventFrame = ceil(firstEventTime * sampleRate);
    if (endFrame > firstEventFrame)
      fillToFrame = static_cast<size_t>(firstEventFrame);
    DCHECK_GE(fillToFrame, startFrame);

    fillToFrame -= startFrame;
    fillToFrame = std::min(fillToFrame, static_cast<size_t>(numberOfValues));
    for (; writeIndex < fillToFrame; ++writeIndex)
      values[writeIndex] = defaultValue;

    currentFrame += fillToFrame;
  }

  float value = defaultValue;

  // Go through each event and render the value buffer where the times overlap,
  // stopping when we've rendered all the requested values.
  int lastSkippedEventIndex = 0;
  for (int i = 0; i < numberOfEvents && writeIndex < numberOfValues; ++i) {
    ParamEvent* event = m_events[i].get();
    ParamEvent* nextEvent = i < numberOfEvents - 1 ? m_events[i + 1].get() : 0;

    // Wait until we get a more recent event.
    //
    // WARNING: due to round-off it might happen that nextEvent->time() is
    // just larger than currentFrame/sampleRate.  This means that we will end
    // up running the |event| again.  The code below had better be prepared
    // for this case!  What should happen is the fillToFrame should be 0 so
    // that while the event is actually run again, nothing actually gets
    // computed, and we move on to the next event.
    //
    // An example of this case is setValueCurveAtTime.  The time at which
    // setValueCurveAtTime ends (and the setValueAtTime begins) might be
    // just past currentTime/sampleRate.  Then setValueCurveAtTime will be
    // processed again before advancing to setValueAtTime.  The number of
    // frames to be processed should be zero in this case.
    if (nextEvent && nextEvent->time() < currentFrame / sampleRate) {
      // But if the current event is a SetValue event and the event time is
      // between currentFrame - 1 and curentFrame (in time). we don't want to
      // skip it.  If we do skip it, the SetValue event is completely skipped
      // and not applied, which is wrong.  Other events don't have this problem.
      // (Because currentFrame is unsigned, we do the time check in this funny,
      // but equivalent way.)
      double eventFrame = event->time() * sampleRate;

      // Condition is currentFrame - 1 < eventFrame <= currentFrame, but
      // currentFrame is unsigned and could be 0, so use
      // currentFrame < eventFrame + 1 instead.
      if (!((event->getType() == ParamEvent::SetValue &&
             (eventFrame <= currentFrame) &&
             (currentFrame < eventFrame + 1)))) {
        // This is not the special SetValue event case, and nextEvent is
        // in the past. We can skip processing of this event since it's
        // in past. We keep track of this event in lastSkippedEventIndex
        // to note what events we've skipped.
        lastSkippedEventIndex = i;
        continue;
      }
    }

    // If there's no next event, set nextEventType to LastType to indicate that.
    ParamEvent::Type nextEventType =
        nextEvent ? static_cast<ParamEvent::Type>(nextEvent->getType())
                  : ParamEvent::LastType;

    // 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->getType() == 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.  We need to update |value|
      // appropriately depending on whether the ramp has started or not.
      //
      // If SetTarget starts somewhere between currentFrame - 1 and
      // currentFrame, we directly compute the value it would have at
      // currentFrame.  If not, we update the value from the value from
      // currentFrame - 1.
      //
      // Can't use the condition currentFrame - 1 <= t0 * sampleRate <=
      // currentFrame because currentFrame is unsigned and could be 0.  Instead,
      // compute the condition this way,
      // where f = currentFrame and Fs = sampleRate:
      //
      //    f - 1 <= t0 * Fs <= f
      //    2 * f - 2 <= 2 * Fs * t0 <= 2 * f
      //    -2 <= 2 * Fs * t0 - 2 * f <= 0
      //    -1 <= 2 * Fs * t0 - 2 * f + 1 <= 1
      //     abs(2 * Fs * t0 - 2 * f + 1) <= 1
      if (fabs(2 * sampleRate * event->time() - 2 * currentFrame + 1) <= 1) {
        // SetTarget is starting somewhere between currentFrame - 1 and
        // currentFrame. Compute the value the SetTarget would have at the
        // currentFrame.
        value = event->value() +
                (value - event->value()) *
                    exp(-(currentFrame / sampleRate - event->time()) /
                        event->timeConstant());
      } else {
        // SetTarget has already started.  Update |value| one frame because it's
        // the value from the previous frame.
        float discreteTimeConstant = static_cast<float>(
            AudioUtilities::discreteTimeConstantForSampleRate(
                event->timeConstant(), controlRate));
        value += (event->value() - value) * discreteTimeConstant;
      }

      // Insert a SetValueEvent to mark the starting value and time.
      // Clear the clamp check because this doesn't need it.
      m_events[i] =
          ParamEvent::createSetValueEvent(value, currentFrame / sampleRate);
      m_events[i]->clearTimeClampCheck();

      // Update our pointer to the current event because we just changed it.
      event = m_events[i].get();
    }

    float value1 = event->value();
    double time1 = event->time();

    float value2 = nextEvent ? nextEvent->value() : value1;
    double time2 = nextEvent ? nextEvent->time() : endFrame / sampleRate + 1;

    // Check to see if an event was cancelled.
    if (nextEventType == ParamEvent::CancelValues) {
      switch (event->getType()) {
        case ParamEvent::LinearRampToValue:
        case ParamEvent::ExponentialRampToValue:
        case ParamEvent::SetValue: {
          // These three events potentially establish a starting value for
          // the following event, so we need to examine the cancelled
          // event to see what to do.
          const ParamEvent* savedEvent = nextEvent->savedEvent();

          // Update the end time and type to pretend that we're running
          // this saved event type.
          time2 = nextEvent->time();
          nextEventType = savedEvent->getType();

          if (nextEvent->hasDefaultCancelledValue()) {
            // We've already established a value for the cancelled
            // event, so just return it.
            value2 = nextEvent->value();
          } else {
            // If the next event would have been a LinearRamp or
            // ExponentialRamp, we need to compute a new end value for
            // the event so that the curve works continues as if it were
            // not cancelled.
            switch (savedEvent->getType()) {
              case ParamEvent::LinearRampToValue:
                value2 =
                    linearRampAtTime(nextEvent->time(), value1, time1,
                                     savedEvent->value(), savedEvent->time());
                break;
              case ParamEvent::ExponentialRampToValue:
                value2 = exponentialRampAtTime(nextEvent->time(), value1, time1,
                                               savedEvent->value(),
                                               savedEvent->time());
                break;
              case ParamEvent::SetValueCurve:
              case ParamEvent::SetValue:
              case ParamEvent::SetTarget:
              case ParamEvent::CancelValues:
                // These cannot be possible types for the saved event
                // because they can't be created.
                // createCancelValuesEvent doesn't allow them (SetValue,
                // SetTarget, CancelValues) or cancelScheduledValues()
                // doesn't create such an event (SetValueCurve).
                NOTREACHED();
                break;
              case ParamEvent::LastType:
                // Illegal event type.
                NOTREACHED();
                break;
            }

            // Cache the new value so we don't keep computing it over and over.
            nextEvent->setCancelledValue(value2);
          }
        } break;
        case ParamEvent::SetValueCurve:
          // Everything needed for this was handled when cancelling was
          // done.
          break;
        case ParamEvent::SetTarget:
        case ParamEvent::CancelValues:
          // Nothing special needs to be done for SetTarget or
          // CancelValues followed by CancelValues.
          break;
        case ParamEvent::LastType:
          NOTREACHED();
          break;
      }
    }

    DCHECK_GE(time2, time1);
    double deltaTime = time2 - time1;
    float k = deltaTime > 0 ? 1 / deltaTime : 0;

    // |fillToEndFrame| is the exclusive upper bound of the last frame to be
    // computed for this event.  It's either the last desired frame (|endFrame|)
    // or derived from the end time of the next event (time2). We compute
    // ceil(time2*sampleRate) because fillToEndFrame is the exclusive upper
    // bound.  Consider the case where |startFrame| = 128 and time2 = 128.1
    // (assuming sampleRate = 1).  Since time2 is greater than 128, we want to
    // output a value for frame 128.  This requires that fillToEndFrame be at
    // least 129.  This is achieved by ceil(time2).
    //
    // However, time2 can be very large, so compute this carefully in the case
    // where time2 exceeds the size of a size_t.

    size_t fillToEndFrame = endFrame;
    if (endFrame > time2 * sampleRate)
      fillToEndFrame = static_cast<size_t>(ceil(time2 * sampleRate));

    DCHECK_GE(fillToEndFrame, startFrame);
    size_t fillToFrame = fillToEndFrame - startFrame;
    fillToFrame = std::min(fillToFrame, static_cast<size_t>(numberOfValues));

    // First handle linear and exponential ramps which require looking ahead to
    // the next event.
    if (nextEventType == ParamEvent::LinearRampToValue) {
      const float valueDelta = value2 - value1;
#if CPU(X86) || CPU(X86_64)
      if (fillToFrame > writeIndex) {
        // Minimize in-loop operations. Calculate starting value and increment.
        // Next step: value += inc.
        //  value = value1 +
        //      (currentFrame/sampleRate - time1) * k * (value2 - value1);
        //  inc = 4 / sampleRate * k * (value2 - value1);
        // Resolve recursion by expanding constants to achieve a 4-step loop
        // unrolling.
        //  value = value1 +
        //    ((currentFrame/sampleRate - time1) + i * sampleFrameTimeIncr) * k
        //    * (value2 -value1), i in 0..3
        __m128 vValue =
            _mm_mul_ps(_mm_set_ps1(1 / sampleRate), _mm_set_ps(3, 2, 1, 0));
        vValue =
            _mm_add_ps(vValue, _mm_set_ps1(currentFrame / sampleRate - time1));
        vValue = _mm_mul_ps(vValue, _mm_set_ps1(k * valueDelta));
        vValue = _mm_add_ps(vValue, _mm_set_ps1(value1));
        __m128 vInc = _mm_set_ps1(4 / sampleRate * k * valueDelta);

        // Truncate loop steps to multiple of 4.
        unsigned fillToFrameTrunc =
            writeIndex + ((fillToFrame - writeIndex) / 4) * 4;
        // Compute final time.
        DCHECK_LE(fillToFrameTrunc, numberOfValues);
        currentFrame += fillToFrameTrunc - writeIndex;

        // Process 4 loop steps.
        for (; writeIndex < fillToFrameTrunc; writeIndex += 4) {
          _mm_storeu_ps(values + writeIndex, vValue);
          vValue = _mm_add_ps(vValue, vInc);
        }
      }
      // Update |value| with the last value computed so that the
      // .value attribute of the AudioParam gets the correct linear
      // ramp value, in case the following loop doesn't execute.
      if (writeIndex >= 1)
        value = values[writeIndex - 1];
#endif
      // Serially process remaining values.
      for (; writeIndex < fillToFrame; ++writeIndex) {
        float x = (currentFrame / sampleRate - time1) * k;
        // value = (1 - x) * value1 + x * value2;
        value = value1 + x * valueDelta;
        values[writeIndex] = value;
        ++currentFrame;
      }
    } else if (nextEventType == ParamEvent::ExponentialRampToValue) {
      if (value1 * value2 <= 0) {
        // It's an error if value1 and value2 have opposite signs or if one of
        // them is zero.  Handle this by propagating the previous value, and
        // making it the default.
        value = value1;

        for (; writeIndex < fillToFrame; ++writeIndex)
          values[writeIndex] = value;
      } else {
        double numSampleFrames = deltaTime * sampleRate;
        // The value goes exponentially from value1 to value2 in a duration of
        // deltaTime seconds according to
        //
        //  v(t) = v1*(v2/v1)^((t-t1)/(t2-t1))
        //
        // Let c be currentFrame and F be the sampleRate.  Then we want to
        // sample v(t) at times t = (c + k)/F for k = 0, 1, ...:
        //
        //   v((c+k)/F) = v1*(v2/v1)^(((c/F+k/F)-t1)/(t2-t1))
        //              = v1*(v2/v1)^((c/F-t1)/(t2-t1))
        //                  *(v2/v1)^((k/F)/(t2-t1))
        //              = v1*(v2/v1)^((c/F-t1)/(t2-t1))
        //                  *[(v2/v1)^(1/(F*(t2-t1)))]^k
        //
        // Thus, this can be written as
        //
        //   v((c+k)/F) = V*m^k
        //
        // where
        //   V = v1*(v2/v1)^((c/F-t1)/(t2-t1))
        //   m = (v2/v1)^(1/(F*(t2-t1)))

        // Compute the per-sample multiplier.
        float multiplier = powf(value2 / value1, 1 / numSampleFrames);
        // Set the starting value of the exponential ramp.
        value = value1 * powf(value2 / value1,
                              (currentFrame / sampleRate - time1) / deltaTime);

        for (; writeIndex < fillToFrame; ++writeIndex) {
          values[writeIndex] = value;
          value *= multiplier;
          ++currentFrame;
        }
        // |value| got updated one extra time in the above loop.  Restore it to
        // the last computed value.
        if (writeIndex >= 1)
          value /= multiplier;

        // 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.
      switch (event->getType()) {
        case ParamEvent::SetValue:
        case ParamEvent::LinearRampToValue: {
          currentFrame = fillToEndFrame;

          // Simply stay at a constant value.
          value = event->value();

          for (; writeIndex < fillToFrame; ++writeIndex)
            values[writeIndex] = value;

          break;
        }

        case ParamEvent::CancelValues: {
          // If the previous event was a SetTarget or ExponentialRamp
          // event, the current value is one sample behind.  Update
          // the sample value by one sample, but only at the start of
          // this CancelValues event.
          if (event->hasDefaultCancelledValue()) {
            value = event->value();
          } else {
            double cancelFrame = time1 * sampleRate;
            if (i >= 1 && cancelFrame <= currentFrame &&
                currentFrame < cancelFrame + 1) {
              ParamEvent::Type lastEventType = m_events[i - 1]->getType();
              if (lastEventType == ParamEvent::SetTarget) {
                float target = m_events[i - 1]->value();
                float timeConstant = m_events[i - 1]->timeConstant();
                float discreteTimeConstant = static_cast<float>(
                    AudioUtilities::discreteTimeConstantForSampleRate(
                        timeConstant, controlRate));
                value += (target - value) * discreteTimeConstant;
              }
            }
          }

          // Simply stay at the current value.
          for (; writeIndex < fillToFrame; ++writeIndex)
            values[writeIndex] = value;

          currentFrame = fillToEndFrame;
          break;
        }

        case ParamEvent::ExponentialRampToValue: {
          currentFrame = fillToEndFrame;

          // If we're here, we've reached the end of the ramp.  If we can
          // (because the start and end values have the same sign, and neither
          // is 0), use the actual end value.  If not, we have to propagate
          // whatever we have.
          if (i >= 1 && ((m_events[i - 1]->value() * event->value()) > 0))
            value = event->value();

          // Simply stay at a constant value from the last time.  We don't want
          // to use the value of the event in case value1 * value2 < 0.  In this
          // case we should propagate the previous value, which is in |value|.
          for (; writeIndex < fillToFrame; ++writeIndex)
            values[writeIndex] = value;

          break;
        }

        case ParamEvent::SetTarget: {
          // Exponential approach to target value with given time constant.
          //
          //   v(t) = v2 + (v1 - v2)*exp(-(t-t1/tau))
          //

          float target = event->value();
          float timeConstant = event->timeConstant();
          float discreteTimeConstant = static_cast<float>(
              AudioUtilities::discreteTimeConstantForSampleRate(timeConstant,
                                                                controlRate));

          // Set the starting value correctly.  This is only needed when the
          // current time is "equal" to the start time of this event.  This is
          // to get the sampling correct if the start time of this automation
          // isn't on a frame boundary.  Otherwise, we can just continue from
          // where we left off from the previous rendering quantum.
          {
            double rampStartFrame = time1 * sampleRate;
            // Condition is c - 1 < r <= c where c = currentFrame and r =
            // rampStartFrame.  Compute it this way because currentFrame is
            // unsigned and could be 0.
            if (rampStartFrame <= currentFrame &&
                currentFrame < rampStartFrame + 1) {
              value =
                  target +
                  (value - target) *
                      exp(-(currentFrame / sampleRate - time1) / timeConstant);
            } else {
              // Otherwise, need to compute a new value bacause |value| is the
              // last computed value of SetTarget.  Time has progressed by one
              // frame, so we need to update the value for the new frame.
              value += (target - value) * discreteTimeConstant;
            }
          }

          // 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)) {
            for (; writeIndex < fillToFrame; ++writeIndex)
              values[writeIndex] = target;
          } else {
#if CPU(X86) || CPU(X86_64)
            if (fillToFrame > writeIndex) {
              // Resolve recursion by expanding constants to achieve a 4-step
              // loop unrolling.
              //
              // v1 = v0 + (t - v0) * c
              // v2 = v1 + (t - v1) * c
              // v2 = v0 + (t - v0) * c + (t - (v0 + (t - v0) * c)) * c
              // v2 = v0 + (t - v0) * c + (t - v0) * c - (t - v0) * c * c
              // v2 = v0 + (t - v0) * c * (2 - c)
              // Thus c0 = c, c1 = c*(2-c). The same logic applies to c2 and c3.
              const float c0 = discreteTimeConstant;
              const float c1 = c0 * (2 - c0);
              const float c2 = c0 * ((c0 - 3) * c0 + 3);
              const float c3 = c0 * (c0 * ((4 - c0) * c0 - 6) + 4);

              float delta;
              __m128 vC = _mm_set_ps(c2, c1, c0, 0);
              __m128 vDelta, vValue, vResult;

              // Process 4 loop steps.
              unsigned fillToFrameTrunc =
                  writeIndex + ((fillToFrame - writeIndex) / 4) * 4;
              DCHECK_LE(fillToFrameTrunc, numberOfValues);

              for (; writeIndex < fillToFrameTrunc; writeIndex += 4) {
                delta = target - value;
                vDelta = _mm_set_ps1(delta);
                vValue = _mm_set_ps1(value);

                vResult = _mm_add_ps(vValue, _mm_mul_ps(vDelta, vC));
                _mm_storeu_ps(values + writeIndex, vResult);

                // Update value for next iteration.
                value += delta * c3;
              }
            }
#endif
            // Serially process remaining values
            for (; writeIndex < fillToFrame; ++writeIndex) {
              values[writeIndex] = value;
              value += (target - value) * discreteTimeConstant;
            }
            // The previous loops may have updated |value| one extra time.
            // Reset it to the last computed value.
            if (writeIndex >= 1)
              value = values[writeIndex - 1];
            currentFrame = fillToEndFrame;
          }
          break;
        }

        case ParamEvent::SetValueCurve: {
          Vector<float> curve = event->curve();
          float* curveData = curve.data();
          unsigned numberOfCurvePoints = curve.size();

          float curveEndValue = event->curveEndValue();

          // Curve events have duration, so don't just use next event time.
          double duration = event->duration();
          // How much to step the curve index for each frame.  This is basically
          // the term (N - 1)/Td in the specification.
          double curvePointsPerFrame =
              event->curvePointsPerSecond() / sampleRate;

          if (!numberOfCurvePoints || duration <= 0 || sampleRate <= 0) {
            // Error condition - simply propagate previous value.
            currentFrame = fillToEndFrame;
            for (; writeIndex < fillToFrame; ++writeIndex)
              values[writeIndex] = value;
            break;
          }

          // Save old values and recalculate information based on the curve's
          // duration instead of the next event time.
          size_t nextEventFillToFrame = fillToFrame;

          // fillToEndFrame = min(endFrame,
          //                      ceil(sampleRate * (time1 + duration))),
          // but compute this carefully in case sampleRate*(time1 + duration) is
          // huge.  fillToEndFrame is an exclusive upper bound of the last frame
          // to be computed, so ceil is used.
          {
            double curveEndFrame = ceil(sampleRate * (time1 + duration));
            if (endFrame > curveEndFrame)
              fillToEndFrame = static_cast<size_t>(curveEndFrame);
            else
              fillToEndFrame = endFrame;
          }

          // |fillToFrame| can be less than |startFrame| when the end of the
          // setValueCurve automation has been reached, but the next automation
          // has not yet started. In this case, |fillToFrame| is clipped to
          // |time1|+|duration| above, but |startFrame| will keep increasing
          // (because the current time is increasing).
          fillToFrame =
              (fillToEndFrame < startFrame) ? 0 : fillToEndFrame - startFrame;
          fillToFrame =
              std::min(fillToFrame, static_cast<size_t>(numberOfValues));

          // Index into the curve data using a floating-point value.
          // We're scaling the number of curve points by the duration (see
          // curvePointsPerFrame).
          double curveVirtualIndex = 0;
          if (time1 < currentFrame / sampleRate) {
            // Index somewhere in the middle of the curve data.
            // Don't use timeToSampleFrame() since we want the exact
            // floating-point frame.
            double frameOffset = currentFrame - time1 * sampleRate;
            curveVirtualIndex = curvePointsPerFrame * frameOffset;
          }

          // Set the default value in case fillToFrame is 0.
          value = curveEndValue;

          // Render the stretched curve data using linear interpolation.
          // Oversampled curve data can be provided if sharp discontinuities are
          // desired.
          unsigned k = 0;
#if CPU(X86) || CPU(X86_64)
          if (fillToFrame > writeIndex) {
            const __m128 vCurveVirtualIndex = _mm_set_ps1(curveVirtualIndex);
            const __m128 vCurvePointsPerFrame =
                _mm_set_ps1(curvePointsPerFrame);
            const __m128 vNumberOfCurvePointsM1 =
                _mm_set_ps1(numberOfCurvePoints - 1);
            const __m128 vN1 = _mm_set_ps1(1.0f);
            const __m128 vN4 = _mm_set_ps1(4.0f);

            __m128 vK = _mm_set_ps(3, 2, 1, 0);
            int aCurveIndex0[4];
            int aCurveIndex1[4];

            // Truncate loop steps to multiple of 4
            unsigned truncatedSteps = ((fillToFrame - writeIndex) / 4) * 4;
            unsigned fillToFrameTrunc = writeIndex + truncatedSteps;
            DCHECK_LE(fillToFrameTrunc, numberOfValues);

            for (; writeIndex < fillToFrameTrunc; writeIndex += 4) {
              // Compute current index this way to minimize round-off that would
              // have occurred by incrementing the index by curvePointsPerFrame.
              __m128 vCurrentVirtualIndex = _mm_add_ps(
                  vCurveVirtualIndex, _mm_mul_ps(vK, vCurvePointsPerFrame));
              vK = _mm_add_ps(vK, vN4);

              // Clamp index to the last element of the array.
              __m128i vCurveIndex0 = _mm_cvttps_epi32(
                  _mm_min_ps(vCurrentVirtualIndex, vNumberOfCurvePointsM1));
              __m128i vCurveIndex1 = _mm_cvttps_epi32(
                  _mm_min_ps(_mm_add_ps(vCurrentVirtualIndex, vN1),
                             vNumberOfCurvePointsM1));

              // Linearly interpolate between the two nearest curve points.
              // |delta| is clamped to 1 because currentVirtualIndex can exceed
              // curveIndex0 by more than one.  This can happen when we reached
              // the end of the curve but still need values to fill out the
              // current rendering quantum.
              _mm_storeu_si128((__m128i*)aCurveIndex0, vCurveIndex0);
              _mm_storeu_si128((__m128i*)aCurveIndex1, vCurveIndex1);
              __m128 vC0 = _mm_set_ps(
                  curveData[aCurveIndex0[3]], curveData[aCurveIndex0[2]],
                  curveData[aCurveIndex0[1]], curveData[aCurveIndex0[0]]);
              __m128 vC1 = _mm_set_ps(
                  curveData[aCurveIndex1[3]], curveData[aCurveIndex1[2]],
                  curveData[aCurveIndex1[1]], curveData[aCurveIndex1[0]]);
              __m128 vDelta =
                  _mm_min_ps(_mm_sub_ps(vCurrentVirtualIndex,
                                        _mm_cvtepi32_ps(vCurveIndex0)),
                             vN1);

              __m128 vValue =
                  _mm_add_ps(vC0, _mm_mul_ps(_mm_sub_ps(vC1, vC0), vDelta));

              _mm_storeu_ps(values + writeIndex, vValue);
            }
            // Pass along k to the serial loop.
            k = truncatedSteps;
          }
          if (writeIndex >= 1)
            value = values[writeIndex - 1];
#endif
          for (; writeIndex < fillToFrame; ++writeIndex, ++k) {
            // Compute current index this way to minimize round-off that would
            // have occurred by incrementing the index by curvePointsPerFrame.
            double currentVirtualIndex =
                curveVirtualIndex + k * curvePointsPerFrame;
            unsigned curveIndex0;

            // Clamp index to the last element of the array.
            if (currentVirtualIndex < numberOfCurvePoints) {
              curveIndex0 = static_cast<unsigned>(currentVirtualIndex);
            } else {
              curveIndex0 = numberOfCurvePoints - 1;
            }

            unsigned curveIndex1 =
                std::min(curveIndex0 + 1, numberOfCurvePoints - 1);

            // Linearly interpolate between the two nearest curve points.
            // |delta| is clamped to 1 because currentVirtualIndex can exceed
            // curveIndex0 by more than one.  This can happen when we reached
            // the end of the curve but still need values to fill out the
            // current rendering quantum.
            DCHECK_LT(curveIndex0, numberOfCurvePoints);
            DCHECK_LT(curveIndex1, numberOfCurvePoints);
            float c0 = curveData[curveIndex0];
            float c1 = curveData[curveIndex1];
            double delta = std::min(currentVirtualIndex - curveIndex0, 1.0);

            value = c0 + (c1 - c0) * delta;

            values[writeIndex] = value;
          }

          // If there's any time left after the duration of this event and the
          // start of the next, then just propagate the last value of the
          // curveData. Don't modify |value| unless there is time left.
          if (writeIndex < nextEventFillToFrame) {
            value = curveEndValue;
            for (; writeIndex < nextEventFillToFrame; ++writeIndex)
              values[writeIndex] = value;
          }

          // Re-adjust current time
          currentFrame += nextEventFillToFrame;

          break;
        }
        case ParamEvent::LastType:
          ASSERT_NOT_REACHED();
          break;
      }
    }
  }

  // If we skipped over any events (because they are in the past), we can
  // remove them so we don't have to check them ever again.  (This MUST be
  // running with the m_events lock so we can safely modify the m_events
  // array.)
  if (lastSkippedEventIndex > 0)
    m_events.remove(0, lastSkippedEventIndex - 1);

  // If there's any time left after processing the last event then just
  // propagate the last value to the end of the values buffer.
  for (; writeIndex < numberOfValues; ++writeIndex)
    values[writeIndex] = value;

  // This value is used to set the .value attribute of the AudioParam.  it
  // should be the last computed value.
  return values[numberOfValues - 1];
}

}  // namespace blink
