| /* |
| * Copyright (C) 2010 Google Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of |
| * its contributors may be used to endorse or promote products derived |
| * from this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY |
| * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY |
| * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #include "config.h" |
| |
| #if ENABLE(WEB_AUDIO) |
| |
| #include "modules/webaudio/AudioListener.h" |
| |
| #include "modules/webaudio/PannerNode.h" |
| #include "platform/audio/AudioBus.h" |
| #include "platform/audio/HRTFDatabaseLoader.h" |
| #include "wtf/MainThread.h" |
| |
| namespace blink { |
| |
| AudioListener::AudioListener() |
| : m_position(0, 0, 0) |
| , m_orientation(0, 0, -1) |
| , m_upVector(0, 1, 0) |
| , m_velocity(0, 0, 0) |
| , m_dopplerFactor(1) |
| , m_speedOfSound(343.3) |
| { |
| } |
| |
| AudioListener::~AudioListener() |
| { |
| } |
| |
| void AudioListener::trace(Visitor* visitor) |
| { |
| visitor->trace(m_panners); |
| visitor->trace(m_hrtfDatabaseLoader); |
| } |
| |
| void AudioListener::addPanner(PannerNode* panner) |
| { |
| ASSERT(isMainThread()); |
| if (!panner) |
| return; |
| |
| m_panners.append(panner); |
| } |
| |
| void AudioListener::removePanner(PannerNode* panner) |
| { |
| ASSERT(isMainThread()); |
| for (unsigned i = 0; i < m_panners.size(); ++i) { |
| if (panner == m_panners[i]) { |
| m_panners.remove(i); |
| break; |
| } |
| } |
| } |
| |
| void AudioListener::createAndLoadHRTFDatabaseLoader(float sampleRate) |
| { |
| if (!m_hrtfDatabaseLoader) |
| m_hrtfDatabaseLoader = HRTFDatabaseLoader::createAndLoadAsynchronouslyIfNecessary(sampleRate); |
| } |
| |
| bool AudioListener::isHRTFDatabaseLoaded() |
| { |
| return m_hrtfDatabaseLoader->isLoaded(); |
| } |
| |
| void AudioListener::waitForHRTFDatabaseLoaderThreadCompletion() |
| { |
| m_hrtfDatabaseLoader->waitForLoaderThreadCompletion(); |
| } |
| |
| void AudioListener::markPannersAsDirty(unsigned type) |
| { |
| for (unsigned i = 0; i < m_panners.size(); ++i) |
| m_panners[i]->markPannerAsDirty(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; |
| markPannersAsDirty(PannerNode::AzimuthElevationDirty | PannerNode::DistanceConeGainDirty | PannerNode::DopplerRateDirty); |
| } |
| |
| void AudioListener::setOrientation(const FloatPoint3D &orientation) |
| { |
| if (m_orientation == orientation) |
| return; |
| |
| // This synchronizes with panner's process(). |
| MutexLocker listenerLocker(m_listenerLock); |
| m_orientation = orientation; |
| markPannersAsDirty(PannerNode::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; |
| markPannersAsDirty(PannerNode::AzimuthElevationDirty); |
| } |
| |
| void AudioListener::setVelocity(const FloatPoint3D &velocity) |
| { |
| if (m_velocity == velocity) |
| return; |
| |
| // This synchronizes with panner's process(). |
| MutexLocker listenerLocker(m_listenerLock); |
| m_velocity = velocity; |
| markPannersAsDirty(PannerNode::DopplerRateDirty); |
| } |
| |
| void AudioListener::setDopplerFactor(double dopplerFactor) |
| { |
| if (m_dopplerFactor == dopplerFactor) |
| return; |
| |
| // This synchronizes with panner's process(). |
| MutexLocker listenerLocker(m_listenerLock); |
| m_dopplerFactor = dopplerFactor; |
| markPannersAsDirty(PannerNode::DopplerRateDirty); |
| } |
| |
| void AudioListener::setSpeedOfSound(double speedOfSound) |
| { |
| if (m_speedOfSound == speedOfSound) |
| return; |
| |
| // This synchronizes with panner's process(). |
| MutexLocker listenerLocker(m_listenerLock); |
| m_speedOfSound = speedOfSound; |
| markPannersAsDirty(PannerNode::DopplerRateDirty); |
| } |
| |
| } // namespace blink |
| |
| #endif // ENABLE(WEB_AUDIO) |