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 |