| 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 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 // This node is the producer for inputBuffer and the consumer for outputBuff
er. | 98 // This node is the producer for inputBuffer and the consumer for outputBuff
er. |
| 99 // The JavaScript code is the consumer of inputBuffer and the producer for o
utputBuffer. | 99 // The JavaScript code is the consumer of inputBuffer and the producer for o
utputBuffer. |
| 100 | 100 |
| 101 // Get input and output busses. | 101 // Get input and output busses. |
| 102 AudioBus* inputBus = input(0).bus(); | 102 AudioBus* inputBus = input(0).bus(); |
| 103 AudioBus* outputBus = output(0).bus(); | 103 AudioBus* outputBus = output(0).bus(); |
| 104 | 104 |
| 105 // Get input and output buffers. We double-buffer both the input and output
sides. | 105 // Get input and output buffers. We double-buffer both the input and output
sides. |
| 106 unsigned doubleBufferIndex = this->doubleBufferIndex(); | 106 unsigned doubleBufferIndex = this->doubleBufferIndex(); |
| 107 bool isDoubleBufferIndexGood = doubleBufferIndex < 2 && doubleBufferIndex <
m_inputBuffers.size() && doubleBufferIndex < m_outputBuffers.size(); | 107 bool isDoubleBufferIndexGood = doubleBufferIndex < 2 && doubleBufferIndex <
m_inputBuffers.size() && doubleBufferIndex < m_outputBuffers.size(); |
| 108 ASSERT(isDoubleBufferIndexGood); | 108 DCHECK(isDoubleBufferIndexGood); |
| 109 if (!isDoubleBufferIndexGood) | 109 if (!isDoubleBufferIndexGood) |
| 110 return; | 110 return; |
| 111 | 111 |
| 112 AudioBuffer* inputBuffer = m_inputBuffers[doubleBufferIndex].get(); | 112 AudioBuffer* inputBuffer = m_inputBuffers[doubleBufferIndex].get(); |
| 113 AudioBuffer* outputBuffer = m_outputBuffers[doubleBufferIndex].get(); | 113 AudioBuffer* outputBuffer = m_outputBuffers[doubleBufferIndex].get(); |
| 114 | 114 |
| 115 // Check the consistency of input and output buffers. | 115 // Check the consistency of input and output buffers. |
| 116 unsigned numberOfInputChannels = m_internalInputBus->numberOfChannels(); | 116 unsigned numberOfInputChannels = m_internalInputBus->numberOfChannels(); |
| 117 bool buffersAreGood = outputBuffer && bufferSize() == outputBuffer->length()
&& m_bufferReadWriteIndex + framesToProcess <= bufferSize(); | 117 bool buffersAreGood = outputBuffer && bufferSize() == outputBuffer->length()
&& m_bufferReadWriteIndex + framesToProcess <= bufferSize(); |
| 118 | 118 |
| 119 // If the number of input channels is zero, it's ok to have inputBuffer = 0. | 119 // If the number of input channels is zero, it's ok to have inputBuffer = 0. |
| 120 if (m_internalInputBus->numberOfChannels()) | 120 if (m_internalInputBus->numberOfChannels()) |
| 121 buffersAreGood = buffersAreGood && inputBuffer && bufferSize() == inputB
uffer->length(); | 121 buffersAreGood = buffersAreGood && inputBuffer && bufferSize() == inputB
uffer->length(); |
| 122 | 122 |
| 123 ASSERT(buffersAreGood); | 123 DCHECK(buffersAreGood); |
| 124 if (!buffersAreGood) | 124 if (!buffersAreGood) |
| 125 return; | 125 return; |
| 126 | 126 |
| 127 // We assume that bufferSize() is evenly divisible by framesToProcess - shou
ld always be true, but we should still check. | 127 // We assume that bufferSize() is evenly divisible by framesToProcess - shou
ld always be true, but we should still check. |
| 128 bool isFramesToProcessGood = framesToProcess && bufferSize() >= framesToProc
ess && !(bufferSize() % framesToProcess); | 128 bool isFramesToProcessGood = framesToProcess && bufferSize() >= framesToProc
ess && !(bufferSize() % framesToProcess); |
| 129 ASSERT(isFramesToProcessGood); | 129 DCHECK(isFramesToProcessGood); |
| 130 if (!isFramesToProcessGood) | 130 if (!isFramesToProcessGood) |
| 131 return; | 131 return; |
| 132 | 132 |
| 133 unsigned numberOfOutputChannels = outputBus->numberOfChannels(); | 133 unsigned numberOfOutputChannels = outputBus->numberOfChannels(); |
| 134 | 134 |
| 135 bool channelsAreGood = (numberOfInputChannels == m_numberOfInputChannels) &&
(numberOfOutputChannels == m_numberOfOutputChannels); | 135 bool channelsAreGood = (numberOfInputChannels == m_numberOfInputChannels) &&
(numberOfOutputChannels == m_numberOfOutputChannels); |
| 136 ASSERT(channelsAreGood); | 136 DCHECK(channelsAreGood); |
| 137 if (!channelsAreGood) | 137 if (!channelsAreGood) |
| 138 return; | 138 return; |
| 139 | 139 |
| 140 for (unsigned i = 0; i < numberOfInputChannels; ++i) | 140 for (unsigned i = 0; i < numberOfInputChannels; ++i) |
| 141 m_internalInputBus->setChannelMemory(i, inputBuffer->getChannelData(i)->
data() + m_bufferReadWriteIndex, framesToProcess); | 141 m_internalInputBus->setChannelMemory(i, inputBuffer->getChannelData(i)->
data() + m_bufferReadWriteIndex, framesToProcess); |
| 142 | 142 |
| 143 if (numberOfInputChannels) | 143 if (numberOfInputChannels) |
| 144 m_internalInputBus->copyFrom(*inputBus); | 144 m_internalInputBus->copyFrom(*inputBus); |
| 145 | 145 |
| 146 // Copy from the output buffer to the output. | 146 // Copy from the output buffer to the output. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 167 context()->getExecutionContext()->postTask(BLINK_FROM_HERE, | 167 context()->getExecutionContext()->postTask(BLINK_FROM_HERE, |
| 168 createCrossThreadTask(&ScriptProcessorHandler::fireProcessEvent,
PassRefPtr<ScriptProcessorHandler>(this), m_doubleBufferIndex)); | 168 createCrossThreadTask(&ScriptProcessorHandler::fireProcessEvent,
PassRefPtr<ScriptProcessorHandler>(this), m_doubleBufferIndex)); |
| 169 } | 169 } |
| 170 | 170 |
| 171 swapBuffers(); | 171 swapBuffers(); |
| 172 } | 172 } |
| 173 } | 173 } |
| 174 | 174 |
| 175 void ScriptProcessorHandler::fireProcessEvent(unsigned doubleBufferIndex) | 175 void ScriptProcessorHandler::fireProcessEvent(unsigned doubleBufferIndex) |
| 176 { | 176 { |
| 177 ASSERT(isMainThread()); | 177 DCHECK(isMainThread()); |
| 178 | 178 |
| 179 ASSERT(doubleBufferIndex < 2); | 179 DCHECK_LT(doubleBufferIndex, 2u); |
| 180 if (doubleBufferIndex > 1) | 180 if (doubleBufferIndex > 1) |
| 181 return; | 181 return; |
| 182 | 182 |
| 183 AudioBuffer* inputBuffer = m_inputBuffers[doubleBufferIndex].get(); | 183 AudioBuffer* inputBuffer = m_inputBuffers[doubleBufferIndex].get(); |
| 184 AudioBuffer* outputBuffer = m_outputBuffers[doubleBufferIndex].get(); | 184 AudioBuffer* outputBuffer = m_outputBuffers[doubleBufferIndex].get(); |
| 185 ASSERT(outputBuffer); | 185 DCHECK(outputBuffer); |
| 186 if (!outputBuffer) | 186 if (!outputBuffer) |
| 187 return; | 187 return; |
| 188 | 188 |
| 189 // Avoid firing the event if the document has already gone away. | 189 // Avoid firing the event if the document has already gone away. |
| 190 if (node() && context() && context()->getExecutionContext()) { | 190 if (node() && context() && context()->getExecutionContext()) { |
| 191 // This synchronizes with process(). | 191 // This synchronizes with process(). |
| 192 MutexLocker processLocker(m_processEventLock); | 192 MutexLocker processLocker(m_processEventLock); |
| 193 | 193 |
| 194 // Calculate a playbackTime with the buffersize which needs to be proces
sed each time onaudioprocess is called. | 194 // Calculate a playbackTime with the buffersize which needs to be proces
sed each time onaudioprocess is called. |
| 195 // The outputBuffer being passed to JS will be played after exhuasting p
revious outputBuffer by double-buffering. | 195 // The outputBuffer being passed to JS will be played after exhuasting p
revious outputBuffer by double-buffering. |
| 196 double playbackTime = (context()->currentSampleFrame() + m_bufferSize) /
static_cast<double>(context()->sampleRate()); | 196 double playbackTime = (context()->currentSampleFrame() + m_bufferSize) /
static_cast<double>(context()->sampleRate()); |
| 197 | 197 |
| 198 // Call the JavaScript event handler which will do the audio processing. | 198 // Call the JavaScript event handler which will do the audio processing. |
| 199 node()->dispatchEvent(AudioProcessingEvent::create(inputBuffer, outputBu
ffer, playbackTime)); | 199 node()->dispatchEvent(AudioProcessingEvent::create(inputBuffer, outputBu
ffer, playbackTime)); |
| 200 } | 200 } |
| 201 } | 201 } |
| 202 | 202 |
| 203 double ScriptProcessorHandler::tailTime() const | 203 double ScriptProcessorHandler::tailTime() const |
| 204 { | 204 { |
| 205 return std::numeric_limits<double>::infinity(); | 205 return std::numeric_limits<double>::infinity(); |
| 206 } | 206 } |
| 207 | 207 |
| 208 double ScriptProcessorHandler::latencyTime() const | 208 double ScriptProcessorHandler::latencyTime() const |
| 209 { | 209 { |
| 210 return std::numeric_limits<double>::infinity(); | 210 return std::numeric_limits<double>::infinity(); |
| 211 } | 211 } |
| 212 | 212 |
| 213 void ScriptProcessorHandler::setChannelCount(unsigned long channelCount, Excepti
onState& exceptionState) | 213 void ScriptProcessorHandler::setChannelCount(unsigned long channelCount, Excepti
onState& exceptionState) |
| 214 { | 214 { |
| 215 ASSERT(isMainThread()); | 215 DCHECK(isMainThread()); |
| 216 BaseAudioContext::AutoLocker locker(context()); | 216 BaseAudioContext::AutoLocker locker(context()); |
| 217 | 217 |
| 218 if (channelCount != m_channelCount) { | 218 if (channelCount != m_channelCount) { |
| 219 exceptionState.throwDOMException( | 219 exceptionState.throwDOMException( |
| 220 NotSupportedError, | 220 NotSupportedError, |
| 221 "channelCount cannot be changed from " + String::number(m_channelCou
nt) + " to " + String::number(channelCount)); | 221 "channelCount cannot be changed from " + String::number(m_channelCou
nt) + " to " + String::number(channelCount)); |
| 222 } | 222 } |
| 223 } | 223 } |
| 224 | 224 |
| 225 void ScriptProcessorHandler::setChannelCountMode(const String& mode, ExceptionSt
ate& exceptionState) | 225 void ScriptProcessorHandler::setChannelCountMode(const String& mode, ExceptionSt
ate& exceptionState) |
| 226 { | 226 { |
| 227 ASSERT(isMainThread()); | 227 DCHECK(isMainThread()); |
| 228 BaseAudioContext::AutoLocker locker(context()); | 228 BaseAudioContext::AutoLocker locker(context()); |
| 229 | 229 |
| 230 if ((mode == "max") || (mode == "clamped-max")) { | 230 if ((mode == "max") || (mode == "clamped-max")) { |
| 231 exceptionState.throwDOMException( | 231 exceptionState.throwDOMException( |
| 232 NotSupportedError, | 232 NotSupportedError, |
| 233 "channelCountMode cannot be changed from 'explicit' to '" + mode + "
'"); | 233 "channelCountMode cannot be changed from 'explicit' to '" + mode + "
'"); |
| 234 } | 234 } |
| 235 } | 235 } |
| 236 | 236 |
| 237 // ---------------------------------------------------------------- | 237 // ---------------------------------------------------------------- |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 378 // If |onaudioprocess| event handler is defined, the node should not be | 378 // If |onaudioprocess| event handler is defined, the node should not be |
| 379 // GCed even if it is out of scope. | 379 // GCed even if it is out of scope. |
| 380 if (hasEventListeners(EventTypeNames::audioprocess)) | 380 if (hasEventListeners(EventTypeNames::audioprocess)) |
| 381 return true; | 381 return true; |
| 382 | 382 |
| 383 return false; | 383 return false; |
| 384 } | 384 } |
| 385 | 385 |
| 386 } // namespace blink | 386 } // namespace blink |
| 387 | 387 |
| OLD | NEW |