| Index: third_party/WebKit/Source/modules/webaudio/AudioListener.cpp
|
| diff --git a/third_party/WebKit/Source/modules/webaudio/AudioListener.cpp b/third_party/WebKit/Source/modules/webaudio/AudioListener.cpp
|
| index b41982d9d05ac5f59cbc674a08261ecb323b8b20..6b09f3775aa86f43d38fc5af5f3c0b1153a862dd 100644
|
| --- a/third_party/WebKit/Source/modules/webaudio/AudioListener.cpp
|
| +++ b/third_party/WebKit/Source/modules/webaudio/AudioListener.cpp
|
| @@ -29,17 +29,39 @@
|
| #include "modules/webaudio/AudioListener.h"
|
| #include "modules/webaudio/PannerNode.h"
|
| #include "platform/audio/AudioBus.h"
|
| +#include "platform/audio/AudioUtilities.h"
|
| #include "platform/audio/HRTFDatabaseLoader.h"
|
|
|
| namespace blink {
|
|
|
| -AudioListener::AudioListener()
|
| - : m_position(0, 0, 0)
|
| - , m_orientation(0, 0, -1)
|
| - , m_upVector(0, 1, 0)
|
| +AudioListener::AudioListener(AbstractAudioContext& context)
|
| + : m_positionX(AudioParam::create(context, ParamTypeAudioListenerPositionX, 0.0))
|
| + , m_positionY(AudioParam::create(context, ParamTypeAudioListenerPositionY, 0.0))
|
| + , m_positionZ(AudioParam::create(context, ParamTypeAudioListenerPositionZ, 0.0))
|
| + , m_forwardX(AudioParam::create(context, ParamTypeAudioListenerForwardX, 0.0))
|
| + , m_forwardY(AudioParam::create(context, ParamTypeAudioListenerForwardY, 0.0))
|
| + , m_forwardZ(AudioParam::create(context, ParamTypeAudioListenerForwardZ, -1.0))
|
| + , m_upX(AudioParam::create(context, ParamTypeAudioListenerUpX, 0.0))
|
| + , m_upY(AudioParam::create(context, ParamTypeAudioListenerUpY, 1.0))
|
| + , m_upZ(AudioParam::create(context, ParamTypeAudioListenerUpZ, 0.0))
|
| , m_dopplerFactor(1)
|
| , m_speedOfSound(343.3)
|
| + , m_lastUpdateTime(-1)
|
| + , m_positionXValues(AudioUtilities::kRenderQuantumFrames)
|
| + , m_positionYValues(AudioUtilities::kRenderQuantumFrames)
|
| + , m_positionZValues(AudioUtilities::kRenderQuantumFrames)
|
| + , m_forwardXValues(AudioUtilities::kRenderQuantumFrames)
|
| + , m_forwardYValues(AudioUtilities::kRenderQuantumFrames)
|
| + , m_forwardZValues(AudioUtilities::kRenderQuantumFrames)
|
| + , m_upXValues(AudioUtilities::kRenderQuantumFrames)
|
| + , m_upYValues(AudioUtilities::kRenderQuantumFrames)
|
| + , m_upZValues(AudioUtilities::kRenderQuantumFrames)
|
| {
|
| + // Initialize the cached values with the current values. Thus, we don't need to notify any
|
| + // panners because we haved moved.
|
| + m_lastPosition = position();
|
| + m_lastForward = orientation();
|
| + m_lastUp = upVector();
|
| }
|
|
|
| AudioListener::~AudioListener()
|
| @@ -48,6 +70,17 @@ AudioListener::~AudioListener()
|
|
|
| DEFINE_TRACE(AudioListener)
|
| {
|
| + visitor->trace(m_positionX);
|
| + visitor->trace(m_positionY);
|
| + visitor->trace(m_positionZ);
|
| +
|
| + visitor->trace(m_forwardX);
|
| + visitor->trace(m_forwardY);
|
| + visitor->trace(m_forwardZ);
|
| +
|
| + visitor->trace(m_upX);
|
| + visitor->trace(m_upY);
|
| + visitor->trace(m_upZ);
|
| }
|
|
|
| void AudioListener::addPanner(PannerHandler& panner)
|
| @@ -63,6 +96,132 @@ void AudioListener::removePanner(PannerHandler& panner)
|
| m_panners.remove(&panner);
|
| }
|
|
|
| +bool AudioListener::hasSampleAccurateValues() const
|
| +{
|
| + return positionX()->handler().hasSampleAccurateValues()
|
| + || positionY()->handler().hasSampleAccurateValues()
|
| + || positionZ()->handler().hasSampleAccurateValues()
|
| + || forwardX()->handler().hasSampleAccurateValues()
|
| + || forwardY()->handler().hasSampleAccurateValues()
|
| + || forwardZ()->handler().hasSampleAccurateValues()
|
| + || upX()->handler().hasSampleAccurateValues()
|
| + || upY()->handler().hasSampleAccurateValues()
|
| + || upZ()->handler().hasSampleAccurateValues();
|
| +}
|
| +
|
| +void AudioListener::updateValuesIfNeeded(size_t framesToProcess)
|
| +{
|
| + double currentTime = positionX()->handler().destinationHandler().currentTime();
|
| + if (m_lastUpdateTime != currentTime) {
|
| + // Time has changed. Update all of the automation values now.
|
| + m_lastUpdateTime = currentTime;
|
| +
|
| + bool sizesAreGood = framesToProcess <= m_positionXValues.size()
|
| + && framesToProcess <= m_positionYValues.size()
|
| + && framesToProcess <= m_positionZValues.size()
|
| + && framesToProcess <= m_forwardXValues.size()
|
| + && framesToProcess <= m_forwardYValues.size()
|
| + && framesToProcess <= m_forwardZValues.size()
|
| + && framesToProcess <= m_upXValues.size()
|
| + && framesToProcess <= m_upYValues.size()
|
| + && framesToProcess <= m_upZValues.size();
|
| +
|
| + DCHECK(sizesAreGood);
|
| + if (!sizesAreGood)
|
| + return;
|
| +
|
| + positionX()->handler().calculateSampleAccurateValues(m_positionXValues.data(), framesToProcess);
|
| + positionY()->handler().calculateSampleAccurateValues(m_positionYValues.data(), framesToProcess);
|
| + positionZ()->handler().calculateSampleAccurateValues(m_positionZValues.data(), framesToProcess);
|
| +
|
| + forwardX()->handler().calculateSampleAccurateValues(m_forwardXValues.data(), framesToProcess);
|
| + forwardY()->handler().calculateSampleAccurateValues(m_forwardYValues.data(), framesToProcess);
|
| + forwardZ()->handler().calculateSampleAccurateValues(m_forwardZValues.data(), framesToProcess);
|
| +
|
| + upX()->handler().calculateSampleAccurateValues(m_upXValues.data(), framesToProcess);
|
| + upY()->handler().calculateSampleAccurateValues(m_upYValues.data(), framesToProcess);
|
| + upZ()->handler().calculateSampleAccurateValues(m_upZValues.data(), framesToProcess);
|
| + }
|
| +}
|
| +
|
| +const float* AudioListener::getPositionXValues(size_t framesToProcess)
|
| +{
|
| + updateValuesIfNeeded(framesToProcess);
|
| + return m_positionXValues.data();
|
| +}
|
| +
|
| +const float* AudioListener::getPositionYValues(size_t framesToProcess)
|
| +{
|
| + updateValuesIfNeeded(framesToProcess);
|
| + return m_positionYValues.data();
|
| +}
|
| +
|
| +const float* AudioListener::getPositionZValues(size_t framesToProcess)
|
| +{
|
| + updateValuesIfNeeded(framesToProcess);
|
| + return m_positionZValues.data();
|
| +}
|
| +
|
| +const float* AudioListener::getForwardXValues(size_t framesToProcess)
|
| +{
|
| + updateValuesIfNeeded(framesToProcess);
|
| + return m_forwardXValues.data();
|
| +}
|
| +
|
| +const float* AudioListener::getForwardYValues(size_t framesToProcess)
|
| +{
|
| + updateValuesIfNeeded(framesToProcess);
|
| + return m_forwardYValues.data();
|
| +}
|
| +
|
| +const float* AudioListener::getForwardZValues(size_t framesToProcess)
|
| +{
|
| + updateValuesIfNeeded(framesToProcess);
|
| + return m_forwardZValues.data();
|
| +}
|
| +
|
| +const float* AudioListener::getUpXValues(size_t framesToProcess)
|
| +{
|
| + updateValuesIfNeeded(framesToProcess);
|
| + return m_upXValues.data();
|
| +}
|
| +
|
| +const float* AudioListener::getUpYValues(size_t framesToProcess)
|
| +{
|
| + updateValuesIfNeeded(framesToProcess);
|
| + return m_upYValues.data();
|
| +}
|
| +
|
| +const float* AudioListener::getUpZValues(size_t framesToProcess)
|
| +{
|
| + updateValuesIfNeeded(framesToProcess);
|
| + return m_upZValues.data();
|
| +}
|
| +
|
| +void AudioListener::updateState()
|
| +{
|
| + FloatPoint3D currentPosition = position();
|
| + FloatPoint3D currentForward = orientation();
|
| + FloatPoint3D currentUp = upVector();
|
| +
|
| + bool hasMoved = currentPosition != m_lastPosition
|
| + || currentForward != m_lastForward
|
| + || currentUp != m_lastUp;
|
| +
|
| + if (hasMoved) {
|
| + m_lastPosition = currentPosition;
|
| + m_lastForward = currentForward;
|
| + m_lastUp = currentUp;
|
| +
|
| + markPannersAsDirty(PannerHandler::AzimuthElevationDirty | PannerHandler::DistanceConeGainDirty);
|
| + } else {
|
| + // Tell each panner to check its dirty state in case the panner position/orientation
|
| + // changed.
|
| + for (PannerHandler* panner : m_panners)
|
| + panner->updateDirtyState();
|
| + }
|
| +}
|
| +
|
| void AudioListener::createAndLoadHRTFDatabaseLoader(float sampleRate)
|
| {
|
| if (!m_hrtfDatabaseLoader)
|
| @@ -88,34 +247,31 @@ void AudioListener::markPannersAsDirty(unsigned type)
|
|
|
| void AudioListener::setPosition(const FloatPoint3D& position)
|
| {
|
| - if (m_position == position)
|
| - return;
|
| -
|
| // This synchronizes with panner's process().
|
| MutexLocker listenerLocker(m_listenerLock);
|
| - m_position = position;
|
| + m_positionX->setValue(position.x());
|
| + m_positionY->setValue(position.y());
|
| + m_positionZ->setValue(position.z());
|
| markPannersAsDirty(PannerHandler::AzimuthElevationDirty | PannerHandler::DistanceConeGainDirty);
|
| }
|
|
|
| void AudioListener::setOrientation(const FloatPoint3D& orientation)
|
| {
|
| - if (m_orientation == orientation)
|
| - return;
|
| -
|
| // This synchronizes with panner's process().
|
| MutexLocker listenerLocker(m_listenerLock);
|
| - m_orientation = orientation;
|
| + m_forwardX->setValue(orientation.x());
|
| + m_forwardY->setValue(orientation.y());
|
| + m_forwardZ->setValue(orientation.z());
|
| markPannersAsDirty(PannerHandler::AzimuthElevationDirty);
|
| }
|
|
|
| void AudioListener::setUpVector(const FloatPoint3D& upVector)
|
| {
|
| - if (m_upVector == upVector)
|
| - return;
|
| -
|
| // This synchronizes with panner's process().
|
| MutexLocker listenerLocker(m_listenerLock);
|
| - m_upVector = upVector;
|
| + m_upX->setValue(upVector.x());
|
| + m_upY->setValue(upVector.y());
|
| + m_upZ->setValue(upVector.z());
|
| markPannersAsDirty(PannerHandler::AzimuthElevationDirty);
|
| }
|
|
|
|
|