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

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: Address review comments Created 4 years 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
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 }
hongchan 2016/12/22 18:41:36 What happens if |savedEvent| is not valid after th
Raymond Toy 2016/12/22 19:06:23 savedEvent is sometimes nullptr depending on the t
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(getType() == ParamEvent::CancelValues);
hongchan 2016/12/22 18:41:36 DCHECK_EQ() might be better.
Raymond Toy 2016/12/22 19:21:34 Done.
254 return m_savedEvent.get();
255 }
256
257 bool AudioParamTimeline::ParamEvent::hasDefaultCancelledValue() const {
258 DCHECK(getType() == ParamEvent::CancelValues);
hongchan 2016/12/22 18:41:36 ditto.
Raymond Toy 2016/12/22 19:21:34 Done.
259 return m_hasDefaultCancelledValue;
260 }
261
262 void AudioParamTimeline::ParamEvent::setCancelledValue(float value) {
263 DCHECK(getType() == ParamEvent::CancelValues);
hongchan 2016/12/22 18:41:36 ditto.
Raymond Toy 2016/12/22 19:21:34 Done.
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
hongchan 2016/12/22 18:41:36 nit: an empty line.
Raymond Toy 2016/12/22 19:21:34 Done.
701 float endValue = valueCurveAtTime(
702 cancelTime, cancelledEvent->time(), cancelledEvent->duration(),
703 cancelledEvent->curve().data(), cancelledEvent->curve().size());
704
705 // Replace the existing SetValueCurve with this new one that is
706 // identical except for the duration.
707 newEvent = ParamEvent::createGeneralEvent(
708 eventType, cancelledEvent->value(), cancelledEvent->time(),
709 cancelledEvent->initialValue(), cancelledEvent->callTime(),
710 cancelledEvent->timeConstant(), newDuration,
711 cancelledEvent->curve(), cancelledEvent->curvePointsPerSecond(),
712 endValue, nullptr);
713
714 newSetValueEvent = ParamEvent::createSetValueEvent(
715 endValue, cancelledEvent->time() + newDuration);
716 }
717 } break;
718 case ParamEvent::SetValue:
719 case ParamEvent::CancelValues:
720 // Nothing needs to be done for a SetValue or CancelValues event.
721 break;
722 case ParamEvent::LastType:
723 NOTREACHED();
724 break;
725 }
726
727 // Now remove all the following events from the timeline.
728 if (cancelledEventIndex < m_events.size())
729 m_events.remove(cancelledEventIndex, m_events.size() - cancelledEventIndex);
730
731 // Insert the new event, if any.
732 if (newEvent) {
733 insertEvent(std::move(newEvent), exceptionState);
734 if (newSetValueEvent)
735 insertEvent(std::move(newSetValueEvent), exceptionState);
736 }
737 }
738
393 float AudioParamTimeline::valueForContextTime( 739 float AudioParamTimeline::valueForContextTime(
394 AudioDestinationHandler& audioDestination, 740 AudioDestinationHandler& audioDestination,
395 float defaultValue, 741 float defaultValue,
396 bool& hasValue, 742 bool& hasValue,
397 float minValue, 743 float minValue,
398 float maxValue) { 744 float maxValue) {
399 { 745 {
400 MutexTryLocker tryLocker(m_eventsLock); 746 MutexTryLocker tryLocker(m_eventsLock);
401 if (!tryLocker.locked() || !m_events.size() || 747 if (!tryLocker.locked() || !m_events.size() ||
402 audioDestination.currentTime() < m_events[0].time()) { 748 audioDestination.currentTime() < m_events[0]->time()) {
403 hasValue = false; 749 hasValue = false;
404 return defaultValue; 750 return defaultValue;
405 } 751 }
406 } 752 }
407 753
408 // Ask for just a single value. 754 // Ask for just a single value.
409 float value; 755 float value;
410 double sampleRate = audioDestination.sampleRate(); 756 double sampleRate = audioDestination.sampleRate();
411 size_t startFrame = audioDestination.currentSampleFrame(); 757 size_t startFrame = audioDestination.currentSampleFrame();
412 // One parameter change per render quantum. 758 // One parameter change per render quantum.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 unsigned numberOfValues, 801 unsigned numberOfValues,
456 double sampleRate, 802 double sampleRate,
457 double controlRate) { 803 double controlRate) {
458 DCHECK(values); 804 DCHECK(values);
459 DCHECK_GE(numberOfValues, 1u); 805 DCHECK_GE(numberOfValues, 1u);
460 if (!values || !(numberOfValues >= 1)) 806 if (!values || !(numberOfValues >= 1))
461 return defaultValue; 807 return defaultValue;
462 808
463 // Return default value if there are no events matching the desired time 809 // Return default value if there are no events matching the desired time
464 // range. 810 // range.
465 if (!m_events.size() || (endFrame / sampleRate <= m_events[0].time())) { 811 if (!m_events.size() || (endFrame / sampleRate <= m_events[0]->time())) {
466 for (unsigned i = 0; i < numberOfValues; ++i) 812 for (unsigned i = 0; i < numberOfValues; ++i)
467 values[i] = defaultValue; 813 values[i] = defaultValue;
468 return defaultValue; 814 return defaultValue;
469 } 815 }
470 816
471 int numberOfEvents = m_events.size(); 817 int numberOfEvents = m_events.size();
472 818
473 if (numberOfEvents > 0) { 819 if (numberOfEvents > 0) {
474 double currentTime = startFrame / sampleRate; 820 double currentTime = startFrame / sampleRate;
475 821
476 // 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
477 // to clamp the start time to the current time. 823 // to clamp the start time to the current time.
478 for (int k = 0; k < numberOfEvents; ++k) { 824 for (int k = 0; k < numberOfEvents; ++k) {
479 ParamEvent& event = m_events[k]; 825 ParamEvent* event = m_events[k].get();
480 826
481 // 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
482 // 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
483 // the rendering quantum). 829 // the rendering quantum).
484 if (event.needsTimeClampCheck()) { 830 if (event->needsTimeClampCheck()) {
485 if (event.time() < currentTime) 831 if (event->time() < currentTime)
486 event.setTime(currentTime); 832 event->setTime(currentTime);
487 833
488 // In all cases, we can clear the flag because the event is either 834 // In all cases, we can clear the flag because the event is either
489 // in the future, or we've already checked it (just now). 835 // in the future, or we've already checked it (just now).
490 event.clearTimeClampCheck(); 836 event->clearTimeClampCheck();
491 } 837 }
492 } 838 }
493 839
494 // Optimize the case where the last event is in the past. 840 // Optimize the case where the last event is in the past.
495 ParamEvent& lastEvent = m_events[m_events.size() - 1]; 841 ParamEvent* lastEvent = m_events[m_events.size() - 1].get();
496 ParamEvent::Type lastEventType = lastEvent.getType(); 842 ParamEvent::Type lastEventType = lastEvent->getType();
497 double lastEventTime = lastEvent.time(); 843 double lastEventTime = lastEvent->time();
498 844
499 // If the last event is in the past and the event has ended, then we can 845 // If the last event is in the past and the event has ended, then we can
500 // just propagate the same value. Except for SetTarget which lasts 846 // just propagate the same value. Except for SetTarget which lasts
501 // "forever". SetValueCurve also has an explicit SetValue at the end of 847 // "forever". SetValueCurve also has an explicit SetValue at the end of
502 // the curve, so we don't need to worry that SetValueCurve time is a 848 // the curve, so we don't need to worry that SetValueCurve time is a
503 // start time, not an end time. 849 // start time, not an end time.
504 if (lastEventTime < currentTime && lastEventType != ParamEvent::SetTarget) { 850 if (lastEventTime < currentTime && lastEventType != ParamEvent::SetTarget) {
505 // The event has finished, so just copy the default value out. 851 // The event has finished, so just copy the default value out.
506 // Since all events are now also in the past, we can just remove all 852 // Since all events are now also in the past, we can just remove all
507 // timeline events too because |defaultValue| has the expected 853 // timeline events too because |defaultValue| has the expected
508 // value. 854 // value.
509 for (unsigned i = 0; i < numberOfValues; ++i) 855 for (unsigned i = 0; i < numberOfValues; ++i)
510 values[i] = defaultValue; 856 values[i] = defaultValue;
511 m_smoothedValue = defaultValue; 857 m_smoothedValue = defaultValue;
512 m_events.clear(); 858 m_events.clear();
513 return defaultValue; 859 return defaultValue;
514 } 860 }
515 } 861 }
516 862
517 // Maintain a running time (frame) and index for writing the values buffer. 863 // Maintain a running time (frame) and index for writing the values buffer.
518 size_t currentFrame = startFrame; 864 size_t currentFrame = startFrame;
519 unsigned writeIndex = 0; 865 unsigned writeIndex = 0;
520 866
521 // If first event is after startFrame then fill initial part of values buffer 867 // If first event is after startFrame then fill initial part of values buffer
522 // with defaultValue until we reach the first event time. 868 // with defaultValue until we reach the first event time.
523 double firstEventTime = m_events[0].time(); 869 double firstEventTime = m_events[0]->time();
524 if (firstEventTime > startFrame / sampleRate) { 870 if (firstEventTime > startFrame / sampleRate) {
525 // |fillToFrame| is an exclusive upper bound, so use ceil() to compute the 871 // |fillToFrame| is an exclusive upper bound, so use ceil() to compute the
526 // bound from the firstEventTime. 872 // bound from the firstEventTime.
527 size_t fillToFrame = endFrame; 873 size_t fillToFrame = endFrame;
528 double firstEventFrame = ceil(firstEventTime * sampleRate); 874 double firstEventFrame = ceil(firstEventTime * sampleRate);
529 if (endFrame > firstEventFrame) 875 if (endFrame > firstEventFrame)
530 fillToFrame = static_cast<size_t>(firstEventFrame); 876 fillToFrame = static_cast<size_t>(firstEventFrame);
531 DCHECK_GE(fillToFrame, startFrame); 877 DCHECK_GE(fillToFrame, startFrame);
532 878
533 fillToFrame -= startFrame; 879 fillToFrame -= startFrame;
534 fillToFrame = std::min(fillToFrame, static_cast<size_t>(numberOfValues)); 880 fillToFrame = std::min(fillToFrame, static_cast<size_t>(numberOfValues));
535 for (; writeIndex < fillToFrame; ++writeIndex) 881 for (; writeIndex < fillToFrame; ++writeIndex)
536 values[writeIndex] = defaultValue; 882 values[writeIndex] = defaultValue;
537 883
538 currentFrame += fillToFrame; 884 currentFrame += fillToFrame;
539 } 885 }
540 886
541 float value = defaultValue; 887 float value = defaultValue;
542 888
543 // Go through each event and render the value buffer where the times overlap, 889 // Go through each event and render the value buffer where the times overlap,
544 // stopping when we've rendered all the requested values. 890 // stopping when we've rendered all the requested values.
545 int lastSkippedEventIndex = 0; 891 int lastSkippedEventIndex = 0;
546 for (int i = 0; i < numberOfEvents && writeIndex < numberOfValues; ++i) { 892 for (int i = 0; i < numberOfEvents && writeIndex < numberOfValues; ++i) {
547 ParamEvent& event = m_events[i]; 893 ParamEvent* event = m_events[i].get();
548 ParamEvent* nextEvent = i < numberOfEvents - 1 ? &(m_events[i + 1]) : 0; 894 ParamEvent* nextEvent = i < numberOfEvents - 1 ? m_events[i + 1].get() : 0;
549 895
550 // Wait until we get a more recent event. 896 // Wait until we get a more recent event.
551 // 897 //
552 // WARNING: due to round-off it might happen that nextEvent->time() is 898 // WARNING: due to round-off it might happen that nextEvent->time() is
553 // just larger than currentFrame/sampleRate. This means that we will end 899 // just larger than currentFrame/sampleRate. This means that we will end
554 // up running the |event| again. The code below had better be prepared 900 // up running the |event| again. The code below had better be prepared
555 // for this case! What should happen is the fillToFrame should be 0 so 901 // for this case! What should happen is the fillToFrame should be 0 so
556 // that while the event is actually run again, nothing actually gets 902 // that while the event is actually run again, nothing actually gets
557 // computed, and we move on to the next event. 903 // computed, and we move on to the next event.
558 // 904 //
559 // An example of this case is setValueCurveAtTime. The time at which 905 // An example of this case is setValueCurveAtTime. The time at which
560 // setValueCurveAtTime ends (and the setValueAtTime begins) might be 906 // setValueCurveAtTime ends (and the setValueAtTime begins) might be
561 // just past currentTime/sampleRate. Then setValueCurveAtTime will be 907 // just past currentTime/sampleRate. Then setValueCurveAtTime will be
562 // processed again before advancing to setValueAtTime. The number of 908 // processed again before advancing to setValueAtTime. The number of
563 // frames to be processed should be zero in this case. 909 // frames to be processed should be zero in this case.
564 if (nextEvent && nextEvent->time() < currentFrame / sampleRate) { 910 if (nextEvent && nextEvent->time() < currentFrame / sampleRate) {
565 // But if the current event is a SetValue event and the event time is 911 // But if the current event is a SetValue event and the event time is
566 // between currentFrame - 1 and curentFrame (in time). we don't want to 912 // between currentFrame - 1 and curentFrame (in time). we don't want to
567 // skip it. If we do skip it, the SetValue event is completely skipped 913 // skip it. If we do skip it, the SetValue event is completely skipped
568 // and not applied, which is wrong. Other events don't have this problem. 914 // and not applied, which is wrong. Other events don't have this problem.
569 // (Because currentFrame is unsigned, we do the time check in this funny, 915 // (Because currentFrame is unsigned, we do the time check in this funny,
570 // but equivalent way.) 916 // but equivalent way.)
571 double eventFrame = event.time() * sampleRate; 917 double eventFrame = event->time() * sampleRate;
572 918
573 // Condition is currentFrame - 1 < eventFrame <= currentFrame, but 919 // Condition is currentFrame - 1 < eventFrame <= currentFrame, but
574 // currentFrame is unsigned and could be 0, so use 920 // currentFrame is unsigned and could be 0, so use
575 // currentFrame < eventFrame + 1 instead. 921 // currentFrame < eventFrame + 1 instead.
576 if (!((event.getType() == ParamEvent::SetValue && 922 if (!((event->getType() == ParamEvent::SetValue &&
577 (eventFrame <= currentFrame) && 923 (eventFrame <= currentFrame) &&
578 (currentFrame < eventFrame + 1)))) { 924 (currentFrame < eventFrame + 1)))) {
579 // This is not the special SetValue event case, and nextEvent is 925 // This is not the special SetValue event case, and nextEvent is
580 // in the past. We can skip processing of this event since it's 926 // in the past. We can skip processing of this event since it's
581 // in past. We keep track of this event in lastSkippedEventIndex 927 // in past. We keep track of this event in lastSkippedEventIndex
582 // to note what events we've skipped. 928 // to note what events we've skipped.
583 lastSkippedEventIndex = i; 929 lastSkippedEventIndex = i;
584 continue; 930 continue;
585 } 931 }
586 } 932 }
587 933
588 // If there's no next event, set nextEventType to LastType to indicate that. 934 // If there's no next event, set nextEventType to LastType to indicate that.
589 ParamEvent::Type nextEventType = 935 ParamEvent::Type nextEventType =
590 nextEvent ? static_cast<ParamEvent::Type>(nextEvent->getType()) 936 nextEvent ? static_cast<ParamEvent::Type>(nextEvent->getType())
591 : ParamEvent::LastType; 937 : ParamEvent::LastType;
592 938
593 // If the current event is SetTarget and the next event is a 939 // If the current event is SetTarget and the next event is a
594 // LinearRampToValue or ExponentialRampToValue, special handling is needed. 940 // LinearRampToValue or ExponentialRampToValue, special handling is needed.
595 // In this case, the linear and exponential ramp should start at wherever 941 // In this case, the linear and exponential ramp should start at wherever
596 // the SetTarget processing has reached. 942 // the SetTarget processing has reached.
597 if (event.getType() == ParamEvent::SetTarget && 943 if (event->getType() == ParamEvent::SetTarget &&
598 (nextEventType == ParamEvent::LinearRampToValue || 944 (nextEventType == ParamEvent::LinearRampToValue ||
599 nextEventType == ParamEvent::ExponentialRampToValue)) { 945 nextEventType == ParamEvent::ExponentialRampToValue)) {
600 // Replace the SetTarget with a SetValue to set the starting time and 946 // Replace the SetTarget with a SetValue to set the starting time and
601 // value for the ramp using the current frame. We need to update |value| 947 // value for the ramp using the current frame. We need to update |value|
602 // appropriately depending on whether the ramp has started or not. 948 // appropriately depending on whether the ramp has started or not.
603 // 949 //
604 // If SetTarget starts somewhere between currentFrame - 1 and 950 // If SetTarget starts somewhere between currentFrame - 1 and
605 // currentFrame, we directly compute the value it would have at 951 // currentFrame, we directly compute the value it would have at
606 // currentFrame. If not, we update the value from the value from 952 // currentFrame. If not, we update the value from the value from
607 // currentFrame - 1. 953 // currentFrame - 1.
608 // 954 //
609 // Can't use the condition currentFrame - 1 <= t0 * sampleRate <= 955 // Can't use the condition currentFrame - 1 <= t0 * sampleRate <=
610 // currentFrame because currentFrame is unsigned and could be 0. Instead, 956 // currentFrame because currentFrame is unsigned and could be 0. Instead,
611 // compute the condition this way, 957 // compute the condition this way,
612 // where f = currentFrame and Fs = sampleRate: 958 // where f = currentFrame and Fs = sampleRate:
613 // 959 //
614 // f - 1 <= t0 * Fs <= f 960 // f - 1 <= t0 * Fs <= f
615 // 2 * f - 2 <= 2 * Fs * t0 <= 2 * f 961 // 2 * f - 2 <= 2 * Fs * t0 <= 2 * f
616 // -2 <= 2 * Fs * t0 - 2 * f <= 0 962 // -2 <= 2 * Fs * t0 - 2 * f <= 0
617 // -1 <= 2 * Fs * t0 - 2 * f + 1 <= 1 963 // -1 <= 2 * Fs * t0 - 2 * f + 1 <= 1
618 // abs(2 * Fs * t0 - 2 * f + 1) <= 1 964 // abs(2 * Fs * t0 - 2 * f + 1) <= 1
619 if (fabs(2 * sampleRate * event.time() - 2 * currentFrame + 1) <= 1) { 965 if (fabs(2 * sampleRate * event->time() - 2 * currentFrame + 1) <= 1) {
620 // SetTarget is starting somewhere between currentFrame - 1 and 966 // SetTarget is starting somewhere between currentFrame - 1 and
621 // currentFrame. Compute the value the SetTarget would have at the 967 // currentFrame. Compute the value the SetTarget would have at the
622 // currentFrame. 968 // currentFrame.
623 value = event.value() + 969 value = event->value() +
624 (value - event.value()) * 970 (value - event->value()) *
625 exp(-(currentFrame / sampleRate - event.time()) / 971 exp(-(currentFrame / sampleRate - event->time()) /
626 event.timeConstant()); 972 event->timeConstant());
627 } else { 973 } else {
628 // SetTarget has already started. Update |value| one frame because it's 974 // SetTarget has already started. Update |value| one frame because it's
629 // the value from the previous frame. 975 // the value from the previous frame.
630 float discreteTimeConstant = static_cast<float>( 976 float discreteTimeConstant = static_cast<float>(
631 AudioUtilities::discreteTimeConstantForSampleRate( 977 AudioUtilities::discreteTimeConstantForSampleRate(
632 event.timeConstant(), controlRate)); 978 event->timeConstant(), controlRate));
633 value += (event.value() - value) * discreteTimeConstant; 979 value += (event->value() - value) * discreteTimeConstant;
634 } 980 }
635 981
636 // Insert a SetValueEvent to mark the starting value and time. 982 // Insert a SetValueEvent to mark the starting value and time.
637 // Clear the clamp check because this doesn't need it. 983 // Clear the clamp check because this doesn't need it.
638 m_events[i] = 984 m_events[i] =
639 ParamEvent::createSetValueEvent(value, currentFrame / sampleRate); 985 ParamEvent::createSetValueEvent(value, currentFrame / sampleRate);
640 m_events[i].clearTimeClampCheck(); 986 m_events[i]->clearTimeClampCheck();
987
988 // Update our pointer to the current event because we just changed it.
989 event = m_events[i].get();
641 } 990 }
642 991
643 float value1 = event.value(); 992 float value1 = event->value();
644 double time1 = event.time(); 993 double time1 = event->time();
645 994
646 float value2 = nextEvent ? nextEvent->value() : value1; 995 float value2 = nextEvent ? nextEvent->value() : value1;
647 double time2 = nextEvent ? nextEvent->time() : endFrame / sampleRate + 1; 996 double time2 = nextEvent ? nextEvent->time() : endFrame / sampleRate + 1;
648 997
998 // Check to see if an event was cancelled.
999 if (nextEventType == ParamEvent::CancelValues) {
1000 switch (event->getType()) {
1001 case ParamEvent::LinearRampToValue:
1002 case ParamEvent::ExponentialRampToValue:
1003 case ParamEvent::SetValue: {
1004 // These three events potentially establish a starting value for
1005 // the following event, so we need to examine the cancelled
1006 // event to see what to do.
1007 const ParamEvent* savedEvent = nextEvent->savedEvent();
1008
1009 // Update the end time and type to pretend that we're running
1010 // this saved event type.
1011 time2 = nextEvent->time();
1012 nextEventType = savedEvent->getType();
1013
1014 if (nextEvent->hasDefaultCancelledValue()) {
1015 // We've already established a value for the cancelled
1016 // event, so just return it.
1017 value2 = nextEvent->value();
1018 } else {
1019 // If the next event would have been a LinearRamp or
1020 // ExponentialRamp, we need to compute a new end value for
1021 // the event so that the curve works continues as if it were
1022 // not cancelled.
1023 switch (savedEvent->getType()) {
1024 case ParamEvent::LinearRampToValue:
1025 value2 =
1026 linearRampAtTime(nextEvent->time(), value1, time1,
1027 savedEvent->value(), savedEvent->time());
1028 break;
1029 case ParamEvent::ExponentialRampToValue:
1030 value2 = exponentialRampAtTime(nextEvent->time(), value1, time1,
1031 savedEvent->value(),
1032 savedEvent->time());
1033 break;
1034 case ParamEvent::SetValueCurve:
1035 case ParamEvent::SetValue:
1036 case ParamEvent::SetTarget:
1037 case ParamEvent::CancelValues:
1038 // These cannot be possible types for the saved event
1039 // because they can't be created.
1040 // createCancelValuesEvent doesn't allow them (SetValue,
1041 // SetTarget, CancelValues) or cancelScheduledValues()
1042 // doesn't create such an event (SetValueCurve).
1043 NOTREACHED();
1044 break;
1045 case ParamEvent::LastType:
1046 // Illegal event type.
1047 NOTREACHED();
1048 break;
1049 }
1050
1051 // Cache the new value so we don't keep computing it over and over.
1052 nextEvent->setCancelledValue(value2);
1053 }
1054 } break;
1055 case ParamEvent::SetValueCurve:
1056 // Everything needed for this was handled when cancelling was
1057 // done.
1058 break;
1059 case ParamEvent::SetTarget:
1060 case ParamEvent::CancelValues:
1061 // Nothing special needs to be done for SetTarget or
1062 // CancelValues followed by CancelValues.
1063 break;
1064 case ParamEvent::LastType:
1065 NOTREACHED();
1066 break;
1067 }
1068 }
1069
649 double deltaTime = time2 - time1; 1070 double deltaTime = time2 - time1;
650 float k = deltaTime > 0 ? 1 / deltaTime : 0; 1071 float k = deltaTime > 0 ? 1 / deltaTime : 0;
651 1072
652 // |fillToEndFrame| is the exclusive upper bound of the last frame to be 1073 // |fillToEndFrame| is the exclusive upper bound of the last frame to be
653 // computed for this event. It's either the last desired frame (|endFrame|) 1074 // computed for this event. It's either the last desired frame (|endFrame|)
654 // or derived from the end time of the next event (time2). We compute 1075 // or derived from the end time of the next event (time2). We compute
655 // ceil(time2*sampleRate) because fillToEndFrame is the exclusive upper 1076 // ceil(time2*sampleRate) because fillToEndFrame is the exclusive upper
656 // bound. Consider the case where |startFrame| = 128 and time2 = 128.1 1077 // bound. Consider the case where |startFrame| = 128 and time2 = 128.1
657 // (assuming sampleRate = 1). Since time2 is greater than 128, we want to 1078 // (assuming sampleRate = 1). Since time2 is greater than 128, we want to
658 // output a value for frame 128. This requires that fillToEndFrame be at 1079 // output a value for frame 128. This requires that fillToEndFrame be at
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
769 if (writeIndex >= 1) 1190 if (writeIndex >= 1)
770 value /= multiplier; 1191 value /= multiplier;
771 1192
772 // Due to roundoff it's possible that value exceeds value2. Clip value 1193 // Due to roundoff it's possible that value exceeds value2. Clip value
773 // to value2 if we are within 1/2 frame of time2. 1194 // to value2 if we are within 1/2 frame of time2.
774 if (currentFrame > time2 * sampleRate - 0.5) 1195 if (currentFrame > time2 * sampleRate - 0.5)
775 value = value2; 1196 value = value2;
776 } 1197 }
777 } else { 1198 } else {
778 // Handle event types not requiring looking ahead to the next event. 1199 // Handle event types not requiring looking ahead to the next event.
779 switch (event.getType()) { 1200 switch (event->getType()) {
780 case ParamEvent::SetValue: 1201 case ParamEvent::SetValue:
781 case ParamEvent::LinearRampToValue: { 1202 case ParamEvent::LinearRampToValue: {
782 currentFrame = fillToEndFrame; 1203 currentFrame = fillToEndFrame;
783 1204
784 // Simply stay at a constant value. 1205 // Simply stay at a constant value.
785 value = event.value(); 1206 value = event->value();
786 1207
787 for (; writeIndex < fillToFrame; ++writeIndex) 1208 for (; writeIndex < fillToFrame; ++writeIndex)
788 values[writeIndex] = value; 1209 values[writeIndex] = value;
789 1210
790 break; 1211 break;
791 } 1212 }
792 1213
1214 case ParamEvent::CancelValues: {
1215 // If the previous event was a SetTarget or ExponentialRamp
1216 // event, the current value is one sample behind. Update
1217 // the sample value by one sample, but only at the start of
1218 // this CancelValues event.
1219 if (event->hasDefaultCancelledValue()) {
1220 value = event->value();
1221 } else {
1222 double cancelFrame = time1 * sampleRate;
1223 if (i >= 1 && cancelFrame <= currentFrame &&
1224 currentFrame < cancelFrame + 1) {
1225 ParamEvent::Type lastEventType = m_events[i - 1]->getType();
1226 if (lastEventType == ParamEvent::SetTarget) {
1227 float target = m_events[i - 1]->value();
1228 float timeConstant = m_events[i - 1]->timeConstant();
1229 float discreteTimeConstant = static_cast<float>(
1230 AudioUtilities::discreteTimeConstantForSampleRate(
1231 timeConstant, controlRate));
1232 value += (target - value) * discreteTimeConstant;
1233 }
1234 }
1235 }
1236
1237 // Simply stay at the current value.
1238 for (; writeIndex < fillToFrame; ++writeIndex)
1239 values[writeIndex] = value;
1240
1241 currentFrame = fillToEndFrame;
1242 break;
1243 }
1244
793 case ParamEvent::ExponentialRampToValue: { 1245 case ParamEvent::ExponentialRampToValue: {
794 currentFrame = fillToEndFrame; 1246 currentFrame = fillToEndFrame;
795 1247
796 // If we're here, we've reached the end of the ramp. If we can 1248 // If we're here, we've reached the end of the ramp. If we can
797 // (because the start and end values have the same sign, and neither 1249 // (because the start and end values have the same sign, and neither
798 // is 0), use the actual end value. If not, we have to propagate 1250 // is 0), use the actual end value. If not, we have to propagate
799 // whatever we have. 1251 // whatever we have.
800 if (i >= 1 && ((m_events[i - 1].value() * event.value()) > 0)) 1252 if (i >= 1 && ((m_events[i - 1]->value() * event->value()) > 0))
801 value = event.value(); 1253 value = event->value();
802 1254
803 // Simply stay at a constant value from the last time. We don't want 1255 // Simply stay at a constant value from the last time. We don't want
804 // to use the value of the event in case value1 * value2 < 0. In this 1256 // to use the value of the event in case value1 * value2 < 0. In this
805 // case we should propagate the previous value, which is in |value|. 1257 // case we should propagate the previous value, which is in |value|.
806 for (; writeIndex < fillToFrame; ++writeIndex) 1258 for (; writeIndex < fillToFrame; ++writeIndex)
807 values[writeIndex] = value; 1259 values[writeIndex] = value;
808 1260
809 break; 1261 break;
810 } 1262 }
811 1263
812 case ParamEvent::SetTarget: { 1264 case ParamEvent::SetTarget: {
813 // Exponential approach to target value with given time constant. 1265 // Exponential approach to target value with given time constant.
814 // 1266 //
815 // v(t) = v2 + (v1 - v2)*exp(-(t-t1/tau)) 1267 // v(t) = v2 + (v1 - v2)*exp(-(t-t1/tau))
816 // 1268 //
817 1269
818 float target = event.value(); 1270 float target = event->value();
819 float timeConstant = event.timeConstant(); 1271 float timeConstant = event->timeConstant();
820 float discreteTimeConstant = static_cast<float>( 1272 float discreteTimeConstant = static_cast<float>(
821 AudioUtilities::discreteTimeConstantForSampleRate(timeConstant, 1273 AudioUtilities::discreteTimeConstantForSampleRate(timeConstant,
822 controlRate)); 1274 controlRate));
823 1275
824 // Set the starting value correctly. This is only needed when the 1276 // Set the starting value correctly. This is only needed when the
825 // current time is "equal" to the start time of this event. This is 1277 // current time is "equal" to the start time of this event. This is
826 // to get the sampling correct if the start time of this automation 1278 // to get the sampling correct if the start time of this automation
827 // isn't on a frame boundary. Otherwise, we can just continue from 1279 // isn't on a frame boundary. Otherwise, we can just continue from
828 // where we left off from the previous rendering quantum. 1280 // where we left off from the previous rendering quantum.
829 { 1281 {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
898 // The previous loops may have updated |value| one extra time. 1350 // The previous loops may have updated |value| one extra time.
899 // Reset it to the last computed value. 1351 // Reset it to the last computed value.
900 if (writeIndex >= 1) 1352 if (writeIndex >= 1)
901 value = values[writeIndex - 1]; 1353 value = values[writeIndex - 1];
902 currentFrame = fillToEndFrame; 1354 currentFrame = fillToEndFrame;
903 } 1355 }
904 break; 1356 break;
905 } 1357 }
906 1358
907 case ParamEvent::SetValueCurve: { 1359 case ParamEvent::SetValueCurve: {
908 Vector<float> curve = event.curve(); 1360 Vector<float> curve = event->curve();
909 float* curveData = curve.data(); 1361 float* curveData = curve.data();
910 unsigned numberOfCurvePoints = curve.size(); 1362 unsigned numberOfCurvePoints = curve.size();
911 1363
1364 float curveEndValue = event->curveEndValue();
1365
912 // Curve events have duration, so don't just use next event time. 1366 // Curve events have duration, so don't just use next event time.
913 double duration = event.duration(); 1367 double duration = event->duration();
914 // How much to step the curve index for each frame. This is basically 1368 // How much to step the curve index for each frame. This is basically
915 // the term (N - 1)/Td in the specification. 1369 // the term (N - 1)/Td in the specification.
916 double curvePointsPerFrame = 1370 double curvePointsPerFrame =
917 (numberOfCurvePoints - 1) / duration / sampleRate; 1371 event->curvePointsPerSecond() / sampleRate;
918 1372
919 if (!numberOfCurvePoints || duration <= 0 || sampleRate <= 0) { 1373 if (!numberOfCurvePoints || duration <= 0 || sampleRate <= 0) {
920 // Error condition - simply propagate previous value. 1374 // Error condition - simply propagate previous value.
921 currentFrame = fillToEndFrame; 1375 currentFrame = fillToEndFrame;
922 for (; writeIndex < fillToFrame; ++writeIndex) 1376 for (; writeIndex < fillToFrame; ++writeIndex)
923 values[writeIndex] = value; 1377 values[writeIndex] = value;
924 break; 1378 break;
925 } 1379 }
926 1380
927 // Save old values and recalculate information based on the curve's 1381 // Save old values and recalculate information based on the curve's
(...skipping 29 matching lines...) Expand all
957 double curveVirtualIndex = 0; 1411 double curveVirtualIndex = 0;
958 if (time1 < currentFrame / sampleRate) { 1412 if (time1 < currentFrame / sampleRate) {
959 // Index somewhere in the middle of the curve data. 1413 // Index somewhere in the middle of the curve data.
960 // Don't use timeToSampleFrame() since we want the exact 1414 // Don't use timeToSampleFrame() since we want the exact
961 // floating-point frame. 1415 // floating-point frame.
962 double frameOffset = currentFrame - time1 * sampleRate; 1416 double frameOffset = currentFrame - time1 * sampleRate;
963 curveVirtualIndex = curvePointsPerFrame * frameOffset; 1417 curveVirtualIndex = curvePointsPerFrame * frameOffset;
964 } 1418 }
965 1419
966 // Set the default value in case fillToFrame is 0. 1420 // Set the default value in case fillToFrame is 0.
967 value = curveData[numberOfCurvePoints - 1]; 1421 value = curveEndValue;
968 1422
969 // Render the stretched curve data using linear interpolation. 1423 // Render the stretched curve data using linear interpolation.
970 // Oversampled curve data can be provided if sharp discontinuities are 1424 // Oversampled curve data can be provided if sharp discontinuities are
971 // desired. 1425 // desired.
972 unsigned k = 0; 1426 unsigned k = 0;
973 #if CPU(X86) || CPU(X86_64) 1427 #if CPU(X86) || CPU(X86_64)
974 if (fillToFrame > writeIndex) { 1428 if (fillToFrame > writeIndex) {
975 const __m128 vCurveVirtualIndex = _mm_set_ps1(curveVirtualIndex); 1429 const __m128 vCurveVirtualIndex = _mm_set_ps1(curveVirtualIndex);
976 const __m128 vCurvePointsPerFrame = 1430 const __m128 vCurvePointsPerFrame =
977 _mm_set_ps1(curvePointsPerFrame); 1431 _mm_set_ps1(curvePointsPerFrame);
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1060 float c1 = curveData[curveIndex1]; 1514 float c1 = curveData[curveIndex1];
1061 double delta = std::min(currentVirtualIndex - curveIndex0, 1.0); 1515 double delta = std::min(currentVirtualIndex - curveIndex0, 1.0);
1062 1516
1063 value = c0 + (c1 - c0) * delta; 1517 value = c0 + (c1 - c0) * delta;
1064 1518
1065 values[writeIndex] = value; 1519 values[writeIndex] = value;
1066 } 1520 }
1067 1521
1068 // If there's any time left after the duration of this event and the 1522 // If there's any time left after the duration of this event and the
1069 // start of the next, then just propagate the last value of the 1523 // start of the next, then just propagate the last value of the
1070 // curveData. 1524 // curveData. Don't modify |value| unless there is time left.
1071 if (writeIndex < nextEventFillToFrame) 1525 if (writeIndex < nextEventFillToFrame) {
1072 value = curveData[numberOfCurvePoints - 1]; 1526 value = curveEndValue;
1073 for (; writeIndex < nextEventFillToFrame; ++writeIndex) 1527 for (; writeIndex < nextEventFillToFrame; ++writeIndex)
1074 values[writeIndex] = value; 1528 values[writeIndex] = value;
1529 }
1075 1530
1076 // Re-adjust current time 1531 // Re-adjust current time
1077 currentFrame += nextEventFillToFrame; 1532 currentFrame += nextEventFillToFrame;
1078 1533
1079 break; 1534 break;
1080 } 1535 }
1081 case ParamEvent::LastType: 1536 case ParamEvent::LastType:
1082 ASSERT_NOT_REACHED(); 1537 ASSERT_NOT_REACHED();
1083 break; 1538 break;
1084 } 1539 }
(...skipping 11 matching lines...) Expand all
1096 // propagate the last value to the end of the values buffer. 1551 // propagate the last value to the end of the values buffer.
1097 for (; writeIndex < numberOfValues; ++writeIndex) 1552 for (; writeIndex < numberOfValues; ++writeIndex)
1098 values[writeIndex] = value; 1553 values[writeIndex] = value;
1099 1554
1100 // This value is used to set the .value attribute of the AudioParam. it 1555 // This value is used to set the .value attribute of the AudioParam. it
1101 // should be the last computed value. 1556 // should be the last computed value.
1102 return values[numberOfValues - 1]; 1557 return values[numberOfValues - 1];
1103 } 1558 }
1104 1559
1105 } // namespace blink 1560 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698