Changeset 109076 in webkit
- Timestamp:
- Feb 27, 2012 10:03:41 PM (12 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r109073 r109076 1 2012-02-27 Wei James <james.wei@intel.com> 2 3 Multi-Channel support in AudioBufferSourceNode 4 https://bugs.webkit.org/show_bug.cgi?id=79202 5 6 Reviewed by Chris Rogers. 7 8 * webaudio/audiobuffersource-channels-expected.txt: 9 * webaudio/audiobuffersource-channels.html: 10 * webaudio/audiobuffersource-multi-channels-expected.wav: Added. 11 * webaudio/audiobuffersource-multi-channels.html: Added. 12 1 13 2012-02-27 Emil A Eklund <eae@chromium.org> 2 14 -
trunk/LayoutTests/webaudio/audiobuffersource-channels-expected.txt
r94878 r109076 6 6 PASS Mono buffer can be set. 7 7 PASS Stereo buffer can be set. 8 PASS 3 channel buffer is not settable.9 PASS 4 channel buffer is not settable.10 PASS 5 channel buffer is not settable.11 PASS 6 channel buffer is not settable.12 PASS 7 channel buffer is not settable.13 PASS 8 channel buffer is not settable.14 PASS 9 channel buffer is not settable.8 PASS 3 channels buffer can be set. 9 PASS 4 channels buffer can be set. 10 PASS 5 channels buffer can be set. 11 PASS 6 channels buffer can be set. 12 PASS 7 channels buffer can be set. 13 PASS 8 channels buffer can be set. 14 PASS 9 channels buffer can be set. 15 15 PASS successfullyParsed is true 16 16 -
trunk/LayoutTests/webaudio/audiobuffersource-channels.html
r99258 r109076 49 49 } 50 50 51 // Check a few buffers with more than two channels and check for failure. 52 // (for now the implementation will only work with mono and stereo buffers) 51 // Check buffers with more than two channels. 53 52 for (var i = 3; i < 10; ++i) { 54 53 try { 55 54 var buffer = context.createBuffer(i, 1024, context.sampleRate); 56 55 source.buffer = buffer; 57 var message = i + " channel buffer should not be settable."; 56 var message = i + " channels buffer can be set."; 57 testPassed(message); 58 } catch(e) { 59 var message = i + " channels buffer can not be set."; 58 60 testFailed(message); 59 } catch(e) {60 var message = i + " channel buffer is not settable.";61 testPassed(message);62 61 } 63 62 } -
trunk/Source/WebCore/ChangeLog
r109074 r109076 1 2012-02-27 Wei James <james.wei@intel.com> 2 3 Multi-Channel support in AudioBufferSourceNode 4 https://bugs.webkit.org/show_bug.cgi?id=79202 5 6 Reviewed by Chris Rogers. 7 8 Test: webaudio/audiobuffersource-multi-channels.html 9 10 * webaudio/AudioBufferSourceNode.cpp: 11 (WebCore::AudioBufferSourceNode::renderSilenceAndFinishIfNotLooping): 12 (WebCore::AudioBufferSourceNode::renderFromBuffer): 13 (WebCore::AudioBufferSourceNode::setBuffer): 14 * webaudio/AudioBufferSourceNode.h: 15 (AudioBufferSourceNode): 16 1 17 2012-02-27 Leo Yang <leo.yang@torchmobile.com.cn> 2 18 -
trunk/Source/WebCore/webaudio/AudioBufferSourceNode.cpp
r106162 r109076 127 127 size_t bufferFramesToProcess = framesToProcess - quantumFrameOffset; 128 128 129 for (unsigned i = 0; i < outputBus->numberOfChannels(); ++i) 130 m_destinationChannels[i] = outputBus->channel(i)->mutableData(); 131 129 132 // Render by reading directly from the buffer. 130 133 renderFromBuffer(outputBus, quantumFrameOffset, bufferFramesToProcess); … … 145 148 if (isSafe) { 146 149 for (unsigned i = 0; i < outputBus->numberOfChannels(); ++i) 147 memset( outputBus->channel(i)->mutableData()+ zeroStartFrame, 0, sizeof(float) * framesToZero);150 memset(m_destinationChannels[i] + zeroStartFrame, 0, sizeof(float) * framesToZero); 148 151 } 149 152 … … 161 164 162 165 // Returns true if we're finished. 163 bool AudioBufferSourceNode::renderSilenceAndFinishIfNotLooping( float* destinationL, float* destinationR, size_t framesToProcess)166 bool AudioBufferSourceNode::renderSilenceAndFinishIfNotLooping(AudioBus*, unsigned index, size_t framesToProcess) 164 167 { 165 168 if (!loop()) { … … 170 173 // We're not looping and we've reached the end of the sample data, but we still need to provide more output, 171 174 // so generate silence for the remaining. 172 memset(destinationL, 0, sizeof(float) * framesToProcess); 173 174 if (destinationR) 175 memset(destinationR, 0, sizeof(float) * framesToProcess); 175 for (unsigned i = 0; i < numberOfChannels(); ++i) 176 memset(m_destinationChannels[i] + index, 0, sizeof(float) * framesToProcess); 176 177 } 177 178 … … 195 196 unsigned busNumberOfChannels = bus->numberOfChannels(); 196 197 197 // FIXME: we can add support for sources with more than two channels, but this is not a common case. 198 bool channelCountGood = numberOfChannels == busNumberOfChannels && (numberOfChannels == 1 || numberOfChannels == 2); 198 bool channelCountGood = numberOfChannels && numberOfChannels == busNumberOfChannels; 199 199 ASSERT(channelCountGood); 200 200 if (!channelCountGood) 201 201 return; 202 202 203 // Get the destination pointers.204 float* destinationL = bus->channel(0)->mutableData();205 ASSERT(destinationL);206 if (!destinationL)207 return;208 float* destinationR = (numberOfChannels < 2) ? 0 : bus->channel(1)->mutableData();209 210 bool isStereo = destinationR;211 212 203 // Sanity check destinationFrameOffset, numberOfFrames. 213 204 size_t destinationLength = bus->length(); … … 222 213 if (!isOffsetGood) 223 214 return; 224 215 225 216 // Potentially zero out initial frames leading up to the offset. 226 217 if (destinationFrameOffset) { 227 memset(destinationL, 0, sizeof(float) * destinationFrameOffset); 228 if (destinationR) 229 memset(destinationR, 0, sizeof(float) * destinationFrameOffset); 218 for (unsigned i = 0; i < numberOfChannels; ++i) 219 memset(m_destinationChannels[i], 0, sizeof(float) * destinationFrameOffset); 230 220 } 231 221 232 222 // Offset the pointers to the correct offset frame. 233 destinationL += destinationFrameOffset; 234 if (destinationR) 235 destinationR += destinationFrameOffset; 223 unsigned writeIndex = destinationFrameOffset; 236 224 237 225 size_t bufferLength = buffer()->length(); … … 265 253 m_virtualReadIndex = startFrame; // reset to start 266 254 267 // Get pointers to the start of the sample buffer.268 float* sourceL = m_buffer->getChannelData(0)->data();269 float* sourceR = m_buffer->numberOfChannels() == 2 ? m_buffer->getChannelData(1)->data() : 0;270 271 255 double pitchRate = totalPitchRate(); 272 256 … … 276 260 // Render loop - reading from the source buffer to the destination using linear interpolation. 277 261 int framesToProcess = numberOfFrames; 262 263 const float** sourceChannels = m_sourceChannels.get(); 264 float** destinationChannels = m_destinationChannels.get(); 278 265 279 266 // Optimize for the very common case of playing back with pitchRate == 1. … … 286 273 framesThisTime = max(0, framesThisTime); 287 274 288 memcpy(destinationL, sourceL + readIndex, sizeof(*sourceL) * framesThisTime); 289 destinationL += framesThisTime; 290 if (isStereo) { 291 memcpy(destinationR, sourceR + readIndex, sizeof(*sourceR) * framesThisTime); 292 destinationR += framesThisTime; 293 } 294 275 for (unsigned i = 0; i < numberOfChannels; ++i) 276 memcpy(destinationChannels[i] + writeIndex, sourceChannels[i] + readIndex, sizeof(float) * framesThisTime); 277 278 writeIndex += framesThisTime; 295 279 readIndex += framesThisTime; 296 280 framesToProcess -= framesThisTime; … … 299 283 if (readIndex >= endFrame) { 300 284 readIndex -= deltaFrames; 301 if (renderSilenceAndFinishIfNotLooping( destinationL, destinationR, framesToProcess))285 if (renderSilenceAndFinishIfNotLooping(bus, writeIndex, framesToProcess)) 302 286 break; 303 287 } … … 325 309 326 310 // Linear interpolation. 327 double sampleL1 = sourceL[readIndex]; 328 double sampleL2 = sourceL[readIndex2]; 329 double sampleL = (1.0 - interpolationFactor) * sampleL1 + interpolationFactor * sampleL2; 330 *destinationL++ = narrowPrecisionToFloat(sampleL); 331 332 if (isStereo) { 333 double sampleR1 = sourceR[readIndex]; 334 double sampleR2 = sourceR[readIndex2]; 335 double sampleR = (1.0 - interpolationFactor) * sampleR1 + interpolationFactor * sampleR2; 336 *destinationR++ = narrowPrecisionToFloat(sampleR); 311 for (unsigned i = 0; i < numberOfChannels; ++i) { 312 float* destination = destinationChannels[i]; 313 const float* source = sourceChannels[i]; 314 315 double sample1 = source[readIndex]; 316 double sample2 = source[readIndex2]; 317 double sample = (1.0 - interpolationFactor) * sample1 + interpolationFactor * sample2; 318 319 destination[writeIndex] = narrowPrecisionToFloat(sample); 337 320 } 321 writeIndex++; 338 322 339 323 virtualReadIndex += pitchRate; … … 343 327 virtualReadIndex -= deltaFrames; 344 328 345 if (renderSilenceAndFinishIfNotLooping( destinationL, destinationR, framesToProcess))329 if (renderSilenceAndFinishIfNotLooping(bus, writeIndex, framesToProcess)) 346 330 break; 347 331 } … … 380 364 // Do any necesssary re-configuration to the buffer's number of channels. 381 365 unsigned numberOfChannels = buffer->numberOfChannels(); 382 if (!numberOfChannels || numberOfChannels > 2) {383 // FIXME: implement multi-channel greater than stereo.384 return false;385 }386 366 output(0)->setNumberOfChannels(numberOfChannels); 367 368 m_sourceChannels = adoptArrayPtr(new const float* [numberOfChannels]); 369 m_destinationChannels = adoptArrayPtr(new float* [numberOfChannels]); 370 371 for (unsigned i = 0; i < numberOfChannels; ++i) 372 m_sourceChannels[i] = buffer->getChannelData(i)->data(); 387 373 } 388 374 -
trunk/Source/WebCore/webaudio/AudioBufferSourceNode.h
r104993 r109076 31 31 #include "AudioPannerNode.h" 32 32 #include "AudioSourceNode.h" 33 #include <wtf/OwnArrayPtr.h> 33 34 #include <wtf/PassRefPtr.h> 34 35 #include <wtf/RefPtr.h> … … 88 89 void renderFromBuffer(AudioBus*, unsigned destinationFrameOffset, size_t numberOfFrames); 89 90 90 inline bool renderSilenceAndFinishIfNotLooping(float* destinationL, float* destinationR, size_t framesToProcess); 91 // Render silence starting from "index" frame in AudioBus. 92 inline bool renderSilenceAndFinishIfNotLooping(AudioBus*, unsigned index, size_t framesToProcess); 91 93 92 94 // m_buffer holds the sample data which this node outputs. 93 95 RefPtr<AudioBuffer> m_buffer; 96 97 // Pointers for the buffer and destination. 98 OwnArrayPtr<const float*> m_sourceChannels; 99 OwnArrayPtr<float*> m_destinationChannels; 94 100 95 101 // Used for the "gain" and "playbackRate" attributes.
Note: See TracChangeset
for help on using the changeset viewer.