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

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

Issue 232453003: Add logic to cache elements of panner node from calculation with own attributes and AudioListener (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 8 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 13 matching lines...) Expand all
24 24
25 #include "config.h" 25 #include "config.h"
26 26
27 #if ENABLE(WEB_AUDIO) 27 #if ENABLE(WEB_AUDIO)
28 28
29 #include "modules/webaudio/PannerNode.h" 29 #include "modules/webaudio/PannerNode.h"
30 30
31 #include "core/dom/ExecutionContext.h" 31 #include "core/dom/ExecutionContext.h"
32 #include "platform/audio/HRTFPanner.h" 32 #include "platform/audio/HRTFPanner.h"
33 #include "modules/webaudio/AudioBufferSourceNode.h" 33 #include "modules/webaudio/AudioBufferSourceNode.h"
34 #include "modules/webaudio/AudioContext.h"
35 #include "modules/webaudio/AudioNodeInput.h" 34 #include "modules/webaudio/AudioNodeInput.h"
36 #include "modules/webaudio/AudioNodeOutput.h" 35 #include "modules/webaudio/AudioNodeOutput.h"
37 #include "wtf/MathExtras.h" 36 #include "wtf/MathExtras.h"
38 37
39 using namespace std; 38 using namespace std;
40 39
41 namespace WebCore { 40 namespace WebCore {
42 41
43 static void fixNANs(double &x) 42 static void fixNANs(double &x)
44 { 43 {
45 if (std::isnan(x) || std::isinf(x)) 44 if (std::isnan(x) || std::isinf(x))
46 x = 0.0; 45 x = 0.0;
47 } 46 }
48 47
49 PannerNode::PannerNode(AudioContext* context, float sampleRate) 48 PannerNode::PannerNode(AudioContext* context, float sampleRate)
50 : AudioNode(context, sampleRate) 49 : AudioNode(context, sampleRate)
51 , m_panningModel(Panner::PanningModelHRTF) 50 , m_panningModel(Panner::PanningModelHRTF)
52 , m_distanceModel(DistanceEffect::ModelInverse) 51 , m_distanceModel(DistanceEffect::ModelInverse)
53 , m_position(0, 0, 0) 52 , m_position(0, 0, 0)
54 , m_orientation(1, 0, 0) 53 , m_orientation(1, 0, 0)
55 , m_velocity(0, 0, 0) 54 , m_velocity(0, 0, 0)
56 , m_cachedPosition(0, 0, 0) 55 , m_isAzimuthElevationDirty(true)
57 , m_cachedOrientation(1, 0, 0) 56 , m_isDistanceConeGainDirty(true)
58 , m_cachedVelocity(0, 0, 0) 57 , m_isDopplerRateDirty(true)
59 , m_lastGain(-1.0) 58 , m_lastGain(-1.0)
60 , m_cachedAzimuth(0) 59 , m_cachedAzimuth(0)
61 , m_cachedElevation(0) 60 , m_cachedElevation(0)
62 , m_cachedDistanceConeGain(1.0f) 61 , m_cachedDistanceConeGain(1.0f)
63 , m_cachedDopplerRate(1) 62 , m_cachedDopplerRate(1)
64 , m_connectionCount(0) 63 , m_connectionCount(0)
65 { 64 {
66 // Load the HRTF database asynchronously so we don't block the Javascript th read while creating the HRTF database. 65 // Load the HRTF database asynchronously so we don't block the Javascript th read while creating the HRTF database.
67 // The HRTF panner will return zeroes until the database is loaded. 66 // The HRTF panner will return zeroes until the database is loaded.
68 m_hrtfDatabaseLoader = HRTFDatabaseLoader::createAndLoadAsynchronouslyIfNece ssary(context->sampleRate()); 67 m_hrtfDatabaseLoader = HRTFDatabaseLoader::createAndLoadAsynchronouslyIfNece ssary(context->sampleRate());
69 68
70 ScriptWrappable::init(this); 69 ScriptWrappable::init(this);
71 addInput(adoptPtr(new AudioNodeInput(this))); 70 addInput(adoptPtr(new AudioNodeInput(this)));
72 addOutput(adoptPtr(new AudioNodeOutput(this, 2))); 71 addOutput(adoptPtr(new AudioNodeOutput(this, 2)));
73 72
74 // Node-specific default mixing rules. 73 // Node-specific default mixing rules.
75 m_channelCount = 2; 74 m_channelCount = 2;
76 m_channelCountMode = ClampedMax; 75 m_channelCountMode = ClampedMax;
77 m_channelInterpretation = AudioBus::Speakers; 76 m_channelInterpretation = AudioBus::Speakers;
78 77
79 m_cachedListener = AudioListener::create();
80
81 setNodeType(NodeTypePanner); 78 setNodeType(NodeTypePanner);
82 79
83 initialize(); 80 initialize();
84 } 81 }
85 82
86 PannerNode::~PannerNode() 83 PannerNode::~PannerNode()
87 { 84 {
88 uninitialize(); 85 uninitialize();
89 } 86 }
90 87
(...skipping 25 matching lines...) Expand all
116 } 113 }
117 114
118 AudioBus* source = input(0)->bus(); 115 AudioBus* source = input(0)->bus();
119 if (!source) { 116 if (!source) {
120 destination->zero(); 117 destination->zero();
121 return; 118 return;
122 } 119 }
123 120
124 // The audio thread can't block on this lock, so we call tryLock() instead. 121 // The audio thread can't block on this lock, so we call tryLock() instead.
125 MutexTryLocker tryLocker(m_processLock); 122 MutexTryLocker tryLocker(m_processLock);
126 if (tryLocker.locked()) { 123 MutexTryLocker tryListenerLocker(listener()->listenerLock());
KhNo 2014/04/14 11:23:30 It is required to lock context's listener.
124
125 if (tryLocker.locked() && tryListenerLocker.locked()) {
127 // HRTFDatabase should be loaded before proceeding for offline audio con text when the panning model is HRTF. 126 // HRTFDatabase should be loaded before proceeding for offline audio con text when the panning model is HRTF.
128 if (m_panningModel == HRTF && !m_hrtfDatabaseLoader->isLoaded()) { 127 if (m_panningModel == HRTF && !m_hrtfDatabaseLoader->isLoaded()) {
129 if (context()->isOfflineContext()) { 128 if (context()->isOfflineContext()) {
130 m_hrtfDatabaseLoader->waitForLoaderThreadCompletion(); 129 m_hrtfDatabaseLoader->waitForLoaderThreadCompletion();
131 } else { 130 } else {
132 destination->zero(); 131 destination->zero();
133 return; 132 return;
134 } 133 }
135 } 134 }
136 135
137 // Apply the panning effect. 136 // Apply the panning effect.
138 double azimuth; 137 double azimuth;
139 double elevation; 138 double elevation;
140 azimuthElevation(&azimuth, &elevation); 139 azimuthElevation(&azimuth, &elevation);
141 140
142 m_panner->pan(azimuth, elevation, source, destination, framesToProcess); 141 m_panner->pan(azimuth, elevation, source, destination, framesToProcess);
143 142
144 // Get the distance and cone gain. 143 // Get the distance and cone gain.
145 float totalGain = distanceConeGain(); 144 float totalGain = distanceConeGain();
146 145
147 // Snap to desired gain at the beginning. 146 // Snap to desired gain at the beginning.
148 if (m_lastGain == -1.0) 147 if (m_lastGain == -1.0)
149 m_lastGain = totalGain; 148 m_lastGain = totalGain;
150 149
151 // Apply gain in-place with de-zippering. 150 // Apply gain in-place with de-zippering.
152 destination->copyWithGainFrom(*destination, &m_lastGain, totalGain); 151 destination->copyWithGainFrom(*destination, &m_lastGain, totalGain);
153
154 // Update the cached listener in case listener has moved.
155 updateCachedListener();
156 // Now update the cached source location in case the source has changed.
157 updateCachedSourceLocationInfo();
158 } else { 152 } else {
159 // Too bad - The tryLock() failed. 153 // Too bad - The tryLock() failed.
160 // We must be in the middle of changing the panning model, the distance model, or the source's location information. 154 // We must be in the middle of changing the panning model, source's loca tion information, listener, distance parameters and sound cones.
161 destination->zero(); 155 destination->zero();
162 } 156 }
163 } 157 }
164 158
165 void PannerNode::initialize() 159 void PannerNode::initialize()
166 { 160 {
167 if (isInitialized()) 161 if (isInitialized())
168 return; 162 return;
169 163
170 m_panner = Panner::create(m_panningModel, sampleRate(), m_hrtfDatabaseLoader .get()); 164 m_panner = Panner::create(m_panningModel, sampleRate(), m_hrtfDatabaseLoader .get());
165 listener()->addPanner(this);
171 166
172 AudioNode::initialize(); 167 AudioNode::initialize();
173 } 168 }
174 169
175 void PannerNode::uninitialize() 170 void PannerNode::uninitialize()
176 { 171 {
177 if (!isInitialized()) 172 if (!isInitialized())
178 return; 173 return;
179 174
180 m_panner.clear(); 175 m_panner.clear();
176 listener()->removePanner(this);
177
181 AudioNode::uninitialize(); 178 AudioNode::uninitialize();
182 } 179 }
183 180
184 AudioListener* PannerNode::listener()
185 {
186 return context()->listener();
187 }
188
189 String PannerNode::panningModel() const 181 String PannerNode::panningModel() const
190 { 182 {
191 switch (m_panningModel) { 183 switch (m_panningModel) {
192 case EQUALPOWER: 184 case EqualPower:
193 return "equalpower"; 185 return "equalpower";
194 case HRTF: 186 case HRTF:
195 return "HRTF"; 187 return "HRTF";
196 default: 188 default:
197 ASSERT_NOT_REACHED(); 189 ASSERT_NOT_REACHED();
198 return "HRTF"; 190 return "HRTF";
199 } 191 }
200 } 192 }
201 193
202 void PannerNode::setPanningModel(const String& model) 194 void PannerNode::setPanningModel(const String& model)
203 { 195 {
204 if (model == "equalpower") 196 if (model == "equalpower")
205 setPanningModel(EQUALPOWER); 197 setPanningModel(EqualPower);
206 else if (model == "HRTF") 198 else if (model == "HRTF")
207 setPanningModel(HRTF); 199 setPanningModel(HRTF);
208 } 200 }
209 201
210 bool PannerNode::setPanningModel(unsigned model) 202 bool PannerNode::setPanningModel(unsigned model)
211 { 203 {
212 switch (model) { 204 switch (model) {
213 case EQUALPOWER: 205 case EqualPower:
214 case HRTF: 206 case HRTF:
215 if (!m_panner.get() || model != m_panningModel) { 207 if (!m_panner.get() || model != m_panningModel) {
216 // This synchronizes with process(). 208 // This synchronizes with process().
217 MutexLocker processLocker(m_processLock); 209 MutexLocker processLocker(m_processLock);
218
219 OwnPtr<Panner> newPanner = Panner::create(model, sampleRate(), m_hrt fDatabaseLoader.get()); 210 OwnPtr<Panner> newPanner = Panner::create(model, sampleRate(), m_hrt fDatabaseLoader.get());
220 m_panner = newPanner.release(); 211 m_panner = newPanner.release();
221 m_panningModel = model; 212 m_panningModel = model;
222 } 213 }
223 break; 214 break;
224 default: 215 default:
225 return false; 216 return false;
226 } 217 }
227 218
228 return true; 219 return true;
229 } 220 }
230 221
231 void PannerNode::setPosition(float x, float y, float z)
232 {
233 FloatPoint3D position = FloatPoint3D(x, y, z);
234
235 if (m_position == position)
236 return;
237
238 // This synchronizes with process().
239 MutexLocker processLocker(m_processLock);
240
241 m_position = position;
242 }
243
244 void PannerNode::setOrientation(float x, float y, float z)
245 {
246 FloatPoint3D orientation = FloatPoint3D(x, y, z);
247
248 if (m_orientation == orientation)
249 return;
250
251 // This synchronizes with process().
252 MutexLocker processLocker(m_processLock);
253
254 m_orientation = orientation;
255 }
256
257 void PannerNode::setVelocity(float x, float y, float z)
258 {
259 FloatPoint3D velocity = FloatPoint3D(x, y, z);
260
261 if (m_velocity == velocity)
262 return;
263
264 // This synchronizes with process().
265 MutexLocker processLocker(m_processLock);
266
267 m_velocity = velocity;
268 }
269
270 String PannerNode::distanceModel() const 222 String PannerNode::distanceModel() const
271 { 223 {
272 switch (const_cast<PannerNode*>(this)->m_distanceEffect.model()) { 224 switch (const_cast<PannerNode*>(this)->m_distanceEffect.model()) {
273 case DistanceEffect::ModelLinear: 225 case DistanceEffect::ModelLinear:
274 return "linear"; 226 return "linear";
275 case DistanceEffect::ModelInverse: 227 case DistanceEffect::ModelInverse:
276 return "inverse"; 228 return "inverse";
277 case DistanceEffect::ModelExponential: 229 case DistanceEffect::ModelExponential:
278 return "exponential"; 230 return "exponential";
279 default: 231 default:
(...skipping 25 matching lines...) Expand all
305 m_distanceModel = model; 257 m_distanceModel = model;
306 } 258 }
307 break; 259 break;
308 default: 260 default:
309 return false; 261 return false;
310 } 262 }
311 263
312 return true; 264 return true;
313 } 265 }
314 266
267 void PannerNode::setRefDistance(double distance)
268 {
269 if (refDistance() == distance)
270 return;
271
272 // This synchronizes with process().
273 MutexLocker processLocker(m_processLock);
274 m_distanceEffect.setRefDistance(distance);
275 updatePannerDirty(PannerNode::DistanceConeGainDirty);
276 }
277
278 void PannerNode::setMaxDistance(double distance)
279 {
280 if (maxDistance() == distance)
281 return;
282
283 // This synchronizes with process().
284 MutexLocker processLocker(m_processLock);
285 m_distanceEffect.setMaxDistance(distance);
286 updatePannerDirty(PannerNode::DistanceConeGainDirty);
287 }
288
289 void PannerNode::setRolloffFactor(double factor)
290 {
291 if (rolloffFactor() == factor)
292 return;
293
294 // This synchronizes with process().
295 MutexLocker processLocker(m_processLock);
296 m_distanceEffect.setRolloffFactor(factor);
297 updatePannerDirty(PannerNode::DistanceConeGainDirty);
298 }
299
300 void PannerNode::setConeInnerAngle(double angle)
301 {
302 if (coneInnerAngle() == angle)
303 return;
304
305 // This synchronizes with process().
306 MutexLocker processLocker(m_processLock);
307 m_coneEffect.setInnerAngle(angle);
308 updatePannerDirty(PannerNode::DistanceConeGainDirty);
309 }
310
311 void PannerNode::setConeOuterAngle(double angle)
312 {
313 if (coneOuterAngle() == angle)
314 return;
315
316 // This synchronizes with process().
317 MutexLocker processLocker(m_processLock);
318 m_coneEffect.setOuterAngle(angle);
319 updatePannerDirty(PannerNode::DistanceConeGainDirty);
320 }
321
322 void PannerNode::setConeOuterGain(double angle)
323 {
324 if (coneOuterGain() == angle)
325 return;
326
327 // This synchronizes with process().
328 MutexLocker processLocker(m_processLock);
329 m_coneEffect.setOuterGain(angle);
330 updatePannerDirty(PannerNode::DistanceConeGainDirty);
331 }
332
333 void PannerNode::setPosition(float x, float y, float z)
334 {
335 FloatPoint3D position = FloatPoint3D(x, y, z);
336
337 if (m_position == position)
338 return;
339
340 // This synchronizes with process().
341 MutexLocker processLocker(m_processLock);
342 m_position = position;
343 updatePannerDirty(PannerNode::AzimuthElevationDirty | PannerNode::DistanceCo neGainDirty | PannerNode::DopplerRateDirty);
344 }
345
346 void PannerNode::setOrientation(float x, float y, float z)
347 {
348 FloatPoint3D orientation = FloatPoint3D(x, y, z);
349
350 if (m_orientation == orientation)
351 return;
352
353 // This synchronizes with process().
354 MutexLocker processLocker(m_processLock);
355 m_orientation = orientation;
356 updatePannerDirty(PannerNode::DistanceConeGainDirty);
357 }
358
359 void PannerNode::setVelocity(float x, float y, float z)
360 {
361 FloatPoint3D velocity = FloatPoint3D(x, y, z);
362
363 if (m_velocity == velocity)
364 return;
365
366 // This synchronizes with process().
367 MutexLocker processLocker(m_processLock);
368 m_velocity = velocity;
369 updatePannerDirty(PannerNode::DopplerRateDirty);
370 }
371
315 void PannerNode::calculateAzimuthElevation(double* outAzimuth, double* outElevat ion) 372 void PannerNode::calculateAzimuthElevation(double* outAzimuth, double* outElevat ion)
316 { 373 {
317 double azimuth = 0.0; 374 double azimuth = 0.0;
318 375
319 // Calculate the source-listener vector 376 // Calculate the source-listener vector
320 FloatPoint3D listenerPosition = listener()->position(); 377 FloatPoint3D listenerPosition = listener()->position();
321 FloatPoint3D sourceListener = m_position - listenerPosition; 378 FloatPoint3D sourceListener = m_position - listenerPosition;
322 379
323 if (sourceListener.isZero()) { 380 if (sourceListener.isZero()) {
324 // degenerate case if source and listener are at the same point 381 // degenerate case if source and listener are at the same point
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
428 double distanceGain = m_distanceEffect.gain(listenerDistance); 485 double distanceGain = m_distanceEffect.gain(listenerDistance);
429 double coneGain = m_coneEffect.gain(m_position, m_orientation, listenerPosit ion); 486 double coneGain = m_coneEffect.gain(m_position, m_orientation, listenerPosit ion);
430 487
431 return float(distanceGain * coneGain); 488 return float(distanceGain * coneGain);
432 } 489 }
433 490
434 void PannerNode::azimuthElevation(double* outAzimuth, double* outElevation) 491 void PannerNode::azimuthElevation(double* outAzimuth, double* outElevation)
435 { 492 {
436 ASSERT(context()->isAudioThread()); 493 ASSERT(context()->isAudioThread());
437 494
438 if (isAzimuthElevationDirty()) 495 if (isAzimuthElevationDirty()) {
439 calculateAzimuthElevation(&m_cachedAzimuth, &m_cachedElevation); 496 calculateAzimuthElevation(&m_cachedAzimuth, &m_cachedElevation);
497 m_isAzimuthElevationDirty = false;
498 }
440 499
441 *outAzimuth = m_cachedAzimuth; 500 *outAzimuth = m_cachedAzimuth;
442 *outElevation = m_cachedElevation; 501 *outElevation = m_cachedElevation;
443 } 502 }
444 503
445 double PannerNode::dopplerRate() 504 double PannerNode::dopplerRate()
446 { 505 {
447 ASSERT(context()->isAudioThread()); 506 ASSERT(context()->isAudioThread());
448 507
449 if (isDopplerRateDirty()) 508 if (isDopplerRateDirty()) {
450 m_cachedDopplerRate = calculateDopplerRate(); 509 m_cachedDopplerRate = calculateDopplerRate();
510 m_isDopplerRateDirty = false;
511 }
451 512
452 return m_cachedDopplerRate; 513 return m_cachedDopplerRate;
453 } 514 }
454 515
455 float PannerNode::distanceConeGain() 516 float PannerNode::distanceConeGain()
456 { 517 {
457 ASSERT(context()->isAudioThread()); 518 ASSERT(context()->isAudioThread());
458 519
459 if (isDistanceConeGainDirty()) 520 if (isDistanceConeGainDirty()) {
460 m_cachedDistanceConeGain = calculateDistanceConeGain(); 521 m_cachedDistanceConeGain = calculateDistanceConeGain();
522 m_isDistanceConeGainDirty = false;
523 }
461 524
462 return m_cachedDistanceConeGain; 525 return m_cachedDistanceConeGain;
463 } 526 }
464 527
465 bool PannerNode::isAzimuthElevationDirty() 528 void PannerNode::updatePannerDirty(unsigned dirty)
466 { 529 {
467 // Do a quick test and return if possible. 530 if (dirty & PannerNode::AzimuthElevationDirty)
468 if (m_cachedPosition != m_position) 531 m_isAzimuthElevationDirty = true;
469 return true;
470 532
471 if (m_cachedListener->position() != listener()->position() 533 if (dirty & PannerNode::DistanceConeGainDirty)
472 || m_cachedListener->orientation() != listener()->orientation() 534 m_isDistanceConeGainDirty = true;
473 || m_cachedListener->upVector() != listener()->upVector())
474 return true;
475 535
476 return false; 536 if (dirty & PannerNode::DopplerRateDirty)
477 } 537 m_isDopplerRateDirty = true;
478
479 bool PannerNode::isDistanceConeGainDirty()
480 {
481 // Do a quick test and return if possible.
482 if (m_cachedPosition != m_position || m_cachedOrientation != m_orientation)
483 return true;
484
485 if (m_cachedListener->position() != listener()->position())
486 return true;
487
488 return false;
489 }
490
491 bool PannerNode::isDopplerRateDirty()
492 {
493 // Do a quick test and return if possible.
494 if (m_cachedPosition != m_position || m_cachedVelocity != m_velocity)
495 return true;
496
497 if (m_cachedListener->position() != listener()->position()
498 || m_cachedListener->velocity() != listener()->velocity()
499 || m_cachedListener->dopplerFactor() != listener()->dopplerFactor()
500 || m_cachedListener->speedOfSound() != listener()->speedOfSound())
501 return true;
502
503 return false;
504 } 538 }
505 539
506 void PannerNode::notifyAudioSourcesConnectedToNode(AudioNode* node, HashMap<Audi oNode*, bool>& visitedNodes) 540 void PannerNode::notifyAudioSourcesConnectedToNode(AudioNode* node, HashMap<Audi oNode*, bool>& visitedNodes)
507 { 541 {
508 ASSERT(node); 542 ASSERT(node);
509 if (!node) 543 if (!node)
510 return; 544 return;
511 545
512 // First check if this node is an AudioBufferSourceNode. If so, let it know about us so that doppler shift pitch can be taken into account. 546 // First check if this node is an AudioBufferSourceNode. If so, let it know about us so that doppler shift pitch can be taken into account.
513 if (node->nodeType() == NodeTypeAudioBufferSource) { 547 if (node->nodeType() == NodeTypeAudioBufferSource) {
(...skipping 14 matching lines...) Expand all
528 // mark it as visited and recurse through the node looking for s ources. 562 // mark it as visited and recurse through the node looking for s ources.
529 if (iterator == visitedNodes.end()) { 563 if (iterator == visitedNodes.end()) {
530 visitedNodes.set(connectedNode, true); 564 visitedNodes.set(connectedNode, true);
531 notifyAudioSourcesConnectedToNode(connectedNode, visitedNode s); // recurse 565 notifyAudioSourcesConnectedToNode(connectedNode, visitedNode s); // recurse
532 } 566 }
533 } 567 }
534 } 568 }
535 } 569 }
536 } 570 }
537 571
538 void PannerNode::updateCachedListener()
539 {
540 ASSERT(context()->isAudioThread());
541
542 m_cachedListener->setPosition(listener()->position());
543 m_cachedListener->setOrientation(listener()->orientation());
544 m_cachedListener->setUpVector(listener()->upVector());
545 m_cachedListener->setVelocity(listener()->velocity());
546 m_cachedListener->setDopplerFactor(listener()->dopplerFactor());
547 m_cachedListener->setSpeedOfSound(listener()->speedOfSound());
548 }
549
550 void PannerNode::updateCachedSourceLocationInfo()
551 {
552 ASSERT(context()->isAudioThread());
553
554 m_cachedPosition = m_position;
555 m_cachedOrientation = m_orientation;
556 m_cachedVelocity = m_velocity;
557 }
558
559 } // namespace WebCore 572 } // namespace WebCore
560 573
561 #endif // ENABLE(WEB_AUDIO) 574 #endif // ENABLE(WEB_AUDIO)
OLDNEW
« Source/modules/webaudio/PannerNode.h ('K') | « Source/modules/webaudio/PannerNode.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698