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

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

Issue 2389253002: reflow comments in modules/{webaudio,vr} (Closed)
Patch Set: . Created 4 years, 2 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
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 19 matching lines...) Expand all
30 #include "wtf/CPU.h" 30 #include "wtf/CPU.h"
31 #include "wtf/MathExtras.h" 31 #include "wtf/MathExtras.h"
32 #include <algorithm> 32 #include <algorithm>
33 33
34 #if CPU(X86) || CPU(X86_64) 34 #if CPU(X86) || CPU(X86_64)
35 #include <emmintrin.h> 35 #include <emmintrin.h>
36 #endif 36 #endif
37 37
38 namespace blink { 38 namespace blink {
39 39
40 // For a SetTarget event, if the relative difference between the current value a nd the target value 40 // For a SetTarget event, if the relative difference between the current value
41 // is less than this, consider them the same and just output the target value. This value MUST be 41 // and the target value is less than this, consider them the same and just
42 // larger than the single precision epsilon of 5.960465e-8. Due to round-off, t his value is not 42 // output the target value. This value MUST be larger than the single precision
43 // achievable in general. This value can vary across the platforms (CPU) and th us it is determined 43 // epsilon of 5.960465e-8. Due to round-off, this value is not achievable in
44 // experimentally. 44 // general. This value can vary across the platforms (CPU) and thus it is
45 // determined experimentally.
45 const float kSetTargetThreshold = 1.5e-6; 46 const float kSetTargetThreshold = 1.5e-6;
46 47
47 // For a SetTarget event, if the target value is 0, and the current value is les s than this 48 // For a SetTarget event, if the target value is 0, and the current value is
48 // threshold, consider the curve to have converged to 0. We need a separate cas e from 49 // less than this threshold, consider the curve to have converged to 0. We need
49 // kSetTargetThreshold because that uses relative error, which is never met if t he target value is 50 // a separate case from kSetTargetThreshold because that uses relative error,
50 // 0, a common case. This value MUST be larger than least positive normalized s ingle precision 51 // which is never met if the target value is 0, a common case. This value MUST
52 // be larger than least positive normalized single precision
51 // value (1.1754944e-38) because we normally operate with flush-to-zero enabled. 53 // value (1.1754944e-38) because we normally operate with flush-to-zero enabled.
52 const float kSetTargetZeroThreshold = 1e-20; 54 const float kSetTargetZeroThreshold = 1e-20;
53 55
54 static bool isNonNegativeAudioParamTime(double time, 56 static bool isNonNegativeAudioParamTime(double time,
55 ExceptionState& exceptionState, 57 ExceptionState& exceptionState,
56 String message = "Time") { 58 String message = "Time") {
57 if (time >= 0) 59 if (time >= 0)
58 return true; 60 return true;
59 61
60 exceptionState.throwDOMException( 62 exceptionState.throwDOMException(
61 InvalidAccessError, message + " must be a finite non-negative number: " + 63 InvalidAccessError, message + " must be a finite non-negative number: " +
62 String::number(time)); 64 String::number(time));
63 return false; 65 return false;
64 } 66 }
65 67
66 static bool isPositiveAudioParamTime(double time, 68 static bool isPositiveAudioParamTime(double time,
67 ExceptionState& exceptionState, 69 ExceptionState& exceptionState,
68 String message) { 70 String message) {
69 if (time > 0) 71 if (time > 0)
70 return true; 72 return true;
71 73
72 exceptionState.throwDOMException( 74 exceptionState.throwDOMException(
73 InvalidAccessError, 75 InvalidAccessError,
74 message + " must be a finite positive number: " + String::number(time)); 76 message + " must be a finite positive number: " + String::number(time));
75 return false; 77 return false;
76 } 78 }
77 79
78 String AudioParamTimeline::eventToString(const ParamEvent& event) { 80 String AudioParamTimeline::eventToString(const ParamEvent& event) {
79 // The default arguments for most automation methods is the value and the time . 81 // The default arguments for most automation methods is the value and the
82 // time.
80 String args = 83 String args =
81 String::number(event.value()) + ", " + String::number(event.time(), 16); 84 String::number(event.value()) + ", " + String::number(event.time(), 16);
82 85
83 // Get a nice printable name for the event and update the args if necessary. 86 // Get a nice printable name for the event and update the args if necessary.
84 String s; 87 String s;
85 switch (event.getType()) { 88 switch (event.getType()) {
86 case ParamEvent::SetValue: 89 case ParamEvent::SetValue:
87 s = "setValueAtTime"; 90 s = "setValueAtTime";
88 break; 91 break;
89 case ParamEvent::LinearRampToValue: 92 case ParamEvent::LinearRampToValue:
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 // beginning. 269 // beginning.
267 insertEvent(ParamEvent::createSetValueEvent( 270 insertEvent(ParamEvent::createSetValueEvent(
268 curve->data()[curve->length() - 1], time + duration), 271 curve->data()[curve->length() - 1], time + duration),
269 exceptionState); 272 exceptionState);
270 } 273 }
271 274
272 void AudioParamTimeline::insertEvent(const ParamEvent& event, 275 void AudioParamTimeline::insertEvent(const ParamEvent& event,
273 ExceptionState& exceptionState) { 276 ExceptionState& exceptionState) {
274 DCHECK(isMainThread()); 277 DCHECK(isMainThread());
275 278
276 // Sanity check the event. Be super careful we're not getting infected with Na N or Inf. These 279 // Sanity check the event. Be super careful we're not getting infected with
277 // should have been handled by the caller. 280 // NaN or Inf. These should have been handled by the caller.
278 bool isValid = event.getType() < ParamEvent::LastType && 281 bool isValid = event.getType() < ParamEvent::LastType &&
279 std::isfinite(event.value()) && std::isfinite(event.time()) && 282 std::isfinite(event.value()) && std::isfinite(event.time()) &&
280 std::isfinite(event.timeConstant()) && 283 std::isfinite(event.timeConstant()) &&
281 std::isfinite(event.duration()) && event.duration() >= 0; 284 std::isfinite(event.duration()) && event.duration() >= 0;
282 285
283 DCHECK(isValid); 286 DCHECK(isValid);
284 if (!isValid) 287 if (!isValid)
285 return; 288 return;
286 289
287 MutexLocker locker(m_eventsLock); 290 MutexLocker locker(m_eventsLock);
288 291
289 unsigned i = 0; 292 unsigned i = 0;
290 double insertTime = event.time(); 293 double insertTime = event.time();
291 294
292 if (!m_events.size() && 295 if (!m_events.size() &&
293 (event.getType() == ParamEvent::LinearRampToValue || 296 (event.getType() == ParamEvent::LinearRampToValue ||
294 event.getType() == ParamEvent::ExponentialRampToValue)) { 297 event.getType() == ParamEvent::ExponentialRampToValue)) {
295 // There are no events preceding these ramps. Insert a new setValueAtTime e vent to set the 298 // There are no events preceding these ramps. Insert a new setValueAtTime
296 // starting point for these events. 299 // event to set the starting point for these events.
297 m_events.insert(0, AudioParamTimeline::ParamEvent::createSetValueEvent( 300 m_events.insert(0, AudioParamTimeline::ParamEvent::createSetValueEvent(
298 event.initialValue(), event.callTime())); 301 event.initialValue(), event.callTime()));
299 } 302 }
300 303
301 for (i = 0; i < m_events.size(); ++i) { 304 for (i = 0; i < m_events.size(); ++i) {
302 if (event.getType() == ParamEvent::SetValueCurve) { 305 if (event.getType() == ParamEvent::SetValueCurve) {
303 // If this event is a SetValueCurve, make sure it doesn't overlap any exis ting 306 // If this event is a SetValueCurve, make sure it doesn't overlap any
304 // event. It's ok if the SetValueCurve starts at the same time as the end of some other 307 // existing event. It's ok if the SetValueCurve starts at the same time as
305 // duration. 308 // the end of some other duration.
306 double endTime = event.time() + event.duration(); 309 double endTime = event.time() + event.duration();
307 if (m_events[i].time() > event.time() && m_events[i].time() < endTime) { 310 if (m_events[i].time() > event.time() && m_events[i].time() < endTime) {
308 exceptionState.throwDOMException( 311 exceptionState.throwDOMException(
309 NotSupportedError, 312 NotSupportedError,
310 eventToString(event) + " overlaps " + eventToString(m_events[i])); 313 eventToString(event) + " overlaps " + eventToString(m_events[i]));
311 return; 314 return;
312 } 315 }
313 } else { 316 } else {
314 // Otherwise, make sure this event doesn't overlap any existing SetValueCu rve event. 317 // Otherwise, make sure this event doesn't overlap any existing
318 // SetValueCurve event.
315 if (m_events[i].getType() == ParamEvent::SetValueCurve) { 319 if (m_events[i].getType() == ParamEvent::SetValueCurve) {
316 double endTime = m_events[i].time() + m_events[i].duration(); 320 double endTime = m_events[i].time() + m_events[i].duration();
317 if (event.time() >= m_events[i].time() && event.time() < endTime) { 321 if (event.time() >= m_events[i].time() && event.time() < endTime) {
318 exceptionState.throwDOMException( 322 exceptionState.throwDOMException(
319 NotSupportedError, 323 NotSupportedError,
320 eventToString(event) + " overlaps " + eventToString(m_events[i])); 324 eventToString(event) + " overlaps " + eventToString(m_events[i]));
321 return; 325 return;
322 } 326 }
323 } 327 }
324 } 328 }
(...skipping 11 matching lines...) Expand all
336 340
337 m_events.insert(i, event); 341 m_events.insert(i, event);
338 } 342 }
339 343
340 bool AudioParamTimeline::hasValues() const { 344 bool AudioParamTimeline::hasValues() const {
341 MutexTryLocker tryLocker(m_eventsLock); 345 MutexTryLocker tryLocker(m_eventsLock);
342 346
343 if (tryLocker.locked()) 347 if (tryLocker.locked())
344 return m_events.size(); 348 return m_events.size();
345 349
346 // Can't get the lock so that means the main thread is trying to insert an eve nt. Just 350 // Can't get the lock so that means the main thread is trying to insert an
347 // return true then. If the main thread releases the lock before valueForCont extTime or 351 // event. Just return true then. If the main thread releases the lock before
348 // valuesForFrameRange runs, then the there will be an event on the timeline, so everything 352 // valueForContextTime or valuesForFrameRange runs, then the there will be an
349 // is fine. If the lock is held so that neither valueForContextTime nor value sForFrameRange 353 // event on the timeline, so everything is fine. If the lock is held so that
350 // can run, this is ok too, because they have tryLocks to produce a default va lue. The 354 // neither valueForContextTime nor valuesForFrameRange can run, this is ok
351 // event will then get processed in the next rendering quantum. 355 // too, because they have tryLocks to produce a default value. The event will
356 // then get processed in the next rendering quantum.
352 // 357 //
353 // Don't want to return false here because that would confuse the processing o f the timeline 358 // Don't want to return false here because that would confuse the processing
354 // if previously we returned true and now suddenly return false, only to retur n true on the 359 // of the timeline if previously we returned true and now suddenly return
355 // next rendering quantum. Currently, once a timeline has been introduced it is always true 360 // false, only to return true on the next rendering quantum. Currently, once
356 // forever because m_events never shrinks. 361 // a timeline has been introduced it is always true forever because m_events
362 // never shrinks.
357 return true; 363 return true;
358 } 364 }
359 365
360 void AudioParamTimeline::cancelScheduledValues(double startTime, 366 void AudioParamTimeline::cancelScheduledValues(double startTime,
361 ExceptionState& exceptionState) { 367 ExceptionState& exceptionState) {
362 DCHECK(isMainThread()); 368 DCHECK(isMainThread());
363 369
364 MutexLocker locker(m_eventsLock); 370 MutexLocker locker(m_eventsLock);
365 371
366 // Remove all events starting at startTime. 372 // Remove all events starting at startTime.
(...skipping 17 matching lines...) Expand all
384 audioDestination.currentTime() < m_events[0].time()) { 390 audioDestination.currentTime() < m_events[0].time()) {
385 hasValue = false; 391 hasValue = false;
386 return defaultValue; 392 return defaultValue;
387 } 393 }
388 } 394 }
389 395
390 // Ask for just a single value. 396 // Ask for just a single value.
391 float value; 397 float value;
392 double sampleRate = audioDestination.sampleRate(); 398 double sampleRate = audioDestination.sampleRate();
393 size_t startFrame = audioDestination.currentSampleFrame(); 399 size_t startFrame = audioDestination.currentSampleFrame();
394 double controlRate = 400 // One parameter change per render quantum.
395 sampleRate / 401 double controlRate = sampleRate / AudioHandler::ProcessingSizeInFrames;
396 AudioHandler::
397 ProcessingSizeInFrames; // one parameter change per render quantum
398 value = valuesForFrameRange(startFrame, startFrame + 1, defaultValue, &value, 402 value = valuesForFrameRange(startFrame, startFrame + 1, defaultValue, &value,
399 1, sampleRate, controlRate, minValue, maxValue); 403 1, sampleRate, controlRate, minValue, maxValue);
400 404
401 hasValue = true; 405 hasValue = true;
402 return value; 406 return value;
403 } 407 }
404 408
405 float AudioParamTimeline::valuesForFrameRange(size_t startFrame, 409 float AudioParamTimeline::valuesForFrameRange(size_t startFrame,
406 size_t endFrame, 410 size_t endFrame,
407 float defaultValue, 411 float defaultValue,
(...skipping 29 matching lines...) Expand all
437 float defaultValue, 441 float defaultValue,
438 float* values, 442 float* values,
439 unsigned numberOfValues, 443 unsigned numberOfValues,
440 double sampleRate, 444 double sampleRate,
441 double controlRate) { 445 double controlRate) {
442 DCHECK(values); 446 DCHECK(values);
443 DCHECK_GE(numberOfValues, 1u); 447 DCHECK_GE(numberOfValues, 1u);
444 if (!values || !(numberOfValues >= 1)) 448 if (!values || !(numberOfValues >= 1))
445 return defaultValue; 449 return defaultValue;
446 450
447 // Return default value if there are no events matching the desired time range . 451 // Return default value if there are no events matching the desired time
452 // range.
448 if (!m_events.size() || (endFrame / sampleRate <= m_events[0].time())) { 453 if (!m_events.size() || (endFrame / sampleRate <= m_events[0].time())) {
449 for (unsigned i = 0; i < numberOfValues; ++i) 454 for (unsigned i = 0; i < numberOfValues; ++i)
450 values[i] = defaultValue; 455 values[i] = defaultValue;
451 return defaultValue; 456 return defaultValue;
452 } 457 }
453 458
454 // Optimize the case where the last event is in the past. 459 // Optimize the case where the last event is in the past.
455 if (m_events.size() > 0) { 460 if (m_events.size() > 0) {
456 ParamEvent& lastEvent = m_events[m_events.size() - 1]; 461 ParamEvent& lastEvent = m_events[m_events.size() - 1];
457 ParamEvent::Type lastEventType = lastEvent.getType(); 462 ParamEvent::Type lastEventType = lastEvent.getType();
(...skipping 15 matching lines...) Expand all
473 m_smoothedValue = defaultValue; 478 m_smoothedValue = defaultValue;
474 m_events.clear(); 479 m_events.clear();
475 return defaultValue; 480 return defaultValue;
476 } 481 }
477 } 482 }
478 483
479 // Maintain a running time (frame) and index for writing the values buffer. 484 // Maintain a running time (frame) and index for writing the values buffer.
480 size_t currentFrame = startFrame; 485 size_t currentFrame = startFrame;
481 unsigned writeIndex = 0; 486 unsigned writeIndex = 0;
482 487
483 // If first event is after startFrame then fill initial part of values buffer with defaultValue 488 // If first event is after startFrame then fill initial part of values buffer
484 // until we reach the first event time. 489 // with defaultValue until we reach the first event time.
485 double firstEventTime = m_events[0].time(); 490 double firstEventTime = m_events[0].time();
486 if (firstEventTime > startFrame / sampleRate) { 491 if (firstEventTime > startFrame / sampleRate) {
487 // |fillToFrame| is an exclusive upper bound, so use ceil() to compute the b ound from the 492 // |fillToFrame| is an exclusive upper bound, so use ceil() to compute the
488 // firstEventTime. 493 // bound from the firstEventTime.
489 size_t fillToFrame = endFrame; 494 size_t fillToFrame = endFrame;
490 double firstEventFrame = ceil(firstEventTime * sampleRate); 495 double firstEventFrame = ceil(firstEventTime * sampleRate);
491 if (endFrame > firstEventFrame) 496 if (endFrame > firstEventFrame)
492 fillToFrame = static_cast<size_t>(firstEventFrame); 497 fillToFrame = static_cast<size_t>(firstEventFrame);
493 DCHECK_GE(fillToFrame, startFrame); 498 DCHECK_GE(fillToFrame, startFrame);
494 499
495 fillToFrame -= startFrame; 500 fillToFrame -= startFrame;
496 fillToFrame = std::min(fillToFrame, static_cast<size_t>(numberOfValues)); 501 fillToFrame = std::min(fillToFrame, static_cast<size_t>(numberOfValues));
497 for (; writeIndex < fillToFrame; ++writeIndex) 502 for (; writeIndex < fillToFrame; ++writeIndex)
498 values[writeIndex] = defaultValue; 503 values[writeIndex] = defaultValue;
(...skipping 19 matching lines...) Expand all
518 // for this case! What should happen is the fillToFrame should be 0 so 523 // for this case! What should happen is the fillToFrame should be 0 so
519 // that while the event is actually run again, nothing actually gets 524 // that while the event is actually run again, nothing actually gets
520 // computed, and we move on to the next event. 525 // computed, and we move on to the next event.
521 // 526 //
522 // An example of this case is setValueCurveAtTime. The time at which 527 // An example of this case is setValueCurveAtTime. The time at which
523 // setValueCurveAtTime ends (and the setValueAtTime begins) might be 528 // setValueCurveAtTime ends (and the setValueAtTime begins) might be
524 // just past currentTime/sampleRate. Then setValueCurveAtTime will be 529 // just past currentTime/sampleRate. Then setValueCurveAtTime will be
525 // processed again before advancing to setValueAtTime. The number of 530 // processed again before advancing to setValueAtTime. The number of
526 // frames to be processed should be zero in this case. 531 // frames to be processed should be zero in this case.
527 if (nextEvent && nextEvent->time() < currentFrame / sampleRate) { 532 if (nextEvent && nextEvent->time() < currentFrame / sampleRate) {
528 // But if the current event is a SetValue event and the event time is betw een 533 // But if the current event is a SetValue event and the event time is
529 // currentFrame - 1 and curentFrame (in time). we don't want to skip it. If we do skip 534 // between currentFrame - 1 and curentFrame (in time). we don't want to
530 // it, the SetValue event is completely skipped and not applied, which is wrong. Other 535 // skip it. If we do skip it, the SetValue event is completely skipped
531 // events don't have this problem. (Because currentFrame is unsigned, we do the time 536 // and not applied, which is wrong. Other events don't have this problem.
532 // check in this funny, but equivalent way.) 537 // (Because currentFrame is unsigned, we do the time check in this funny,
538 // but equivalent way.)
533 double eventFrame = event.time() * sampleRate; 539 double eventFrame = event.time() * sampleRate;
534 540
535 // Condition is currentFrame - 1 < eventFrame <= currentFrame, but current Frame is 541 // Condition is currentFrame - 1 < eventFrame <= currentFrame, but
536 // unsigned and could be 0, so use currentFrame < eventFrame + 1 instead. 542 // currentFrame is unsigned and could be 0, so use
543 // currentFrame < eventFrame + 1 instead.
537 if (!((event.getType() == ParamEvent::SetValue && 544 if (!((event.getType() == ParamEvent::SetValue &&
538 (eventFrame <= currentFrame) && 545 (eventFrame <= currentFrame) &&
539 (currentFrame < eventFrame + 1)))) { 546 (currentFrame < eventFrame + 1)))) {
540 // This is not the special SetValue event case, and nextEvent is 547 // This is not the special SetValue event case, and nextEvent is
541 // in the past. We can skip processing of this event since it's 548 // in the past. We can skip processing of this event since it's
542 // in past. We keep track of this event in lastSkippedEventIndex 549 // in past. We keep track of this event in lastSkippedEventIndex
543 // to note what events we've skipped. 550 // to note what events we've skipped.
544 lastSkippedEventIndex = i; 551 lastSkippedEventIndex = i;
545 continue; 552 continue;
546 } 553 }
547 } 554 }
548 555
549 // If there's no next event, set nextEventType to LastType to indicate that. 556 // If there's no next event, set nextEventType to LastType to indicate that.
550 ParamEvent::Type nextEventType = 557 ParamEvent::Type nextEventType =
551 nextEvent ? static_cast<ParamEvent::Type>(nextEvent->getType()) 558 nextEvent ? static_cast<ParamEvent::Type>(nextEvent->getType())
552 : ParamEvent::LastType; 559 : ParamEvent::LastType;
553 560
554 // If the current event is SetTarget and the next event is a LinearRampToVal ue or 561 // If the current event is SetTarget and the next event is a
555 // ExponentialRampToValue, special handling is needed. In this case, the li near and 562 // LinearRampToValue or ExponentialRampToValue, special handling is needed.
556 // exponential ramp should start at wherever the SetTarget processing has re ached. 563 // In this case, the linear and exponential ramp should start at wherever
564 // the SetTarget processing has reached.
557 if (event.getType() == ParamEvent::SetTarget && 565 if (event.getType() == ParamEvent::SetTarget &&
558 (nextEventType == ParamEvent::LinearRampToValue || 566 (nextEventType == ParamEvent::LinearRampToValue ||
559 nextEventType == ParamEvent::ExponentialRampToValue)) { 567 nextEventType == ParamEvent::ExponentialRampToValue)) {
560 // Replace the SetTarget with a SetValue to set the starting time and valu e for the ramp 568 // Replace the SetTarget with a SetValue to set the starting time and
561 // using the current frame. We need to update |value| appropriately depen ding on 569 // value for the ramp using the current frame. We need to update |value|
562 // whether the ramp has started or not. 570 // appropriately depending on whether the ramp has started or not.
563 // 571 //
564 // If SetTarget starts somewhere between currentFrame - 1 and currentFrame , we directly 572 // If SetTarget starts somewhere between currentFrame - 1 and
565 // compute the value it would have at currentFrame. If not, we update the value from 573 // currentFrame, we directly compute the value it would have at
566 // the value from currentFrame - 1. 574 // currentFrame. If not, we update the value from the value from
575 // currentFrame - 1.
567 // 576 //
568 // Can't use the condition currentFrame - 1 <= t0 * sampleRate <= currentF rame because 577 // Can't use the condition currentFrame - 1 <= t0 * sampleRate <=
569 // currentFrame is unsigned and could be 0. Instead, compute the conditio n this way, 578 // currentFrame because currentFrame is unsigned and could be 0. Instead,
579 // compute the condition this way,
570 // where f = currentFrame and Fs = sampleRate: 580 // where f = currentFrame and Fs = sampleRate:
571 // 581 //
572 // f - 1 <= t0 * Fs <= f 582 // f - 1 <= t0 * Fs <= f
573 // 2 * f - 2 <= 2 * Fs * t0 <= 2 * f 583 // 2 * f - 2 <= 2 * Fs * t0 <= 2 * f
574 // -2 <= 2 * Fs * t0 - 2 * f <= 0 584 // -2 <= 2 * Fs * t0 - 2 * f <= 0
575 // -1 <= 2 * Fs * t0 - 2 * f + 1 <= 1 585 // -1 <= 2 * Fs * t0 - 2 * f + 1 <= 1
576 // abs(2 * Fs * t0 - 2 * f + 1) <= 1 586 // abs(2 * Fs * t0 - 2 * f + 1) <= 1
577 if (fabs(2 * sampleRate * event.time() - 2 * currentFrame + 1) <= 1) { 587 if (fabs(2 * sampleRate * event.time() - 2 * currentFrame + 1) <= 1) {
578 // SetTarget is starting somewhere between currentFrame - 1 and 588 // SetTarget is starting somewhere between currentFrame - 1 and
579 // currentFrame. Compute the value the SetTarget would have at the curre ntFrame. 589 // currentFrame. Compute the value the SetTarget would have at the
590 // currentFrame.
580 value = event.value() + 591 value = event.value() +
581 (value - event.value()) * 592 (value - event.value()) *
582 exp(-(currentFrame / sampleRate - event.time()) / 593 exp(-(currentFrame / sampleRate - event.time()) /
583 event.timeConstant()); 594 event.timeConstant());
584 } else { 595 } else {
585 // SetTarget has already started. Update |value| one frame because it's the value from 596 // SetTarget has already started. Update |value| one frame because it's
586 // the previous frame. 597 // the value from the previous frame.
587 float discreteTimeConstant = static_cast<float>( 598 float discreteTimeConstant = static_cast<float>(
588 AudioUtilities::discreteTimeConstantForSampleRate( 599 AudioUtilities::discreteTimeConstantForSampleRate(
589 event.timeConstant(), controlRate)); 600 event.timeConstant(), controlRate));
590 value += (event.value() - value) * discreteTimeConstant; 601 value += (event.value() - value) * discreteTimeConstant;
591 } 602 }
592 m_events[i] = 603 m_events[i] =
593 ParamEvent::createSetValueEvent(value, currentFrame / sampleRate); 604 ParamEvent::createSetValueEvent(value, currentFrame / sampleRate);
594 } 605 }
595 606
596 float value1 = event.value(); 607 float value1 = event.value();
597 double time1 = event.time(); 608 double time1 = event.time();
598 609
599 float value2 = nextEvent ? nextEvent->value() : value1; 610 float value2 = nextEvent ? nextEvent->value() : value1;
600 double time2 = nextEvent ? nextEvent->time() : endFrame / sampleRate + 1; 611 double time2 = nextEvent ? nextEvent->time() : endFrame / sampleRate + 1;
601 612
602 double deltaTime = time2 - time1; 613 double deltaTime = time2 - time1;
603 float k = deltaTime > 0 ? 1 / deltaTime : 0; 614 float k = deltaTime > 0 ? 1 / deltaTime : 0;
604 615
605 // |fillToEndFrame| is the exclusive upper bound of the last frame to be com puted for this 616 // |fillToEndFrame| is the exclusive upper bound of the last frame to be
606 // event. It's either the last desired frame (|endFrame|) or derived from t he end time of 617 // computed for this event. It's either the last desired frame (|endFrame|)
607 // the next event (time2). We compute ceil(time2*sampleRate) because fillToE ndFrame is the 618 // or derived from the end time of the next event (time2). We compute
608 // exclusive upper bound. Consider the case where |startFrame| = 128 and ti me2 = 128.1 619 // ceil(time2*sampleRate) because fillToEndFrame is the exclusive upper
609 // (assuming sampleRate = 1). Since time2 is greater than 128, we want to o utput a value 620 // bound. Consider the case where |startFrame| = 128 and time2 = 128.1
610 // for frame 128. This requires that fillToEndFrame be at least 129. This is achieved by 621 // (assuming sampleRate = 1). Since time2 is greater than 128, we want to
611 // ceil(time2). 622 // output a value for frame 128. This requires that fillToEndFrame be at
623 // least 129. This is achieved by ceil(time2).
612 // 624 //
613 // However, time2 can be very large, so compute this carefully in the case w here time2 625 // However, time2 can be very large, so compute this carefully in the case
614 // exceeds the size of a size_t. 626 // where time2 exceeds the size of a size_t.
615 627
616 size_t fillToEndFrame = endFrame; 628 size_t fillToEndFrame = endFrame;
617 if (endFrame > time2 * sampleRate) 629 if (endFrame > time2 * sampleRate)
618 fillToEndFrame = static_cast<size_t>(ceil(time2 * sampleRate)); 630 fillToEndFrame = static_cast<size_t>(ceil(time2 * sampleRate));
619 631
620 DCHECK_GE(fillToEndFrame, startFrame); 632 DCHECK_GE(fillToEndFrame, startFrame);
621 size_t fillToFrame = fillToEndFrame - startFrame; 633 size_t fillToFrame = fillToEndFrame - startFrame;
622 fillToFrame = std::min(fillToFrame, static_cast<size_t>(numberOfValues)); 634 fillToFrame = std::min(fillToFrame, static_cast<size_t>(numberOfValues));
623 635
624 // First handle linear and exponential ramps which require looking ahead to the next event. 636 // First handle linear and exponential ramps which require looking ahead to
637 // the next event.
625 if (nextEventType == ParamEvent::LinearRampToValue) { 638 if (nextEventType == ParamEvent::LinearRampToValue) {
626 const float valueDelta = value2 - value1; 639 const float valueDelta = value2 - value1;
627 #if CPU(X86) || CPU(X86_64) 640 #if CPU(X86) || CPU(X86_64)
628 // Minimize in-loop operations. Calculate starting value and increment. Ne xt step: value += inc. 641 // Minimize in-loop operations. Calculate starting value and increment.
629 // value = value1 + (currentFrame/sampleRate - time1) * k * (value2 - val ue1); 642 // Next step: value += inc.
643 // value = value1 +
644 // (currentFrame/sampleRate - time1) * k * (value2 - value1);
630 // inc = 4 / sampleRate * k * (value2 - value1); 645 // inc = 4 / sampleRate * k * (value2 - value1);
631 // Resolve recursion by expanding constants to achieve a 4-step loop unrol ling. 646 // Resolve recursion by expanding constants to achieve a 4-step loop
632 // value = value1 + ((currentFrame/sampleRate - time1) + i * sampleFrameT imeIncr) * k * (value2 -value1), i in 0..3 647 // unrolling.
648 // value = value1 +
649 // ((currentFrame/sampleRate - time1) + i * sampleFrameTimeIncr) * k
650 // * (value2 -value1), i in 0..3
633 __m128 vValue = 651 __m128 vValue =
634 _mm_mul_ps(_mm_set_ps1(1 / sampleRate), _mm_set_ps(3, 2, 1, 0)); 652 _mm_mul_ps(_mm_set_ps1(1 / sampleRate), _mm_set_ps(3, 2, 1, 0));
635 vValue = 653 vValue =
636 _mm_add_ps(vValue, _mm_set_ps1(currentFrame / sampleRate - time1)); 654 _mm_add_ps(vValue, _mm_set_ps1(currentFrame / sampleRate - time1));
637 vValue = _mm_mul_ps(vValue, _mm_set_ps1(k * valueDelta)); 655 vValue = _mm_mul_ps(vValue, _mm_set_ps1(k * valueDelta));
638 vValue = _mm_add_ps(vValue, _mm_set_ps1(value1)); 656 vValue = _mm_add_ps(vValue, _mm_set_ps1(value1));
639 __m128 vInc = _mm_set_ps1(4 / sampleRate * k * valueDelta); 657 __m128 vInc = _mm_set_ps1(4 / sampleRate * k * valueDelta);
640 658
641 // Truncate loop steps to multiple of 4. 659 // Truncate loop steps to multiple of 4.
642 unsigned fillToFrameTrunc = 660 unsigned fillToFrameTrunc =
643 writeIndex + ((fillToFrame - writeIndex) / 4) * 4; 661 writeIndex + ((fillToFrame - writeIndex) / 4) * 4;
644 // Compute final time. 662 // Compute final time.
645 currentFrame += fillToFrameTrunc - writeIndex; 663 currentFrame += fillToFrameTrunc - writeIndex;
646 664
647 // Process 4 loop steps. 665 // Process 4 loop steps.
648 for (; writeIndex < fillToFrameTrunc; writeIndex += 4) { 666 for (; writeIndex < fillToFrameTrunc; writeIndex += 4) {
649 _mm_storeu_ps(values + writeIndex, vValue); 667 _mm_storeu_ps(values + writeIndex, vValue);
650 vValue = _mm_add_ps(vValue, vInc); 668 vValue = _mm_add_ps(vValue, vInc);
651 } 669 }
652 // Update |value| with the last value computed so that the .value attribut e of the 670 // Update |value| with the last value computed so that the .value
653 // AudioParam gets the correct linear ramp value, in case the following lo op doesn't 671 // attribute of the AudioParam gets the correct linear ramp value, in case
654 // execute. 672 // the following loop doesn't execute.
655 if (writeIndex >= 1) 673 if (writeIndex >= 1)
656 value = values[writeIndex - 1]; 674 value = values[writeIndex - 1];
657 #endif 675 #endif
658 // Serially process remaining values. 676 // Serially process remaining values.
659 for (; writeIndex < fillToFrame; ++writeIndex) { 677 for (; writeIndex < fillToFrame; ++writeIndex) {
660 float x = (currentFrame / sampleRate - time1) * k; 678 float x = (currentFrame / sampleRate - time1) * k;
661 // value = (1 - x) * value1 + x * value2; 679 // value = (1 - x) * value1 + x * value2;
662 value = value1 + x * valueDelta; 680 value = value1 + x * valueDelta;
663 values[writeIndex] = value; 681 values[writeIndex] = value;
664 ++currentFrame; 682 ++currentFrame;
665 } 683 }
666 } else if (nextEventType == ParamEvent::ExponentialRampToValue) { 684 } else if (nextEventType == ParamEvent::ExponentialRampToValue) {
667 if (value1 * value2 <= 0) { 685 if (value1 * value2 <= 0) {
668 // It's an error if value1 and value2 have opposite signs or if one of t hem is zero. 686 // It's an error if value1 and value2 have opposite signs or if one of
669 // Handle this by propagating the previous value, and making it the defa ult. 687 // them is zero. Handle this by propagating the previous value, and
688 // making it the default.
670 value = value1; 689 value = value1;
671 690
672 for (; writeIndex < fillToFrame; ++writeIndex) 691 for (; writeIndex < fillToFrame; ++writeIndex)
673 values[writeIndex] = value; 692 values[writeIndex] = value;
674 } else { 693 } else {
675 float numSampleFrames = deltaTime * sampleRate; 694 float numSampleFrames = deltaTime * sampleRate;
676 // The value goes exponentially from value1 to value2 in a duration of d eltaTime 695 // The value goes exponentially from value1 to value2 in a duration of
677 // seconds according to 696 // deltaTime seconds according to
678 // 697 //
679 // v(t) = v1*(v2/v1)^((t-t1)/(t2-t1)) 698 // v(t) = v1*(v2/v1)^((t-t1)/(t2-t1))
680 // 699 //
681 // Let c be currentFrame and F be the sampleRate. Then we want to sampl e v(t) 700 // Let c be currentFrame and F be the sampleRate. Then we want to
682 // at times t = (c + k)/F for k = 0, 1, ...: 701 // sample v(t) at times t = (c + k)/F for k = 0, 1, ...:
683 // 702 //
684 // v((c+k)/F) = v1*(v2/v1)^(((c/F+k/F)-t1)/(t2-t1)) 703 // v((c+k)/F) = v1*(v2/v1)^(((c/F+k/F)-t1)/(t2-t1))
685 // = v1*(v2/v1)^((c/F-t1)/(t2-t1)) 704 // = v1*(v2/v1)^((c/F-t1)/(t2-t1))
686 // *(v2/v1)^((k/F)/(t2-t1)) 705 // *(v2/v1)^((k/F)/(t2-t1))
687 // = v1*(v2/v1)^((c/F-t1)/(t2-t1)) 706 // = v1*(v2/v1)^((c/F-t1)/(t2-t1))
688 // *[(v2/v1)^(1/(F*(t2-t1)))]^k 707 // *[(v2/v1)^(1/(F*(t2-t1)))]^k
689 // 708 //
690 // Thus, this can be written as 709 // Thus, this can be written as
691 // 710 //
692 // v((c+k)/F) = V*m^k 711 // v((c+k)/F) = V*m^k
693 // 712 //
694 // where 713 // where
695 // V = v1*(v2/v1)^((c/F-t1)/(t2-t1)) 714 // V = v1*(v2/v1)^((c/F-t1)/(t2-t1))
696 // m = (v2/v1)^(1/(F*(t2-t1))) 715 // m = (v2/v1)^(1/(F*(t2-t1)))
697 716
698 // Compute the per-sample multiplier. 717 // Compute the per-sample multiplier.
699 float multiplier = powf(value2 / value1, 1 / numSampleFrames); 718 float multiplier = powf(value2 / value1, 1 / numSampleFrames);
700 // Set the starting value of the exponential ramp. 719 // Set the starting value of the exponential ramp.
701 value = value1 * powf(value2 / value1, 720 value = value1 * powf(value2 / value1,
702 (currentFrame / sampleRate - time1) / deltaTime); 721 (currentFrame / sampleRate - time1) / deltaTime);
703 722
704 for (; writeIndex < fillToFrame; ++writeIndex) { 723 for (; writeIndex < fillToFrame; ++writeIndex) {
705 values[writeIndex] = value; 724 values[writeIndex] = value;
706 value *= multiplier; 725 value *= multiplier;
707 ++currentFrame; 726 ++currentFrame;
708 } 727 }
709 // |value| got updated one extra time in the above loop. Restore it to the last 728 // |value| got updated one extra time in the above loop. Restore it to
710 // computed value. 729 // the last computed value.
711 if (writeIndex >= 1) 730 if (writeIndex >= 1)
712 value /= multiplier; 731 value /= multiplier;
713 732
714 // Due to roundoff it's possible that value exceeds value2. Clip value to value2 if 733 // Due to roundoff it's possible that value exceeds value2. Clip value
715 // we are within 1/2 frame of time2. 734 // to value2 if we are within 1/2 frame of time2.
716 if (currentFrame > time2 * sampleRate - 0.5) 735 if (currentFrame > time2 * sampleRate - 0.5)
717 value = value2; 736 value = value2;
718 } 737 }
719 } else { 738 } else {
720 // Handle event types not requiring looking ahead to the next event. 739 // Handle event types not requiring looking ahead to the next event.
721 switch (event.getType()) { 740 switch (event.getType()) {
722 case ParamEvent::SetValue: 741 case ParamEvent::SetValue:
723 case ParamEvent::LinearRampToValue: { 742 case ParamEvent::LinearRampToValue: {
724 currentFrame = fillToEndFrame; 743 currentFrame = fillToEndFrame;
725 744
726 // Simply stay at a constant value. 745 // Simply stay at a constant value.
727 value = event.value(); 746 value = event.value();
728 747
729 for (; writeIndex < fillToFrame; ++writeIndex) 748 for (; writeIndex < fillToFrame; ++writeIndex)
730 values[writeIndex] = value; 749 values[writeIndex] = value;
731 750
732 break; 751 break;
733 } 752 }
734 753
735 case ParamEvent::ExponentialRampToValue: { 754 case ParamEvent::ExponentialRampToValue: {
736 currentFrame = fillToEndFrame; 755 currentFrame = fillToEndFrame;
737 756
738 // If we're here, we've reached the end of the ramp. If we can (becau se the 757 // If we're here, we've reached the end of the ramp. If we can
739 // start and end values have the same sign, and neither is 0), use the actual 758 // (because the start and end values have the same sign, and neither
740 // end value. If not, we have to propagate whatever we have. 759 // is 0), use the actual end value. If not, we have to propagate
760 // whatever we have.
741 if (i >= 1 && ((m_events[i - 1].value() * event.value()) > 0)) 761 if (i >= 1 && ((m_events[i - 1].value() * event.value()) > 0))
742 value = event.value(); 762 value = event.value();
743 763
744 // Simply stay at a constant value from the last time. We don't want to use the 764 // Simply stay at a constant value from the last time. We don't want
745 // value of the event in case value1 * value2 < 0. In this case we sh ould 765 // to use the value of the event in case value1 * value2 < 0. In this
746 // propagate the previous value, which is in |value|. 766 // case we should propagate the previous value, which is in |value|.
747 for (; writeIndex < fillToFrame; ++writeIndex) 767 for (; writeIndex < fillToFrame; ++writeIndex)
748 values[writeIndex] = value; 768 values[writeIndex] = value;
749 769
750 break; 770 break;
751 } 771 }
752 772
753 case ParamEvent::SetTarget: { 773 case ParamEvent::SetTarget: {
754 // Exponential approach to target value with given time constant. 774 // Exponential approach to target value with given time constant.
755 // 775 //
756 // v(t) = v2 + (v1 - v2)*exp(-(t-t1/tau)) 776 // v(t) = v2 + (v1 - v2)*exp(-(t-t1/tau))
757 // 777 //
758 778
759 float target = event.value(); 779 float target = event.value();
760 float timeConstant = event.timeConstant(); 780 float timeConstant = event.timeConstant();
761 float discreteTimeConstant = static_cast<float>( 781 float discreteTimeConstant = static_cast<float>(
762 AudioUtilities::discreteTimeConstantForSampleRate(timeConstant, 782 AudioUtilities::discreteTimeConstantForSampleRate(timeConstant,
763 controlRate)); 783 controlRate));
764 784
765 // Set the starting value correctly. This is only needed when the cur rent time 785 // Set the starting value correctly. This is only needed when the
766 // is "equal" to the start time of this event. This is to get the sam pling 786 // current time is "equal" to the start time of this event. This is
767 // correct if the start time of this automation isn't on a frame bound ary. 787 // to get the sampling correct if the start time of this automation
768 // Otherwise, we can just continue from where we left off from the pre vious 788 // isn't on a frame boundary. Otherwise, we can just continue from
769 // rendering quantum. 789 // where we left off from the previous rendering quantum.
770 { 790 {
771 double rampStartFrame = time1 * sampleRate; 791 double rampStartFrame = time1 * sampleRate;
772 // Condition is c - 1 < r <= c where c = currentFrame and r = 792 // Condition is c - 1 < r <= c where c = currentFrame and r =
773 // rampStartFrame. Compute it this way because currentFrame is unsi gned and 793 // rampStartFrame. Compute it this way because currentFrame is
774 // could be 0. 794 // unsigned and could be 0.
775 if (rampStartFrame <= currentFrame && 795 if (rampStartFrame <= currentFrame &&
776 currentFrame < rampStartFrame + 1) { 796 currentFrame < rampStartFrame + 1) {
777 value = 797 value =
778 target + 798 target +
779 (value - target) * 799 (value - target) *
780 exp(-(currentFrame / sampleRate - time1) / timeConstant); 800 exp(-(currentFrame / sampleRate - time1) / timeConstant);
781 } else { 801 } else {
782 // Otherwise, need to compute a new value bacause |value| is the l ast 802 // Otherwise, need to compute a new value bacause |value| is the
783 // computed value of SetTarget. Time has progressed by one frame, so we 803 // last computed value of SetTarget. Time has progressed by one
784 // need to update the value for the new frame. 804 // frame, so we need to update the value for the new frame.
785 value += (target - value) * discreteTimeConstant; 805 value += (target - value) * discreteTimeConstant;
786 } 806 }
787 } 807 }
788 808
789 // If the value is close enough to the target, just fill in the data w ith the 809 // If the value is close enough to the target, just fill in the data
790 // target value. 810 // with the target value.
791 if (fabs(value - target) < kSetTargetThreshold * fabs(target) || 811 if (fabs(value - target) < kSetTargetThreshold * fabs(target) ||
792 (!target && fabs(value) < kSetTargetZeroThreshold)) { 812 (!target && fabs(value) < kSetTargetZeroThreshold)) {
793 for (; writeIndex < fillToFrame; ++writeIndex) 813 for (; writeIndex < fillToFrame; ++writeIndex)
794 values[writeIndex] = target; 814 values[writeIndex] = target;
795 } else { 815 } else {
796 #if CPU(X86) || CPU(X86_64) 816 #if CPU(X86) || CPU(X86_64)
797 // Resolve recursion by expanding constants to achieve a 4-step loop unrolling. 817 // Resolve recursion by expanding constants to achieve a 4-step loop
818 // unrolling.
798 // v1 = v0 + (t - v0) * c 819 // v1 = v0 + (t - v0) * c
799 // v2 = v1 + (t - v1) * c 820 // v2 = v1 + (t - v1) * c
800 // v2 = v0 + (t - v0) * c + (t - (v0 + (t - v0) * c)) * c 821 // v2 = v0 + (t - v0) * c + (t - (v0 + (t - v0) * c)) * c
801 // v2 = v0 + (t - v0) * c + (t - v0) * c - (t - v0) * c * c 822 // v2 = v0 + (t - v0) * c + (t - v0) * c - (t - v0) * c * c
802 // v2 = v0 + (t - v0) * c * (2 - c) 823 // v2 = v0 + (t - v0) * c * (2 - c)
803 // Thus c0 = c, c1 = c*(2-c). The same logic applies to c2 and c3. 824 // Thus c0 = c, c1 = c*(2-c). The same logic applies to c2 and c3.
804 const float c0 = discreteTimeConstant; 825 const float c0 = discreteTimeConstant;
805 const float c1 = c0 * (2 - c0); 826 const float c1 = c0 * (2 - c0);
806 const float c2 = c0 * ((c0 - 3) * c0 + 3); 827 const float c2 = c0 * ((c0 - 3) * c0 + 3);
807 const float c3 = c0 * (c0 * ((4 - c0) * c0 - 6) + 4); 828 const float c3 = c0 * (c0 * ((4 - c0) * c0 - 6) + 4);
(...skipping 15 matching lines...) Expand all
823 844
824 // Update value for next iteration. 845 // Update value for next iteration.
825 value += delta * c3; 846 value += delta * c3;
826 } 847 }
827 #endif 848 #endif
828 // Serially process remaining values 849 // Serially process remaining values
829 for (; writeIndex < fillToFrame; ++writeIndex) { 850 for (; writeIndex < fillToFrame; ++writeIndex) {
830 values[writeIndex] = value; 851 values[writeIndex] = value;
831 value += (target - value) * discreteTimeConstant; 852 value += (target - value) * discreteTimeConstant;
832 } 853 }
833 // The previous loops may have updated |value| one extra time. Rese t it to 854 // The previous loops may have updated |value| one extra time.
834 // the last computed value. 855 // Reset it to the last computed value.
835 if (writeIndex >= 1) 856 if (writeIndex >= 1)
836 value = values[writeIndex - 1]; 857 value = values[writeIndex - 1];
837 currentFrame = fillToEndFrame; 858 currentFrame = fillToEndFrame;
838 } 859 }
839 break; 860 break;
840 } 861 }
841 862
842 case ParamEvent::SetValueCurve: { 863 case ParamEvent::SetValueCurve: {
843 Vector<float> curve = event.curve(); 864 Vector<float> curve = event.curve();
844 float* curveData = curve.data(); 865 float* curveData = curve.data();
845 unsigned numberOfCurvePoints = curve.size(); 866 unsigned numberOfCurvePoints = curve.size();
846 867
847 // Curve events have duration, so don't just use next event time. 868 // Curve events have duration, so don't just use next event time.
848 double duration = event.duration(); 869 double duration = event.duration();
849 // How much to step the curve index for each frame. This is basically the term 870 // How much to step the curve index for each frame. This is basically
850 // (N - 1)/Td in the specification. 871 // the term (N - 1)/Td in the specification.
851 double curvePointsPerFrame = 872 double curvePointsPerFrame =
852 (numberOfCurvePoints - 1) / duration / sampleRate; 873 (numberOfCurvePoints - 1) / duration / sampleRate;
853 874
854 if (!numberOfCurvePoints || duration <= 0 || sampleRate <= 0) { 875 if (!numberOfCurvePoints || duration <= 0 || sampleRate <= 0) {
855 // Error condition - simply propagate previous value. 876 // Error condition - simply propagate previous value.
856 currentFrame = fillToEndFrame; 877 currentFrame = fillToEndFrame;
857 for (; writeIndex < fillToFrame; ++writeIndex) 878 for (; writeIndex < fillToFrame; ++writeIndex)
858 values[writeIndex] = value; 879 values[writeIndex] = value;
859 break; 880 break;
860 } 881 }
861 882
862 // Save old values and recalculate information based on the curve's du ration 883 // Save old values and recalculate information based on the curve's
863 // instead of the next event time. 884 // duration instead of the next event time.
864 size_t nextEventFillToFrame = fillToFrame; 885 size_t nextEventFillToFrame = fillToFrame;
865 886
866 // fillToEndFrame = min(endFrame, ceil(sampleRate * (time1 + duration) )), but 887 // fillToEndFrame = min(endFrame,
867 // compute this carefully in case sampleRate*(time1 + duration) is hug e. 888 // ceil(sampleRate * (time1 + duration))),
868 // fillToEndFrame is an exclusive upper bound of the last frame to be computed, 889 // but compute this carefully in case sampleRate*(time1 + duration) is
869 // so ceil is used. 890 // huge. fillToEndFrame is an exclusive upper bound of the last frame
891 // to be computed, so ceil is used.
870 { 892 {
871 double curveEndFrame = ceil(sampleRate * (time1 + duration)); 893 double curveEndFrame = ceil(sampleRate * (time1 + duration));
872 if (endFrame > curveEndFrame) 894 if (endFrame > curveEndFrame)
873 fillToEndFrame = static_cast<size_t>(curveEndFrame); 895 fillToEndFrame = static_cast<size_t>(curveEndFrame);
874 else 896 else
875 fillToEndFrame = endFrame; 897 fillToEndFrame = endFrame;
876 } 898 }
877 899
878 // |fillToFrame| can be less than |startFrame| when the end of the 900 // |fillToFrame| can be less than |startFrame| when the end of the
879 // setValueCurve automation has been reached, but the next automation has not 901 // setValueCurve automation has been reached, but the next automation
880 // yet started. In this case, |fillToFrame| is clipped to |time1|+|dur ation| 902 // has not yet started. In this case, |fillToFrame| is clipped to
881 // above, but |startFrame| will keep increasing (because the current t ime is 903 // |time1|+|duration| above, but |startFrame| will keep increasing
882 // increasing). 904 // (because the current time is increasing).
883 fillToFrame = 905 fillToFrame =
884 (fillToEndFrame < startFrame) ? 0 : fillToEndFrame - startFrame; 906 (fillToEndFrame < startFrame) ? 0 : fillToEndFrame - startFrame;
885 fillToFrame = 907 fillToFrame =
886 std::min(fillToFrame, static_cast<size_t>(numberOfValues)); 908 std::min(fillToFrame, static_cast<size_t>(numberOfValues));
887 909
888 // Index into the curve data using a floating-point value. 910 // Index into the curve data using a floating-point value.
889 // We're scaling the number of curve points by the duration (see curve PointsPerFrame). 911 // We're scaling the number of curve points by the duration (see
912 // curvePointsPerFrame).
890 double curveVirtualIndex = 0; 913 double curveVirtualIndex = 0;
891 if (time1 < currentFrame / sampleRate) { 914 if (time1 < currentFrame / sampleRate) {
892 // Index somewhere in the middle of the curve data. 915 // Index somewhere in the middle of the curve data.
893 // Don't use timeToSampleFrame() since we want the exact floating-po int frame. 916 // Don't use timeToSampleFrame() since we want the exact
917 // floating-point frame.
894 double frameOffset = currentFrame - time1 * sampleRate; 918 double frameOffset = currentFrame - time1 * sampleRate;
895 curveVirtualIndex = curvePointsPerFrame * frameOffset; 919 curveVirtualIndex = curvePointsPerFrame * frameOffset;
896 } 920 }
897 921
898 // Set the default value in case fillToFrame is 0. 922 // Set the default value in case fillToFrame is 0.
899 value = curveData[numberOfCurvePoints - 1]; 923 value = curveData[numberOfCurvePoints - 1];
900 924
901 // Render the stretched curve data using linear interpolation. Oversa mpled 925 // Render the stretched curve data using linear interpolation.
902 // curve data can be provided if sharp discontinuities are desired. 926 // Oversampled curve data can be provided if sharp discontinuities are
927 // desired.
903 unsigned k = 0; 928 unsigned k = 0;
904 #if CPU(X86) || CPU(X86_64) 929 #if CPU(X86) || CPU(X86_64)
905 const __m128 vCurveVirtualIndex = _mm_set_ps1(curveVirtualIndex); 930 const __m128 vCurveVirtualIndex = _mm_set_ps1(curveVirtualIndex);
906 const __m128 vCurvePointsPerFrame = _mm_set_ps1(curvePointsPerFrame); 931 const __m128 vCurvePointsPerFrame = _mm_set_ps1(curvePointsPerFrame);
907 const __m128 vNumberOfCurvePointsM1 = 932 const __m128 vNumberOfCurvePointsM1 =
908 _mm_set_ps1(numberOfCurvePoints - 1); 933 _mm_set_ps1(numberOfCurvePoints - 1);
909 const __m128 vN1 = _mm_set_ps1(1.0f); 934 const __m128 vN1 = _mm_set_ps1(1.0f);
910 const __m128 vN4 = _mm_set_ps1(4.0f); 935 const __m128 vN4 = _mm_set_ps1(4.0f);
911 936
912 __m128 vK = _mm_set_ps(3, 2, 1, 0); 937 __m128 vK = _mm_set_ps(3, 2, 1, 0);
913 int aCurveIndex0[4]; 938 int aCurveIndex0[4];
914 int aCurveIndex1[4]; 939 int aCurveIndex1[4];
915 940
916 // Truncate loop steps to multiple of 4 941 // Truncate loop steps to multiple of 4
917 unsigned truncatedSteps = ((fillToFrame - writeIndex) / 4) * 4; 942 unsigned truncatedSteps = ((fillToFrame - writeIndex) / 4) * 4;
918 unsigned fillToFrameTrunc = writeIndex + truncatedSteps; 943 unsigned fillToFrameTrunc = writeIndex + truncatedSteps;
919 for (; writeIndex < fillToFrameTrunc; writeIndex += 4) { 944 for (; writeIndex < fillToFrameTrunc; writeIndex += 4) {
920 // Compute current index this way to minimize round-off that would h ave 945 // Compute current index this way to minimize round-off that would
921 // occurred by incrementing the index by curvePointsPerFrame. 946 // have occurred by incrementing the index by curvePointsPerFrame.
922 __m128 vCurrentVirtualIndex = _mm_add_ps( 947 __m128 vCurrentVirtualIndex = _mm_add_ps(
923 vCurveVirtualIndex, _mm_mul_ps(vK, vCurvePointsPerFrame)); 948 vCurveVirtualIndex, _mm_mul_ps(vK, vCurvePointsPerFrame));
924 vK = _mm_add_ps(vK, vN4); 949 vK = _mm_add_ps(vK, vN4);
925 950
926 // Clamp index to the last element of the array. 951 // Clamp index to the last element of the array.
927 __m128i vCurveIndex0 = _mm_cvttps_epi32( 952 __m128i vCurveIndex0 = _mm_cvttps_epi32(
928 _mm_min_ps(vCurrentVirtualIndex, vNumberOfCurvePointsM1)); 953 _mm_min_ps(vCurrentVirtualIndex, vNumberOfCurvePointsM1));
929 __m128i vCurveIndex1 = _mm_cvttps_epi32(_mm_min_ps( 954 __m128i vCurveIndex1 = _mm_cvttps_epi32(_mm_min_ps(
930 _mm_add_ps(vCurrentVirtualIndex, vN1), vNumberOfCurvePointsM1)); 955 _mm_add_ps(vCurrentVirtualIndex, vN1), vNumberOfCurvePointsM1));
931 956
932 // Linearly interpolate between the two nearest curve points. |delt a| is 957 // Linearly interpolate between the two nearest curve points.
933 // clamped to 1 because currentVirtualIndex can exceed curveIndex0 b y more 958 // |delta| is clamped to 1 because currentVirtualIndex can exceed
934 // than one. This can happen when we reached the end of the curve b ut still 959 // curveIndex0 by more than one. This can happen when we reached
935 // need values to fill out the current rendering quantum. 960 // the end of the curve but still need values to fill out the
961 // current rendering quantum.
936 _mm_storeu_si128((__m128i*)aCurveIndex0, vCurveIndex0); 962 _mm_storeu_si128((__m128i*)aCurveIndex0, vCurveIndex0);
937 _mm_storeu_si128((__m128i*)aCurveIndex1, vCurveIndex1); 963 _mm_storeu_si128((__m128i*)aCurveIndex1, vCurveIndex1);
938 __m128 vC0 = _mm_set_ps( 964 __m128 vC0 = _mm_set_ps(
939 curveData[aCurveIndex0[3]], curveData[aCurveIndex0[2]], 965 curveData[aCurveIndex0[3]], curveData[aCurveIndex0[2]],
940 curveData[aCurveIndex0[1]], curveData[aCurveIndex0[0]]); 966 curveData[aCurveIndex0[1]], curveData[aCurveIndex0[0]]);
941 __m128 vC1 = _mm_set_ps( 967 __m128 vC1 = _mm_set_ps(
942 curveData[aCurveIndex1[3]], curveData[aCurveIndex1[2]], 968 curveData[aCurveIndex1[3]], curveData[aCurveIndex1[2]],
943 curveData[aCurveIndex1[1]], curveData[aCurveIndex1[0]]); 969 curveData[aCurveIndex1[1]], curveData[aCurveIndex1[0]]);
944 __m128 vDelta = _mm_min_ps( 970 __m128 vDelta = _mm_min_ps(
945 _mm_sub_ps(vCurrentVirtualIndex, _mm_cvtepi32_ps(vCurveIndex0)), 971 _mm_sub_ps(vCurrentVirtualIndex, _mm_cvtepi32_ps(vCurveIndex0)),
946 vN1); 972 vN1);
947 973
948 __m128 vValue = 974 __m128 vValue =
949 _mm_add_ps(vC0, _mm_mul_ps(_mm_sub_ps(vC1, vC0), vDelta)); 975 _mm_add_ps(vC0, _mm_mul_ps(_mm_sub_ps(vC1, vC0), vDelta));
950 976
951 _mm_storeu_ps(values + writeIndex, vValue); 977 _mm_storeu_ps(values + writeIndex, vValue);
952 } 978 }
953 // Pass along k to the serial loop. 979 // Pass along k to the serial loop.
954 k = truncatedSteps; 980 k = truncatedSteps;
955 // If the above loop was run, pass along the last computed value. 981 // If the above loop was run, pass along the last computed value.
956 if (truncatedSteps > 0) { 982 if (truncatedSteps > 0) {
957 value = values[writeIndex - 1]; 983 value = values[writeIndex - 1];
958 } 984 }
959 #endif 985 #endif
960 for (; writeIndex < fillToFrame; ++writeIndex, ++k) { 986 for (; writeIndex < fillToFrame; ++writeIndex, ++k) {
961 // Compute current index this way to minimize round-off that would h ave 987 // Compute current index this way to minimize round-off that would
962 // occurred by incrementing the index by curvePointsPerFrame. 988 // have occurred by incrementing the index by curvePointsPerFrame.
963 double currentVirtualIndex = 989 double currentVirtualIndex =
964 curveVirtualIndex + k * curvePointsPerFrame; 990 curveVirtualIndex + k * curvePointsPerFrame;
965 unsigned curveIndex0; 991 unsigned curveIndex0;
966 992
967 // Clamp index to the last element of the array. 993 // Clamp index to the last element of the array.
968 if (currentVirtualIndex < numberOfCurvePoints) { 994 if (currentVirtualIndex < numberOfCurvePoints) {
969 curveIndex0 = static_cast<unsigned>(currentVirtualIndex); 995 curveIndex0 = static_cast<unsigned>(currentVirtualIndex);
970 } else { 996 } else {
971 curveIndex0 = numberOfCurvePoints - 1; 997 curveIndex0 = numberOfCurvePoints - 1;
972 } 998 }
973 999
974 unsigned curveIndex1 = 1000 unsigned curveIndex1 =
975 std::min(curveIndex0 + 1, numberOfCurvePoints - 1); 1001 std::min(curveIndex0 + 1, numberOfCurvePoints - 1);
976 1002
977 // Linearly interpolate between the two nearest curve points. |delt a| is 1003 // Linearly interpolate between the two nearest curve points.
978 // clamped to 1 because currentVirtualIndex can exceed curveIndex0 b y more 1004 // |delta| is clamped to 1 because currentVirtualIndex can exceed
979 // than one. This can happen when we reached the end of the curve b ut still 1005 // curveIndex0 by more than one. This can happen when we reached
980 // need values to fill out the current rendering quantum. 1006 // the end of the curve but still need values to fill out the
1007 // current rendering quantum.
981 DCHECK_LT(curveIndex0, numberOfCurvePoints); 1008 DCHECK_LT(curveIndex0, numberOfCurvePoints);
982 DCHECK_LT(curveIndex1, numberOfCurvePoints); 1009 DCHECK_LT(curveIndex1, numberOfCurvePoints);
983 float c0 = curveData[curveIndex0]; 1010 float c0 = curveData[curveIndex0];
984 float c1 = curveData[curveIndex1]; 1011 float c1 = curveData[curveIndex1];
985 double delta = std::min(currentVirtualIndex - curveIndex0, 1.0); 1012 double delta = std::min(currentVirtualIndex - curveIndex0, 1.0);
986 1013
987 value = c0 + (c1 - c0) * delta; 1014 value = c0 + (c1 - c0) * delta;
988 1015
989 values[writeIndex] = value; 1016 values[writeIndex] = value;
990 } 1017 }
991 1018
992 // If there's any time left after the duration of this event and the s tart 1019 // If there's any time left after the duration of this event and the
993 // of the next, then just propagate the last value of the curveData. 1020 // start of the next, then just propagate the last value of the
1021 // curveData.
994 if (writeIndex < nextEventFillToFrame) 1022 if (writeIndex < nextEventFillToFrame)
995 value = curveData[numberOfCurvePoints - 1]; 1023 value = curveData[numberOfCurvePoints - 1];
996 for (; writeIndex < nextEventFillToFrame; ++writeIndex) 1024 for (; writeIndex < nextEventFillToFrame; ++writeIndex)
997 values[writeIndex] = value; 1025 values[writeIndex] = value;
998 1026
999 // Re-adjust current time 1027 // Re-adjust current time
1000 currentFrame += nextEventFillToFrame; 1028 currentFrame += nextEventFillToFrame;
1001 1029
1002 break; 1030 break;
1003 } 1031 }
1004 case ParamEvent::LastType: 1032 case ParamEvent::LastType:
1005 ASSERT_NOT_REACHED(); 1033 ASSERT_NOT_REACHED();
1006 break; 1034 break;
1007 } 1035 }
1008 } 1036 }
1009 } 1037 }
1010 1038
1011 // If we skipped over any events (because they are in the past), we can 1039 // If we skipped over any events (because they are in the past), we can
1012 // remove them so we don't have to check them ever again. (This MUST be 1040 // remove them so we don't have to check them ever again. (This MUST be
1013 // running with the m_events lock so we can safely modify the m_events 1041 // running with the m_events lock so we can safely modify the m_events
1014 // array.) 1042 // array.)
1015 if (lastSkippedEventIndex > 0) 1043 if (lastSkippedEventIndex > 0)
1016 m_events.remove(0, lastSkippedEventIndex - 1); 1044 m_events.remove(0, lastSkippedEventIndex - 1);
1017 1045
1018 // If there's any time left after processing the last event then just propagat e the last value 1046 // If there's any time left after processing the last event then just
1019 // to the end of the values buffer. 1047 // propagate the last value to the end of the values buffer.
1020 for (; writeIndex < numberOfValues; ++writeIndex) 1048 for (; writeIndex < numberOfValues; ++writeIndex)
1021 values[writeIndex] = value; 1049 values[writeIndex] = value;
1022 1050
1023 // This value is used to set the .value attribute of the AudioParam. it shoul d be the last 1051 // This value is used to set the .value attribute of the AudioParam. it
1024 // computed value. 1052 // should be the last computed value.
1025 return values[numberOfValues - 1]; 1053 return values[numberOfValues - 1];
1026 } 1054 }
1027 1055
1028 } // namespace blink 1056 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698