| 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 13 matching lines...) Expand all Loading... |
| 24 */ | 24 */ |
| 25 | 25 |
| 26 #include "config.h" | 26 #include "config.h" |
| 27 #if ENABLE(WEB_AUDIO) | 27 #if ENABLE(WEB_AUDIO) |
| 28 #include "modules/webaudio/AudioParamTimeline.h" | 28 #include "modules/webaudio/AudioParamTimeline.h" |
| 29 | 29 |
| 30 #include "bindings/core/v8/ExceptionState.h" | 30 #include "bindings/core/v8/ExceptionState.h" |
| 31 #include "core/dom/ExceptionCode.h" | 31 #include "core/dom/ExceptionCode.h" |
| 32 #include "platform/FloatConversion.h" | 32 #include "platform/FloatConversion.h" |
| 33 #include "platform/audio/AudioUtilities.h" | 33 #include "platform/audio/AudioUtilities.h" |
| 34 #include "wtf/CPU.h" |
| 34 #include "wtf/MathExtras.h" | 35 #include "wtf/MathExtras.h" |
| 35 #include <algorithm> | 36 #include <algorithm> |
| 36 | 37 |
| 38 #if CPU(X86) || CPU(X86_64) |
| 39 #include <emmintrin.h> |
| 40 #endif |
| 41 |
| 37 namespace blink { | 42 namespace blink { |
| 38 | 43 |
| 39 static bool isPositiveAudioParamValue(float value, ExceptionState& exceptionStat
e) | 44 static bool isPositiveAudioParamValue(float value, ExceptionState& exceptionStat
e) |
| 40 { | 45 { |
| 41 if (value > 0) | 46 if (value > 0) |
| 42 return true; | 47 return true; |
| 43 | 48 |
| 44 // Use denorm_min() in error message to make it clear what the mininum posit
ive value is. The | 49 // Use denorm_min() in error message to make it clear what the mininum posit
ive value is. The |
| 45 // Javascript API uses doubles, which gets converted to floats, sometimes ca
using an underflow. | 50 // Javascript API uses doubles, which gets converted to floats, sometimes ca
using an underflow. |
| 46 // This is confusing if the user specified a small non-zero (double) value t
hat underflowed to | 51 // This is confusing if the user specified a small non-zero (double) value t
hat underflowed to |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 | 347 |
| 343 case ParamEvent::SetTarget: | 348 case ParamEvent::SetTarget: |
| 344 { | 349 { |
| 345 currentTime = fillToTime; | 350 currentTime = fillToTime; |
| 346 | 351 |
| 347 // Exponential approach to target value with given time cons
tant. | 352 // Exponential approach to target value with given time cons
tant. |
| 348 float target = event.value(); | 353 float target = event.value(); |
| 349 float timeConstant = event.timeConstant(); | 354 float timeConstant = event.timeConstant(); |
| 350 float discreteTimeConstant = static_cast<float>(AudioUtiliti
es::discreteTimeConstantForSampleRate(timeConstant, controlRate)); | 355 float discreteTimeConstant = static_cast<float>(AudioUtiliti
es::discreteTimeConstantForSampleRate(timeConstant, controlRate)); |
| 351 | 356 |
| 357 #if CPU(X86) || CPU(X86_64) |
| 358 // Resolve recursion by expanding constants to achieve a 4-s
tep loop unrolling. |
| 359 // v1 = v0 + (t - v0) * c |
| 360 // v2 = v1 + (t - v1) * c |
| 361 // v2 = v0 + (t - v0) * c + (t - (v0 + (t - v0) * c)) * c |
| 362 // v2 = v0 + (t - v0) * c + (t - v0) * c - (t - v0) * c * c |
| 363 // v2 = v0 + (t - v0) * c * (2 - c) |
| 364 // Thus c0 = c, c1 = c*(2-c). The same logic applies to c2 a
nd c3. |
| 365 const float c0 = discreteTimeConstant; |
| 366 const float c1 = c0 * (2 - c0); |
| 367 const float c2 = c0 * ((c0 - 3) * c0 + 3); |
| 368 const float c3 = c0 * (c0 * ((4 - c0) * c0 - 6) + 4); |
| 369 |
| 370 float delta; |
| 371 __m128 vC = _mm_set_ps(c2, c1, c0, 0); |
| 372 __m128 vDelta, vValue, vResult; |
| 373 |
| 374 // Process 4 loop steps. |
| 375 unsigned fillToFrameTrunc = writeIndex + ((fillToFrame - wri
teIndex) / 4) * 4; |
| 376 for (; writeIndex < fillToFrameTrunc; writeIndex += 4) { |
| 377 delta = target - value; |
| 378 vDelta = _mm_set_ps1(delta); |
| 379 vValue = _mm_set_ps1(value); |
| 380 |
| 381 vResult = _mm_add_ps(vValue, _mm_mul_ps(vDelta, vC)); |
| 382 _mm_storeu_ps(values + writeIndex, vResult); |
| 383 |
| 384 // Update value for next iteration. |
| 385 value += delta * c3; |
| 386 } |
| 387 #endif |
| 388 // Serially process remaining values |
| 352 for (; writeIndex < fillToFrame; ++writeIndex) { | 389 for (; writeIndex < fillToFrame; ++writeIndex) { |
| 353 values[writeIndex] = value; | 390 values[writeIndex] = value; |
| 354 value += (target - value) * discreteTimeConstant; | 391 value += (target - value) * discreteTimeConstant; |
| 355 } | 392 } |
| 356 | 393 |
| 357 break; | 394 break; |
| 358 } | 395 } |
| 359 | 396 |
| 360 case ParamEvent::SetValueCurve: | 397 case ParamEvent::SetValueCurve: |
| 361 { | 398 { |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 458 // to the end of the values buffer. | 495 // to the end of the values buffer. |
| 459 for (; writeIndex < numberOfValues; ++writeIndex) | 496 for (; writeIndex < numberOfValues; ++writeIndex) |
| 460 values[writeIndex] = value; | 497 values[writeIndex] = value; |
| 461 | 498 |
| 462 return value; | 499 return value; |
| 463 } | 500 } |
| 464 | 501 |
| 465 } // namespace blink | 502 } // namespace blink |
| 466 | 503 |
| 467 #endif // ENABLE(WEB_AUDIO) | 504 #endif // ENABLE(WEB_AUDIO) |
| OLD | NEW |