Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(96)

Side by Side Diff: third_party/WebKit/Source/modules/webaudio/ScriptProcessorNode.cpp

Issue 2389253002: reflow comments in modules/{webaudio,vr} (Closed)
Patch Set: . Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 unsigned numberOfOutputChannels) 45 unsigned numberOfOutputChannels)
46 : AudioHandler(NodeTypeJavaScript, node, sampleRate), 46 : AudioHandler(NodeTypeJavaScript, node, sampleRate),
47 m_doubleBufferIndex(0), 47 m_doubleBufferIndex(0),
48 m_bufferSize(bufferSize), 48 m_bufferSize(bufferSize),
49 m_bufferReadWriteIndex(0), 49 m_bufferReadWriteIndex(0),
50 m_numberOfInputChannels(numberOfInputChannels), 50 m_numberOfInputChannels(numberOfInputChannels),
51 m_numberOfOutputChannels(numberOfOutputChannels), 51 m_numberOfOutputChannels(numberOfOutputChannels),
52 m_internalInputBus(AudioBus::create(numberOfInputChannels, 52 m_internalInputBus(AudioBus::create(numberOfInputChannels,
53 ProcessingSizeInFrames, 53 ProcessingSizeInFrames,
54 false)) { 54 false)) {
55 // Regardless of the allowed buffer sizes, we still need to process at the gra nularity of the AudioNode. 55 // Regardless of the allowed buffer sizes, we still need to process at the
56 // granularity of the AudioNode.
56 if (m_bufferSize < ProcessingSizeInFrames) 57 if (m_bufferSize < ProcessingSizeInFrames)
57 m_bufferSize = ProcessingSizeInFrames; 58 m_bufferSize = ProcessingSizeInFrames;
58 59
59 DCHECK_LE(numberOfInputChannels, BaseAudioContext::maxNumberOfChannels()); 60 DCHECK_LE(numberOfInputChannels, BaseAudioContext::maxNumberOfChannels());
60 61
61 addInput(); 62 addInput();
62 addOutput(numberOfOutputChannels); 63 addOutput(numberOfOutputChannels);
63 64
64 m_channelCount = numberOfInputChannels; 65 m_channelCount = numberOfInputChannels;
65 setInternalChannelCountMode(Explicit); 66 setInternalChannelCountMode(Explicit);
(...skipping 16 matching lines...) Expand all
82 uninitialize(); 83 uninitialize();
83 } 84 }
84 85
85 void ScriptProcessorHandler::initialize() { 86 void ScriptProcessorHandler::initialize() {
86 if (isInitialized()) 87 if (isInitialized())
87 return; 88 return;
88 89
89 float sampleRate = context()->sampleRate(); 90 float sampleRate = context()->sampleRate();
90 91
91 // Create double buffers on both the input and output sides. 92 // Create double buffers on both the input and output sides.
92 // These AudioBuffers will be directly accessed in the main thread by JavaScri pt. 93 // These AudioBuffers will be directly accessed in the main thread by
94 // JavaScript.
93 for (unsigned i = 0; i < 2; ++i) { 95 for (unsigned i = 0; i < 2; ++i) {
94 AudioBuffer* inputBuffer = 96 AudioBuffer* inputBuffer =
95 m_numberOfInputChannels ? AudioBuffer::create(m_numberOfInputChannels, 97 m_numberOfInputChannels ? AudioBuffer::create(m_numberOfInputChannels,
96 bufferSize(), sampleRate) 98 bufferSize(), sampleRate)
97 : 0; 99 : 0;
98 AudioBuffer* outputBuffer = 100 AudioBuffer* outputBuffer =
99 m_numberOfOutputChannels ? AudioBuffer::create(m_numberOfOutputChannels, 101 m_numberOfOutputChannels ? AudioBuffer::create(m_numberOfOutputChannels,
100 bufferSize(), sampleRate) 102 bufferSize(), sampleRate)
101 : 0; 103 : 0;
102 104
103 m_inputBuffers.append(inputBuffer); 105 m_inputBuffers.append(inputBuffer);
104 m_outputBuffers.append(outputBuffer); 106 m_outputBuffers.append(outputBuffer);
105 } 107 }
106 108
107 AudioHandler::initialize(); 109 AudioHandler::initialize();
108 } 110 }
109 111
110 void ScriptProcessorHandler::process(size_t framesToProcess) { 112 void ScriptProcessorHandler::process(size_t framesToProcess) {
111 // Discussion about inputs and outputs: 113 // Discussion about inputs and outputs:
112 // As in other AudioNodes, ScriptProcessorNode uses an AudioBus for its input and output (see inputBus and outputBus below). 114 // As in other AudioNodes, ScriptProcessorNode uses an AudioBus for its input
113 // Additionally, there is a double-buffering for input and output which is exp osed directly to JavaScript (see inputBuffer and outputBuffer below). 115 // and output (see inputBus and outputBus below). Additionally, there is a
114 // This node is the producer for inputBuffer and the consumer for outputBuffer . 116 // double-buffering for input and output which is exposed directly to
115 // The JavaScript code is the consumer of inputBuffer and the producer for out putBuffer. 117 // JavaScript (see inputBuffer and outputBuffer below). This node is the
118 // producer for inputBuffer and the consumer for outputBuffer. The JavaScript
119 // code is the consumer of inputBuffer and the producer for outputBuffer.
116 120
117 // Get input and output busses. 121 // Get input and output busses.
118 AudioBus* inputBus = input(0).bus(); 122 AudioBus* inputBus = input(0).bus();
119 AudioBus* outputBus = output(0).bus(); 123 AudioBus* outputBus = output(0).bus();
120 124
121 // Get input and output buffers. We double-buffer both the input and output si des. 125 // Get input and output buffers. We double-buffer both the input and output
126 // sides.
122 unsigned doubleBufferIndex = this->doubleBufferIndex(); 127 unsigned doubleBufferIndex = this->doubleBufferIndex();
123 bool isDoubleBufferIndexGood = doubleBufferIndex < 2 && 128 bool isDoubleBufferIndexGood = doubleBufferIndex < 2 &&
124 doubleBufferIndex < m_inputBuffers.size() && 129 doubleBufferIndex < m_inputBuffers.size() &&
125 doubleBufferIndex < m_outputBuffers.size(); 130 doubleBufferIndex < m_outputBuffers.size();
126 DCHECK(isDoubleBufferIndexGood); 131 DCHECK(isDoubleBufferIndexGood);
127 if (!isDoubleBufferIndexGood) 132 if (!isDoubleBufferIndexGood)
128 return; 133 return;
129 134
130 AudioBuffer* inputBuffer = m_inputBuffers[doubleBufferIndex].get(); 135 AudioBuffer* inputBuffer = m_inputBuffers[doubleBufferIndex].get();
131 AudioBuffer* outputBuffer = m_outputBuffers[doubleBufferIndex].get(); 136 AudioBuffer* outputBuffer = m_outputBuffers[doubleBufferIndex].get();
132 137
133 // Check the consistency of input and output buffers. 138 // Check the consistency of input and output buffers.
134 unsigned numberOfInputChannels = m_internalInputBus->numberOfChannels(); 139 unsigned numberOfInputChannels = m_internalInputBus->numberOfChannels();
135 bool buffersAreGood = 140 bool buffersAreGood =
136 outputBuffer && bufferSize() == outputBuffer->length() && 141 outputBuffer && bufferSize() == outputBuffer->length() &&
137 m_bufferReadWriteIndex + framesToProcess <= bufferSize(); 142 m_bufferReadWriteIndex + framesToProcess <= bufferSize();
138 143
139 // If the number of input channels is zero, it's ok to have inputBuffer = 0. 144 // If the number of input channels is zero, it's ok to have inputBuffer = 0.
140 if (m_internalInputBus->numberOfChannels()) 145 if (m_internalInputBus->numberOfChannels())
141 buffersAreGood = 146 buffersAreGood =
142 buffersAreGood && inputBuffer && bufferSize() == inputBuffer->length(); 147 buffersAreGood && inputBuffer && bufferSize() == inputBuffer->length();
143 148
144 DCHECK(buffersAreGood); 149 DCHECK(buffersAreGood);
145 if (!buffersAreGood) 150 if (!buffersAreGood)
146 return; 151 return;
147 152
148 // We assume that bufferSize() is evenly divisible by framesToProcess - should always be true, but we should still check. 153 // We assume that bufferSize() is evenly divisible by framesToProcess - should
154 // always be true, but we should still check.
149 bool isFramesToProcessGood = framesToProcess && 155 bool isFramesToProcessGood = framesToProcess &&
150 bufferSize() >= framesToProcess && 156 bufferSize() >= framesToProcess &&
151 !(bufferSize() % framesToProcess); 157 !(bufferSize() % framesToProcess);
152 DCHECK(isFramesToProcessGood); 158 DCHECK(isFramesToProcessGood);
153 if (!isFramesToProcessGood) 159 if (!isFramesToProcessGood)
154 return; 160 return;
155 161
156 unsigned numberOfOutputChannels = outputBus->numberOfChannels(); 162 unsigned numberOfOutputChannels = outputBus->numberOfChannels();
157 163
158 bool channelsAreGood = (numberOfInputChannels == m_numberOfInputChannels) && 164 bool channelsAreGood = (numberOfInputChannels == m_numberOfInputChannels) &&
(...skipping 13 matching lines...) Expand all
172 // Copy from the output buffer to the output. 178 // Copy from the output buffer to the output.
173 for (unsigned i = 0; i < numberOfOutputChannels; ++i) 179 for (unsigned i = 0; i < numberOfOutputChannels; ++i)
174 memcpy(outputBus->channel(i)->mutableData(), 180 memcpy(outputBus->channel(i)->mutableData(),
175 outputBuffer->getChannelData(i)->data() + m_bufferReadWriteIndex, 181 outputBuffer->getChannelData(i)->data() + m_bufferReadWriteIndex,
176 sizeof(float) * framesToProcess); 182 sizeof(float) * framesToProcess);
177 183
178 // Update the buffering index. 184 // Update the buffering index.
179 m_bufferReadWriteIndex = 185 m_bufferReadWriteIndex =
180 (m_bufferReadWriteIndex + framesToProcess) % bufferSize(); 186 (m_bufferReadWriteIndex + framesToProcess) % bufferSize();
181 187
182 // m_bufferReadWriteIndex will wrap back around to 0 when the current input an d output buffers are full. 188 // m_bufferReadWriteIndex will wrap back around to 0 when the current input
189 // and output buffers are full.
183 // When this happens, fire an event and swap buffers. 190 // When this happens, fire an event and swap buffers.
184 if (!m_bufferReadWriteIndex) { 191 if (!m_bufferReadWriteIndex) {
185 // Avoid building up requests on the main thread to fire process events when they're not being handled. 192 // Avoid building up requests on the main thread to fire process events when
186 // This could be a problem if the main thread is very busy doing other thing s and is being held up handling previous requests. 193 // they're not being handled. This could be a problem if the main thread is
187 // The audio thread can't block on this lock, so we call tryLock() instead. 194 // very busy doing other things and is being held up handling previous
195 // requests. The audio thread can't block on this lock, so we call
196 // tryLock() instead.
188 MutexTryLocker tryLocker(m_processEventLock); 197 MutexTryLocker tryLocker(m_processEventLock);
189 if (!tryLocker.locked()) { 198 if (!tryLocker.locked()) {
190 // We're late in handling the previous request. The main thread must be ve ry busy. 199 // We're late in handling the previous request. The main thread must be
191 // The best we can do is clear out the buffer ourself here. 200 // very busy. The best we can do is clear out the buffer ourself here.
192 outputBuffer->zero(); 201 outputBuffer->zero();
193 } else if (context()->getExecutionContext()) { 202 } else if (context()->getExecutionContext()) {
194 // With the realtime context, execute the script code asynchronously 203 // With the realtime context, execute the script code asynchronously
195 // and do not wait. 204 // and do not wait.
196 if (context()->hasRealtimeConstraint()) { 205 if (context()->hasRealtimeConstraint()) {
197 // Fire the event on the main thread with the appropriate buffer 206 // Fire the event on the main thread with the appropriate buffer
198 // index. 207 // index.
199 context()->getExecutionContext()->postTask( 208 context()->getExecutionContext()->postTask(
200 BLINK_FROM_HERE, 209 BLINK_FROM_HERE,
201 createCrossThreadTask(&ScriptProcessorHandler::fireProcessEvent, 210 createCrossThreadTask(&ScriptProcessorHandler::fireProcessEvent,
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 AudioBuffer* outputBuffer = m_outputBuffers[doubleBufferIndex].get(); 244 AudioBuffer* outputBuffer = m_outputBuffers[doubleBufferIndex].get();
236 DCHECK(outputBuffer); 245 DCHECK(outputBuffer);
237 if (!outputBuffer) 246 if (!outputBuffer)
238 return; 247 return;
239 248
240 // Avoid firing the event if the document has already gone away. 249 // Avoid firing the event if the document has already gone away.
241 if (node() && context() && context()->getExecutionContext()) { 250 if (node() && context() && context()->getExecutionContext()) {
242 // This synchronizes with process(). 251 // This synchronizes with process().
243 MutexLocker processLocker(m_processEventLock); 252 MutexLocker processLocker(m_processEventLock);
244 253
245 // Calculate a playbackTime with the buffersize which needs to be processed each time onaudioprocess is called. 254 // Calculate a playbackTime with the buffersize which needs to be processed
246 // The outputBuffer being passed to JS will be played after exhuasting previ ous outputBuffer by double-buffering. 255 // each time onaudioprocess is called. The outputBuffer being passed to JS
256 // will be played after exhuasting previous outputBuffer by
257 // double-buffering.
247 double playbackTime = (context()->currentSampleFrame() + m_bufferSize) / 258 double playbackTime = (context()->currentSampleFrame() + m_bufferSize) /
248 static_cast<double>(context()->sampleRate()); 259 static_cast<double>(context()->sampleRate());
249 260
250 // Call the JavaScript event handler which will do the audio processing. 261 // Call the JavaScript event handler which will do the audio processing.
251 node()->dispatchEvent( 262 node()->dispatchEvent(
252 AudioProcessingEvent::create(inputBuffer, outputBuffer, playbackTime)); 263 AudioProcessingEvent::create(inputBuffer, outputBuffer, playbackTime));
253 } 264 }
254 } 265 }
255 266
256 void ScriptProcessorHandler::fireProcessEventForOfflineAudioContext( 267 void ScriptProcessorHandler::fireProcessEventForOfflineAudioContext(
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
325 size_t bufferSize, 336 size_t bufferSize,
326 unsigned numberOfInputChannels, 337 unsigned numberOfInputChannels,
327 unsigned numberOfOutputChannels) 338 unsigned numberOfOutputChannels)
328 : AudioNode(context), ActiveScriptWrappable(this) { 339 : AudioNode(context), ActiveScriptWrappable(this) {
329 setHandler(ScriptProcessorHandler::create(*this, sampleRate, bufferSize, 340 setHandler(ScriptProcessorHandler::create(*this, sampleRate, bufferSize,
330 numberOfInputChannels, 341 numberOfInputChannels,
331 numberOfOutputChannels)); 342 numberOfOutputChannels));
332 } 343 }
333 344
334 static size_t chooseBufferSize() { 345 static size_t chooseBufferSize() {
335 // Choose a buffer size based on the audio hardware buffer size. Arbitarily ma ke it a power of 346 // Choose a buffer size based on the audio hardware buffer size. Arbitarily
336 // two that is 4 times greater than the hardware buffer size. 347 // make it a power of two that is 4 times greater than the hardware buffer
348 // size.
337 // FIXME: What is the best way to choose this? 349 // FIXME: What is the best way to choose this?
338 size_t hardwareBufferSize = Platform::current()->audioHardwareBufferSize(); 350 size_t hardwareBufferSize = Platform::current()->audioHardwareBufferSize();
339 size_t bufferSize = 351 size_t bufferSize =
340 1 << static_cast<unsigned>(log2(4 * hardwareBufferSize) + 0.5); 352 1 << static_cast<unsigned>(log2(4 * hardwareBufferSize) + 0.5);
341 353
342 if (bufferSize < 256) 354 if (bufferSize < 256)
343 return 256; 355 return 256;
344 if (bufferSize > 16384) 356 if (bufferSize > 16384)
345 return 16384; 357 return 16384;
346 358
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
461 473
462 // If |onaudioprocess| event handler is defined, the node should not be 474 // If |onaudioprocess| event handler is defined, the node should not be
463 // GCed even if it is out of scope. 475 // GCed even if it is out of scope.
464 if (hasEventListeners(EventTypeNames::audioprocess)) 476 if (hasEventListeners(EventTypeNames::audioprocess))
465 return true; 477 return true;
466 478
467 return false; 479 return false;
468 } 480 }
469 481
470 } // namespace blink 482 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698