| 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 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 bufferLength); | 134 bufferLength); |
| 135 | 135 |
| 136 bufferBus->setSampleRate(buffer->sampleRate()); | 136 bufferBus->setSampleRate(buffer->sampleRate()); |
| 137 | 137 |
| 138 // Create the reverb with the given impulse response. | 138 // Create the reverb with the given impulse response. |
| 139 std::unique_ptr<Reverb> reverb = WTF::wrapUnique(new Reverb( | 139 std::unique_ptr<Reverb> reverb = WTF::wrapUnique(new Reverb( |
| 140 bufferBus.get(), AudioUtilities::kRenderQuantumFrames, MaxFFTSize, | 140 bufferBus.get(), AudioUtilities::kRenderQuantumFrames, MaxFFTSize, |
| 141 context() && context()->hasRealtimeConstraint(), m_normalize)); | 141 context() && context()->hasRealtimeConstraint(), m_normalize)); |
| 142 | 142 |
| 143 { | 143 { |
| 144 // The context must be locked since changing the buffer can |
| 145 // re-configure the number of channels that are output. |
| 146 BaseAudioContext::AutoLocker contextLocker(context()); |
| 147 |
| 144 // Synchronize with process(). | 148 // Synchronize with process(). |
| 145 MutexLocker locker(m_processLock); | 149 MutexLocker locker(m_processLock); |
| 146 m_reverb = std::move(reverb); | 150 m_reverb = std::move(reverb); |
| 147 m_buffer = buffer; | 151 m_buffer = buffer; |
| 152 if (buffer) { |
| 153 // This will propagate the channel count to any nodes connected further |
| 154 // downstream in the graph. |
| 155 output(0).setNumberOfChannels(computeNumberOfOutputChannels( |
| 156 input(0).numberOfChannels(), m_buffer->numberOfChannels())); |
| 157 } |
| 148 } | 158 } |
| 149 } | 159 } |
| 150 | 160 |
| 151 AudioBuffer* ConvolverHandler::buffer() { | 161 AudioBuffer* ConvolverHandler::buffer() { |
| 152 DCHECK(isMainThread()); | 162 DCHECK(isMainThread()); |
| 153 return m_buffer.get(); | 163 return m_buffer.get(); |
| 154 } | 164 } |
| 155 | 165 |
| 156 double ConvolverHandler::tailTime() const { | 166 double ConvolverHandler::tailTime() const { |
| 157 MutexTryLocker tryLocker(m_processLock); | 167 MutexTryLocker tryLocker(m_processLock); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 170 if (tryLocker.locked()) | 180 if (tryLocker.locked()) |
| 171 return m_reverb | 181 return m_reverb |
| 172 ? m_reverb->latencyFrames() / | 182 ? m_reverb->latencyFrames() / |
| 173 static_cast<double>(context()->sampleRate()) | 183 static_cast<double>(context()->sampleRate()) |
| 174 : 0; | 184 : 0; |
| 175 // Since we don't want to block the Audio Device thread, we return a large | 185 // Since we don't want to block the Audio Device thread, we return a large |
| 176 // value instead of trying to acquire the lock. | 186 // value instead of trying to acquire the lock. |
| 177 return std::numeric_limits<double>::infinity(); | 187 return std::numeric_limits<double>::infinity(); |
| 178 } | 188 } |
| 179 | 189 |
| 190 unsigned ConvolverHandler::computeNumberOfOutputChannels( |
| 191 unsigned inputChannels, |
| 192 unsigned responseChannels) const { |
| 193 // The number of output channels for a Convolver must be one or two. |
| 194 // And can only be one if there's a mono source and a mono response |
| 195 // buffer. |
| 196 return clampTo(std::max(inputChannels, responseChannels), 1, 2); |
| 197 } |
| 198 |
| 180 void ConvolverHandler::setChannelCount(unsigned long channelCount, | 199 void ConvolverHandler::setChannelCount(unsigned long channelCount, |
| 181 ExceptionState& exceptionState) { | 200 ExceptionState& exceptionState) { |
| 182 DCHECK(isMainThread()); | 201 DCHECK(isMainThread()); |
| 183 BaseAudioContext::AutoLocker locker(context()); | 202 BaseAudioContext::AutoLocker locker(context()); |
| 184 | 203 |
| 185 // channelCount must be 2. | 204 // channelCount must be 2. |
| 186 if (channelCount != 2) { | 205 if (channelCount != 2) { |
| 187 exceptionState.throwDOMException( | 206 exceptionState.throwDOMException( |
| 188 NotSupportedError, | 207 NotSupportedError, |
| 189 "ConvolverNode: channelCount cannot be changed from 2"); | 208 "ConvolverNode: channelCount cannot be changed from 2"); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 208 #if DCHECK_IS_ON() | 227 #if DCHECK_IS_ON() |
| 209 DCHECK(context()->isGraphOwner()); | 228 DCHECK(context()->isGraphOwner()); |
| 210 #endif | 229 #endif |
| 211 | 230 |
| 212 DCHECK(input); | 231 DCHECK(input); |
| 213 DCHECK_EQ(input, &this->input(0)); | 232 DCHECK_EQ(input, &this->input(0)); |
| 214 if (input != &this->input(0)) | 233 if (input != &this->input(0)) |
| 215 return; | 234 return; |
| 216 | 235 |
| 217 if (m_buffer) { | 236 if (m_buffer) { |
| 218 unsigned numberOfChannels = input->numberOfChannels(); | 237 unsigned numberOfOutputChannels = computeNumberOfOutputChannels( |
| 219 unsigned numberOfReverbeChannels = m_buffer->numberOfChannels(); | 238 input->numberOfChannels(), m_buffer->numberOfChannels()); |
| 220 unsigned numberOfOutputChannels = | |
| 221 std::min(2u, std::max(numberOfChannels, numberOfReverbeChannels)); | |
| 222 | 239 |
| 223 if (isInitialized() && | 240 if (isInitialized() && |
| 224 numberOfOutputChannels != output(0).numberOfChannels()) { | 241 numberOfOutputChannels != output(0).numberOfChannels()) { |
| 225 // We're already initialized but the channel count has changed. | 242 // We're already initialized but the channel count has changed. |
| 226 uninitialize(); | 243 uninitialize(); |
| 227 } | 244 } |
| 228 | 245 |
| 229 if (!isInitialized()) { | 246 if (!isInitialized()) { |
| 230 // This will propagate the channel count to any nodes connected further | 247 // This will propagate the channel count to any nodes connected further |
| 231 // downstream in the graph. | 248 // downstream in the graph. |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 288 | 305 |
| 289 bool ConvolverNode::normalize() const { | 306 bool ConvolverNode::normalize() const { |
| 290 return convolverHandler().normalize(); | 307 return convolverHandler().normalize(); |
| 291 } | 308 } |
| 292 | 309 |
| 293 void ConvolverNode::setNormalize(bool normalize) { | 310 void ConvolverNode::setNormalize(bool normalize) { |
| 294 convolverHandler().setNormalize(normalize); | 311 convolverHandler().setNormalize(normalize); |
| 295 } | 312 } |
| 296 | 313 |
| 297 } // namespace blink | 314 } // namespace blink |
| OLD | NEW |