OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2011 Google Inc. All rights reserved. | 2 * Copyright (C) 2011 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
413 double eventFrame = event.time() * sampleRate; | 413 double eventFrame = event.time() * sampleRate; |
414 | 414 |
415 // Condition is currentFrame - 1 < eventFrame <= currentFrame, but c
urrentFrame is | 415 // Condition is currentFrame - 1 < eventFrame <= currentFrame, but c
urrentFrame is |
416 // unsigned and could be 0, so use currentFrame < eventFrame + 1 ins
tead. | 416 // unsigned and could be 0, so use currentFrame < eventFrame + 1 ins
tead. |
417 if (!((event.getType() == ParamEvent::SetValue | 417 if (!((event.getType() == ParamEvent::SetValue |
418 && (eventFrame <= currentFrame) | 418 && (eventFrame <= currentFrame) |
419 && (currentFrame < eventFrame + 1)))) | 419 && (currentFrame < eventFrame + 1)))) |
420 continue; | 420 continue; |
421 } | 421 } |
422 | 422 |
| 423 // If there's no next event, set nextEventType to LastType to indicate t
hat. |
| 424 ParamEvent::Type nextEventType = nextEvent ? static_cast<ParamEvent::Typ
e>(nextEvent->getType()) : ParamEvent::LastType; |
| 425 |
| 426 // If the current event is SetTarget and the next event is a LinearRampT
oValue or |
| 427 // ExponentialRampToValue, special handling is needed. In this case, th
e linear and |
| 428 // exponential ramp should start at wherever the SetTarget processing ha
s reached. |
| 429 if (event.getType() == ParamEvent::SetTarget |
| 430 && (nextEventType == ParamEvent::LinearRampToValue |
| 431 || nextEventType == ParamEvent::ExponentialRampToValue)) { |
| 432 // Replace the SetTarget with a SetValue to set the starting time an
d value for the ramp |
| 433 // using the current frame. We need to update |value| appropriately
depending on |
| 434 // whether the ramp has started or not. |
| 435 // |
| 436 // If SetTarget starts somewhere between currentFrame - 1 and curren
tFrame, we directly |
| 437 // compute the value it would have at currentFrame. If not, we upda
te the value from |
| 438 // the value from currentFrame - 1. |
| 439 // |
| 440 // Can't use the condition currentFrame - 1 <= t0 * sampleRate <= cu
rrentFrame because |
| 441 // currentFrame is unsigned and could be 0. Instead, compute the co
ndition this way, |
| 442 // where f = currentFrame and Fs = sampleRate: |
| 443 // |
| 444 // f - 1 <= t0 * Fs <= f |
| 445 // 2 * f - 2 <= 2 * Fs * t0 <= 2 * f |
| 446 // -2 <= 2 * Fs * t0 - 2 * f <= 0 |
| 447 // -1 <= 2 * Fs * t0 - 2 * f + 1 <= 1 |
| 448 // abs(2 * Fs * t0 - 2 * f + 1) <= 1 |
| 449 if (fabs(2 * sampleRate * event.time() - 2 * currentFrame + 1) <= 1)
{ |
| 450 // SetTarget is starting somewhere between currentFrame - 1 and |
| 451 // currentFrame. Compute the value the SetTarget would have at t
he currentFrame. |
| 452 value = event.value() + (value - event.value()) * exp(-(currentF
rame / sampleRate - event.time()) / event.timeConstant()); |
| 453 } else { |
| 454 // SetTarget has already started. Update |value| one frame beca
use it's the value from |
| 455 // the previous frame. |
| 456 float discreteTimeConstant = static_cast<float>(AudioUtilities::
discreteTimeConstantForSampleRate( |
| 457 event.timeConstant(), controlRate)); |
| 458 value += (event.value() - value) * discreteTimeConstant; |
| 459 } |
| 460 m_events[i] = ParamEvent::createSetValueEvent(value, currentFrame /
sampleRate); |
| 461 } |
| 462 |
423 float value1 = event.value(); | 463 float value1 = event.value(); |
424 double time1 = event.time(); | 464 double time1 = event.time(); |
425 | 465 |
426 float value2 = nextEvent ? nextEvent->value() : value1; | 466 float value2 = nextEvent ? nextEvent->value() : value1; |
427 double time2 = nextEvent ? nextEvent->time() : endFrame / sampleRate + 1
; | 467 double time2 = nextEvent ? nextEvent->time() : endFrame / sampleRate + 1
; |
428 | 468 |
429 double deltaTime = time2 - time1; | 469 double deltaTime = time2 - time1; |
430 float k = deltaTime > 0 ? 1 / deltaTime : 0; | 470 float k = deltaTime > 0 ? 1 / deltaTime : 0; |
431 | 471 |
432 // |fillToEndFrame| is the exclusive upper bound of the last frame to be
computed for this | 472 // |fillToEndFrame| is the exclusive upper bound of the last frame to be
computed for this |
433 // event. It's either the last desired frame (|endFrame|) or derived fr
om the end time of | 473 // event. It's either the last desired frame (|endFrame|) or derived fr
om the end time of |
434 // the next event (time2). We compute ceil(time2*sampleRate) because fil
lToEndFrame is the | 474 // the next event (time2). We compute ceil(time2*sampleRate) because fil
lToEndFrame is the |
435 // exclusive upper bound. Consider the case where |startFrame| = 128 an
d time2 = 128.1 | 475 // exclusive upper bound. Consider the case where |startFrame| = 128 an
d time2 = 128.1 |
436 // (assuming sampleRate = 1). Since time2 is greater than 128, we want
to output a value | 476 // (assuming sampleRate = 1). Since time2 is greater than 128, we want
to output a value |
437 // for frame 128. This requires that fillToEndFrame be at least 129. T
his is achieved by | 477 // for frame 128. This requires that fillToEndFrame be at least 129. T
his is achieved by |
438 // ceil(time2). | 478 // ceil(time2). |
439 // | 479 // |
440 // However, time2 can be very large, so compute this carefully in the ca
se where time2 | 480 // However, time2 can be very large, so compute this carefully in the ca
se where time2 |
441 // exceeds the size of a size_t. | 481 // exceeds the size of a size_t. |
442 | 482 |
443 size_t fillToEndFrame = endFrame; | 483 size_t fillToEndFrame = endFrame; |
444 if (endFrame > time2 * sampleRate) | 484 if (endFrame > time2 * sampleRate) |
445 fillToEndFrame = static_cast<size_t>(ceil(time2 * sampleRate)); | 485 fillToEndFrame = static_cast<size_t>(ceil(time2 * sampleRate)); |
446 | 486 |
447 ASSERT(fillToEndFrame >= startFrame); | 487 ASSERT(fillToEndFrame >= startFrame); |
448 size_t fillToFrame = fillToEndFrame - startFrame; | 488 size_t fillToFrame = fillToEndFrame - startFrame; |
449 fillToFrame = std::min(fillToFrame, static_cast<size_t>(numberOfValues))
; | 489 fillToFrame = std::min(fillToFrame, static_cast<size_t>(numberOfValues))
; |
450 | 490 |
451 ParamEvent::Type nextEventType = nextEvent ? static_cast<ParamEvent::Typ
e>(nextEvent->getType()) : ParamEvent::LastType /* unknown */; | |
452 | |
453 // First handle linear and exponential ramps which require looking ahead
to the next event. | 491 // First handle linear and exponential ramps which require looking ahead
to the next event. |
454 if (nextEventType == ParamEvent::LinearRampToValue) { | 492 if (nextEventType == ParamEvent::LinearRampToValue) { |
455 const float valueDelta = value2 - value1; | 493 const float valueDelta = value2 - value1; |
456 #if CPU(X86) || CPU(X86_64) | 494 #if CPU(X86) || CPU(X86_64) |
457 // Minimize in-loop operations. Calculate starting value and increme
nt. Next step: value += inc. | 495 // Minimize in-loop operations. Calculate starting value and increme
nt. Next step: value += inc. |
458 // value = value1 + (currentFrame/sampleRate - time1) * k * (value2
- value1); | 496 // value = value1 + (currentFrame/sampleRate - time1) * k * (value2
- value1); |
459 // inc = 4 / sampleRate * k * (value2 - value1); | 497 // inc = 4 / sampleRate * k * (value2 - value1); |
460 // Resolve recursion by expanding constants to achieve a 4-step loop
unrolling. | 498 // Resolve recursion by expanding constants to achieve a 4-step loop
unrolling. |
461 // value = value1 + ((currentFrame/sampleRate - time1) + i * sample
FrameTimeIncr) * k * (value2 -value1), i in 0..3 | 499 // value = value1 + ((currentFrame/sampleRate - time1) + i * sample
FrameTimeIncr) * k * (value2 -value1), i in 0..3 |
462 __m128 vValue = _mm_mul_ps(_mm_set_ps1(1 / sampleRate), _mm_set_ps(3
, 2, 1, 0)); | 500 __m128 vValue = _mm_mul_ps(_mm_set_ps1(1 / sampleRate), _mm_set_ps(3
, 2, 1, 0)); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
529 | 567 |
530 for (; writeIndex < fillToFrame; ++writeIndex) { | 568 for (; writeIndex < fillToFrame; ++writeIndex) { |
531 values[writeIndex] = value; | 569 values[writeIndex] = value; |
532 value *= multiplier; | 570 value *= multiplier; |
533 ++currentFrame; | 571 ++currentFrame; |
534 } | 572 } |
535 // |value| got updated one extra time in the above loop. Restor
e it to the last | 573 // |value| got updated one extra time in the above loop. Restor
e it to the last |
536 // computed value. | 574 // computed value. |
537 if (writeIndex >= 1) | 575 if (writeIndex >= 1) |
538 value /= multiplier; | 576 value /= multiplier; |
| 577 |
| 578 // Due to roundoff it's possible that value exceeds value2. Cli
p value to value2 if |
| 579 // we are within 1/2 frame of time2. |
| 580 if (currentFrame > time2 * sampleRate - 0.5) |
| 581 value = value2; |
539 } | 582 } |
540 } else { | 583 } else { |
541 // Handle event types not requiring looking ahead to the next event. | 584 // Handle event types not requiring looking ahead to the next event. |
542 switch (event.getType()) { | 585 switch (event.getType()) { |
543 case ParamEvent::SetValue: | 586 case ParamEvent::SetValue: |
544 case ParamEvent::LinearRampToValue: | 587 case ParamEvent::LinearRampToValue: |
545 { | 588 { |
546 currentFrame = fillToEndFrame; | 589 currentFrame = fillToEndFrame; |
547 | 590 |
548 // Simply stay at a constant value. | 591 // Simply stay at a constant value. |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
815 for (; writeIndex < numberOfValues; ++writeIndex) | 858 for (; writeIndex < numberOfValues; ++writeIndex) |
816 values[writeIndex] = value; | 859 values[writeIndex] = value; |
817 | 860 |
818 // This value is used to set the .value attribute of the AudioParam. it sho
uld be the last | 861 // This value is used to set the .value attribute of the AudioParam. it sho
uld be the last |
819 // computed value. | 862 // computed value. |
820 return values[numberOfValues - 1]; | 863 return values[numberOfValues - 1]; |
821 } | 864 } |
822 | 865 |
823 } // namespace blink | 866 } // namespace blink |
824 | 867 |
OLD | NEW |