Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(164)

Side by Side Diff: third_party/WebKit/Source/modules/webaudio/AudioParamTimeline.cpp

Issue 1533103002: Implement cancelValuesAndHoldAtTime (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/WebKit/Source/modules/webaudio/AudioParamTimeline.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 11 matching lines...) Expand all
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */ 24 */
25 25
26 #include "modules/webaudio/AudioParamTimeline.h" 26 #include "modules/webaudio/AudioParamTimeline.h"
27 #include "bindings/core/v8/ExceptionState.h" 27 #include "bindings/core/v8/ExceptionState.h"
28 #include "core/dom/ExceptionCode.h" 28 #include "core/dom/ExceptionCode.h"
29 #include "platform/audio/AudioUtilities.h" 29 #include "platform/audio/AudioUtilities.h"
30 #include "wtf/CPU.h" 30 #include "wtf/CPU.h"
31 #include "wtf/MathExtras.h" 31 #include "wtf/MathExtras.h"
32 #include "wtf/PtrUtil.h"
32 #include <algorithm> 33 #include <algorithm>
33 34
34 #if CPU(X86) || CPU(X86_64) 35 #if CPU(X86) || CPU(X86_64)
35 #include <emmintrin.h> 36 #include <emmintrin.h>
36 #endif 37 #endif
37 38
38 namespace blink { 39 namespace blink {
39 40
40 // For a SetTarget event, if the relative difference between the current value 41 // For a SetTarget event, if the relative difference between the current value
41 // and the target value is less than this, consider them the same and just 42 // and the target value is less than this, consider them the same and just
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 s = "setTargetAtTime"; 100 s = "setTargetAtTime";
100 // This has an extra time constant arg 101 // This has an extra time constant arg
101 args = args + ", " + String::number(event.timeConstant(), 16); 102 args = args + ", " + String::number(event.timeConstant(), 16);
102 break; 103 break;
103 case ParamEvent::SetValueCurve: 104 case ParamEvent::SetValueCurve:
104 s = "setValueCurveAtTime"; 105 s = "setValueCurveAtTime";
105 // Replace the default arg, using "..." to denote the curve argument. 106 // Replace the default arg, using "..." to denote the curve argument.
106 args = "..., " + String::number(event.time(), 16) + ", " + 107 args = "..., " + String::number(event.time(), 16) + ", " +
107 String::number(event.duration(), 16); 108 String::number(event.duration(), 16);
108 break; 109 break;
110 case ParamEvent::CancelValues:
111 // Fall through; we should never have to print out the internal
112 // CancelValues event.
109 case ParamEvent::LastType: 113 case ParamEvent::LastType:
110 ASSERT_NOT_REACHED(); 114 ASSERT_NOT_REACHED();
111 break; 115 break;
112 }; 116 };
113 117
114 return s + "(" + args + ")"; 118 return s + "(" + args + ")";
115 } 119 }
116 120
117 AudioParamTimeline::ParamEvent::ParamEvent(Type type, 121 // Computes the value of a linear ramp event at time t with the given event
118 float value, 122 // parameters.
119 double time, 123 float AudioParamTimeline::linearRampAtTime(double t,
120 double timeConstant, 124 float value1,
121 double duration, 125 double time1,
122 const DOMFloat32Array* curve, 126 float value2,
123 float initialValue, 127 double time2) {
124 double callTime) 128 return value1 + (value2 - value1) * (t - time1) / (time2 - time1);
125 : m_type(type),
126 m_value(value),
127 m_time(time),
128 m_timeConstant(timeConstant),
129 m_duration(duration),
130 m_initialValue(initialValue),
131 m_callTime(callTime),
132 m_needsTimeClampCheck(true) {
133 if (curve) {
134 // Copy the curve data
135 unsigned curveLength = curve->length();
136 m_curve.resize(curveLength);
137 memcpy(m_curve.data(), curve->data(), curveLength * sizeof(float));
138 }
139 } 129 }
140 130
141 AudioParamTimeline::ParamEvent 131 // Computes the value of an exponential ramp event at time t with the given
142 AudioParamTimeline::ParamEvent::createSetValueEvent(float value, double time) { 132 // event parameters.
143 return ParamEvent(ParamEvent::SetValue, value, time, 0, 0, nullptr); 133 float AudioParamTimeline::exponentialRampAtTime(double t,
134 float value1,
135 double time1,
136 float value2,
137 double time2) {
138 return value1 * pow(value2 / value1, (t - time1) / (time2 - time1));
144 } 139 }
145 140
146 AudioParamTimeline::ParamEvent 141 // Compute the value of a set target event at time t with the given event
142 // parameters.
143 float AudioParamTimeline::targetValueAtTime(double t,
144 float value1,
145 double time1,
146 float value2,
147 float timeConstant) {
148 return value2 + (value1 - value2) * exp(-(t - time1) / timeConstant);
149 }
150
151 // Compute the value of a set curve event at time t with the given event
152 // parameters.
153 float AudioParamTimeline::valueCurveAtTime(double t,
154 double time1,
155 double duration,
156 const float* curveData,
157 unsigned curveLength) {
158 double curveIndex = (curveLength - 1) / duration * (t - time1);
159 unsigned k = std::min(static_cast<unsigned>(curveIndex), curveLength - 1);
160 unsigned k1 = std::min(k + 1, curveLength - 1);
161 float c0 = curveData[k];
162 float c1 = curveData[k1];
163 float delta = std::min(curveIndex - k, 1.0);
164
165 return c0 + (c1 - c0) * delta;
166 }
167
168 std::unique_ptr<AudioParamTimeline::ParamEvent>
169 AudioParamTimeline::ParamEvent::createSetValueEvent(float value, double time) {
170 return WTF::wrapUnique(new ParamEvent(ParamEvent::SetValue, value, time));
171 }
172
173 std::unique_ptr<AudioParamTimeline::ParamEvent>
147 AudioParamTimeline::ParamEvent::createLinearRampEvent(float value, 174 AudioParamTimeline::ParamEvent::createLinearRampEvent(float value,
148 double time, 175 double time,
149 float initialValue, 176 float initialValue,
150 double callTime) { 177 double callTime) {
151 return ParamEvent(ParamEvent::LinearRampToValue, value, time, 0, 0, nullptr, 178 return WTF::wrapUnique(new ParamEvent(ParamEvent::LinearRampToValue, value,
152 initialValue, callTime); 179 time, initialValue, callTime));
153 } 180 }
154 181
155 AudioParamTimeline::ParamEvent 182 std::unique_ptr<AudioParamTimeline::ParamEvent>
156 AudioParamTimeline::ParamEvent::createExponentialRampEvent(float value, 183 AudioParamTimeline::ParamEvent::createExponentialRampEvent(float value,
157 double time, 184 double time,
158 float initialValue, 185 float initialValue,
159 double callTime) { 186 double callTime) {
160 return ParamEvent(ParamEvent::ExponentialRampToValue, value, time, 0, 0, 187 return WTF::wrapUnique(new ParamEvent(ParamEvent::ExponentialRampToValue,
161 nullptr, initialValue, callTime); 188 value, time, initialValue, callTime));
162 } 189 }
163 190
164 AudioParamTimeline::ParamEvent 191 std::unique_ptr<AudioParamTimeline::ParamEvent>
165 AudioParamTimeline::ParamEvent::createSetTargetEvent(float value, 192 AudioParamTimeline::ParamEvent::createSetTargetEvent(float value,
166 double time, 193 double time,
167 double timeConstant) { 194 double timeConstant) {
168 // The time line code does not expect a timeConstant of 0. (IT 195 // The time line code does not expect a timeConstant of 0. (IT
169 // returns NaN or Infinity due to division by zero. The caller 196 // returns NaN or Infinity due to division by zero. The caller
170 // should have converted this to a SetValueEvent. 197 // should have converted this to a SetValueEvent.
171 DCHECK_NE(timeConstant, 0); 198 DCHECK_NE(timeConstant, 0);
172 return ParamEvent(ParamEvent::SetTarget, value, time, timeConstant, 0, 199 return WTF::wrapUnique(
173 nullptr); 200 new ParamEvent(ParamEvent::SetTarget, value, time, timeConstant));
174 } 201 }
175 202
176 AudioParamTimeline::ParamEvent 203 std::unique_ptr<AudioParamTimeline::ParamEvent>
177 AudioParamTimeline::ParamEvent::createSetValueCurveEvent( 204 AudioParamTimeline::ParamEvent::createSetValueCurveEvent(
178 const DOMFloat32Array* curve, 205 const DOMFloat32Array* curve,
179 double time, 206 double time,
180 double duration) { 207 double duration) {
181 return ParamEvent(ParamEvent::SetValueCurve, 0, time, 0, duration, curve); 208 double curvePoints = (curve->length() - 1) / duration;
209 float endValue = curve->data()[curve->length() - 1];
210
211 return WTF::wrapUnique(new ParamEvent(
212 ParamEvent::SetValueCurve, time, duration, curve, curvePoints, endValue));
213 }
214
215 std::unique_ptr<AudioParamTimeline::ParamEvent>
216 AudioParamTimeline::ParamEvent::createCancelValuesEvent(
217 double time,
218 std::unique_ptr<ParamEvent> savedEvent) {
219 if (savedEvent) {
220 // The savedEvent can only have certain event types. Verify that.
221 ParamEvent::Type savedType = savedEvent->getType();
222
223 DCHECK_NE(savedType, ParamEvent::LastType);
224 DCHECK(savedType == ParamEvent::LinearRampToValue ||
225 savedType == ParamEvent::ExponentialRampToValue ||
226 savedType == ParamEvent::SetValueCurve);
227 }
228
229 return WTF::wrapUnique(
230 new ParamEvent(ParamEvent::CancelValues, time, std::move(savedEvent)));
231 }
232
233 std::unique_ptr<AudioParamTimeline::ParamEvent>
234 AudioParamTimeline::ParamEvent::createGeneralEvent(
235 Type type,
236 float value,
237 double time,
238 float initialValue,
239 double callTime,
240 double timeConstant,
241 double duration,
242 Vector<float>& curve,
243 double curvePointsPerSecond,
244 float curveEndValue,
245 std::unique_ptr<ParamEvent> savedEvent) {
246 return WTF::wrapUnique(new ParamEvent(
247 type, value, time, initialValue, callTime, timeConstant, duration, curve,
248 curvePointsPerSecond, curveEndValue, std::move(savedEvent)));
249 }
250
251 AudioParamTimeline::ParamEvent* AudioParamTimeline::ParamEvent::savedEvent()
252 const {
253 DCHECK_EQ(getType(), ParamEvent::CancelValues);
254 return m_savedEvent.get();
255 }
256
257 bool AudioParamTimeline::ParamEvent::hasDefaultCancelledValue() const {
258 DCHECK_EQ(getType(), ParamEvent::CancelValues);
259 return m_hasDefaultCancelledValue;
260 }
261
262 void AudioParamTimeline::ParamEvent::setCancelledValue(float value) {
263 DCHECK_EQ(getType(), ParamEvent::CancelValues);
264 m_value = value;
265 m_hasDefaultCancelledValue = true;
266 }
267
268 // General event
269 AudioParamTimeline::ParamEvent::ParamEvent(
270 ParamEvent::Type type,
271 float value,
272 double time,
273 float initialValue,
274 double callTime,
275 double timeConstant,
276 double duration,
277 Vector<float>& curve,
278 double curvePointsPerSecond,
279 float curveEndValue,
280 std::unique_ptr<ParamEvent> savedEvent)
281 : m_type(type),
282 m_value(value),
283 m_time(time),
284 m_initialValue(initialValue),
285 m_callTime(callTime),
286 m_timeConstant(timeConstant),
287 m_duration(duration),
288 m_curvePointsPerSecond(curvePointsPerSecond),
289 m_curveEndValue(curveEndValue),
290 m_savedEvent(std::move(savedEvent)),
291 m_needsTimeClampCheck(true),
292 m_hasDefaultCancelledValue(false) {
293 m_curve = curve;
294 }
295
296 // Create simplest event needing just a value and time, like setValueAtTime
297 AudioParamTimeline::ParamEvent::ParamEvent(ParamEvent::Type type,
298 float value,
299 double time)
300 : m_type(type),
301 m_value(value),
302 m_time(time),
303 m_initialValue(0),
304 m_callTime(0),
305 m_timeConstant(0),
306 m_duration(0),
307 m_curvePointsPerSecond(0),
308 m_curveEndValue(0),
309 m_savedEvent(nullptr),
310 m_needsTimeClampCheck(true),
311 m_hasDefaultCancelledValue(false) {
312 DCHECK_EQ(type, ParamEvent::SetValue);
313 }
314
315 // Create a linear or exponential ramp that requires an initial value and
316 // time in case
317 // there is no actual event that preceeds this event.
318 AudioParamTimeline::ParamEvent::ParamEvent(ParamEvent::Type type,
319 float value,
320 double time,
321 float initialValue,
322 double callTime)
323 : m_type(type),
324 m_value(value),
325 m_time(time),
326 m_initialValue(initialValue),
327 m_callTime(callTime),
328 m_timeConstant(0),
329 m_duration(0),
330 m_curvePointsPerSecond(0),
331 m_curveEndValue(0),
332 m_savedEvent(nullptr),
333 m_needsTimeClampCheck(true),
334 m_hasDefaultCancelledValue(false) {
335 DCHECK(type == ParamEvent::LinearRampToValue ||
336 type == ParamEvent::ExponentialRampToValue);
337 }
338
339 // Create an event needing a time constant (setTargetAtTime)
340 AudioParamTimeline::ParamEvent::ParamEvent(ParamEvent::Type type,
341 float value,
342 double time,
343 double timeConstant)
344 : m_type(type),
345 m_value(value),
346 m_time(time),
347 m_initialValue(0),
348 m_callTime(0),
349 m_timeConstant(timeConstant),
350 m_duration(0),
351 m_curvePointsPerSecond(0),
352 m_curveEndValue(0),
353 m_savedEvent(nullptr),
354 m_needsTimeClampCheck(true),
355 m_hasDefaultCancelledValue(false) {
356 DCHECK_EQ(type, ParamEvent::SetTarget);
357 }
358
359 // Create a setValueCurve event
360 AudioParamTimeline::ParamEvent::ParamEvent(ParamEvent::Type type,
361 double time,
362 double duration,
363 const DOMFloat32Array* curve,
364 double curvePointsPerSecond,
365 float curveEndValue)
366 : m_type(type),
367 m_value(0),
368 m_time(time),
369 m_initialValue(0),
370 m_callTime(0),
371 m_timeConstant(0),
372 m_duration(duration),
373 m_curvePointsPerSecond(curvePointsPerSecond),
374 m_curveEndValue(curveEndValue),
375 m_savedEvent(nullptr),
376 m_needsTimeClampCheck(true),
377 m_hasDefaultCancelledValue(false) {
378 DCHECK_EQ(type, ParamEvent::SetValueCurve);
379 if (curve) {
380 unsigned curveLength = curve->length();
381 m_curve.resize(curve->length());
382 memcpy(m_curve.data(), curve->data(), curveLength * sizeof(float));
383 }
384 }
385
386 // Create CancelValues event
387 AudioParamTimeline::ParamEvent::ParamEvent(
388 ParamEvent::Type type,
389 double time,
390 std::unique_ptr<ParamEvent> savedEvent)
391 : m_type(type),
392 m_value(0),
393 m_time(time),
394 m_initialValue(0),
395 m_callTime(0),
396 m_timeConstant(0),
397 m_duration(0),
398 m_curvePointsPerSecond(0),
399 m_curveEndValue(0),
400 m_savedEvent(std::move(savedEvent)),
401 m_needsTimeClampCheck(true),
402 m_hasDefaultCancelledValue(false) {
403 DCHECK_EQ(type, ParamEvent::CancelValues);
182 } 404 }
183 405
184 void AudioParamTimeline::setValueAtTime(float value, 406 void AudioParamTimeline::setValueAtTime(float value,
185 double time, 407 double time,
186 ExceptionState& exceptionState) { 408 ExceptionState& exceptionState) {
187 DCHECK(isMainThread()); 409 DCHECK(isMainThread());
188 410
189 if (!isNonNegativeAudioParamTime(time, exceptionState)) 411 if (!isNonNegativeAudioParamTime(time, exceptionState))
190 return; 412 return;
191 413
414 MutexLocker locker(m_eventsLock);
192 insertEvent(ParamEvent::createSetValueEvent(value, time), exceptionState); 415 insertEvent(ParamEvent::createSetValueEvent(value, time), exceptionState);
193 } 416 }
194 417
195 void AudioParamTimeline::linearRampToValueAtTime( 418 void AudioParamTimeline::linearRampToValueAtTime(
196 float value, 419 float value,
197 double time, 420 double time,
198 float initialValue, 421 float initialValue,
199 double callTime, 422 double callTime,
200 ExceptionState& exceptionState) { 423 ExceptionState& exceptionState) {
201 DCHECK(isMainThread()); 424 DCHECK(isMainThread());
202 425
203 if (!isNonNegativeAudioParamTime(time, exceptionState)) 426 if (!isNonNegativeAudioParamTime(time, exceptionState))
204 return; 427 return;
205 428
429 MutexLocker locker(m_eventsLock);
206 insertEvent( 430 insertEvent(
207 ParamEvent::createLinearRampEvent(value, time, initialValue, callTime), 431 ParamEvent::createLinearRampEvent(value, time, initialValue, callTime),
208 exceptionState); 432 exceptionState);
209 } 433 }
210 434
211 void AudioParamTimeline::exponentialRampToValueAtTime( 435 void AudioParamTimeline::exponentialRampToValueAtTime(
212 float value, 436 float value,
213 double time, 437 double time,
214 float initialValue, 438 float initialValue,
215 double callTime, 439 double callTime,
216 ExceptionState& exceptionState) { 440 ExceptionState& exceptionState) {
217 DCHECK(isMainThread()); 441 DCHECK(isMainThread());
218 442
219 if (!isNonNegativeAudioParamTime(time, exceptionState)) 443 if (!isNonNegativeAudioParamTime(time, exceptionState))
220 return; 444 return;
221 445
222 if (!value) { 446 if (!value) {
223 exceptionState.throwDOMException( 447 exceptionState.throwDOMException(
224 InvalidAccessError, 448 InvalidAccessError,
225 "The float target value provided (" + String::number(value) + 449 "The float target value provided (" + String::number(value) +
226 ") should not be in the range (" + 450 ") should not be in the range (" +
227 String::number(-std::numeric_limits<float>::denorm_min()) + ", " + 451 String::number(-std::numeric_limits<float>::denorm_min()) + ", " +
228 String::number(std::numeric_limits<float>::denorm_min()) + ")."); 452 String::number(std::numeric_limits<float>::denorm_min()) + ").");
229 return; 453 return;
230 } 454 }
231 455
456 MutexLocker locker(m_eventsLock);
232 insertEvent(ParamEvent::createExponentialRampEvent(value, time, initialValue, 457 insertEvent(ParamEvent::createExponentialRampEvent(value, time, initialValue,
233 callTime), 458 callTime),
234 exceptionState); 459 exceptionState);
235 } 460 }
236 461
237 void AudioParamTimeline::setTargetAtTime(float target, 462 void AudioParamTimeline::setTargetAtTime(float target,
238 double time, 463 double time,
239 double timeConstant, 464 double timeConstant,
240 ExceptionState& exceptionState) { 465 ExceptionState& exceptionState) {
241 DCHECK(isMainThread()); 466 DCHECK(isMainThread());
242 467
243 if (!isNonNegativeAudioParamTime(time, exceptionState) || 468 if (!isNonNegativeAudioParamTime(time, exceptionState) ||
244 !isNonNegativeAudioParamTime(timeConstant, exceptionState, 469 !isNonNegativeAudioParamTime(timeConstant, exceptionState,
245 "Time constant")) 470 "Time constant"))
246 return; 471 return;
247 472
473 MutexLocker locker(m_eventsLock);
474
248 // If timeConstant = 0, we instantly jump to the target value, so 475 // If timeConstant = 0, we instantly jump to the target value, so
249 // insert a SetValueEvent instead of SetTargetEvent. 476 // insert a SetValueEvent instead of SetTargetEvent.
250 if (timeConstant == 0) { 477 if (timeConstant == 0) {
251 insertEvent(ParamEvent::createSetValueEvent(target, time), exceptionState); 478 insertEvent(ParamEvent::createSetValueEvent(target, time), exceptionState);
252 } else { 479 } else {
253 insertEvent(ParamEvent::createSetTargetEvent(target, time, timeConstant), 480 insertEvent(ParamEvent::createSetTargetEvent(target, time, timeConstant),
254 exceptionState); 481 exceptionState);
255 } 482 }
256 } 483 }
257 484
258 void AudioParamTimeline::setValueCurveAtTime(DOMFloat32Array* curve, 485 void AudioParamTimeline::setValueCurveAtTime(DOMFloat32Array* curve,
259 double time, 486 double time,
260 double duration, 487 double duration,
261 ExceptionState& exceptionState) { 488 ExceptionState& exceptionState) {
262 DCHECK(isMainThread()); 489 DCHECK(isMainThread());
263 DCHECK(curve); 490 DCHECK(curve);
264 491
265 if (!isNonNegativeAudioParamTime(time, exceptionState) || 492 if (!isNonNegativeAudioParamTime(time, exceptionState) ||
266 !isPositiveAudioParamTime(duration, exceptionState, "Duration")) 493 !isPositiveAudioParamTime(duration, exceptionState, "Duration"))
267 return; 494 return;
268 495
269 if (curve->length() < 2) { 496 if (curve->length() < 2) {
270 exceptionState.throwDOMException( 497 exceptionState.throwDOMException(
271 InvalidStateError, ExceptionMessages::indexExceedsMinimumBound( 498 InvalidStateError, ExceptionMessages::indexExceedsMinimumBound(
272 "curve length", curve->length(), 2U)); 499 "curve length", curve->length(), 2U));
273 return; 500 return;
274 } 501 }
275 502
503 MutexLocker locker(m_eventsLock);
276 insertEvent(ParamEvent::createSetValueCurveEvent(curve, time, duration), 504 insertEvent(ParamEvent::createSetValueCurveEvent(curve, time, duration),
277 exceptionState); 505 exceptionState);
278 506
279 // Insert a setValueAtTime event too to establish an event so that all 507 // Insert a setValueAtTime event too to establish an event so that all
280 // following events will process from the end of the curve instead of the 508 // following events will process from the end of the curve instead of the
281 // beginning. 509 // beginning.
282 insertEvent(ParamEvent::createSetValueEvent( 510 insertEvent(ParamEvent::createSetValueEvent(
283 curve->data()[curve->length() - 1], time + duration), 511 curve->data()[curve->length() - 1], time + duration),
284 exceptionState); 512 exceptionState);
285 } 513 }
286 514
287 void AudioParamTimeline::insertEvent(const ParamEvent& event, 515 void AudioParamTimeline::insertEvent(std::unique_ptr<ParamEvent> event,
288 ExceptionState& exceptionState) { 516 ExceptionState& exceptionState) {
289 DCHECK(isMainThread()); 517 DCHECK(isMainThread());
290 518
291 // Sanity check the event. Be super careful we're not getting infected with 519 // Sanity check the event. Be super careful we're not getting infected with
292 // NaN or Inf. These should have been handled by the caller. 520 // NaN or Inf. These should have been handled by the caller.
293 bool isValid = event.getType() < ParamEvent::LastType && 521 bool isValid = event->getType() < ParamEvent::LastType &&
294 std::isfinite(event.value()) && std::isfinite(event.time()) && 522 std::isfinite(event->value()) &&
295 std::isfinite(event.timeConstant()) && 523 std::isfinite(event->time()) &&
296 std::isfinite(event.duration()) && event.duration() >= 0; 524 std::isfinite(event->timeConstant()) &&
525 std::isfinite(event->duration()) && event->duration() >= 0;
297 526
298 DCHECK(isValid); 527 DCHECK(isValid);
299 if (!isValid) 528 if (!isValid)
300 return; 529 return;
301 530
302 MutexLocker locker(m_eventsLock);
303
304 unsigned i = 0; 531 unsigned i = 0;
305 double insertTime = event.time(); 532 double insertTime = event->time();
306 533
307 if (!m_events.size() && 534 if (!m_events.size() &&
308 (event.getType() == ParamEvent::LinearRampToValue || 535 (event->getType() == ParamEvent::LinearRampToValue ||
309 event.getType() == ParamEvent::ExponentialRampToValue)) { 536 event->getType() == ParamEvent::ExponentialRampToValue)) {
310 // There are no events preceding these ramps. Insert a new setValueAtTime 537 // There are no events preceding these ramps. Insert a new setValueAtTime
311 // event to set the starting point for these events. 538 // event to set the starting point for these events.
312 m_events.insert(0, AudioParamTimeline::ParamEvent::createSetValueEvent( 539 m_events.insert(0, AudioParamTimeline::ParamEvent::createSetValueEvent(
313 event.initialValue(), event.callTime())); 540 event->initialValue(), event->callTime()));
314 } 541 }
315 542
316 for (i = 0; i < m_events.size(); ++i) { 543 for (i = 0; i < m_events.size(); ++i) {
317 if (event.getType() == ParamEvent::SetValueCurve) { 544 if (event->getType() == ParamEvent::SetValueCurve) {
318 // If this event is a SetValueCurve, make sure it doesn't overlap any 545 // If this event is a SetValueCurve, make sure it doesn't overlap any
319 // existing event. It's ok if the SetValueCurve starts at the same time as 546 // existing event. It's ok if the SetValueCurve starts at the same time as
320 // the end of some other duration. 547 // the end of some other duration.
321 double endTime = event.time() + event.duration(); 548 double endTime = event->time() + event->duration();
322 if (m_events[i].time() > event.time() && m_events[i].time() < endTime) { 549 if (m_events[i]->time() > event->time() &&
550 m_events[i]->time() < endTime) {
323 exceptionState.throwDOMException( 551 exceptionState.throwDOMException(
324 NotSupportedError, 552 NotSupportedError,
325 eventToString(event) + " overlaps " + eventToString(m_events[i])); 553 eventToString(*event) + " overlaps " + eventToString(*m_events[i]));
326 return; 554 return;
327 } 555 }
328 } else { 556 } else {
329 // Otherwise, make sure this event doesn't overlap any existing 557 // Otherwise, make sure this event doesn't overlap any existing
330 // SetValueCurve event. 558 // SetValueCurve event.
331 if (m_events[i].getType() == ParamEvent::SetValueCurve) { 559 if (m_events[i]->getType() == ParamEvent::SetValueCurve) {
332 double endTime = m_events[i].time() + m_events[i].duration(); 560 double endTime = m_events[i]->time() + m_events[i]->duration();
333 if (event.time() >= m_events[i].time() && event.time() < endTime) { 561 if (event->time() >= m_events[i]->time() && event->time() < endTime) {
334 exceptionState.throwDOMException( 562 exceptionState.throwDOMException(
335 NotSupportedError, 563 NotSupportedError, eventToString(*event) + " overlaps " +
336 eventToString(event) + " overlaps " + eventToString(m_events[i])); 564 eventToString(*m_events[i]));
337 return; 565 return;
338 } 566 }
339 } 567 }
340 } 568 }
341 569
342 // Overwrite same event type and time. 570 // Overwrite same event type and time.
343 if (m_events[i].time() == insertTime && 571 if (m_events[i]->time() == insertTime &&
344 m_events[i].getType() == event.getType()) { 572 m_events[i]->getType() == event->getType()) {
345 m_events[i] = event; 573 m_events[i] = std::move(event);
346 return; 574 return;
347 } 575 }
348 576
349 if (m_events[i].time() > insertTime) 577 if (m_events[i]->time() > insertTime)
350 break; 578 break;
351 } 579 }
352 580
353 m_events.insert(i, event); 581 m_events.insert(i, std::move(event));
354 } 582 }
355 583
356 bool AudioParamTimeline::hasValues() const { 584 bool AudioParamTimeline::hasValues() const {
357 MutexTryLocker tryLocker(m_eventsLock); 585 MutexTryLocker tryLocker(m_eventsLock);
358 586
359 if (tryLocker.locked()) 587 if (tryLocker.locked())
360 return m_events.size(); 588 return m_events.size();
361 589
362 // Can't get the lock so that means the main thread is trying to insert an 590 // Can't get the lock so that means the main thread is trying to insert an
363 // event. Just return true then. If the main thread releases the lock before 591 // event. Just return true then. If the main thread releases the lock before
(...skipping 12 matching lines...) Expand all
376 } 604 }
377 605
378 void AudioParamTimeline::cancelScheduledValues(double startTime, 606 void AudioParamTimeline::cancelScheduledValues(double startTime,
379 ExceptionState& exceptionState) { 607 ExceptionState& exceptionState) {
380 DCHECK(isMainThread()); 608 DCHECK(isMainThread());
381 609
382 MutexLocker locker(m_eventsLock); 610 MutexLocker locker(m_eventsLock);
383 611
384 // Remove all events starting at startTime. 612 // Remove all events starting at startTime.
385 for (unsigned i = 0; i < m_events.size(); ++i) { 613 for (unsigned i = 0; i < m_events.size(); ++i) {
386 if (m_events[i].time() >= startTime) { 614 if (m_events[i]->time() >= startTime) {
387 m_events.remove(i, m_events.size() - i); 615 m_events.remove(i, m_events.size() - i);
388 break; 616 break;
389 } 617 }
390 } 618 }
391 } 619 }
392 620
621 void AudioParamTimeline::cancelValuesAndHoldAtTime(
622 double cancelTime,
623 ExceptionState& exceptionState) {
624 DCHECK(isMainThread());
625
626 if (!isNonNegativeAudioParamTime(cancelTime, exceptionState))
627 return;
628
629 MutexLocker locker(m_eventsLock);
630
631 unsigned i;
632 // Find the first event at or just past cancelTime.
633 for (i = 0; i < m_events.size(); ++i) {
634 if (m_events[i]->time() > cancelTime) {
635 break;
636 }
637 }
638
639 // The event that is being cancelled. This is the event just past
640 // cancelTime, if any.
641 unsigned cancelledEventIndex = i;
642
643 // If the event just before cancelTime is a SetTarget or SetValueCurve
644 // event, we need to handle that event specially instead of the event after.
645 if (i > 0 && ((m_events[i - 1]->getType() == ParamEvent::SetTarget) ||
646 (m_events[i - 1]->getType() == ParamEvent::SetValueCurve))) {
647 cancelledEventIndex = i - 1;
648 } else if (i >= m_events.size()) {
649 // If there were no events occurring after |cancelTime| (and the
650 // previous event is not SetTarget or SetValueCurve, we're done.
651 return;
652 }
653
654 // cancelledEvent is the event that is being cancelled.
655 ParamEvent* cancelledEvent = m_events[cancelledEventIndex].get();
656 ParamEvent::Type eventType = cancelledEvent->getType();
657
658 // New event to be inserted, if any, and a SetValueEvent if needed.
659 std::unique_ptr<ParamEvent> newEvent = nullptr;
660 std::unique_ptr<ParamEvent> newSetValueEvent = nullptr;
661
662 switch (eventType) {
663 case ParamEvent::LinearRampToValue:
664 case ParamEvent::ExponentialRampToValue: {
665 // For these events we need to remember the parameters of the event
666 // for a CancelValues event so that we can properly cancel the event
667 // and hold the value.
668 std::unique_ptr<ParamEvent> savedEvent = ParamEvent::createGeneralEvent(
669 eventType, cancelledEvent->value(), cancelledEvent->time(),
670 cancelledEvent->initialValue(), cancelledEvent->callTime(),
671 cancelledEvent->timeConstant(), cancelledEvent->duration(),
672 cancelledEvent->curve(), cancelledEvent->curvePointsPerSecond(),
673 cancelledEvent->curveEndValue(), nullptr);
674
675 newEvent = ParamEvent::createCancelValuesEvent(cancelTime,
676 std::move(savedEvent));
677 } break;
678 case ParamEvent::SetTarget: {
679 // Don't want to remove the SetTarget event, so bump the index. But
680 // we do want to insert a cancelEvent so that we stop this
681 // automation and hold the value when we get there.
682 ++cancelledEventIndex;
683
684 newEvent = ParamEvent::createCancelValuesEvent(cancelTime, nullptr);
685 } break;
686 case ParamEvent::SetValueCurve: {
687 double newDuration = cancelTime - cancelledEvent->time();
688
689 if (cancelTime > cancelledEvent->time() + cancelledEvent->duration()) {
690 // If the cancellation time is past the end of the curve,
691 // there's nothing to do except remove the following events.
692 ++cancelledEventIndex;
693 } else {
694 // Cancellation time is in the middle of the curve. Therefore,
695 // create a new SetValueCurve event with the appropriate new
696 // parameters to cancel this event properly. Since it's illegal
697 // to insert any event within a SetValueCurve event, we can
698 // compute the new end value now instead of doing when running
699 // the timeline.
700 float endValue = valueCurveAtTime(
701 cancelTime, cancelledEvent->time(), cancelledEvent->duration(),
702 cancelledEvent->curve().data(), cancelledEvent->curve().size());
703
704 // Replace the existing SetValueCurve with this new one that is
705 // identical except for the duration.
706 newEvent = ParamEvent::createGeneralEvent(
707 eventType, cancelledEvent->value(), cancelledEvent->time(),
708 cancelledEvent->initialValue(), cancelledEvent->callTime(),
709 cancelledEvent->timeConstant(), newDuration,
710 cancelledEvent->curve(), cancelledEvent->curvePointsPerSecond(),
711 endValue, nullptr);
712
713 newSetValueEvent = ParamEvent::createSetValueEvent(
714 endValue, cancelledEvent->time() + newDuration);
715 }
716 } break;
717 case ParamEvent::SetValue:
718 case ParamEvent::CancelValues:
719 // Nothing needs to be done for a SetValue or CancelValues event.
720 break;
721 case ParamEvent::LastType:
722 NOTREACHED();
723 break;
724 }
725
726 // Now remove all the following events from the timeline.
727 if (cancelledEventIndex < m_events.size())
728 m_events.remove(cancelledEventIndex, m_events.size() - cancelledEventIndex);
729
730 // Insert the new event, if any.
731 if (newEvent) {
732 insertEvent(std::move(newEvent), exceptionState);
733 if (newSetValueEvent)
734 insertEvent(std::move(newSetValueEvent), exceptionState);
735 }
736 }
737
393 float AudioParamTimeline::valueForContextTime( 738 float AudioParamTimeline::valueForContextTime(
394 AudioDestinationHandler& audioDestination, 739 AudioDestinationHandler& audioDestination,
395 float defaultValue, 740 float defaultValue,
396 bool& hasValue, 741 bool& hasValue,
397 float minValue, 742 float minValue,
398 float maxValue) { 743 float maxValue) {
399 { 744 {
400 MutexTryLocker tryLocker(m_eventsLock); 745 MutexTryLocker tryLocker(m_eventsLock);
401 if (!tryLocker.locked() || !m_events.size() || 746 if (!tryLocker.locked() || !m_events.size() ||
402 audioDestination.currentTime() < m_events[0].time()) { 747 audioDestination.currentTime() < m_events[0]->time()) {
403 hasValue = false; 748 hasValue = false;
404 return defaultValue; 749 return defaultValue;
405 } 750 }
406 } 751 }
407 752
408 // Ask for just a single value. 753 // Ask for just a single value.
409 float value; 754 float value;
410 double sampleRate = audioDestination.sampleRate(); 755 double sampleRate = audioDestination.sampleRate();
411 size_t startFrame = audioDestination.currentSampleFrame(); 756 size_t startFrame = audioDestination.currentSampleFrame();
412 // One parameter change per render quantum. 757 // One parameter change per render quantum.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 unsigned numberOfValues, 800 unsigned numberOfValues,
456 double sampleRate, 801 double sampleRate,
457 double controlRate) { 802 double controlRate) {
458 DCHECK(values); 803 DCHECK(values);
459 DCHECK_GE(numberOfValues, 1u); 804 DCHECK_GE(numberOfValues, 1u);
460 if (!values || !(numberOfValues >= 1)) 805 if (!values || !(numberOfValues >= 1))
461 return defaultValue; 806 return defaultValue;
462 807
463 // Return default value if there are no events matching the desired time 808 // Return default value if there are no events matching the desired time
464 // range. 809 // range.
465 if (!m_events.size() || (endFrame / sampleRate <= m_events[0].time())) { 810 if (!m_events.size() || (endFrame / sampleRate <= m_events[0]->time())) {
466 for (unsigned i = 0; i < numberOfValues; ++i) 811 for (unsigned i = 0; i < numberOfValues; ++i)
467 values[i] = defaultValue; 812 values[i] = defaultValue;
468 return defaultValue; 813 return defaultValue;
469 } 814 }
470 815
471 int numberOfEvents = m_events.size(); 816 int numberOfEvents = m_events.size();
472 817
473 if (numberOfEvents > 0) { 818 if (numberOfEvents > 0) {
474 bool clampedSomeEventTime = false; 819 bool clampedSomeEventTime = false;
475 double currentTime = startFrame / sampleRate; 820 double currentTime = startFrame / sampleRate;
476 821
477 // Look at all the events in the timeline and check to see if any needs 822 // Look at all the events in the timeline and check to see if any needs
478 // to clamp the start time to the current time. 823 // to clamp the start time to the current time.
479 for (int k = 0; k < numberOfEvents; ++k) { 824 for (int k = 0; k < numberOfEvents; ++k) {
480 ParamEvent& event = m_events[k]; 825 ParamEvent* event = m_events[k].get();
481 826
482 // We're examining the event for the first time and the event time is 827 // We're examining the event for the first time and the event time is
483 // in the past so clamp the event time to the current time (start of 828 // in the past so clamp the event time to the current time (start of
484 // the rendering quantum). 829 // the rendering quantum).
485 if (event.needsTimeClampCheck()) { 830 if (event->needsTimeClampCheck()) {
486 if (event.time() < currentTime) { 831 if (event->time() < currentTime) {
487 event.setTime(currentTime); 832 event->setTime(currentTime);
488 clampedSomeEventTime = true; 833 clampedSomeEventTime = true;
489 } 834 }
490 835
491 // In all cases, we can clear the flag because the event is either 836 // In all cases, we can clear the flag because the event is either
492 // in the future, or we've already checked it (just now). 837 // in the future, or we've already checked it (just now).
493 event.clearTimeClampCheck(); 838 event->clearTimeClampCheck();
494 } 839 }
495 } 840 }
496 841
497 if (clampedSomeEventTime) { 842 if (clampedSomeEventTime) {
498 // If we clamped some event time to current time, we need to 843 // If we clamped some event time to current time, we need to
499 // sort the event list in time order again, but it must be 844 // sort the event list in time order again, but it must be
500 // stable! 845 // stable!
501 std::stable_sort(m_events.begin(), m_events.end(), 846 std::stable_sort(m_events.begin(), m_events.end(),
502 ParamEvent::eventPreceeds); 847 ParamEvent::eventPreceeds);
503 } 848 }
504 849
505 // Optimize the case where the last event is in the past. 850 // Optimize the case where the last event is in the past.
506 ParamEvent& lastEvent = m_events[m_events.size() - 1]; 851 ParamEvent* lastEvent = m_events[m_events.size() - 1].get();
507 ParamEvent::Type lastEventType = lastEvent.getType(); 852 ParamEvent::Type lastEventType = lastEvent->getType();
508 double lastEventTime = lastEvent.time(); 853 double lastEventTime = lastEvent->time();
509 854
510 // If the last event is in the past and the event has ended, then we can 855 // If the last event is in the past and the event has ended, then we can
511 // just propagate the same value. Except for SetTarget which lasts 856 // just propagate the same value. Except for SetTarget which lasts
512 // "forever". SetValueCurve also has an explicit SetValue at the end of 857 // "forever". SetValueCurve also has an explicit SetValue at the end of
513 // the curve, so we don't need to worry that SetValueCurve time is a 858 // the curve, so we don't need to worry that SetValueCurve time is a
514 // start time, not an end time. 859 // start time, not an end time.
515 if (lastEventTime < currentTime && lastEventType != ParamEvent::SetTarget) { 860 if (lastEventTime < currentTime && lastEventType != ParamEvent::SetTarget) {
516 // The event has finished, so just copy the default value out. 861 // The event has finished, so just copy the default value out.
517 // Since all events are now also in the past, we can just remove all 862 // Since all events are now also in the past, we can just remove all
518 // timeline events too because |defaultValue| has the expected 863 // timeline events too because |defaultValue| has the expected
519 // value. 864 // value.
520 for (unsigned i = 0; i < numberOfValues; ++i) 865 for (unsigned i = 0; i < numberOfValues; ++i)
521 values[i] = defaultValue; 866 values[i] = defaultValue;
522 m_smoothedValue = defaultValue; 867 m_smoothedValue = defaultValue;
523 m_events.clear(); 868 m_events.clear();
524 return defaultValue; 869 return defaultValue;
525 } 870 }
526 } 871 }
527 872
528 // Maintain a running time (frame) and index for writing the values buffer. 873 // Maintain a running time (frame) and index for writing the values buffer.
529 size_t currentFrame = startFrame; 874 size_t currentFrame = startFrame;
530 unsigned writeIndex = 0; 875 unsigned writeIndex = 0;
531 876
532 // If first event is after startFrame then fill initial part of values buffer 877 // If first event is after startFrame then fill initial part of values buffer
533 // with defaultValue until we reach the first event time. 878 // with defaultValue until we reach the first event time.
534 double firstEventTime = m_events[0].time(); 879 double firstEventTime = m_events[0]->time();
535 if (firstEventTime > startFrame / sampleRate) { 880 if (firstEventTime > startFrame / sampleRate) {
536 // |fillToFrame| is an exclusive upper bound, so use ceil() to compute the 881 // |fillToFrame| is an exclusive upper bound, so use ceil() to compute the
537 // bound from the firstEventTime. 882 // bound from the firstEventTime.
538 size_t fillToFrame = endFrame; 883 size_t fillToFrame = endFrame;
539 double firstEventFrame = ceil(firstEventTime * sampleRate); 884 double firstEventFrame = ceil(firstEventTime * sampleRate);
540 if (endFrame > firstEventFrame) 885 if (endFrame > firstEventFrame)
541 fillToFrame = static_cast<size_t>(firstEventFrame); 886 fillToFrame = static_cast<size_t>(firstEventFrame);
542 DCHECK_GE(fillToFrame, startFrame); 887 DCHECK_GE(fillToFrame, startFrame);
543 888
544 fillToFrame -= startFrame; 889 fillToFrame -= startFrame;
545 fillToFrame = std::min(fillToFrame, static_cast<size_t>(numberOfValues)); 890 fillToFrame = std::min(fillToFrame, static_cast<size_t>(numberOfValues));
546 for (; writeIndex < fillToFrame; ++writeIndex) 891 for (; writeIndex < fillToFrame; ++writeIndex)
547 values[writeIndex] = defaultValue; 892 values[writeIndex] = defaultValue;
548 893
549 currentFrame += fillToFrame; 894 currentFrame += fillToFrame;
550 } 895 }
551 896
552 float value = defaultValue; 897 float value = defaultValue;
553 898
554 // Go through each event and render the value buffer where the times overlap, 899 // Go through each event and render the value buffer where the times overlap,
555 // stopping when we've rendered all the requested values. 900 // stopping when we've rendered all the requested values.
556 int lastSkippedEventIndex = 0; 901 int lastSkippedEventIndex = 0;
557 for (int i = 0; i < numberOfEvents && writeIndex < numberOfValues; ++i) { 902 for (int i = 0; i < numberOfEvents && writeIndex < numberOfValues; ++i) {
558 ParamEvent& event = m_events[i]; 903 ParamEvent* event = m_events[i].get();
559 ParamEvent* nextEvent = i < numberOfEvents - 1 ? &(m_events[i + 1]) : 0; 904 ParamEvent* nextEvent = i < numberOfEvents - 1 ? m_events[i + 1].get() : 0;
560 905
561 // Wait until we get a more recent event. 906 // Wait until we get a more recent event.
562 // 907 //
563 // WARNING: due to round-off it might happen that nextEvent->time() is 908 // WARNING: due to round-off it might happen that nextEvent->time() is
564 // just larger than currentFrame/sampleRate. This means that we will end 909 // just larger than currentFrame/sampleRate. This means that we will end
565 // up running the |event| again. The code below had better be prepared 910 // up running the |event| again. The code below had better be prepared
566 // for this case! What should happen is the fillToFrame should be 0 so 911 // for this case! What should happen is the fillToFrame should be 0 so
567 // that while the event is actually run again, nothing actually gets 912 // that while the event is actually run again, nothing actually gets
568 // computed, and we move on to the next event. 913 // computed, and we move on to the next event.
569 // 914 //
570 // An example of this case is setValueCurveAtTime. The time at which 915 // An example of this case is setValueCurveAtTime. The time at which
571 // setValueCurveAtTime ends (and the setValueAtTime begins) might be 916 // setValueCurveAtTime ends (and the setValueAtTime begins) might be
572 // just past currentTime/sampleRate. Then setValueCurveAtTime will be 917 // just past currentTime/sampleRate. Then setValueCurveAtTime will be
573 // processed again before advancing to setValueAtTime. The number of 918 // processed again before advancing to setValueAtTime. The number of
574 // frames to be processed should be zero in this case. 919 // frames to be processed should be zero in this case.
575 if (nextEvent && nextEvent->time() < currentFrame / sampleRate) { 920 if (nextEvent && nextEvent->time() < currentFrame / sampleRate) {
576 // But if the current event is a SetValue event and the event time is 921 // But if the current event is a SetValue event and the event time is
577 // between currentFrame - 1 and curentFrame (in time). we don't want to 922 // between currentFrame - 1 and curentFrame (in time). we don't want to
578 // skip it. If we do skip it, the SetValue event is completely skipped 923 // skip it. If we do skip it, the SetValue event is completely skipped
579 // and not applied, which is wrong. Other events don't have this problem. 924 // and not applied, which is wrong. Other events don't have this problem.
580 // (Because currentFrame is unsigned, we do the time check in this funny, 925 // (Because currentFrame is unsigned, we do the time check in this funny,
581 // but equivalent way.) 926 // but equivalent way.)
582 double eventFrame = event.time() * sampleRate; 927 double eventFrame = event->time() * sampleRate;
583 928
584 // Condition is currentFrame - 1 < eventFrame <= currentFrame, but 929 // Condition is currentFrame - 1 < eventFrame <= currentFrame, but
585 // currentFrame is unsigned and could be 0, so use 930 // currentFrame is unsigned and could be 0, so use
586 // currentFrame < eventFrame + 1 instead. 931 // currentFrame < eventFrame + 1 instead.
587 if (!((event.getType() == ParamEvent::SetValue && 932 if (!((event->getType() == ParamEvent::SetValue &&
588 (eventFrame <= currentFrame) && 933 (eventFrame <= currentFrame) &&
589 (currentFrame < eventFrame + 1)))) { 934 (currentFrame < eventFrame + 1)))) {
590 // This is not the special SetValue event case, and nextEvent is 935 // This is not the special SetValue event case, and nextEvent is
591 // in the past. We can skip processing of this event since it's 936 // in the past. We can skip processing of this event since it's
592 // in past. We keep track of this event in lastSkippedEventIndex 937 // in past. We keep track of this event in lastSkippedEventIndex
593 // to note what events we've skipped. 938 // to note what events we've skipped.
594 lastSkippedEventIndex = i; 939 lastSkippedEventIndex = i;
595 continue; 940 continue;
596 } 941 }
597 } 942 }
598 943
599 // If there's no next event, set nextEventType to LastType to indicate that. 944 // If there's no next event, set nextEventType to LastType to indicate that.
600 ParamEvent::Type nextEventType = 945 ParamEvent::Type nextEventType =
601 nextEvent ? static_cast<ParamEvent::Type>(nextEvent->getType()) 946 nextEvent ? static_cast<ParamEvent::Type>(nextEvent->getType())
602 : ParamEvent::LastType; 947 : ParamEvent::LastType;
603 948
604 // If the current event is SetTarget and the next event is a 949 // If the current event is SetTarget and the next event is a
605 // LinearRampToValue or ExponentialRampToValue, special handling is needed. 950 // LinearRampToValue or ExponentialRampToValue, special handling is needed.
606 // In this case, the linear and exponential ramp should start at wherever 951 // In this case, the linear and exponential ramp should start at wherever
607 // the SetTarget processing has reached. 952 // the SetTarget processing has reached.
608 if (event.getType() == ParamEvent::SetTarget && 953 if (event->getType() == ParamEvent::SetTarget &&
609 (nextEventType == ParamEvent::LinearRampToValue || 954 (nextEventType == ParamEvent::LinearRampToValue ||
610 nextEventType == ParamEvent::ExponentialRampToValue)) { 955 nextEventType == ParamEvent::ExponentialRampToValue)) {
611 // Replace the SetTarget with a SetValue to set the starting time and 956 // Replace the SetTarget with a SetValue to set the starting time and
612 // value for the ramp using the current frame. We need to update |value| 957 // value for the ramp using the current frame. We need to update |value|
613 // appropriately depending on whether the ramp has started or not. 958 // appropriately depending on whether the ramp has started or not.
614 // 959 //
615 // If SetTarget starts somewhere between currentFrame - 1 and 960 // If SetTarget starts somewhere between currentFrame - 1 and
616 // currentFrame, we directly compute the value it would have at 961 // currentFrame, we directly compute the value it would have at
617 // currentFrame. If not, we update the value from the value from 962 // currentFrame. If not, we update the value from the value from
618 // currentFrame - 1. 963 // currentFrame - 1.
619 // 964 //
620 // Can't use the condition currentFrame - 1 <= t0 * sampleRate <= 965 // Can't use the condition currentFrame - 1 <= t0 * sampleRate <=
621 // currentFrame because currentFrame is unsigned and could be 0. Instead, 966 // currentFrame because currentFrame is unsigned and could be 0. Instead,
622 // compute the condition this way, 967 // compute the condition this way,
623 // where f = currentFrame and Fs = sampleRate: 968 // where f = currentFrame and Fs = sampleRate:
624 // 969 //
625 // f - 1 <= t0 * Fs <= f 970 // f - 1 <= t0 * Fs <= f
626 // 2 * f - 2 <= 2 * Fs * t0 <= 2 * f 971 // 2 * f - 2 <= 2 * Fs * t0 <= 2 * f
627 // -2 <= 2 * Fs * t0 - 2 * f <= 0 972 // -2 <= 2 * Fs * t0 - 2 * f <= 0
628 // -1 <= 2 * Fs * t0 - 2 * f + 1 <= 1 973 // -1 <= 2 * Fs * t0 - 2 * f + 1 <= 1
629 // abs(2 * Fs * t0 - 2 * f + 1) <= 1 974 // abs(2 * Fs * t0 - 2 * f + 1) <= 1
630 if (fabs(2 * sampleRate * event.time() - 2 * currentFrame + 1) <= 1) { 975 if (fabs(2 * sampleRate * event->time() - 2 * currentFrame + 1) <= 1) {
631 // SetTarget is starting somewhere between currentFrame - 1 and 976 // SetTarget is starting somewhere between currentFrame - 1 and
632 // currentFrame. Compute the value the SetTarget would have at the 977 // currentFrame. Compute the value the SetTarget would have at the
633 // currentFrame. 978 // currentFrame.
634 value = event.value() + 979 value = event->value() +
635 (value - event.value()) * 980 (value - event->value()) *
636 exp(-(currentFrame / sampleRate - event.time()) / 981 exp(-(currentFrame / sampleRate - event->time()) /
637 event.timeConstant()); 982 event->timeConstant());
638 } else { 983 } else {
639 // SetTarget has already started. Update |value| one frame because it's 984 // SetTarget has already started. Update |value| one frame because it's
640 // the value from the previous frame. 985 // the value from the previous frame.
641 float discreteTimeConstant = static_cast<float>( 986 float discreteTimeConstant = static_cast<float>(
642 AudioUtilities::discreteTimeConstantForSampleRate( 987 AudioUtilities::discreteTimeConstantForSampleRate(
643 event.timeConstant(), controlRate)); 988 event->timeConstant(), controlRate));
644 value += (event.value() - value) * discreteTimeConstant; 989 value += (event->value() - value) * discreteTimeConstant;
645 } 990 }
646 991
647 // Insert a SetValueEvent to mark the starting value and time. 992 // Insert a SetValueEvent to mark the starting value and time.
648 // Clear the clamp check because this doesn't need it. 993 // Clear the clamp check because this doesn't need it.
649 m_events[i] = 994 m_events[i] =
650 ParamEvent::createSetValueEvent(value, currentFrame / sampleRate); 995 ParamEvent::createSetValueEvent(value, currentFrame / sampleRate);
651 m_events[i].clearTimeClampCheck(); 996 m_events[i]->clearTimeClampCheck();
997
998 // Update our pointer to the current event because we just changed it.
999 event = m_events[i].get();
652 } 1000 }
653 1001
654 float value1 = event.value(); 1002 float value1 = event->value();
655 double time1 = event.time(); 1003 double time1 = event->time();
656 1004
657 float value2 = nextEvent ? nextEvent->value() : value1; 1005 float value2 = nextEvent ? nextEvent->value() : value1;
658 double time2 = nextEvent ? nextEvent->time() : endFrame / sampleRate + 1; 1006 double time2 = nextEvent ? nextEvent->time() : endFrame / sampleRate + 1;
659 1007
1008 // Check to see if an event was cancelled.
1009 if (nextEventType == ParamEvent::CancelValues) {
1010 switch (event->getType()) {
1011 case ParamEvent::LinearRampToValue:
1012 case ParamEvent::ExponentialRampToValue:
1013 case ParamEvent::SetValue: {
1014 // These three events potentially establish a starting value for
1015 // the following event, so we need to examine the cancelled
1016 // event to see what to do.
1017 const ParamEvent* savedEvent = nextEvent->savedEvent();
1018
1019 // Update the end time and type to pretend that we're running
1020 // this saved event type.
1021 time2 = nextEvent->time();
1022 nextEventType = savedEvent->getType();
1023
1024 if (nextEvent->hasDefaultCancelledValue()) {
1025 // We've already established a value for the cancelled
1026 // event, so just return it.
1027 value2 = nextEvent->value();
1028 } else {
1029 // If the next event would have been a LinearRamp or
1030 // ExponentialRamp, we need to compute a new end value for
1031 // the event so that the curve works continues as if it were
1032 // not cancelled.
1033 switch (savedEvent->getType()) {
1034 case ParamEvent::LinearRampToValue:
1035 value2 =
1036 linearRampAtTime(nextEvent->time(), value1, time1,
1037 savedEvent->value(), savedEvent->time());
1038 break;
1039 case ParamEvent::ExponentialRampToValue:
1040 value2 = exponentialRampAtTime(nextEvent->time(), value1, time1,
1041 savedEvent->value(),
1042 savedEvent->time());
1043 break;
1044 case ParamEvent::SetValueCurve:
1045 case ParamEvent::SetValue:
1046 case ParamEvent::SetTarget:
1047 case ParamEvent::CancelValues:
1048 // These cannot be possible types for the saved event
1049 // because they can't be created.
1050 // createCancelValuesEvent doesn't allow them (SetValue,
1051 // SetTarget, CancelValues) or cancelScheduledValues()
1052 // doesn't create such an event (SetValueCurve).
1053 NOTREACHED();
1054 break;
1055 case ParamEvent::LastType:
1056 // Illegal event type.
1057 NOTREACHED();
1058 break;
1059 }
1060
1061 // Cache the new value so we don't keep computing it over and over.
1062 nextEvent->setCancelledValue(value2);
1063 }
1064 } break;
1065 case ParamEvent::SetValueCurve:
1066 // Everything needed for this was handled when cancelling was
1067 // done.
1068 break;
1069 case ParamEvent::SetTarget:
1070 case ParamEvent::CancelValues:
1071 // Nothing special needs to be done for SetTarget or
1072 // CancelValues followed by CancelValues.
1073 break;
1074 case ParamEvent::LastType:
1075 NOTREACHED();
1076 break;
1077 }
1078 }
1079
660 DCHECK_GE(time2, time1); 1080 DCHECK_GE(time2, time1);
661 double deltaTime = time2 - time1; 1081 double deltaTime = time2 - time1;
662 float k = deltaTime > 0 ? 1 / deltaTime : 0; 1082 float k = deltaTime > 0 ? 1 / deltaTime : 0;
663 1083
664 // |fillToEndFrame| is the exclusive upper bound of the last frame to be 1084 // |fillToEndFrame| is the exclusive upper bound of the last frame to be
665 // computed for this event. It's either the last desired frame (|endFrame|) 1085 // computed for this event. It's either the last desired frame (|endFrame|)
666 // or derived from the end time of the next event (time2). We compute 1086 // or derived from the end time of the next event (time2). We compute
667 // ceil(time2*sampleRate) because fillToEndFrame is the exclusive upper 1087 // ceil(time2*sampleRate) because fillToEndFrame is the exclusive upper
668 // bound. Consider the case where |startFrame| = 128 and time2 = 128.1 1088 // bound. Consider the case where |startFrame| = 128 and time2 = 128.1
669 // (assuming sampleRate = 1). Since time2 is greater than 128, we want to 1089 // (assuming sampleRate = 1). Since time2 is greater than 128, we want to
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
781 if (writeIndex >= 1) 1201 if (writeIndex >= 1)
782 value /= multiplier; 1202 value /= multiplier;
783 1203
784 // Due to roundoff it's possible that value exceeds value2. Clip value 1204 // Due to roundoff it's possible that value exceeds value2. Clip value
785 // to value2 if we are within 1/2 frame of time2. 1205 // to value2 if we are within 1/2 frame of time2.
786 if (currentFrame > time2 * sampleRate - 0.5) 1206 if (currentFrame > time2 * sampleRate - 0.5)
787 value = value2; 1207 value = value2;
788 } 1208 }
789 } else { 1209 } else {
790 // Handle event types not requiring looking ahead to the next event. 1210 // Handle event types not requiring looking ahead to the next event.
791 switch (event.getType()) { 1211 switch (event->getType()) {
792 case ParamEvent::SetValue: 1212 case ParamEvent::SetValue:
793 case ParamEvent::LinearRampToValue: { 1213 case ParamEvent::LinearRampToValue: {
794 currentFrame = fillToEndFrame; 1214 currentFrame = fillToEndFrame;
795 1215
796 // Simply stay at a constant value. 1216 // Simply stay at a constant value.
797 value = event.value(); 1217 value = event->value();
798 1218
799 for (; writeIndex < fillToFrame; ++writeIndex) 1219 for (; writeIndex < fillToFrame; ++writeIndex)
800 values[writeIndex] = value; 1220 values[writeIndex] = value;
801 1221
802 break; 1222 break;
803 } 1223 }
804 1224
1225 case ParamEvent::CancelValues: {
1226 // If the previous event was a SetTarget or ExponentialRamp
1227 // event, the current value is one sample behind. Update
1228 // the sample value by one sample, but only at the start of
1229 // this CancelValues event.
1230 if (event->hasDefaultCancelledValue()) {
1231 value = event->value();
1232 } else {
1233 double cancelFrame = time1 * sampleRate;
1234 if (i >= 1 && cancelFrame <= currentFrame &&
1235 currentFrame < cancelFrame + 1) {
1236 ParamEvent::Type lastEventType = m_events[i - 1]->getType();
1237 if (lastEventType == ParamEvent::SetTarget) {
1238 float target = m_events[i - 1]->value();
1239 float timeConstant = m_events[i - 1]->timeConstant();
1240 float discreteTimeConstant = static_cast<float>(
1241 AudioUtilities::discreteTimeConstantForSampleRate(
1242 timeConstant, controlRate));
1243 value += (target - value) * discreteTimeConstant;
1244 }
1245 }
1246 }
1247
1248 // Simply stay at the current value.
1249 for (; writeIndex < fillToFrame; ++writeIndex)
1250 values[writeIndex] = value;
1251
1252 currentFrame = fillToEndFrame;
1253 break;
1254 }
1255
805 case ParamEvent::ExponentialRampToValue: { 1256 case ParamEvent::ExponentialRampToValue: {
806 currentFrame = fillToEndFrame; 1257 currentFrame = fillToEndFrame;
807 1258
808 // If we're here, we've reached the end of the ramp. If we can 1259 // If we're here, we've reached the end of the ramp. If we can
809 // (because the start and end values have the same sign, and neither 1260 // (because the start and end values have the same sign, and neither
810 // is 0), use the actual end value. If not, we have to propagate 1261 // is 0), use the actual end value. If not, we have to propagate
811 // whatever we have. 1262 // whatever we have.
812 if (i >= 1 && ((m_events[i - 1].value() * event.value()) > 0)) 1263 if (i >= 1 && ((m_events[i - 1]->value() * event->value()) > 0))
813 value = event.value(); 1264 value = event->value();
814 1265
815 // Simply stay at a constant value from the last time. We don't want 1266 // Simply stay at a constant value from the last time. We don't want
816 // to use the value of the event in case value1 * value2 < 0. In this 1267 // to use the value of the event in case value1 * value2 < 0. In this
817 // case we should propagate the previous value, which is in |value|. 1268 // case we should propagate the previous value, which is in |value|.
818 for (; writeIndex < fillToFrame; ++writeIndex) 1269 for (; writeIndex < fillToFrame; ++writeIndex)
819 values[writeIndex] = value; 1270 values[writeIndex] = value;
820 1271
821 break; 1272 break;
822 } 1273 }
823 1274
824 case ParamEvent::SetTarget: { 1275 case ParamEvent::SetTarget: {
825 // Exponential approach to target value with given time constant. 1276 // Exponential approach to target value with given time constant.
826 // 1277 //
827 // v(t) = v2 + (v1 - v2)*exp(-(t-t1/tau)) 1278 // v(t) = v2 + (v1 - v2)*exp(-(t-t1/tau))
828 // 1279 //
829 1280
830 float target = event.value(); 1281 float target = event->value();
831 float timeConstant = event.timeConstant(); 1282 float timeConstant = event->timeConstant();
832 float discreteTimeConstant = static_cast<float>( 1283 float discreteTimeConstant = static_cast<float>(
833 AudioUtilities::discreteTimeConstantForSampleRate(timeConstant, 1284 AudioUtilities::discreteTimeConstantForSampleRate(timeConstant,
834 controlRate)); 1285 controlRate));
835 1286
836 // Set the starting value correctly. This is only needed when the 1287 // Set the starting value correctly. This is only needed when the
837 // current time is "equal" to the start time of this event. This is 1288 // current time is "equal" to the start time of this event. This is
838 // to get the sampling correct if the start time of this automation 1289 // to get the sampling correct if the start time of this automation
839 // isn't on a frame boundary. Otherwise, we can just continue from 1290 // isn't on a frame boundary. Otherwise, we can just continue from
840 // where we left off from the previous rendering quantum. 1291 // where we left off from the previous rendering quantum.
841 { 1292 {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
910 // The previous loops may have updated |value| one extra time. 1361 // The previous loops may have updated |value| one extra time.
911 // Reset it to the last computed value. 1362 // Reset it to the last computed value.
912 if (writeIndex >= 1) 1363 if (writeIndex >= 1)
913 value = values[writeIndex - 1]; 1364 value = values[writeIndex - 1];
914 currentFrame = fillToEndFrame; 1365 currentFrame = fillToEndFrame;
915 } 1366 }
916 break; 1367 break;
917 } 1368 }
918 1369
919 case ParamEvent::SetValueCurve: { 1370 case ParamEvent::SetValueCurve: {
920 Vector<float> curve = event.curve(); 1371 Vector<float> curve = event->curve();
921 float* curveData = curve.data(); 1372 float* curveData = curve.data();
922 unsigned numberOfCurvePoints = curve.size(); 1373 unsigned numberOfCurvePoints = curve.size();
923 1374
1375 float curveEndValue = event->curveEndValue();
1376
924 // Curve events have duration, so don't just use next event time. 1377 // Curve events have duration, so don't just use next event time.
925 double duration = event.duration(); 1378 double duration = event->duration();
926 // How much to step the curve index for each frame. This is basically 1379 // How much to step the curve index for each frame. This is basically
927 // the term (N - 1)/Td in the specification. 1380 // the term (N - 1)/Td in the specification.
928 double curvePointsPerFrame = 1381 double curvePointsPerFrame =
929 (numberOfCurvePoints - 1) / duration / sampleRate; 1382 event->curvePointsPerSecond() / sampleRate;
930 1383
931 if (!numberOfCurvePoints || duration <= 0 || sampleRate <= 0) { 1384 if (!numberOfCurvePoints || duration <= 0 || sampleRate <= 0) {
932 // Error condition - simply propagate previous value. 1385 // Error condition - simply propagate previous value.
933 currentFrame = fillToEndFrame; 1386 currentFrame = fillToEndFrame;
934 for (; writeIndex < fillToFrame; ++writeIndex) 1387 for (; writeIndex < fillToFrame; ++writeIndex)
935 values[writeIndex] = value; 1388 values[writeIndex] = value;
936 break; 1389 break;
937 } 1390 }
938 1391
939 // Save old values and recalculate information based on the curve's 1392 // Save old values and recalculate information based on the curve's
(...skipping 29 matching lines...) Expand all
969 double curveVirtualIndex = 0; 1422 double curveVirtualIndex = 0;
970 if (time1 < currentFrame / sampleRate) { 1423 if (time1 < currentFrame / sampleRate) {
971 // Index somewhere in the middle of the curve data. 1424 // Index somewhere in the middle of the curve data.
972 // Don't use timeToSampleFrame() since we want the exact 1425 // Don't use timeToSampleFrame() since we want the exact
973 // floating-point frame. 1426 // floating-point frame.
974 double frameOffset = currentFrame - time1 * sampleRate; 1427 double frameOffset = currentFrame - time1 * sampleRate;
975 curveVirtualIndex = curvePointsPerFrame * frameOffset; 1428 curveVirtualIndex = curvePointsPerFrame * frameOffset;
976 } 1429 }
977 1430
978 // Set the default value in case fillToFrame is 0. 1431 // Set the default value in case fillToFrame is 0.
979 value = curveData[numberOfCurvePoints - 1]; 1432 value = curveEndValue;
980 1433
981 // Render the stretched curve data using linear interpolation. 1434 // Render the stretched curve data using linear interpolation.
982 // Oversampled curve data can be provided if sharp discontinuities are 1435 // Oversampled curve data can be provided if sharp discontinuities are
983 // desired. 1436 // desired.
984 unsigned k = 0; 1437 unsigned k = 0;
985 #if CPU(X86) || CPU(X86_64) 1438 #if CPU(X86) || CPU(X86_64)
986 if (fillToFrame > writeIndex) { 1439 if (fillToFrame > writeIndex) {
987 const __m128 vCurveVirtualIndex = _mm_set_ps1(curveVirtualIndex); 1440 const __m128 vCurveVirtualIndex = _mm_set_ps1(curveVirtualIndex);
988 const __m128 vCurvePointsPerFrame = 1441 const __m128 vCurvePointsPerFrame =
989 _mm_set_ps1(curvePointsPerFrame); 1442 _mm_set_ps1(curvePointsPerFrame);
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1072 float c1 = curveData[curveIndex1]; 1525 float c1 = curveData[curveIndex1];
1073 double delta = std::min(currentVirtualIndex - curveIndex0, 1.0); 1526 double delta = std::min(currentVirtualIndex - curveIndex0, 1.0);
1074 1527
1075 value = c0 + (c1 - c0) * delta; 1528 value = c0 + (c1 - c0) * delta;
1076 1529
1077 values[writeIndex] = value; 1530 values[writeIndex] = value;
1078 } 1531 }
1079 1532
1080 // If there's any time left after the duration of this event and the 1533 // If there's any time left after the duration of this event and the
1081 // start of the next, then just propagate the last value of the 1534 // start of the next, then just propagate the last value of the
1082 // curveData. 1535 // curveData. Don't modify |value| unless there is time left.
1083 if (writeIndex < nextEventFillToFrame) 1536 if (writeIndex < nextEventFillToFrame) {
1084 value = curveData[numberOfCurvePoints - 1]; 1537 value = curveEndValue;
1085 for (; writeIndex < nextEventFillToFrame; ++writeIndex) 1538 for (; writeIndex < nextEventFillToFrame; ++writeIndex)
1086 values[writeIndex] = value; 1539 values[writeIndex] = value;
1540 }
1087 1541
1088 // Re-adjust current time 1542 // Re-adjust current time
1089 currentFrame += nextEventFillToFrame; 1543 currentFrame += nextEventFillToFrame;
1090 1544
1091 break; 1545 break;
1092 } 1546 }
1093 case ParamEvent::LastType: 1547 case ParamEvent::LastType:
1094 ASSERT_NOT_REACHED(); 1548 ASSERT_NOT_REACHED();
1095 break; 1549 break;
1096 } 1550 }
(...skipping 11 matching lines...) Expand all
1108 // propagate the last value to the end of the values buffer. 1562 // propagate the last value to the end of the values buffer.
1109 for (; writeIndex < numberOfValues; ++writeIndex) 1563 for (; writeIndex < numberOfValues; ++writeIndex)
1110 values[writeIndex] = value; 1564 values[writeIndex] = value;
1111 1565
1112 // This value is used to set the .value attribute of the AudioParam. it 1566 // This value is used to set the .value attribute of the AudioParam. it
1113 // should be the last computed value. 1567 // should be the last computed value.
1114 return values[numberOfValues - 1]; 1568 return values[numberOfValues - 1];
1115 } 1569 }
1116 1570
1117 } // namespace blink 1571 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/modules/webaudio/AudioParamTimeline.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698