OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2010 Google Inc. All rights reserved. | 2 * Copyright (C) 2010 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 |
11 * notice, this list of conditions and the following disclaimer in the | 11 * notice, this list of conditions and the following disclaimer in the |
12 * documentation and/or other materials provided with the distribution. | 12 * documentation and/or other materials provided with the distribution. |
13 * | 13 * |
14 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY | 14 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY |
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
17 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY | 17 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY |
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
20 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | 20 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
24 */ | 24 */ |
25 | 25 |
26 #include "modules/webaudio/AudioParam.h" | 26 #include "modules/webaudio/AudioParam.h" |
27 | |
28 #include "core/inspector/ConsoleMessage.h" | |
27 #include "modules/webaudio/AudioNode.h" | 29 #include "modules/webaudio/AudioNode.h" |
28 #include "modules/webaudio/AudioNodeOutput.h" | 30 #include "modules/webaudio/AudioNodeOutput.h" |
29 #include "platform/FloatConversion.h" | 31 #include "platform/FloatConversion.h" |
30 #include "platform/Histogram.h" | 32 #include "platform/Histogram.h" |
31 #include "platform/audio/AudioUtilities.h" | 33 #include "platform/audio/AudioUtilities.h" |
34 #include "platform/v8_inspector/public/ConsoleTypes.h" | |
32 #include "wtf/MathExtras.h" | 35 #include "wtf/MathExtras.h" |
33 | 36 |
34 namespace blink { | 37 namespace blink { |
35 | 38 |
36 const double AudioParamHandler::DefaultSmoothingConstant = 0.05; | 39 const double AudioParamHandler::DefaultSmoothingConstant = 0.05; |
37 const double AudioParamHandler::SnapThreshold = 0.001; | 40 const double AudioParamHandler::SnapThreshold = 0.001; |
38 | 41 |
39 AudioParamHandler::AudioParamHandler(AbstractAudioContext& context, AudioParamTy pe paramType, double defaultValue) | 42 AudioParamHandler::AudioParamHandler(AbstractAudioContext& context, AudioParamTy pe paramType, double defaultValue, float minValue, float maxValue) |
40 : AudioSummingJunction(context.deferredTaskHandler()) | 43 : AudioSummingJunction(context.deferredTaskHandler()) |
41 , m_paramType(paramType) | 44 , m_paramType(paramType) |
42 , m_intrinsicValue(defaultValue) | 45 , m_intrinsicValue(defaultValue) |
43 , m_defaultValue(defaultValue) | 46 , m_defaultValue(defaultValue) |
47 , m_minValue(minValue) | |
48 , m_maxValue(maxValue) | |
44 , m_smoothedValue(defaultValue) | 49 , m_smoothedValue(defaultValue) |
45 { | 50 { |
46 // The destination MUST exist because we need the destination handler for th e AudioParam. | 51 // The destination MUST exist because we need the destination handler for th e AudioParam. |
47 RELEASE_ASSERT(context.destination()); | 52 RELEASE_ASSERT(context.destination()); |
48 | 53 |
49 m_destinationHandler = &context.destination()->audioDestinationHandler(); | 54 m_destinationHandler = &context.destination()->audioDestinationHandler(); |
50 } | 55 } |
51 | 56 |
52 AudioDestinationHandler& AudioParamHandler::destinationHandler() const | 57 AudioDestinationHandler& AudioParamHandler::destinationHandler() const |
53 { | 58 { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
115 float timelineValue = m_timeline.valueForContextTime(destinationHandler( ), v, hasValue); | 120 float timelineValue = m_timeline.valueForContextTime(destinationHandler( ), v, hasValue); |
116 | 121 |
117 if (hasValue) | 122 if (hasValue) |
118 v = timelineValue; | 123 v = timelineValue; |
119 } | 124 } |
120 | 125 |
121 setIntrinsicValue(v); | 126 setIntrinsicValue(v); |
122 return v; | 127 return v; |
123 } | 128 } |
124 | 129 |
130 void AudioParamHandler::setIntrinsicValue(float newValue) | |
131 { | |
132 newValue = clampTo(newValue, m_minValue, m_maxValue); | |
133 noBarrierStore(&m_intrinsicValue, newValue); | |
134 } | |
135 | |
125 void AudioParamHandler::setValue(float value) | 136 void AudioParamHandler::setValue(float value) |
126 { | 137 { |
127 setIntrinsicValue(value); | 138 setIntrinsicValue(value); |
128 updateHistograms(value); | 139 updateHistograms(value); |
129 } | 140 } |
130 | 141 |
131 float AudioParamHandler::smoothedValue() | 142 float AudioParamHandler::smoothedValue() |
132 { | 143 { |
133 return m_smoothedValue; | 144 return m_smoothedValue; |
134 } | 145 } |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
287 } | 298 } |
288 break; | 299 break; |
289 default: | 300 default: |
290 // Nothing to do for all other types. | 301 // Nothing to do for all other types. |
291 break; | 302 break; |
292 } | 303 } |
293 } | 304 } |
294 | 305 |
295 // ---------------------------------------------------------------- | 306 // ---------------------------------------------------------------- |
296 | 307 |
297 AudioParam::AudioParam(AbstractAudioContext& context, AudioParamType paramType, double defaultValue) | 308 AudioParam::AudioParam(AbstractAudioContext& context, AudioParamType paramType, double defaultValue, float minValue, float maxValue) |
298 : m_handler(AudioParamHandler::create(context, paramType, defaultValue)) | 309 : m_handler(AudioParamHandler::create(context, paramType, defaultValue, minV alue, maxValue)) |
299 , m_context(context) | 310 , m_context(context) |
300 { | 311 { |
301 } | 312 } |
302 | 313 |
303 AudioParam* AudioParam::create(AbstractAudioContext& context, AudioParamType par amType, double defaultValue) | 314 AudioParam* AudioParam::create(AbstractAudioContext& context, AudioParamType par amType, double defaultValue) |
304 { | 315 { |
305 return new AudioParam(context, paramType, defaultValue); | 316 // Default nominal range is most negative float to most positive. This basi cally means any |
317 // value is valid, except that floating-point infinities are excluded. | |
318 float limit = std::numeric_limits<float>::max(); | |
319 return new AudioParam(context, paramType, defaultValue, -limit, limit); | |
320 } | |
321 | |
322 AudioParam* AudioParam::create(AbstractAudioContext& context, AudioParamType par amType, double defaultValue, float minValue, float maxValue) | |
323 { | |
324 DCHECK(minValue <= maxValue); | |
tkent
2016/05/15 23:50:10
DCHECK -> DCHECK_LE
| |
325 return new AudioParam(context, paramType, defaultValue, minValue, maxValue); | |
306 } | 326 } |
307 | 327 |
308 DEFINE_TRACE(AudioParam) | 328 DEFINE_TRACE(AudioParam) |
309 { | 329 { |
310 visitor->trace(m_context); | 330 visitor->trace(m_context); |
311 } | 331 } |
312 | 332 |
313 float AudioParam::value() const | 333 float AudioParam::value() const |
314 { | 334 { |
315 return handler().value(); | 335 return handler().value(); |
316 } | 336 } |
317 | 337 |
338 void AudioParam::warnIfOutsideRange(const String& paramMethod, float value) | |
339 { | |
340 if (value < minValue() || value > maxValue()) { | |
341 context()->getExecutionContext()->addConsoleMessage( | |
342 ConsoleMessage::create( | |
343 JSMessageSource, | |
344 WarningMessageLevel, | |
345 handler().getParamName() | |
346 + "." | |
347 + paramMethod | |
348 + " " | |
349 + String::number(value) | |
350 + " outside nominal range [" | |
351 + String::number(minValue()) + ", " + String::number(maxValue()) | |
352 + "]; value will be clamped.")); | |
353 } | |
354 } | |
355 | |
318 void AudioParam::setValue(float value) | 356 void AudioParam::setValue(float value) |
319 { | 357 { |
358 warnIfOutsideRange("value", value); | |
320 handler().setValue(value); | 359 handler().setValue(value); |
321 } | 360 } |
322 | 361 |
323 float AudioParam::defaultValue() const | 362 float AudioParam::defaultValue() const |
324 { | 363 { |
325 return handler().defaultValue(); | 364 return handler().defaultValue(); |
326 } | 365 } |
327 | 366 |
367 float AudioParam::minValue() const | |
368 { | |
369 return handler().minValue(); | |
370 } | |
371 | |
372 float AudioParam::maxValue() const | |
373 { | |
374 return handler().maxValue(); | |
375 } | |
376 | |
328 void AudioParam::setParamType(AudioParamType paramType) | 377 void AudioParam::setParamType(AudioParamType paramType) |
329 { | 378 { |
330 handler().setParamType(paramType); | 379 handler().setParamType(paramType); |
331 } | 380 } |
332 | 381 |
333 AudioParam* AudioParam::setValueAtTime(float value, double time, ExceptionState& exceptionState) | 382 AudioParam* AudioParam::setValueAtTime(float value, double time, ExceptionState& exceptionState) |
334 { | 383 { |
384 warnIfOutsideRange("setValueAtTime value", value); | |
335 handler().timeline().setValueAtTime(value, time, exceptionState); | 385 handler().timeline().setValueAtTime(value, time, exceptionState); |
336 handler().updateHistograms(value); | 386 handler().updateHistograms(value); |
337 return this; | 387 return this; |
338 } | 388 } |
339 | 389 |
340 AudioParam* AudioParam::linearRampToValueAtTime(float value, double time, Except ionState& exceptionState) | 390 AudioParam* AudioParam::linearRampToValueAtTime(float value, double time, Except ionState& exceptionState) |
341 { | 391 { |
392 warnIfOutsideRange("linearRampToValueAtTime value", value); | |
342 handler().timeline().linearRampToValueAtTime( | 393 handler().timeline().linearRampToValueAtTime( |
343 value, time, handler().intrinsicValue(), context()->currentTime(), excep tionState); | 394 value, time, handler().intrinsicValue(), context()->currentTime(), excep tionState); |
344 | 395 |
345 // This is probably the best we can do for the histogram. We don't want to run the automation | 396 // This is probably the best we can do for the histogram. We don't want to run the automation |
346 // to get all the values and use them to update the histogram. | 397 // to get all the values and use them to update the histogram. |
347 handler().updateHistograms(value); | 398 handler().updateHistograms(value); |
348 | 399 |
349 return this; | 400 return this; |
350 } | 401 } |
351 | 402 |
352 AudioParam* AudioParam::exponentialRampToValueAtTime(float value, double time, E xceptionState& exceptionState) | 403 AudioParam* AudioParam::exponentialRampToValueAtTime(float value, double time, E xceptionState& exceptionState) |
353 { | 404 { |
405 warnIfOutsideRange("exponentialRampToValue value", value); | |
354 handler().timeline().exponentialRampToValueAtTime(value, time, handler().int rinsicValue(), context()->currentTime(), exceptionState); | 406 handler().timeline().exponentialRampToValueAtTime(value, time, handler().int rinsicValue(), context()->currentTime(), exceptionState); |
355 | 407 |
356 // This is probably the best we can do for the histogram. We don't want to run the automation | 408 // This is probably the best we can do for the histogram. We don't want to run the automation |
357 // to get all the values and use them to update the histogram. | 409 // to get all the values and use them to update the histogram. |
358 handler().updateHistograms(value); | 410 handler().updateHistograms(value); |
359 | 411 |
360 return this; | 412 return this; |
361 } | 413 } |
362 | 414 |
363 AudioParam* AudioParam::setTargetAtTime(float target, double time, double timeCo nstant, ExceptionState& exceptionState) | 415 AudioParam* AudioParam::setTargetAtTime(float target, double time, double timeCo nstant, ExceptionState& exceptionState) |
364 { | 416 { |
417 warnIfOutsideRange("setTargetAtTime value", target); | |
365 handler().timeline().setTargetAtTime(target, time, timeConstant, exceptionSt ate); | 418 handler().timeline().setTargetAtTime(target, time, timeConstant, exceptionSt ate); |
366 | 419 |
367 // Don't update the histogram here. It's not clear in normal usage if the p arameter value will | 420 // Don't update the histogram here. It's not clear in normal usage if the p arameter value will |
368 // actually reach |target|. | 421 // actually reach |target|. |
369 return this; | 422 return this; |
370 } | 423 } |
371 | 424 |
372 AudioParam* AudioParam::setValueCurveAtTime(DOMFloat32Array* curve, double time, double duration, ExceptionState& exceptionState) | 425 AudioParam* AudioParam::setValueCurveAtTime(DOMFloat32Array* curve, double time, double duration, ExceptionState& exceptionState) |
373 { | 426 { |
427 // Just find the first value in the curve (if any) that is outside the nomin al range. It's | |
428 // probably not necessary to produce a warning on every value outside the no minal range. | |
429 float* curveData = curve->data(); | |
430 float min = minValue(); | |
431 float max = maxValue(); | |
432 | |
433 for (unsigned k = 0; k < curve->length(); ++k) { | |
434 if (curveData[k] < min || curveData[k] > max) { | |
435 warnIfOutsideRange("setValueCurveAtTime value", curveData[k]); | |
436 break; | |
437 } | |
438 } | |
439 | |
374 handler().timeline().setValueCurveAtTime(curve, time, duration, exceptionSta te); | 440 handler().timeline().setValueCurveAtTime(curve, time, duration, exceptionSta te); |
375 | 441 |
376 // We could update the histogram with every value in the curve, due to inter polation, we'll | 442 // We could update the histogram with every value in the curve, due to inter polation, we'll |
377 // probably be missing many values. So we don't update the histogram. setV alueCurveAtTime is | 443 // probably be missing many values. So we don't update the histogram. setV alueCurveAtTime is |
378 // probably a fairly rare method anyway. | 444 // probably a fairly rare method anyway. |
379 return this; | 445 return this; |
380 } | 446 } |
381 | 447 |
382 AudioParam* AudioParam::cancelScheduledValues(double startTime, ExceptionState& exceptionState) | 448 AudioParam* AudioParam::cancelScheduledValues(double startTime, ExceptionState& exceptionState) |
383 { | 449 { |
384 handler().timeline().cancelScheduledValues(startTime, exceptionState); | 450 handler().timeline().cancelScheduledValues(startTime, exceptionState); |
385 return this; | 451 return this; |
386 } | 452 } |
387 | 453 |
388 } // namespace blink | 454 } // namespace blink |
389 | 455 |
OLD | NEW |