| 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 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 218 exceptionState.throwDOMException( | 218 exceptionState.throwDOMException( |
| 219 InvalidStateError, | 219 InvalidStateError, |
| 220 ExceptionMessages::indexExceedsMinimumBound( | 220 ExceptionMessages::indexExceedsMinimumBound( |
| 221 "curve length", | 221 "curve length", |
| 222 curve->length(), | 222 curve->length(), |
| 223 2U)); | 223 2U)); |
| 224 return; | 224 return; |
| 225 } | 225 } |
| 226 | 226 |
| 227 insertEvent(ParamEvent::createSetValueCurveEvent(curve, time, duration), exc
eptionState); | 227 insertEvent(ParamEvent::createSetValueCurveEvent(curve, time, duration), exc
eptionState); |
| 228 |
| 229 // Insert a setValueAtTime event too to establish an event so that all |
| 230 // following events will process from the end of the curve instead of the |
| 231 // beginning. |
| 232 insertEvent(ParamEvent::createSetValueEvent(curve->data()[curve->length() -
1], time + duration), exceptionState); |
| 228 } | 233 } |
| 229 | 234 |
| 230 void AudioParamTimeline::insertEvent(const ParamEvent& event, ExceptionState& ex
ceptionState) | 235 void AudioParamTimeline::insertEvent(const ParamEvent& event, ExceptionState& ex
ceptionState) |
| 231 { | 236 { |
| 232 ASSERT(isMainThread()); | 237 ASSERT(isMainThread()); |
| 233 | 238 |
| 234 // Sanity check the event. Be super careful we're not getting infected with
NaN or Inf. These | 239 // Sanity check the event. Be super careful we're not getting infected with
NaN or Inf. These |
| 235 // should have been handled by the caller. | 240 // should have been handled by the caller. |
| 236 bool isValid = event.getType() < ParamEvent::LastType | 241 bool isValid = event.getType() < ParamEvent::LastType |
| 237 && std::isfinite(event.value()) | 242 && std::isfinite(event.value()) |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 424 | 429 |
| 425 // Go through each event and render the value buffer where the times overlap
, | 430 // Go through each event and render the value buffer where the times overlap
, |
| 426 // stopping when we've rendered all the requested values. | 431 // stopping when we've rendered all the requested values. |
| 427 int n = m_events.size(); | 432 int n = m_events.size(); |
| 428 int lastSkippedEventIndex = 0; | 433 int lastSkippedEventIndex = 0; |
| 429 for (int i = 0; i < n && writeIndex < numberOfValues; ++i) { | 434 for (int i = 0; i < n && writeIndex < numberOfValues; ++i) { |
| 430 ParamEvent& event = m_events[i]; | 435 ParamEvent& event = m_events[i]; |
| 431 ParamEvent* nextEvent = i < n - 1 ? &(m_events[i + 1]) : 0; | 436 ParamEvent* nextEvent = i < n - 1 ? &(m_events[i + 1]) : 0; |
| 432 | 437 |
| 433 // Wait until we get a more recent event. | 438 // Wait until we get a more recent event. |
| 439 // |
| 440 // WARNING: due to round-off it might happen that nextEvent->time() is |
| 441 // just larger than currentFrame/sampleRate. This means that we will en
d |
| 442 // up running the |event| again. The code below had better be prepared |
| 443 // for this case! What should happen is the fillToFrame should be 0 so |
| 444 // that while the event is actually run again, nothing actually gets |
| 445 // computed, and we move on to the next event. |
| 446 // |
| 447 // An example of this case is setValueCurveAtTime. The time at which |
| 448 // setValueCurveAtTime ends (and the setValueAtTime begins) might be |
| 449 // just past currentTime/sampleRate. Then setValueCurveAtTime will be |
| 450 // processed again before advancing to setValueAtTime. The number of |
| 451 // frames to be processed should be zero in this case. |
| 434 if (nextEvent && nextEvent->time() < currentFrame / sampleRate) { | 452 if (nextEvent && nextEvent->time() < currentFrame / sampleRate) { |
| 435 // But if the current event is a SetValue event and the event time i
s between | 453 // But if the current event is a SetValue event and the event time i
s between |
| 436 // currentFrame - 1 and curentFrame (in time). we don't want to skip
it. If we do skip | 454 // currentFrame - 1 and curentFrame (in time). we don't want to skip
it. If we do skip |
| 437 // it, the SetValue event is completely skipped and not applied, whi
ch is wrong. Other | 455 // it, the SetValue event is completely skipped and not applied, whi
ch is wrong. Other |
| 438 // events don't have this problem. (Because currentFrame is unsigne
d, we do the time | 456 // events don't have this problem. (Because currentFrame is unsigne
d, we do the time |
| 439 // check in this funny, but equivalent way.) | 457 // check in this funny, but equivalent way.) |
| 440 double eventFrame = event.time() * sampleRate; | 458 double eventFrame = event.time() * sampleRate; |
| 441 | 459 |
| 442 // Condition is currentFrame - 1 < eventFrame <= currentFrame, but c
urrentFrame is | 460 // Condition is currentFrame - 1 < eventFrame <= currentFrame, but c
urrentFrame is |
| 443 // unsigned and could be 0, so use currentFrame < eventFrame + 1 ins
tead. | 461 // unsigned and could be 0, so use currentFrame < eventFrame + 1 ins
tead. |
| (...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 868 } | 886 } |
| 869 | 887 |
| 870 // If there's any time left after the duration of this event
and the start | 888 // If there's any time left after the duration of this event
and the start |
| 871 // of the next, then just propagate the last value of the cu
rveData. | 889 // of the next, then just propagate the last value of the cu
rveData. |
| 872 if (writeIndex < nextEventFillToFrame) | 890 if (writeIndex < nextEventFillToFrame) |
| 873 value = curveData[numberOfCurvePoints - 1]; | 891 value = curveData[numberOfCurvePoints - 1]; |
| 874 for (; writeIndex < nextEventFillToFrame; ++writeIndex) | 892 for (; writeIndex < nextEventFillToFrame; ++writeIndex) |
| 875 values[writeIndex] = value; | 893 values[writeIndex] = value; |
| 876 | 894 |
| 877 // Re-adjust current time | 895 // Re-adjust current time |
| 878 currentFrame = nextEventFillToFrame; | 896 currentFrame += nextEventFillToFrame; |
| 879 | 897 |
| 880 break; | 898 break; |
| 881 } | 899 } |
| 882 case ParamEvent::LastType: | 900 case ParamEvent::LastType: |
| 883 ASSERT_NOT_REACHED(); | 901 ASSERT_NOT_REACHED(); |
| 884 break; | 902 break; |
| 885 } | 903 } |
| 886 } | 904 } |
| 887 } | 905 } |
| 888 | 906 |
| 889 // If we skipped over any events (because they are in the past), we can | 907 // If we skipped over any events (because they are in the past), we can |
| 890 // remove them so we don't have to check them ever again. (This MUST be | 908 // remove them so we don't have to check them ever again. (This MUST be |
| 891 // running with the m_events lock so we can safely modify the m_events | 909 // running with the m_events lock so we can safely modify the m_events |
| 892 // array.) | 910 // array.) |
| 893 if (lastSkippedEventIndex > 0) | 911 if (lastSkippedEventIndex > 0) |
| 894 m_events.remove(0, lastSkippedEventIndex - 1); | 912 m_events.remove(0, lastSkippedEventIndex - 1); |
| 895 | 913 |
| 896 // If there's any time left after processing the last event then just propag
ate the last value | 914 // If there's any time left after processing the last event then just propag
ate the last value |
| 897 // to the end of the values buffer. | 915 // to the end of the values buffer. |
| 898 for (; writeIndex < numberOfValues; ++writeIndex) | 916 for (; writeIndex < numberOfValues; ++writeIndex) |
| 899 values[writeIndex] = value; | 917 values[writeIndex] = value; |
| 900 | 918 |
| 901 // This value is used to set the .value attribute of the AudioParam. it sho
uld be the last | 919 // This value is used to set the .value attribute of the AudioParam. it sho
uld be the last |
| 902 // computed value. | 920 // computed value. |
| 903 return values[numberOfValues - 1]; | 921 return values[numberOfValues - 1]; |
| 904 } | 922 } |
| 905 | 923 |
| 906 } // namespace blink | 924 } // namespace blink |
| 907 | 925 |
| OLD | NEW |