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

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

Issue 1820403002: Implement Automations for PannerNode and AutioListener (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Update test because CL for min/maxValue AudioParam landed 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 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 24 matching lines...) Expand all
35 #include "wtf/MathExtras.h" 35 #include "wtf/MathExtras.h"
36 36
37 namespace blink { 37 namespace blink {
38 38
39 static void fixNANs(double& x) 39 static void fixNANs(double& x)
40 { 40 {
41 if (std::isnan(x) || std::isinf(x)) 41 if (std::isnan(x) || std::isinf(x))
42 x = 0.0; 42 x = 0.0;
43 } 43 }
44 44
45 PannerHandler::PannerHandler(AudioNode& node, float sampleRate) 45 PannerHandler::PannerHandler(
46 AudioNode& node, float sampleRate,
47 AudioParamHandler& positionX,
48 AudioParamHandler& positionY,
49 AudioParamHandler& positionZ,
50 AudioParamHandler& orientationX,
51 AudioParamHandler& orientationY,
52 AudioParamHandler& orientationZ)
46 : AudioHandler(NodeTypePanner, node, sampleRate) 53 : AudioHandler(NodeTypePanner, node, sampleRate)
47 , m_listener(node.context()->listener()) 54 , m_listener(node.context()->listener())
48 , m_panningModel(Panner::PanningModelEqualPower) 55 , m_panningModel(Panner::PanningModelEqualPower)
49 , m_distanceModel(DistanceEffect::ModelInverse) 56 , m_distanceModel(DistanceEffect::ModelInverse)
50 , m_position(0, 0, 0)
51 , m_orientation(1, 0, 0)
52 , m_isAzimuthElevationDirty(true) 57 , m_isAzimuthElevationDirty(true)
53 , m_isDistanceConeGainDirty(true) 58 , m_isDistanceConeGainDirty(true)
54 , m_lastGain(-1.0) 59 , m_lastGain(-1.0)
55 , m_cachedAzimuth(0) 60 , m_cachedAzimuth(0)
56 , m_cachedElevation(0) 61 , m_cachedElevation(0)
57 , m_cachedDistanceConeGain(1.0f) 62 , m_cachedDistanceConeGain(1.0f)
63 , m_positionX(positionX)
64 , m_positionY(positionY)
65 , m_positionZ(positionZ)
66 , m_orientationX(orientationX)
67 , m_orientationY(orientationY)
68 , m_orientationZ(orientationZ)
58 { 69 {
59 // Load the HRTF database asynchronously so we don't block the Javascript th read while creating the HRTF database. 70 // Load the HRTF database asynchronously so we don't block the Javascript th read while creating the HRTF database.
60 // The HRTF panner will return zeroes until the database is loaded. 71 // The HRTF panner will return zeroes until the database is loaded.
61 listener()->createAndLoadHRTFDatabaseLoader(node.context()->sampleRate()); 72 listener()->createAndLoadHRTFDatabaseLoader(node.context()->sampleRate());
62 73
63 addInput(); 74 addInput();
64 addOutput(2); 75 addOutput(2);
65 76
66 // Node-specific default mixing rules. 77 // Node-specific default mixing rules.
67 m_channelCount = 2; 78 m_channelCount = 2;
68 m_channelCountMode = ClampedMax; 79 m_channelCountMode = ClampedMax;
69 m_channelInterpretation = AudioBus::Speakers; 80 m_channelInterpretation = AudioBus::Speakers;
70 81
71 initialize(); 82 initialize();
72 } 83 }
73 84
74 PassRefPtr<PannerHandler> PannerHandler::create(AudioNode& node, float sampleRat e) 85 PassRefPtr<PannerHandler> PannerHandler::create(
86 AudioNode& node, float sampleRate,
87 AudioParamHandler& positionX,
88 AudioParamHandler& positionY,
89 AudioParamHandler& positionZ,
90 AudioParamHandler& orientationX,
91 AudioParamHandler& orientationY,
92 AudioParamHandler& orientationZ)
75 { 93 {
76 return adoptRef(new PannerHandler(node, sampleRate)); 94 return adoptRef(new PannerHandler(
95 node,
96 sampleRate,
97 positionX,
98 positionY,
99 positionZ,
100 orientationX,
101 orientationY,
102 orientationZ));
77 } 103 }
78 104
79 PannerHandler::~PannerHandler() 105 PannerHandler::~PannerHandler()
80 { 106 {
81 uninitialize(); 107 uninitialize();
82 } 108 }
83 109
84 void PannerHandler::process(size_t framesToProcess) 110 void PannerHandler::process(size_t framesToProcess)
85 { 111 {
86 AudioBus* destination = output(0).bus(); 112 AudioBus* destination = output(0).bus();
(...skipping 18 matching lines...) Expand all
105 if (m_panningModel == Panner::PanningModelHRTF && !listener()->isHRTFDat abaseLoaded()) { 131 if (m_panningModel == Panner::PanningModelHRTF && !listener()->isHRTFDat abaseLoaded()) {
106 if (context()->hasRealtimeConstraint()) { 132 if (context()->hasRealtimeConstraint()) {
107 // Some AbstractAudioContexts cannot block on the HRTFDatabase l oader. 133 // Some AbstractAudioContexts cannot block on the HRTFDatabase l oader.
108 destination->zero(); 134 destination->zero();
109 return; 135 return;
110 } 136 }
111 137
112 listener()->waitForHRTFDatabaseLoaderThreadCompletion(); 138 listener()->waitForHRTFDatabaseLoaderThreadCompletion();
113 } 139 }
114 140
115 // Apply the panning effect. 141 if (hasSampleAccurateValues() || listener()->hasSampleAccurateValues()) {
116 double azimuth; 142 // It's tempting to skip sample-accurate processing if isAzimuthElev ationDirty() and
117 double elevation; 143 // isDistanceConeGain() both return false. But in general we can't because something
118 azimuthElevation(&azimuth, &elevation); 144 // may scheduled to start in the middle of the rendering quantum. O n the other hand,
145 // the audible effect may be small enough that we can afford to do t his optimization.
146 processSampleAccurateValues(destination, source, framesToProcess);
147 } else {
148 // Apply the panning effect.
149 double azimuth;
150 double elevation;
151 azimuthElevation(&azimuth, &elevation);
119 152
120 m_panner->pan(azimuth, elevation, source, destination, framesToProcess); 153 m_panner->pan(azimuth, elevation, source, destination, framesToProce ss);
121 154
122 // Get the distance and cone gain. 155 // Get the distance and cone gain.
123 float totalGain = distanceConeGain(); 156 float totalGain = distanceConeGain();
124 157
125 // Snap to desired gain at the beginning.
126 if (m_lastGain == -1.0)
127 m_lastGain = totalGain; 158 m_lastGain = totalGain;
128 159
129 // Apply gain in-place with de-zippering. 160 // Apply gain in-place with de-zippering.
130 destination->copyWithGainFrom(*destination, &m_lastGain, totalGain); 161 destination->copyWithGainFrom(*destination, &m_lastGain, totalGain);
162 }
131 } else { 163 } else {
132 // Too bad - The tryLock() failed. 164 // Too bad - The tryLock() failed.
133 // We must be in the middle of changing the properties of the panner or the listener. 165 // We must be in the middle of changing the properties of the panner or the listener.
134 destination->zero(); 166 destination->zero();
135 } 167 }
136 } 168 }
137 169
170 void PannerHandler::processSampleAccurateValues(AudioBus* destination, const Aud ioBus* source, size_t framesToProcess)
171 {
172 RELEASE_ASSERT(framesToProcess <= ProcessingSizeInFrames);
173
174 // Get the sample accurate values from all of the AudioParams, including the values from the
175 // AudioListener.
176 float pannerX[ProcessingSizeInFrames];
177 float pannerY[ProcessingSizeInFrames];
178 float pannerZ[ProcessingSizeInFrames];
179
180 float orientationX[ProcessingSizeInFrames];
181 float orientationY[ProcessingSizeInFrames];
182 float orientationZ[ProcessingSizeInFrames];
183
184 m_positionX->calculateSampleAccurateValues(pannerX, framesToProcess);
185 m_positionY->calculateSampleAccurateValues(pannerY, framesToProcess);
186 m_positionZ->calculateSampleAccurateValues(pannerZ, framesToProcess);
187 m_orientationX->calculateSampleAccurateValues(orientationX, framesToProcess) ;
188 m_orientationY->calculateSampleAccurateValues(orientationY, framesToProcess) ;
189 m_orientationZ->calculateSampleAccurateValues(orientationZ, framesToProcess) ;
190
191 // Get the automation values from the listener.
192 const float* listenerX = listener()->getPositionXValues(ProcessingSizeInFram es);
193 const float* listenerY = listener()->getPositionYValues(ProcessingSizeInFram es);
194 const float* listenerZ = listener()->getPositionZValues(ProcessingSizeInFram es);
195
196 const float* forwardX = listener()->getForwardXValues(ProcessingSizeInFrames );
197 const float* forwardY = listener()->getForwardYValues(ProcessingSizeInFrames );
198 const float* forwardZ = listener()->getForwardZValues(ProcessingSizeInFrames );
199
200 const float* upX = listener()->getUpXValues(ProcessingSizeInFrames);
201 const float* upY = listener()->getUpYValues(ProcessingSizeInFrames);
202 const float* upZ = listener()->getUpZValues(ProcessingSizeInFrames);
203
204 // Compute the azimuth, elevation, and total gains for each position.
205 double azimuth[ProcessingSizeInFrames];
206 double elevation[ProcessingSizeInFrames];
207 float totalGain[ProcessingSizeInFrames];
208
209 for (unsigned k = 0; k < framesToProcess; ++k) {
210 FloatPoint3D pannerPosition(pannerX[k], pannerY[k], pannerZ[k]);
211 FloatPoint3D orientation(orientationX[k], orientationY[k], orientationZ[ k]);
212 FloatPoint3D listenerPosition(listenerX[k], listenerY[k], listenerZ[k]);
213 FloatPoint3D listenerForward(forwardX[k], forwardY[k], forwardZ[k]);
214 FloatPoint3D listenerUp(upX[k], upY[k], upZ[k]);
215
216 calculateAzimuthElevation(&azimuth[k], &elevation[k],
217 pannerPosition, listenerPosition, listenerForward, listenerUp);
218
219 // Get distance and cone gain
220 totalGain[k] = calculateDistanceConeGain(pannerPosition, orientation, li stenerPosition);
221 }
222
223 m_panner->panWithSampleAccurateValues(azimuth, elevation, source, destinatio n, framesToProcess);
224 destination->copyWithSampleAccurateGainValuesFrom(*destination, totalGain, f ramesToProcess);
225 }
226
138 void PannerHandler::initialize() 227 void PannerHandler::initialize()
139 { 228 {
140 if (isInitialized()) 229 if (isInitialized())
141 return; 230 return;
142 231
143 m_panner = Panner::create(m_panningModel, sampleRate(), listener()->hrtfData baseLoader()); 232 m_panner = Panner::create(m_panningModel, sampleRate(), listener()->hrtfData baseLoader());
144 listener()->addPanner(*this); 233 listener()->addPanner(*this);
145 234
235 // Set the cached values to the current values to start things off. The pan ner is already
236 // marked as dirty, so this won't matter.
237 m_lastPosition = position();
238 m_lastOrientation = orientation();
239
146 AudioHandler::initialize(); 240 AudioHandler::initialize();
147 } 241 }
148 242
149 void PannerHandler::uninitialize() 243 void PannerHandler::uninitialize()
150 { 244 {
151 if (!isInitialized()) 245 if (!isInitialized())
152 return; 246 return;
153 247
154 m_panner.clear(); 248 m_panner.clear();
155 listener()->removePanner(*this); 249 listener()->removePanner(*this);
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 return; 404 return;
311 405
312 // This synchronizes with process(). 406 // This synchronizes with process().
313 MutexLocker processLocker(m_processLock); 407 MutexLocker processLocker(m_processLock);
314 m_coneEffect.setOuterGain(angle); 408 m_coneEffect.setOuterGain(angle);
315 markPannerAsDirty(PannerHandler::DistanceConeGainDirty); 409 markPannerAsDirty(PannerHandler::DistanceConeGainDirty);
316 } 410 }
317 411
318 void PannerHandler::setPosition(float x, float y, float z) 412 void PannerHandler::setPosition(float x, float y, float z)
319 { 413 {
320 FloatPoint3D position = FloatPoint3D(x, y, z);
321
322 if (m_position == position)
323 return;
324
325 // This synchronizes with process(). 414 // This synchronizes with process().
326 MutexLocker processLocker(m_processLock); 415 MutexLocker processLocker(m_processLock);
327 m_position = position; 416
417 m_positionX->setValue(x);
418 m_positionY->setValue(y);
419 m_positionZ->setValue(z);
420
328 markPannerAsDirty(PannerHandler::AzimuthElevationDirty | PannerHandler::Dist anceConeGainDirty); 421 markPannerAsDirty(PannerHandler::AzimuthElevationDirty | PannerHandler::Dist anceConeGainDirty);
329 } 422 }
330 423
331 void PannerHandler::setOrientation(float x, float y, float z) 424 void PannerHandler::setOrientation(float x, float y, float z)
332 { 425 {
333 FloatPoint3D orientation = FloatPoint3D(x, y, z);
334
335 if (m_orientation == orientation)
336 return;
337
338 // This synchronizes with process(). 426 // This synchronizes with process().
339 MutexLocker processLocker(m_processLock); 427 MutexLocker processLocker(m_processLock);
340 m_orientation = orientation; 428
429 m_orientationX->setValue(x);
430 m_orientationY->setValue(y);
431 m_orientationZ->setValue(z);
432
341 markPannerAsDirty(PannerHandler::DistanceConeGainDirty); 433 markPannerAsDirty(PannerHandler::DistanceConeGainDirty);
342 } 434 }
343 435
344 void PannerHandler::calculateAzimuthElevation(double* outAzimuth, double* outEle vation) 436 void PannerHandler::calculateAzimuthElevation(
437 double* outAzimuth,
438 double* outElevation,
439 const FloatPoint3D& position,
440 const FloatPoint3D& listenerPosition,
441 const FloatPoint3D& listenerForward,
442 const FloatPoint3D& listenerUp)
345 { 443 {
346 double azimuth = 0.0; 444 double azimuth = 0.0;
347 445
348 // Calculate the source-listener vector 446 // Calculate the source-listener vector
349 FloatPoint3D listenerPosition = listener()->position(); 447 FloatPoint3D sourceListener = position - listenerPosition;
350 FloatPoint3D sourceListener = m_position - listenerPosition;
351 448
352 // normalize() does nothing if the length of |sourceListener| is zero. 449 // normalize() does nothing if the length of |sourceListener| is zero.
353 sourceListener.normalize(); 450 sourceListener.normalize();
354 451
355 // Align axes 452 // Align axes
356 FloatPoint3D listenerFront = listener()->orientation(); 453 FloatPoint3D listenerRight = listenerForward.cross(listenerUp);
357 FloatPoint3D listenerUp = listener()->upVector();
358 FloatPoint3D listenerRight = listenerFront.cross(listenerUp);
359 listenerRight.normalize(); 454 listenerRight.normalize();
360 455
361 FloatPoint3D listenerFrontNorm = listenerFront; 456 FloatPoint3D listenerForwardNorm = listenerForward;
362 listenerFrontNorm.normalize(); 457 listenerForwardNorm.normalize();
363 458
364 FloatPoint3D up = listenerRight.cross(listenerFrontNorm); 459 FloatPoint3D up = listenerRight.cross(listenerForwardNorm);
365 460
366 float upProjection = sourceListener.dot(up); 461 float upProjection = sourceListener.dot(up);
367 462
368 FloatPoint3D projectedSource = sourceListener - upProjection * up; 463 FloatPoint3D projectedSource = sourceListener - upProjection * up;
369 464
370 azimuth = rad2deg(projectedSource.angleBetween(listenerRight)); 465 azimuth = rad2deg(projectedSource.angleBetween(listenerRight));
371 fixNANs(azimuth); // avoid illegal values 466 fixNANs(azimuth); // avoid illegal values
372 467
373 // Source in front or behind the listener 468 // Source in front or behind the listener
374 double frontBack = projectedSource.dot(listenerFrontNorm); 469 double frontBack = projectedSource.dot(listenerForwardNorm);
375 if (frontBack < 0.0) 470 if (frontBack < 0.0)
376 azimuth = 360.0 - azimuth; 471 azimuth = 360.0 - azimuth;
377 472
378 // Make azimuth relative to "front" and not "right" listener vector 473 // Make azimuth relative to "front" and not "right" listener vector
379 if ((azimuth >= 0.0) && (azimuth <= 270.0)) 474 if ((azimuth >= 0.0) && (azimuth <= 270.0))
380 azimuth = 90.0 - azimuth; 475 azimuth = 90.0 - azimuth;
381 else 476 else
382 azimuth = 450.0 - azimuth; 477 azimuth = 450.0 - azimuth;
383 478
384 // Elevation 479 // Elevation
385 double elevation = 90 - rad2deg(sourceListener.angleBetween(up)); 480 double elevation = 90 - rad2deg(sourceListener.angleBetween(up));
386 fixNANs(elevation); // avoid illegal values 481 fixNANs(elevation); // avoid illegal values
387 482
388 if (elevation > 90.0) 483 if (elevation > 90.0)
389 elevation = 180.0 - elevation; 484 elevation = 180.0 - elevation;
390 else if (elevation < -90.0) 485 else if (elevation < -90.0)
391 elevation = -180.0 - elevation; 486 elevation = -180.0 - elevation;
392 487
393 if (outAzimuth) 488 if (outAzimuth)
394 *outAzimuth = azimuth; 489 *outAzimuth = azimuth;
395 if (outElevation) 490 if (outElevation)
396 *outElevation = elevation; 491 *outElevation = elevation;
397 } 492 }
398 493
399 float PannerHandler::calculateDistanceConeGain() 494 float PannerHandler::calculateDistanceConeGain(
495 const FloatPoint3D& position,
496 const FloatPoint3D& orientation,
497 const FloatPoint3D& listenerPosition)
400 { 498 {
401 FloatPoint3D listenerPosition = listener()->position(); 499 double listenerDistance = position.distanceTo(listenerPosition);
402
403 double listenerDistance = m_position.distanceTo(listenerPosition);
404 double distanceGain = m_distanceEffect.gain(listenerDistance); 500 double distanceGain = m_distanceEffect.gain(listenerDistance);
405 double coneGain = m_coneEffect.gain(m_position, m_orientation, listenerPosit ion); 501 double coneGain = m_coneEffect.gain(position, orientation, listenerPosition) ;
406 502
407 return float(distanceGain * coneGain); 503 return float(distanceGain * coneGain);
408 } 504 }
409 505
410 void PannerHandler::azimuthElevation(double* outAzimuth, double* outElevation) 506 void PannerHandler::azimuthElevation(double* outAzimuth, double* outElevation)
411 { 507 {
412 ASSERT(context()->isAudioThread()); 508 ASSERT(context()->isAudioThread());
413 509
414 if (isAzimuthElevationDirty()) { 510 if (isAzimuthElevationDirty()) {
415 calculateAzimuthElevation(&m_cachedAzimuth, &m_cachedElevation); 511 calculateAzimuthElevation(
512 &m_cachedAzimuth,
513 &m_cachedElevation,
514 position(),
515 listener()->position(),
516 listener()->orientation(),
517 listener()->upVector());
416 m_isAzimuthElevationDirty = false; 518 m_isAzimuthElevationDirty = false;
417 } 519 }
418 520
419 *outAzimuth = m_cachedAzimuth; 521 *outAzimuth = m_cachedAzimuth;
420 *outElevation = m_cachedElevation; 522 *outElevation = m_cachedElevation;
421 } 523 }
422 524
423 float PannerHandler::distanceConeGain() 525 float PannerHandler::distanceConeGain()
424 { 526 {
425 ASSERT(context()->isAudioThread()); 527 ASSERT(context()->isAudioThread());
426 528
427 if (isDistanceConeGainDirty()) { 529 if (isDistanceConeGainDirty()) {
428 m_cachedDistanceConeGain = calculateDistanceConeGain(); 530 m_cachedDistanceConeGain = calculateDistanceConeGain(position(), orienta tion(), listener()->position());
429 m_isDistanceConeGainDirty = false; 531 m_isDistanceConeGainDirty = false;
430 } 532 }
431 533
432 return m_cachedDistanceConeGain; 534 return m_cachedDistanceConeGain;
433 } 535 }
434 536
435 void PannerHandler::markPannerAsDirty(unsigned dirty) 537 void PannerHandler::markPannerAsDirty(unsigned dirty)
436 { 538 {
437 if (dirty & PannerHandler::AzimuthElevationDirty) 539 if (dirty & PannerHandler::AzimuthElevationDirty)
438 m_isAzimuthElevationDirty = true; 540 m_isAzimuthElevationDirty = true;
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
485 m_newChannelCountMode = oldMode; 587 m_newChannelCountMode = oldMode;
486 } else { 588 } else {
487 // Do nothing for other invalid values. 589 // Do nothing for other invalid values.
488 m_newChannelCountMode = oldMode; 590 m_newChannelCountMode = oldMode;
489 } 591 }
490 592
491 if (m_newChannelCountMode != oldMode) 593 if (m_newChannelCountMode != oldMode)
492 context()->deferredTaskHandler().addChangedChannelCountMode(this); 594 context()->deferredTaskHandler().addChangedChannelCountMode(this);
493 } 595 }
494 596
597 bool PannerHandler::hasSampleAccurateValues() const
598 {
599 return m_positionX->hasSampleAccurateValues()
600 || m_positionY->hasSampleAccurateValues()
601 || m_positionZ->hasSampleAccurateValues()
602 || m_orientationX->hasSampleAccurateValues()
603 || m_orientationY->hasSampleAccurateValues()
604 || m_orientationZ->hasSampleAccurateValues();
605 }
606
607 void PannerHandler::updateDirtyState()
608 {
609 FloatPoint3D currentPosition = position();
610 FloatPoint3D currentOrientation = orientation();
611
612 bool hasMoved = currentPosition != m_lastPosition
613 || currentOrientation != m_lastOrientation;
614
615 if (hasMoved) {
616 m_lastPosition = currentPosition;
617 m_lastOrientation = currentOrientation;
618
619 markPannerAsDirty(PannerHandler::AzimuthElevationDirty | PannerHandler:: DistanceConeGainDirty);
620 }
621 }
495 // ---------------------------------------------------------------- 622 // ----------------------------------------------------------------
496 623
497 PannerNode::PannerNode(AbstractAudioContext& context, float sampelRate) 624 PannerNode::PannerNode(AbstractAudioContext& context, float sampleRate)
498 : AudioNode(context) 625 : AudioNode(context)
626 , m_positionX(AudioParam::create(context, ParamTypePannerPositionX, 0.0))
627 , m_positionY(AudioParam::create(context, ParamTypePannerPositionY, 0.0))
628 , m_positionZ(AudioParam::create(context, ParamTypePannerPositionZ, 0.0))
629 , m_orientationX(AudioParam::create(context, ParamTypePannerOrientationX, 1. 0))
630 , m_orientationY(AudioParam::create(context, ParamTypePannerOrientationY, 0. 0))
631 , m_orientationZ(AudioParam::create(context, ParamTypePannerOrientationZ, 0. 0))
499 { 632 {
500 setHandler(PannerHandler::create(*this, sampelRate)); 633 setHandler(PannerHandler::create(
634 *this,
635 sampleRate,
636 m_positionX->handler(),
637 m_positionY->handler(),
638 m_positionZ->handler(),
639 m_orientationX->handler(),
640 m_orientationY->handler(),
641 m_orientationZ->handler()));
501 } 642 }
502 643
503 PannerNode* PannerNode::create(AbstractAudioContext& context, float sampleRate) 644 PannerNode* PannerNode::create(AbstractAudioContext& context, float sampleRate)
504 { 645 {
505 return new PannerNode(context, sampleRate); 646 return new PannerNode(context, sampleRate);
506 } 647 }
507 648
508 PannerHandler& PannerNode::pannerHandler() const 649 PannerHandler& PannerNode::pannerHandler() const
509 { 650 {
510 return static_cast<PannerHandler&>(handler()); 651 return static_cast<PannerHandler&>(handler());
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
599 double PannerNode::coneOuterGain() const 740 double PannerNode::coneOuterGain() const
600 { 741 {
601 return pannerHandler().coneOuterGain(); 742 return pannerHandler().coneOuterGain();
602 } 743 }
603 744
604 void PannerNode::setConeOuterGain(double gain) 745 void PannerNode::setConeOuterGain(double gain)
605 { 746 {
606 pannerHandler().setConeOuterGain(gain); 747 pannerHandler().setConeOuterGain(gain);
607 } 748 }
608 749
750 DEFINE_TRACE(PannerNode)
751 {
752 visitor->trace(m_positionX);
753 visitor->trace(m_positionY);
754 visitor->trace(m_positionZ);
755
756 visitor->trace(m_orientationX);
757 visitor->trace(m_orientationY);
758 visitor->trace(m_orientationZ);
759
760 AudioNode::trace(visitor);
761 }
762
609 } // namespace blink 763 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/modules/webaudio/PannerNode.h ('k') | third_party/WebKit/Source/modules/webaudio/PannerNode.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698