Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(133)

Side by Side Diff: third_party/WebKit/Source/modules/webaudio/AudioParam.cpp

Issue 1934683002: Add histograms for Biquad lowpass and highpass Q values (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address comments and rebase Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 #include "modules/webaudio/AudioNode.h" 27 #include "modules/webaudio/AudioNode.h"
28 #include "modules/webaudio/AudioNodeOutput.h" 28 #include "modules/webaudio/AudioNodeOutput.h"
29 #include "platform/FloatConversion.h" 29 #include "platform/FloatConversion.h"
30 #include "platform/Histogram.h"
30 #include "platform/audio/AudioUtilities.h" 31 #include "platform/audio/AudioUtilities.h"
31 #include "wtf/MathExtras.h" 32 #include "wtf/MathExtras.h"
32 33
33 namespace blink { 34 namespace blink {
34 35
35 const double AudioParamHandler::DefaultSmoothingConstant = 0.05; 36 const double AudioParamHandler::DefaultSmoothingConstant = 0.05;
36 const double AudioParamHandler::SnapThreshold = 0.001; 37 const double AudioParamHandler::SnapThreshold = 0.001;
37 38
38 AudioParamHandler::AudioParamHandler(AbstractAudioContext& context, AudioParamTy pe paramType, double defaultValue) 39 AudioParamHandler::AudioParamHandler(AbstractAudioContext& context, AudioParamTy pe paramType, double defaultValue)
39 : AudioSummingJunction(context.deferredTaskHandler()) 40 : AudioSummingJunction(context.deferredTaskHandler())
40 , m_paramType(paramType) 41 , m_paramType(paramType)
41 , m_intrinsicValue(defaultValue) 42 , m_intrinsicValue(defaultValue)
42 , m_defaultValue(defaultValue) 43 , m_defaultValue(defaultValue)
43 , m_smoothedValue(defaultValue) 44 , m_smoothedValue(defaultValue)
44 { 45 {
45 // The destination MUST exist because we need the destination handler for th e AudioParam. 46 // The destination MUST exist because we need the destination handler for th e AudioParam.
46 RELEASE_ASSERT(context.destination()); 47 RELEASE_ASSERT(context.destination());
47 48
48 m_destinationHandler = &context.destination()->audioDestinationHandler(); 49 m_destinationHandler = &context.destination()->audioDestinationHandler();
49 } 50 }
50 51
51 AudioDestinationHandler& AudioParamHandler::destinationHandler() const 52 AudioDestinationHandler& AudioParamHandler::destinationHandler() const
52 { 53 {
53 return *m_destinationHandler; 54 return *m_destinationHandler;
54 } 55 }
55 56
57 void AudioParamHandler::setParamType(AudioParamType paramType)
58 {
59 m_paramType = paramType;
60 }
61
56 String AudioParamHandler::getParamName() const 62 String AudioParamHandler::getParamName() const
57 { 63 {
58 // The returned string should be the name of the node and the name of the Au dioParam for 64 // The returned string should be the name of the node and the name of the Au dioParam for
59 // that node. 65 // that node.
60 switch (m_paramType) { 66 switch (m_paramType) {
61 case ParamTypeAudioBufferSourcePlaybackRate: 67 case ParamTypeAudioBufferSourcePlaybackRate:
62 return "AudioBufferSource.playbackRate"; 68 return "AudioBufferSource.playbackRate";
63 case ParamTypeAudioBufferSourceDetune: 69 case ParamTypeAudioBufferSourceDetune:
64 return "AudioBufferSource.detune"; 70 return "AudioBufferSource.detune";
65 case ParamTypeBiquadFilterFrequency: 71 case ParamTypeBiquadFilterFrequency:
66 return "BiquadFilter.frequency"; 72 return "BiquadFilter.frequency";
67 case ParamTypeBiquadFilterQ: 73 case ParamTypeBiquadFilterQ:
74 case ParamTypeBiquadFilterQLowpass:
75 case ParamTypeBiquadFilterQHighpass:
76 // We don't really need separate names for the Q parameter for lowpass a nd highpass filters.
77 // The difference is only for the histograms.
68 return "BiquadFilter.Q"; 78 return "BiquadFilter.Q";
69 case ParamTypeBiquadFilterGain: 79 case ParamTypeBiquadFilterGain:
70 return "BiquadFilter.gain"; 80 return "BiquadFilter.gain";
71 case ParamTypeBiquadFilterDetune: 81 case ParamTypeBiquadFilterDetune:
72 return "BiquadFilter.detune"; 82 return "BiquadFilter.detune";
73 case ParamTypeDelayDelayTime: 83 case ParamTypeDelayDelayTime:
74 return "Delay.delayTime"; 84 return "Delay.delayTime";
75 case ParamTypeDynamicsCompressorThreshold: 85 case ParamTypeDynamicsCompressorThreshold:
76 return "DynamicsCompressor.threshold"; 86 return "DynamicsCompressor.threshold";
77 case ParamTypeDynamicsCompressorKnee: 87 case ParamTypeDynamicsCompressorKnee:
(...skipping 30 matching lines...) Expand all
108 v = timelineValue; 118 v = timelineValue;
109 } 119 }
110 120
111 setIntrinsicValue(v); 121 setIntrinsicValue(v);
112 return v; 122 return v;
113 } 123 }
114 124
115 void AudioParamHandler::setValue(float value) 125 void AudioParamHandler::setValue(float value)
116 { 126 {
117 setIntrinsicValue(value); 127 setIntrinsicValue(value);
128 updateHistograms(value);
118 } 129 }
119 130
120 float AudioParamHandler::smoothedValue() 131 float AudioParamHandler::smoothedValue()
121 { 132 {
122 return m_smoothedValue; 133 return m_smoothedValue;
123 } 134 }
124 135
125 bool AudioParamHandler::smooth() 136 bool AudioParamHandler::smooth()
126 { 137 {
127 // If values have been explicitly scheduled on the timeline, then use the ex act value. 138 // If values have been explicitly scheduled on the timeline, then use the ex act value.
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 { 251 {
241 ASSERT(deferredTaskHandler().isGraphOwner()); 252 ASSERT(deferredTaskHandler().isGraphOwner());
242 253
243 if (m_outputs.contains(&output)) { 254 if (m_outputs.contains(&output)) {
244 m_outputs.remove(&output); 255 m_outputs.remove(&output);
245 changedOutputs(); 256 changedOutputs();
246 output.removeParam(*this); 257 output.removeParam(*this);
247 } 258 }
248 } 259 }
249 260
261 int AudioParamHandler::computeQHistogramValue(float newValue) const
262 {
263 // For the Q value, assume a useful range is [0, 25] and that 0.25 dB resolu tion is good enough.
264 // Then, we can map the floating point Q value (in dB) to an integer just by multipling by 4 and
265 // rounding.
266 newValue = clampTo(newValue, 0.0, 25.0);
267 int histogramValue = static_cast<int>(4 * newValue + 0.5);
Mark P 2016/05/09 21:48:33 I don't know WebKit style but, for the record, thi
268 return histogramValue;
269 }
270
271 void AudioParamHandler::updateHistograms(float newValue)
272 {
273 switch (m_paramType) {
274 case ParamTypeBiquadFilterQLowpass:
275 {
276 // The histogram for the Q value for a lowpass biquad filter.
277 DEFINE_STATIC_LOCAL(SparseHistogram, lowpassQHistogram, ("WebAudio.B iquadFilter.Q.Lowpass"));
278
279 int histogramValue = computeQHistogramValue(newValue);
280 lowpassQHistogram.sample(histogramValue);
281 }
282 break;
283 case ParamTypeBiquadFilterQHighpass:
284 {
285 // The histogram for the Q value for a highpass biquad filter.
286 DEFINE_STATIC_LOCAL(SparseHistogram, highpassQHistogram, ("WebAudio. BiquadFilter.Q.Highpass"));
287
288 int histogramValue = computeQHistogramValue(newValue);
289 highpassQHistogram.sample(histogramValue);
290 }
291 break;
292 default:
293 // Nothing to do for all other types.
294 break;
295 }
296 }
297
250 // ---------------------------------------------------------------- 298 // ----------------------------------------------------------------
251 299
252 AudioParam::AudioParam(AbstractAudioContext& context, AudioParamType paramType, double defaultValue) 300 AudioParam::AudioParam(AbstractAudioContext& context, AudioParamType paramType, double defaultValue)
253 : m_handler(AudioParamHandler::create(context, paramType, defaultValue)) 301 : m_handler(AudioParamHandler::create(context, paramType, defaultValue))
254 , m_context(context) 302 , m_context(context)
255 { 303 {
256 } 304 }
257 305
258 AudioParam* AudioParam::create(AbstractAudioContext& context, AudioParamType par amType, double defaultValue) 306 AudioParam* AudioParam::create(AbstractAudioContext& context, AudioParamType par amType, double defaultValue)
259 { 307 {
(...skipping 13 matching lines...) Expand all
273 void AudioParam::setValue(float value) 321 void AudioParam::setValue(float value)
274 { 322 {
275 handler().setValue(value); 323 handler().setValue(value);
276 } 324 }
277 325
278 float AudioParam::defaultValue() const 326 float AudioParam::defaultValue() const
279 { 327 {
280 return handler().defaultValue(); 328 return handler().defaultValue();
281 } 329 }
282 330
331 void AudioParam::setParamType(AudioParamType paramType)
332 {
333 handler().setParamType(paramType);
334 }
335
283 AudioParam* AudioParam::setValueAtTime(float value, double time, ExceptionState& exceptionState) 336 AudioParam* AudioParam::setValueAtTime(float value, double time, ExceptionState& exceptionState)
284 { 337 {
285 handler().timeline().setValueAtTime(value, time, exceptionState); 338 handler().timeline().setValueAtTime(value, time, exceptionState);
339 handler().updateHistograms(value);
286 return this; 340 return this;
287 } 341 }
288 342
289 AudioParam* AudioParam::linearRampToValueAtTime(float value, double time, Except ionState& exceptionState) 343 AudioParam* AudioParam::linearRampToValueAtTime(float value, double time, Except ionState& exceptionState)
290 { 344 {
291 handler().timeline().linearRampToValueAtTime( 345 handler().timeline().linearRampToValueAtTime(
292 value, time, handler().intrinsicValue(), context()->currentTime(), excep tionState); 346 value, time, handler().intrinsicValue(), context()->currentTime(), excep tionState);
347
348 // This is probably the best we can do for the histogram. We don't want to run the automation
349 // to get all the values and use them to update the histogram.
350 handler().updateHistograms(value);
351
293 return this; 352 return this;
294 } 353 }
295 354
296 AudioParam* AudioParam::exponentialRampToValueAtTime(float value, double time, E xceptionState& exceptionState) 355 AudioParam* AudioParam::exponentialRampToValueAtTime(float value, double time, E xceptionState& exceptionState)
297 { 356 {
298 handler().timeline().exponentialRampToValueAtTime(value, time, handler().int rinsicValue(), context()->currentTime(), exceptionState); 357 handler().timeline().exponentialRampToValueAtTime(value, time, handler().int rinsicValue(), context()->currentTime(), exceptionState);
358
359 // This is probably the best we can do for the histogram. We don't want to run the automation
360 // to get all the values and use them to update the histogram.
361 handler().updateHistograms(value);
362
299 return this; 363 return this;
300 } 364 }
301 365
302 AudioParam* AudioParam::setTargetAtTime(float target, double time, double timeCo nstant, ExceptionState& exceptionState) 366 AudioParam* AudioParam::setTargetAtTime(float target, double time, double timeCo nstant, ExceptionState& exceptionState)
303 { 367 {
304 handler().timeline().setTargetAtTime(target, time, timeConstant, exceptionSt ate); 368 handler().timeline().setTargetAtTime(target, time, timeConstant, exceptionSt ate);
369
370 // Don't update the histogram here. It's not clear in normal usage if the p arameter value will
371 // actually reach |target|.
305 return this; 372 return this;
306 } 373 }
307 374
308 AudioParam* AudioParam::setValueCurveAtTime(DOMFloat32Array* curve, double time, double duration, ExceptionState& exceptionState) 375 AudioParam* AudioParam::setValueCurveAtTime(DOMFloat32Array* curve, double time, double duration, ExceptionState& exceptionState)
309 { 376 {
310 handler().timeline().setValueCurveAtTime(curve, time, duration, exceptionSta te); 377 handler().timeline().setValueCurveAtTime(curve, time, duration, exceptionSta te);
378
379 // We could update the histogram with every value in the curve, due to inter polation, we'll
380 // probably be missing many values. So we don't update the histogram. setV alueCurveAtTime is
381 // probably a fairly rare method anyway.
311 return this; 382 return this;
312 } 383 }
313 384
314 AudioParam* AudioParam::cancelScheduledValues(double startTime, ExceptionState& exceptionState) 385 AudioParam* AudioParam::cancelScheduledValues(double startTime, ExceptionState& exceptionState)
315 { 386 {
316 handler().timeline().cancelScheduledValues(startTime, exceptionState); 387 handler().timeline().cancelScheduledValues(startTime, exceptionState);
317 return this; 388 return this;
318 } 389 }
319 390
320 } // namespace blink 391 } // namespace blink
321 392
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698