| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2011 Google Inc. All rights reserved. | 2 * Copyright (C) 2011 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * | 7 * |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 149 return ParamEvent(ParamEvent::SetTarget, value, time, timeConstant, 0, nullp
tr); | 149 return ParamEvent(ParamEvent::SetTarget, value, time, timeConstant, 0, nullp
tr); |
| 150 } | 150 } |
| 151 | 151 |
| 152 AudioParamTimeline::ParamEvent AudioParamTimeline::ParamEvent::createSetValueCur
veEvent(const DOMFloat32Array* curve, double time, double duration) | 152 AudioParamTimeline::ParamEvent AudioParamTimeline::ParamEvent::createSetValueCur
veEvent(const DOMFloat32Array* curve, double time, double duration) |
| 153 { | 153 { |
| 154 return ParamEvent(ParamEvent::SetValueCurve, 0, time, 0, duration, curve); | 154 return ParamEvent(ParamEvent::SetValueCurve, 0, time, 0, duration, curve); |
| 155 } | 155 } |
| 156 | 156 |
| 157 void AudioParamTimeline::setValueAtTime(float value, double time, ExceptionState
& exceptionState) | 157 void AudioParamTimeline::setValueAtTime(float value, double time, ExceptionState
& exceptionState) |
| 158 { | 158 { |
| 159 ASSERT(isMainThread()); | 159 DCHECK(isMainThread()); |
| 160 | 160 |
| 161 if (!isNonNegativeAudioParamTime(time, exceptionState)) | 161 if (!isNonNegativeAudioParamTime(time, exceptionState)) |
| 162 return; | 162 return; |
| 163 | 163 |
| 164 insertEvent(ParamEvent::createSetValueEvent(value, time), exceptionState); | 164 insertEvent(ParamEvent::createSetValueEvent(value, time), exceptionState); |
| 165 } | 165 } |
| 166 | 166 |
| 167 void AudioParamTimeline::linearRampToValueAtTime(float value, double time, float
initialValue, double callTime, ExceptionState& exceptionState) | 167 void AudioParamTimeline::linearRampToValueAtTime(float value, double time, float
initialValue, double callTime, ExceptionState& exceptionState) |
| 168 { | 168 { |
| 169 ASSERT(isMainThread()); | 169 DCHECK(isMainThread()); |
| 170 | 170 |
| 171 if (!isNonNegativeAudioParamTime(time, exceptionState)) | 171 if (!isNonNegativeAudioParamTime(time, exceptionState)) |
| 172 return; | 172 return; |
| 173 | 173 |
| 174 insertEvent(ParamEvent::createLinearRampEvent(value, time, initialValue, cal
lTime), exceptionState); | 174 insertEvent(ParamEvent::createLinearRampEvent(value, time, initialValue, cal
lTime), exceptionState); |
| 175 } | 175 } |
| 176 | 176 |
| 177 void AudioParamTimeline::exponentialRampToValueAtTime(float value, double time,
float initialValue, double callTime, ExceptionState& exceptionState) | 177 void AudioParamTimeline::exponentialRampToValueAtTime(float value, double time,
float initialValue, double callTime, ExceptionState& exceptionState) |
| 178 { | 178 { |
| 179 ASSERT(isMainThread()); | 179 DCHECK(isMainThread()); |
| 180 | 180 |
| 181 if (!isNonNegativeAudioParamTime(time, exceptionState)) | 181 if (!isNonNegativeAudioParamTime(time, exceptionState)) |
| 182 return; | 182 return; |
| 183 | 183 |
| 184 if (!value) { | 184 if (!value) { |
| 185 exceptionState.throwDOMException( | 185 exceptionState.throwDOMException( |
| 186 InvalidAccessError, | 186 InvalidAccessError, |
| 187 "The float target value provided (" + String::number(value) | 187 "The float target value provided (" + String::number(value) |
| 188 + ") should not be in the range (" + String::number(-std::numeric_li
mits<float>::denorm_min()) | 188 + ") should not be in the range (" + String::number(-std::numeric_li
mits<float>::denorm_min()) |
| 189 + ", " + String::number(std::numeric_limits<float>::denorm_min()) | 189 + ", " + String::number(std::numeric_limits<float>::denorm_min()) |
| 190 + ")."); | 190 + ")."); |
| 191 return; | 191 return; |
| 192 } | 192 } |
| 193 | 193 |
| 194 insertEvent(ParamEvent::createExponentialRampEvent(value, time, initialValue
, callTime), exceptionState); | 194 insertEvent(ParamEvent::createExponentialRampEvent(value, time, initialValue
, callTime), exceptionState); |
| 195 } | 195 } |
| 196 | 196 |
| 197 void AudioParamTimeline::setTargetAtTime(float target, double time, double timeC
onstant, ExceptionState& exceptionState) | 197 void AudioParamTimeline::setTargetAtTime(float target, double time, double timeC
onstant, ExceptionState& exceptionState) |
| 198 { | 198 { |
| 199 ASSERT(isMainThread()); | 199 DCHECK(isMainThread()); |
| 200 | 200 |
| 201 if (!isNonNegativeAudioParamTime(time, exceptionState) | 201 if (!isNonNegativeAudioParamTime(time, exceptionState) |
| 202 || !isPositiveAudioParamTime(timeConstant, exceptionState, "Time constan
t")) | 202 || !isPositiveAudioParamTime(timeConstant, exceptionState, "Time constan
t")) |
| 203 return; | 203 return; |
| 204 | 204 |
| 205 insertEvent(ParamEvent::createSetTargetEvent(target, time, timeConstant), ex
ceptionState); | 205 insertEvent(ParamEvent::createSetTargetEvent(target, time, timeConstant), ex
ceptionState); |
| 206 } | 206 } |
| 207 | 207 |
| 208 void AudioParamTimeline::setValueCurveAtTime(DOMFloat32Array* curve, double time
, double duration, ExceptionState& exceptionState) | 208 void AudioParamTimeline::setValueCurveAtTime(DOMFloat32Array* curve, double time
, double duration, ExceptionState& exceptionState) |
| 209 { | 209 { |
| 210 ASSERT(isMainThread()); | 210 DCHECK(isMainThread()); |
| 211 ASSERT(curve); | 211 DCHECK(curve); |
| 212 | 212 |
| 213 if (!isNonNegativeAudioParamTime(time, exceptionState) | 213 if (!isNonNegativeAudioParamTime(time, exceptionState) |
| 214 || !isPositiveAudioParamTime(duration, exceptionState, "Duration")) | 214 || !isPositiveAudioParamTime(duration, exceptionState, "Duration")) |
| 215 return; | 215 return; |
| 216 | 216 |
| 217 if (curve->length() < 2) { | 217 if (curve->length() < 2) { |
| 218 exceptionState.throwDOMException( | 218 exceptionState.throwDOMException( |
| 219 InvalidStateError, | 219 InvalidStateError, |
| 220 ExceptionMessages::indexExceedsMinimumBound( | 220 ExceptionMessages::indexExceedsMinimumBound( |
| 221 "curve length", | 221 "curve length", |
| 222 curve->length(), | 222 curve->length(), |
| 223 2U)); | 223 2U)); |
| 224 return; | 224 return; |
| 225 } | 225 } |
| 226 | 226 |
| 227 insertEvent(ParamEvent::createSetValueCurveEvent(curve, time, duration), exc
eptionState); | 227 insertEvent(ParamEvent::createSetValueCurveEvent(curve, time, duration), exc
eptionState); |
| 228 | 228 |
| 229 // Insert a setValueAtTime event too to establish an event so that all | 229 // Insert a setValueAtTime event too to establish an event so that all |
| 230 // following events will process from the end of the curve instead of the | 230 // following events will process from the end of the curve instead of the |
| 231 // beginning. | 231 // beginning. |
| 232 insertEvent(ParamEvent::createSetValueEvent(curve->data()[curve->length() -
1], time + duration), exceptionState); | 232 insertEvent(ParamEvent::createSetValueEvent(curve->data()[curve->length() -
1], time + duration), exceptionState); |
| 233 } | 233 } |
| 234 | 234 |
| 235 void AudioParamTimeline::insertEvent(const ParamEvent& event, ExceptionState& ex
ceptionState) | 235 void AudioParamTimeline::insertEvent(const ParamEvent& event, ExceptionState& ex
ceptionState) |
| 236 { | 236 { |
| 237 ASSERT(isMainThread()); | 237 DCHECK(isMainThread()); |
| 238 | 238 |
| 239 // Sanity check the event. Be super careful we're not getting infected with
NaN or Inf. These | 239 // Sanity check the event. Be super careful we're not getting infected with
NaN or Inf. These |
| 240 // should have been handled by the caller. | 240 // should have been handled by the caller. |
| 241 bool isValid = event.getType() < ParamEvent::LastType | 241 bool isValid = event.getType() < ParamEvent::LastType |
| 242 && std::isfinite(event.value()) | 242 && std::isfinite(event.value()) |
| 243 && std::isfinite(event.time()) | 243 && std::isfinite(event.time()) |
| 244 && std::isfinite(event.timeConstant()) | 244 && std::isfinite(event.timeConstant()) |
| 245 && std::isfinite(event.duration()) | 245 && std::isfinite(event.duration()) |
| 246 && event.duration() >= 0; | 246 && event.duration() >= 0; |
| 247 | 247 |
| 248 ASSERT(isValid); | 248 DCHECK(isValid); |
| 249 if (!isValid) | 249 if (!isValid) |
| 250 return; | 250 return; |
| 251 | 251 |
| 252 MutexLocker locker(m_eventsLock); | 252 MutexLocker locker(m_eventsLock); |
| 253 | 253 |
| 254 unsigned i = 0; | 254 unsigned i = 0; |
| 255 double insertTime = event.time(); | 255 double insertTime = event.time(); |
| 256 | 256 |
| 257 if (!m_events.size() | 257 if (!m_events.size() |
| 258 && (event.getType() == ParamEvent::LinearRampToValue | 258 && (event.getType() == ParamEvent::LinearRampToValue |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 317 // | 317 // |
| 318 // Don't want to return false here because that would confuse the processing
of the timeline | 318 // Don't want to return false here because that would confuse the processing
of the timeline |
| 319 // if previously we returned true and now suddenly return false, only to ret
urn true on the | 319 // if previously we returned true and now suddenly return false, only to ret
urn true on the |
| 320 // next rendering quantum. Currently, once a timeline has been introduced i
t is always true | 320 // next rendering quantum. Currently, once a timeline has been introduced i
t is always true |
| 321 // forever because m_events never shrinks. | 321 // forever because m_events never shrinks. |
| 322 return true; | 322 return true; |
| 323 } | 323 } |
| 324 | 324 |
| 325 void AudioParamTimeline::cancelScheduledValues(double startTime, ExceptionState&
exceptionState) | 325 void AudioParamTimeline::cancelScheduledValues(double startTime, ExceptionState&
exceptionState) |
| 326 { | 326 { |
| 327 ASSERT(isMainThread()); | 327 DCHECK(isMainThread()); |
| 328 | 328 |
| 329 MutexLocker locker(m_eventsLock); | 329 MutexLocker locker(m_eventsLock); |
| 330 | 330 |
| 331 // Remove all events starting at startTime. | 331 // Remove all events starting at startTime. |
| 332 for (unsigned i = 0; i < m_events.size(); ++i) { | 332 for (unsigned i = 0; i < m_events.size(); ++i) { |
| 333 if (m_events[i].time() >= startTime) { | 333 if (m_events[i].time() >= startTime) { |
| 334 m_events.remove(i, m_events.size() - i); | 334 m_events.remove(i, m_events.size() - i); |
| 335 break; | 335 break; |
| 336 } | 336 } |
| 337 } | 337 } |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 390 | 390 |
| 391 float AudioParamTimeline::valuesForFrameRangeImpl( | 391 float AudioParamTimeline::valuesForFrameRangeImpl( |
| 392 size_t startFrame, | 392 size_t startFrame, |
| 393 size_t endFrame, | 393 size_t endFrame, |
| 394 float defaultValue, | 394 float defaultValue, |
| 395 float* values, | 395 float* values, |
| 396 unsigned numberOfValues, | 396 unsigned numberOfValues, |
| 397 double sampleRate, | 397 double sampleRate, |
| 398 double controlRate) | 398 double controlRate) |
| 399 { | 399 { |
| 400 ASSERT(values); | 400 DCHECK(values); |
| 401 ASSERT(numberOfValues >= 1); | 401 DCHECK_GE(static_cast<int>(numberOfValues), 1); |
| 402 if (!values || !(numberOfValues >= 1)) | 402 if (!values || !(numberOfValues >= 1)) |
| 403 return defaultValue; | 403 return defaultValue; |
| 404 | 404 |
| 405 // Return default value if there are no events matching the desired time ran
ge. | 405 // Return default value if there are no events matching the desired time ran
ge. |
| 406 if (!m_events.size() || (endFrame / sampleRate <= m_events[0].time())) { | 406 if (!m_events.size() || (endFrame / sampleRate <= m_events[0].time())) { |
| 407 for (unsigned i = 0; i < numberOfValues; ++i) | 407 for (unsigned i = 0; i < numberOfValues; ++i) |
| 408 values[i] = defaultValue; | 408 values[i] = defaultValue; |
| 409 return defaultValue; | 409 return defaultValue; |
| 410 } | 410 } |
| 411 | 411 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 441 // If first event is after startFrame then fill initial part of values buffe
r with defaultValue | 441 // If first event is after startFrame then fill initial part of values buffe
r with defaultValue |
| 442 // until we reach the first event time. | 442 // until we reach the first event time. |
| 443 double firstEventTime = m_events[0].time(); | 443 double firstEventTime = m_events[0].time(); |
| 444 if (firstEventTime > startFrame / sampleRate) { | 444 if (firstEventTime > startFrame / sampleRate) { |
| 445 // |fillToFrame| is an exclusive upper bound, so use ceil() to compute t
he bound from the | 445 // |fillToFrame| is an exclusive upper bound, so use ceil() to compute t
he bound from the |
| 446 // firstEventTime. | 446 // firstEventTime. |
| 447 size_t fillToFrame = endFrame; | 447 size_t fillToFrame = endFrame; |
| 448 double firstEventFrame = ceil(firstEventTime * sampleRate); | 448 double firstEventFrame = ceil(firstEventTime * sampleRate); |
| 449 if (endFrame > firstEventFrame) | 449 if (endFrame > firstEventFrame) |
| 450 fillToFrame = static_cast<size_t>(firstEventFrame); | 450 fillToFrame = static_cast<size_t>(firstEventFrame); |
| 451 ASSERT(fillToFrame >= startFrame); | 451 DCHECK_GE(fillToFrame, startFrame); |
| 452 | 452 |
| 453 fillToFrame -= startFrame; | 453 fillToFrame -= startFrame; |
| 454 fillToFrame = std::min(fillToFrame, static_cast<size_t>(numberOfValues))
; | 454 fillToFrame = std::min(fillToFrame, static_cast<size_t>(numberOfValues))
; |
| 455 for (; writeIndex < fillToFrame; ++writeIndex) | 455 for (; writeIndex < fillToFrame; ++writeIndex) |
| 456 values[writeIndex] = defaultValue; | 456 values[writeIndex] = defaultValue; |
| 457 | 457 |
| 458 currentFrame += fillToFrame; | 458 currentFrame += fillToFrame; |
| 459 } | 459 } |
| 460 | 460 |
| 461 float value = defaultValue; | 461 float value = defaultValue; |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 561 // for frame 128. This requires that fillToEndFrame be at least 129. T
his is achieved by | 561 // for frame 128. This requires that fillToEndFrame be at least 129. T
his is achieved by |
| 562 // ceil(time2). | 562 // ceil(time2). |
| 563 // | 563 // |
| 564 // However, time2 can be very large, so compute this carefully in the ca
se where time2 | 564 // However, time2 can be very large, so compute this carefully in the ca
se where time2 |
| 565 // exceeds the size of a size_t. | 565 // exceeds the size of a size_t. |
| 566 | 566 |
| 567 size_t fillToEndFrame = endFrame; | 567 size_t fillToEndFrame = endFrame; |
| 568 if (endFrame > time2 * sampleRate) | 568 if (endFrame > time2 * sampleRate) |
| 569 fillToEndFrame = static_cast<size_t>(ceil(time2 * sampleRate)); | 569 fillToEndFrame = static_cast<size_t>(ceil(time2 * sampleRate)); |
| 570 | 570 |
| 571 ASSERT(fillToEndFrame >= startFrame); | 571 DCHECK_GE(fillToEndFrame, startFrame); |
| 572 size_t fillToFrame = fillToEndFrame - startFrame; | 572 size_t fillToFrame = fillToEndFrame - startFrame; |
| 573 fillToFrame = std::min(fillToFrame, static_cast<size_t>(numberOfValues))
; | 573 fillToFrame = std::min(fillToFrame, static_cast<size_t>(numberOfValues))
; |
| 574 | 574 |
| 575 // First handle linear and exponential ramps which require looking ahead
to the next event. | 575 // First handle linear and exponential ramps which require looking ahead
to the next event. |
| 576 if (nextEventType == ParamEvent::LinearRampToValue) { | 576 if (nextEventType == ParamEvent::LinearRampToValue) { |
| 577 const float valueDelta = value2 - value1; | 577 const float valueDelta = value2 - value1; |
| 578 #if CPU(X86) || CPU(X86_64) | 578 #if CPU(X86) || CPU(X86_64) |
| 579 // Minimize in-loop operations. Calculate starting value and increme
nt. Next step: value += inc. | 579 // Minimize in-loop operations. Calculate starting value and increme
nt. Next step: value += inc. |
| 580 // value = value1 + (currentFrame/sampleRate - time1) * k * (value2
- value1); | 580 // value = value1 + (currentFrame/sampleRate - time1) * k * (value2
- value1); |
| 581 // inc = 4 / sampleRate * k * (value2 - value1); | 581 // inc = 4 / sampleRate * k * (value2 - value1); |
| (...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 900 } else { | 900 } else { |
| 901 curveIndex0 = numberOfCurvePoints - 1; | 901 curveIndex0 = numberOfCurvePoints - 1; |
| 902 } | 902 } |
| 903 | 903 |
| 904 unsigned curveIndex1 = std::min(curveIndex0 + 1, numberO
fCurvePoints - 1); | 904 unsigned curveIndex1 = std::min(curveIndex0 + 1, numberO
fCurvePoints - 1); |
| 905 | 905 |
| 906 // Linearly interpolate between the two nearest curve po
ints. |delta| is | 906 // Linearly interpolate between the two nearest curve po
ints. |delta| is |
| 907 // clamped to 1 because currentVirtualIndex can exceed c
urveIndex0 by more | 907 // clamped to 1 because currentVirtualIndex can exceed c
urveIndex0 by more |
| 908 // than one. This can happen when we reached the end of
the curve but still | 908 // than one. This can happen when we reached the end of
the curve but still |
| 909 // need values to fill out the current rendering quantum
. | 909 // need values to fill out the current rendering quantum
. |
| 910 ASSERT(curveIndex0 < numberOfCurvePoints); | 910 DCHECK_LT(curveIndex0, numberOfCurvePoints); |
| 911 ASSERT(curveIndex1 < numberOfCurvePoints); | 911 DCHECK_LT(curveIndex1, numberOfCurvePoints); |
| 912 float c0 = curveData[curveIndex0]; | 912 float c0 = curveData[curveIndex0]; |
| 913 float c1 = curveData[curveIndex1]; | 913 float c1 = curveData[curveIndex1]; |
| 914 double delta = std::min(currentVirtualIndex - curveIndex
0, 1.0); | 914 double delta = std::min(currentVirtualIndex - curveIndex
0, 1.0); |
| 915 | 915 |
| 916 value = c0 + (c1 - c0) * delta; | 916 value = c0 + (c1 - c0) * delta; |
| 917 | 917 |
| 918 values[writeIndex] = value; | 918 values[writeIndex] = value; |
| 919 } | 919 } |
| 920 | 920 |
| 921 // If there's any time left after the duration of this event
and the start | 921 // If there's any time left after the duration of this event
and the start |
| (...skipping 27 matching lines...) Expand all Loading... |
| 949 for (; writeIndex < numberOfValues; ++writeIndex) | 949 for (; writeIndex < numberOfValues; ++writeIndex) |
| 950 values[writeIndex] = value; | 950 values[writeIndex] = value; |
| 951 | 951 |
| 952 // This value is used to set the .value attribute of the AudioParam. it sho
uld be the last | 952 // This value is used to set the .value attribute of the AudioParam. it sho
uld be the last |
| 953 // computed value. | 953 // computed value. |
| 954 return values[numberOfValues - 1]; | 954 return values[numberOfValues - 1]; |
| 955 } | 955 } |
| 956 | 956 |
| 957 } // namespace blink | 957 } // namespace blink |
| 958 | 958 |
| OLD | NEW |