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 30 matching lines...) Expand all Loading... |
41 // a good value. But, the Reverb object is multi-threaded, so we want this as | 41 // a good value. But, the Reverb object is multi-threaded, so we want this as |
42 // high as possible without losing too much accuracy. Very large FFTs will have | 42 // high as possible without losing too much accuracy. Very large FFTs will have |
43 // worse phase errors. Given these constraints 32768 is a good compromise. | 43 // worse phase errors. Given these constraints 32768 is a good compromise. |
44 const size_t MaxFFTSize = 32768; | 44 const size_t MaxFFTSize = 32768; |
45 | 45 |
46 namespace blink { | 46 namespace blink { |
47 | 47 |
48 ConvolverHandler::ConvolverHandler(AudioNode& node, float sampleRate) | 48 ConvolverHandler::ConvolverHandler(AudioNode& node, float sampleRate) |
49 : AudioHandler(NodeTypeConvolver, node, sampleRate), m_normalize(true) { | 49 : AudioHandler(NodeTypeConvolver, node, sampleRate), m_normalize(true) { |
50 addInput(); | 50 addInput(); |
51 addOutput(2); | 51 addOutput(1); |
52 | 52 |
53 // Node-specific default mixing rules. | 53 // Node-specific default mixing rules. |
54 m_channelCount = 2; | 54 m_channelCount = 2; |
55 setInternalChannelCountMode(ClampedMax); | 55 setInternalChannelCountMode(ClampedMax); |
56 setInternalChannelInterpretation(AudioBus::Speakers); | 56 setInternalChannelInterpretation(AudioBus::Speakers); |
57 | 57 |
58 initialize(); | 58 initialize(); |
59 } | 59 } |
60 | 60 |
61 PassRefPtr<ConvolverHandler> ConvolverHandler::create(AudioNode& node, | 61 PassRefPtr<ConvolverHandler> ConvolverHandler::create(AudioNode& node, |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 RefPtr<AudioBus> bufferBus = | 130 RefPtr<AudioBus> bufferBus = |
131 AudioBus::create(numberOfChannels, bufferLength, false); | 131 AudioBus::create(numberOfChannels, bufferLength, false); |
132 for (unsigned i = 0; i < numberOfChannels; ++i) | 132 for (unsigned i = 0; i < numberOfChannels; ++i) |
133 bufferBus->setChannelMemory(i, buffer->getChannelData(i)->data(), | 133 bufferBus->setChannelMemory(i, buffer->getChannelData(i)->data(), |
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, 2, | 140 bufferBus.get(), AudioUtilities::kRenderQuantumFrames, MaxFFTSize, |
141 context() && context()->hasRealtimeConstraint(), m_normalize)); | 141 context() && context()->hasRealtimeConstraint(), m_normalize)); |
142 | 142 |
143 { | 143 { |
144 // Synchronize with process(). | 144 // Synchronize with process(). |
145 MutexLocker locker(m_processLock); | 145 MutexLocker locker(m_processLock); |
146 m_reverb = std::move(reverb); | 146 m_reverb = std::move(reverb); |
147 m_buffer = buffer; | 147 m_buffer = buffer; |
148 } | 148 } |
149 } | 149 } |
150 | 150 |
(...skipping 19 matching lines...) Expand all Loading... |
170 if (tryLocker.locked()) | 170 if (tryLocker.locked()) |
171 return m_reverb | 171 return m_reverb |
172 ? m_reverb->latencyFrames() / | 172 ? m_reverb->latencyFrames() / |
173 static_cast<double>(context()->sampleRate()) | 173 static_cast<double>(context()->sampleRate()) |
174 : 0; | 174 : 0; |
175 // Since we don't want to block the Audio Device thread, we return a large | 175 // Since we don't want to block the Audio Device thread, we return a large |
176 // value instead of trying to acquire the lock. | 176 // value instead of trying to acquire the lock. |
177 return std::numeric_limits<double>::infinity(); | 177 return std::numeric_limits<double>::infinity(); |
178 } | 178 } |
179 | 179 |
| 180 void ConvolverHandler::setChannelCount(unsigned long channelCount, |
| 181 ExceptionState& exceptionState) { |
| 182 DCHECK(isMainThread()); |
| 183 BaseAudioContext::AutoLocker locker(context()); |
| 184 |
| 185 // channelCount must be 2. |
| 186 if (channelCount != 2) { |
| 187 exceptionState.throwDOMException( |
| 188 NotSupportedError, |
| 189 "ConvolverNode: channelCount cannot be changed from 2"); |
| 190 } |
| 191 } |
| 192 |
| 193 void ConvolverHandler::setChannelCountMode(const String& mode, |
| 194 ExceptionState& exceptionState) { |
| 195 DCHECK(isMainThread()); |
| 196 BaseAudioContext::AutoLocker locker(context()); |
| 197 |
| 198 // channcelCountMode must be 'clamped-max'. |
| 199 if (mode != "clamped-max") { |
| 200 exceptionState.throwDOMException( |
| 201 NotSupportedError, |
| 202 "ConvolverNode: channelCountMode cannot be changed from 'clamped-max'"); |
| 203 } |
| 204 } |
| 205 |
| 206 void ConvolverHandler::checkNumberOfChannelsForInput(AudioNodeInput* input) { |
| 207 DCHECK(context()->isAudioThread()); |
| 208 #if DCHECK_IS_ON() |
| 209 DCHECK(context()->isGraphOwner()); |
| 210 #endif |
| 211 |
| 212 DCHECK(input); |
| 213 DCHECK_EQ(input, &this->input(0)); |
| 214 if (input != &this->input(0)) |
| 215 return; |
| 216 |
| 217 if (m_buffer) { |
| 218 unsigned numberOfChannels = input->numberOfChannels(); |
| 219 unsigned numberOfReverbeChannels = m_buffer->numberOfChannels(); |
| 220 unsigned numberOfOutputChannels = |
| 221 std::min(2u, std::max(numberOfChannels, numberOfReverbeChannels)); |
| 222 |
| 223 if (isInitialized() && |
| 224 numberOfOutputChannels != output(0).numberOfChannels()) { |
| 225 // We're already initialized but the channel count has changed. |
| 226 uninitialize(); |
| 227 } |
| 228 |
| 229 if (!isInitialized()) { |
| 230 // This will propagate the channel count to any nodes connected further |
| 231 // downstream in the graph. |
| 232 output(0).setNumberOfChannels(numberOfOutputChannels); |
| 233 initialize(); |
| 234 } |
| 235 } |
| 236 |
| 237 // Update the input's internal bus if needed. |
| 238 AudioHandler::checkNumberOfChannelsForInput(input); |
| 239 } |
180 // ---------------------------------------------------------------- | 240 // ---------------------------------------------------------------- |
181 | 241 |
182 ConvolverNode::ConvolverNode(BaseAudioContext& context) : AudioNode(context) { | 242 ConvolverNode::ConvolverNode(BaseAudioContext& context) : AudioNode(context) { |
183 setHandler(ConvolverHandler::create(*this, context.sampleRate())); | 243 setHandler(ConvolverHandler::create(*this, context.sampleRate())); |
184 } | 244 } |
185 | 245 |
186 ConvolverNode* ConvolverNode::create(BaseAudioContext& context, | 246 ConvolverNode* ConvolverNode::create(BaseAudioContext& context, |
187 ExceptionState& exceptionState) { | 247 ExceptionState& exceptionState) { |
188 DCHECK(isMainThread()); | 248 DCHECK(isMainThread()); |
189 | 249 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
228 | 288 |
229 bool ConvolverNode::normalize() const { | 289 bool ConvolverNode::normalize() const { |
230 return convolverHandler().normalize(); | 290 return convolverHandler().normalize(); |
231 } | 291 } |
232 | 292 |
233 void ConvolverNode::setNormalize(bool normalize) { | 293 void ConvolverNode::setNormalize(bool normalize) { |
234 convolverHandler().setNormalize(normalize); | 294 convolverHandler().setNormalize(normalize); |
235 } | 295 } |
236 | 296 |
237 } // namespace blink | 297 } // namespace blink |
OLD | NEW |