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); |
hongchan
2017/03/28 16:44:35
Why 1? The default channel value is 1 and then can
Raymond Toy
2017/03/28 17:34:49
We start the convolver with 1 output channel. m_c
hongchan
2017/03/28 19:01:43
Acknowledged.
| |
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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
129 // reference to it is kept for later use in that class. | 129 // reference to it is kept for later use in that class. |
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( |
140 bufferBus.get(), AudioUtilities::kRenderQuantumFrames, MaxFFTSize, 2, | 140 new Reverb(bufferBus.get(), AudioUtilities::kRenderQuantumFrames, |
141 context() && context()->hasRealtimeConstraint(), m_normalize)); | 141 MaxFFTSize, numberOfChannels, |
142 context() && context()->hasRealtimeConstraint(), m_normalize)); | |
142 | 143 |
143 { | 144 { |
144 // Synchronize with process(). | 145 // Synchronize with process(). |
145 MutexLocker locker(m_processLock); | 146 MutexLocker locker(m_processLock); |
146 m_reverb = std::move(reverb); | 147 m_reverb = std::move(reverb); |
147 m_buffer = buffer; | 148 m_buffer = buffer; |
148 } | 149 } |
149 } | 150 } |
150 | 151 |
151 AudioBuffer* ConvolverHandler::buffer() { | 152 AudioBuffer* ConvolverHandler::buffer() { |
(...skipping 18 matching lines...) Expand all Loading... | |
170 if (tryLocker.locked()) | 171 if (tryLocker.locked()) |
171 return m_reverb | 172 return m_reverb |
172 ? m_reverb->latencyFrames() / | 173 ? m_reverb->latencyFrames() / |
173 static_cast<double>(context()->sampleRate()) | 174 static_cast<double>(context()->sampleRate()) |
174 : 0; | 175 : 0; |
175 // Since we don't want to block the Audio Device thread, we return a large | 176 // Since we don't want to block the Audio Device thread, we return a large |
176 // value instead of trying to acquire the lock. | 177 // value instead of trying to acquire the lock. |
177 return std::numeric_limits<double>::infinity(); | 178 return std::numeric_limits<double>::infinity(); |
178 } | 179 } |
179 | 180 |
181 void ConvolverHandler::setChannelCount(unsigned long channelCount, | |
182 ExceptionState& exceptionState) { | |
183 DCHECK(isMainThread()); | |
184 BaseAudioContext::AutoLocker locker(context()); | |
185 | |
186 // channelCount must be 2. | |
187 if (channelCount != 2) { | |
hongchan
2017/03/28 16:44:35
If this cannot be changed, why did we start from 1
Raymond Toy
2017/03/28 17:34:49
m_channelCount is initialized to 2.
hongchan
2017/03/28 19:01:43
Acknowledged.
| |
188 exceptionState.throwDOMException( | |
189 NotSupportedError, | |
190 "ConvolverNode: channelCount cannot be changed from 2"); | |
191 } | |
192 } | |
193 | |
194 void ConvolverHandler::setChannelCountMode(const String& mode, | |
195 ExceptionState& exceptionState) { | |
196 DCHECK(isMainThread()); | |
197 BaseAudioContext::AutoLocker locker(context()); | |
198 | |
199 // channcelCountMode must be 'clamped-max'. | |
200 if (mode != "clamped-max") { | |
201 exceptionState.throwDOMException( | |
202 NotSupportedError, | |
203 "ConvolverNode: channelCountMode cannot be changed from 'clamped-max'"); | |
204 } | |
205 } | |
206 | |
207 void ConvolverHandler::checkNumberOfChannelsForInput(AudioNodeInput* input) { | |
208 DCHECK(context()->isAudioThread()); | |
209 #if DCHECK_IS_ON() | |
210 DCHECK(context()->isGraphOwner()); | |
211 #endif | |
212 | |
213 DCHECK(input); | |
214 DCHECK_EQ(input, &this->input(0)); | |
215 if (input != &this->input(0)) | |
216 return; | |
217 | |
218 if (m_buffer) { | |
219 unsigned numberOfChannels = input->numberOfChannels(); | |
220 unsigned numReverbChannels = m_buffer->numberOfChannels(); | |
hongchan
2017/03/28 16:44:35
numReverbChannels => numberOfReverbChannels
Raymond Toy
2017/03/28 17:34:49
I was following the style in other parts of this f
| |
221 unsigned numOutputsDesired = | |
hongchan
2017/03/28 16:44:35
Ditto. I think it's better to spell out as much as
| |
222 std::min(2u, std::max(numberOfChannels, numReverbChannels)); | |
223 | |
224 if (isInitialized() && numOutputsDesired != 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(numOutputsDesired); | |
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 |