| OLD | NEW |
| 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 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 121 if (tryLocker.locked() && tryListenerLocker.locked()) { | 121 if (tryLocker.locked() && tryListenerLocker.locked()) { |
| 122 if (!context()->hasRealtimeConstraint() && | 122 if (!context()->hasRealtimeConstraint() && |
| 123 m_panningModel == Panner::PanningModelHRTF) { | 123 m_panningModel == Panner::PanningModelHRTF) { |
| 124 // For an OfflineAudioContext, we need to make sure the HRTFDatabase | 124 // For an OfflineAudioContext, we need to make sure the HRTFDatabase |
| 125 // is loaded before proceeding. For realtime contexts, we don't | 125 // is loaded before proceeding. For realtime contexts, we don't |
| 126 // have to wait. The HRTF panner handles that case itself. | 126 // have to wait. The HRTF panner handles that case itself. |
| 127 listener()->waitForHRTFDatabaseLoaderThreadCompletion(); | 127 listener()->waitForHRTFDatabaseLoaderThreadCompletion(); |
| 128 } | 128 } |
| 129 | 129 |
| 130 if (hasSampleAccurateValues() || listener()->hasSampleAccurateValues()) { | 130 if (hasSampleAccurateValues() || listener()->hasSampleAccurateValues()) { |
| 131 // It's tempting to skip sample-accurate processing if isAzimuthElevationD
irty() and | 131 // It's tempting to skip sample-accurate processing if |
| 132 // isDistanceConeGain() both return false. But in general we can't becaus
e something | 132 // isAzimuthElevationDirty() and isDistanceConeGain() both return false. |
| 133 // may scheduled to start in the middle of the rendering quantum. On the
other hand, | 133 // But in general we can't because something may scheduled to start in the |
| 134 // the audible effect may be small enough that we can afford to do this op
timization. | 134 // middle of the rendering quantum. On the other hand, the audible effect |
| 135 // may be small enough that we can afford to do this optimization. |
| 135 processSampleAccurateValues(destination, source, framesToProcess); | 136 processSampleAccurateValues(destination, source, framesToProcess); |
| 136 } else { | 137 } else { |
| 137 // Apply the panning effect. | 138 // Apply the panning effect. |
| 138 double azimuth; | 139 double azimuth; |
| 139 double elevation; | 140 double elevation; |
| 140 | 141 |
| 141 // Update dirty state in case something has moved; this can happen if the
AudioParam for | 142 // Update dirty state in case something has moved; this can happen if the |
| 142 // the position or orientation component is set directly. | 143 // AudioParam for the position or orientation component is set directly. |
| 143 updateDirtyState(); | 144 updateDirtyState(); |
| 144 | 145 |
| 145 azimuthElevation(&azimuth, &elevation); | 146 azimuthElevation(&azimuth, &elevation); |
| 146 | 147 |
| 147 m_panner->pan(azimuth, elevation, source, destination, framesToProcess, | 148 m_panner->pan(azimuth, elevation, source, destination, framesToProcess, |
| 148 internalChannelInterpretation()); | 149 internalChannelInterpretation()); |
| 149 | 150 |
| 150 // Get the distance and cone gain. | 151 // Get the distance and cone gain. |
| 151 float totalGain = distanceConeGain(); | 152 float totalGain = distanceConeGain(); |
| 152 | 153 |
| 153 m_lastGain = totalGain; | 154 m_lastGain = totalGain; |
| 154 | 155 |
| 155 // Apply gain in-place with de-zippering. | 156 // Apply gain in-place with de-zippering. |
| 156 destination->copyWithGainFrom(*destination, &m_lastGain, totalGain); | 157 destination->copyWithGainFrom(*destination, &m_lastGain, totalGain); |
| 157 } | 158 } |
| 158 } else { | 159 } else { |
| 159 // Too bad - The tryLock() failed. | 160 // Too bad - The tryLock() failed. We must be in the middle of changing the |
| 160 // We must be in the middle of changing the properties of the panner or the
listener. | 161 // properties of the panner or the listener. |
| 161 destination->zero(); | 162 destination->zero(); |
| 162 } | 163 } |
| 163 } | 164 } |
| 164 | 165 |
| 165 void PannerHandler::processSampleAccurateValues(AudioBus* destination, | 166 void PannerHandler::processSampleAccurateValues(AudioBus* destination, |
| 166 const AudioBus* source, | 167 const AudioBus* source, |
| 167 size_t framesToProcess) { | 168 size_t framesToProcess) { |
| 168 RELEASE_ASSERT(framesToProcess <= ProcessingSizeInFrames); | 169 RELEASE_ASSERT(framesToProcess <= ProcessingSizeInFrames); |
| 169 | 170 |
| 170 // Get the sample accurate values from all of the AudioParams, including the v
alues from the | 171 // Get the sample accurate values from all of the AudioParams, including the |
| 171 // AudioListener. | 172 // values from the AudioListener. |
| 172 float pannerX[ProcessingSizeInFrames]; | 173 float pannerX[ProcessingSizeInFrames]; |
| 173 float pannerY[ProcessingSizeInFrames]; | 174 float pannerY[ProcessingSizeInFrames]; |
| 174 float pannerZ[ProcessingSizeInFrames]; | 175 float pannerZ[ProcessingSizeInFrames]; |
| 175 | 176 |
| 176 float orientationX[ProcessingSizeInFrames]; | 177 float orientationX[ProcessingSizeInFrames]; |
| 177 float orientationY[ProcessingSizeInFrames]; | 178 float orientationY[ProcessingSizeInFrames]; |
| 178 float orientationZ[ProcessingSizeInFrames]; | 179 float orientationZ[ProcessingSizeInFrames]; |
| 179 | 180 |
| 180 m_positionX->calculateSampleAccurateValues(pannerX, framesToProcess); | 181 m_positionX->calculateSampleAccurateValues(pannerX, framesToProcess); |
| 181 m_positionY->calculateSampleAccurateValues(pannerY, framesToProcess); | 182 m_positionY->calculateSampleAccurateValues(pannerY, framesToProcess); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 228 } | 229 } |
| 229 | 230 |
| 230 void PannerHandler::initialize() { | 231 void PannerHandler::initialize() { |
| 231 if (isInitialized()) | 232 if (isInitialized()) |
| 232 return; | 233 return; |
| 233 | 234 |
| 234 m_panner = Panner::create(m_panningModel, sampleRate(), | 235 m_panner = Panner::create(m_panningModel, sampleRate(), |
| 235 listener()->hrtfDatabaseLoader()); | 236 listener()->hrtfDatabaseLoader()); |
| 236 listener()->addPanner(*this); | 237 listener()->addPanner(*this); |
| 237 | 238 |
| 238 // Set the cached values to the current values to start things off. The panne
r is already | 239 // Set the cached values to the current values to start things off. The |
| 239 // marked as dirty, so this won't matter. | 240 // panner is already marked as dirty, so this won't matter. |
| 240 m_lastPosition = position(); | 241 m_lastPosition = position(); |
| 241 m_lastOrientation = orientation(); | 242 m_lastOrientation = orientation(); |
| 242 | 243 |
| 243 AudioHandler::initialize(); | 244 AudioHandler::initialize(); |
| 244 } | 245 } |
| 245 | 246 |
| 246 void PannerHandler::uninitialize() { | 247 void PannerHandler::uninitialize() { |
| 247 if (!isInitialized()) | 248 if (!isInitialized()) |
| 248 return; | 249 return; |
| 249 | 250 |
| (...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 563 DCHECK(isMainThread()); | 564 DCHECK(isMainThread()); |
| 564 BaseAudioContext::AutoLocker locker(context()); | 565 BaseAudioContext::AutoLocker locker(context()); |
| 565 | 566 |
| 566 ChannelCountMode oldMode = internalChannelCountMode(); | 567 ChannelCountMode oldMode = internalChannelCountMode(); |
| 567 | 568 |
| 568 if (mode == "clamped-max") { | 569 if (mode == "clamped-max") { |
| 569 m_newChannelCountMode = ClampedMax; | 570 m_newChannelCountMode = ClampedMax; |
| 570 } else if (mode == "explicit") { | 571 } else if (mode == "explicit") { |
| 571 m_newChannelCountMode = Explicit; | 572 m_newChannelCountMode = Explicit; |
| 572 } else if (mode == "max") { | 573 } else if (mode == "max") { |
| 573 // This is not supported for a PannerNode, which can only handle 1 or 2 chan
nels. | 574 // This is not supported for a PannerNode, which can only handle 1 or 2 |
| 575 // channels. |
| 574 exceptionState.throwDOMException(NotSupportedError, | 576 exceptionState.throwDOMException(NotSupportedError, |
| 575 "Panner: 'max' is not allowed"); | 577 "Panner: 'max' is not allowed"); |
| 576 m_newChannelCountMode = oldMode; | 578 m_newChannelCountMode = oldMode; |
| 577 } else { | 579 } else { |
| 578 // Do nothing for other invalid values. | 580 // Do nothing for other invalid values. |
| 579 m_newChannelCountMode = oldMode; | 581 m_newChannelCountMode = oldMode; |
| 580 } | 582 } |
| 581 | 583 |
| 582 if (m_newChannelCountMode != oldMode) | 584 if (m_newChannelCountMode != oldMode) |
| 583 context()->deferredTaskHandler().addChangedChannelCountMode(this); | 585 context()->deferredTaskHandler().addChangedChannelCountMode(this); |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 772 visitor->trace(m_positionZ); | 774 visitor->trace(m_positionZ); |
| 773 | 775 |
| 774 visitor->trace(m_orientationX); | 776 visitor->trace(m_orientationX); |
| 775 visitor->trace(m_orientationY); | 777 visitor->trace(m_orientationY); |
| 776 visitor->trace(m_orientationZ); | 778 visitor->trace(m_orientationZ); |
| 777 | 779 |
| 778 AudioNode::trace(visitor); | 780 AudioNode::trace(visitor); |
| 779 } | 781 } |
| 780 | 782 |
| 781 } // namespace blink | 783 } // namespace blink |
| OLD | NEW |