1 /* 2 * Copyright (C) 2010 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 14 * its contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include "config.h" 30 31 #if ENABLE(WEB_AUDIO) 32 33 #include "platform/audio/AudioBus.h" 34 35 #include "platform/audio/AudioFileReader.h" 36 #include "platform/audio/DenormalDisabler.h" 37 #include "platform/audio/SincResampler.h" 38 #include "platform/audio/VectorMath.h" 39 #include "public/platform/Platform.h" 40 #include "public/platform/WebAudioBus.h" 41 #include "wtf/OwnPtr.h" 42 43 #include <assert.h> 44 #include <math.h> 45 #include <algorithm> 46 47 namespace blink { 48 49 using namespace VectorMath; 50 51 const unsigned MaxBusChannels = 32; 52 53 PassRefPtr<AudioBus> AudioBus::create(unsigned numberOfChannels, size_t length, bool allocate) 54 { 55 ASSERT(numberOfChannels <= MaxBusChannels); 56 if (numberOfChannels > MaxBusChannels) 57 return nullptr; 58 59 return adoptRef(new AudioBus(numberOfChannels, length, allocate)); 60 } 61 62 AudioBus::AudioBus(unsigned numberOfChannels, size_t length, bool allocate) 63 : m_length(length) 64 , m_busGain(1) 65 , m_isFirstTime(true) 66 , m_sampleRate(0) 67 { 68 m_channels.reserveInitialCapacity(numberOfChannels); 69 70 for (unsigned i = 0; i < numberOfChannels; ++i) { 71 PassOwnPtr<AudioChannel> channel = allocate ? adoptPtr(new AudioChannel(length)) : adoptPtr(new AudioChannel(0, length)); 72 m_channels.append(channel); 73 } 74 75 m_layout = LayoutCanonical; // for now this is the only layout we define 76 } 77 78 void AudioBus::setChannelMemory(unsigned channelIndex, float* storage, size_t length) 79 { 80 if (channelIndex < m_channels.size()) { 81 channel(channelIndex)->set(storage, length); 82 m_length = length; // FIXME: verify that this length matches all the other channel lengths 83 } 84 } 85 86 void AudioBus::resizeSmaller(size_t newLength) 87 { 88 ASSERT(newLength <= m_length); 89 if (newLength <= m_length) 90 m_length = newLength; 91 92 for (unsigned i = 0; i < m_channels.size(); ++i) 93 m_channels[i]->resizeSmaller(newLength); 94 } 95 96 void AudioBus::zero() 97 { 98 for (unsigned i = 0; i < m_channels.size(); ++i) 99 m_channels[i]->zero(); 100 } 101 102 AudioChannel* AudioBus::channelByType(unsigned channelType) 103 { 104 // For now we only support canonical channel layouts... 105 if (m_layout != LayoutCanonical) 106 return 0; 107 108 switch (numberOfChannels()) { 109 case 1: // mono 110 if (channelType == ChannelMono || channelType == ChannelLeft) 111 return channel(0); 112 return 0; 113 114 case 2: // stereo 115 switch (channelType) { 116 case ChannelLeft: return channel(0); 117 case ChannelRight: return channel(1); 118 default: return 0; 119 } 120 121 case 4: // quad 122 switch (channelType) { 123 case ChannelLeft: return channel(0); 124 case ChannelRight: return channel(1); 125 case ChannelSurroundLeft: return channel(2); 126 case ChannelSurroundRight: return channel(3); 127 default: return 0; 128 } 129 130 case 5: // 5.0 131 switch (channelType) { 132 case ChannelLeft: return channel(0); 133 case ChannelRight: return channel(1); 134 case ChannelCenter: return channel(2); 135 case ChannelSurroundLeft: return channel(3); 136 case ChannelSurroundRight: return channel(4); 137 default: return 0; 138 } 139 140 case 6: // 5.1 141 switch (channelType) { 142 case ChannelLeft: return channel(0); 143 case ChannelRight: return channel(1); 144 case ChannelCenter: return channel(2); 145 case ChannelLFE: return channel(3); 146 case ChannelSurroundLeft: return channel(4); 147 case ChannelSurroundRight: return channel(5); 148 default: return 0; 149 } 150 } 151 152 ASSERT_NOT_REACHED(); 153 return 0; 154 } 155 156 const AudioChannel* AudioBus::channelByType(unsigned type) const 157 { 158 return const_cast<AudioBus*>(this)->channelByType(type); 159 } 160 161 // Returns true if the channel count and frame-size match. 162 bool AudioBus::topologyMatches(const AudioBus& bus) const 163 { 164 if (numberOfChannels() != bus.numberOfChannels()) 165 return false; // channel mismatch 166 167 // Make sure source bus has enough frames. 168 if (length() > bus.length()) 169 return false; // frame-size mismatch 170 171 return true; 172 } 173 174 PassRefPtr<AudioBus> AudioBus::createBufferFromRange(const AudioBus* sourceBuffer, unsigned startFrame, unsigned endFrame) 175 { 176 size_t numberOfSourceFrames = sourceBuffer->length(); 177 unsigned numberOfChannels = sourceBuffer->numberOfChannels(); 178 179 // Sanity checking 180 bool isRangeSafe = startFrame < endFrame && endFrame <= numberOfSourceFrames; 181 ASSERT(isRangeSafe); 182 if (!isRangeSafe) 183 return nullptr; 184 185 size_t rangeLength = endFrame - startFrame; 186 187 RefPtr<AudioBus> audioBus = create(numberOfChannels, rangeLength); 188 audioBus->setSampleRate(sourceBuffer->sampleRate()); 189 190 for (unsigned i = 0; i < numberOfChannels; ++i) 191 audioBus->channel(i)->copyFromRange(sourceBuffer->channel(i), startFrame, endFrame); 192 193 return audioBus; 194 } 195 196 float AudioBus::maxAbsValue() const 197 { 198 float max = 0.0f; 199 for (unsigned i = 0; i < numberOfChannels(); ++i) { 200 const AudioChannel* channel = this->channel(i); 201 max = std::max(max, channel->maxAbsValue()); 202 } 203 204 return max; 205 } 206 207 void AudioBus::normalize() 208 { 209 float max = maxAbsValue(); 210 if (max) 211 scale(1.0f / max); 212 } 213 214 void AudioBus::scale(float scale) 215 { 216 for (unsigned i = 0; i < numberOfChannels(); ++i) 217 channel(i)->scale(scale); 218 } 219 220 void AudioBus::copyFrom(const AudioBus& sourceBus, ChannelInterpretation channelInterpretation) 221 { 222 if (&sourceBus == this) 223 return; 224 225 unsigned numberOfSourceChannels = sourceBus.numberOfChannels(); 226 unsigned numberOfDestinationChannels = numberOfChannels(); 227 228 if (numberOfDestinationChannels == numberOfSourceChannels) { 229 for (unsigned i = 0; i < numberOfSourceChannels; ++i) 230 channel(i)->copyFrom(sourceBus.channel(i)); 231 } else { 232 switch (channelInterpretation) { 233 case Speakers: 234 speakersCopyFrom(sourceBus); 235 break; 236 case Discrete: 237 discreteCopyFrom(sourceBus); 238 break; 239 default: 240 ASSERT_NOT_REACHED(); 241 } 242 } 243 } 244 245 void AudioBus::sumFrom(const AudioBus& sourceBus, ChannelInterpretation channelInterpretation) 246 { 247 if (&sourceBus == this) 248 return; 249 250 unsigned numberOfSourceChannels = sourceBus.numberOfChannels(); 251 unsigned numberOfDestinationChannels = numberOfChannels(); 252 253 if (numberOfDestinationChannels == numberOfSourceChannels) { 254 for (unsigned i = 0; i < numberOfSourceChannels; ++i) 255 channel(i)->sumFrom(sourceBus.channel(i)); 256 } else { 257 switch (channelInterpretation) { 258 case Speakers: 259 speakersSumFrom(sourceBus); 260 break; 261 case Discrete: 262 discreteSumFrom(sourceBus); 263 break; 264 default: 265 ASSERT_NOT_REACHED(); 266 } 267 } 268 } 269 270 void AudioBus::speakersCopyFrom(const AudioBus& sourceBus) 271 { 272 // FIXME: Implement down mixing 5.1 to stereo. 273 // https://bugs.webkit.org/show_bug.cgi?id=79192 274 275 unsigned numberOfSourceChannels = sourceBus.numberOfChannels(); 276 unsigned numberOfDestinationChannels = numberOfChannels(); 277 278 if (numberOfDestinationChannels == 2 && numberOfSourceChannels == 1) { 279 // Handle mono -> stereo case (for now simply copy mono channel into both left and right) 280 // FIXME: Really we should apply an equal-power scaling factor here, since we're effectively panning center... 281 const AudioChannel* sourceChannel = sourceBus.channel(0); 282 channel(0)->copyFrom(sourceChannel); 283 channel(1)->copyFrom(sourceChannel); 284 } else if (numberOfDestinationChannels == 1 && numberOfSourceChannels == 2) { 285 // Handle stereo -> mono case. output = 0.5 * (input.L + input.R). 286 AudioBus& sourceBusSafe = const_cast<AudioBus&>(sourceBus); 287 288 const float* sourceL = sourceBusSafe.channelByType(ChannelLeft)->data(); 289 const float* sourceR = sourceBusSafe.channelByType(ChannelRight)->data(); 290 291 float* destination = channelByType(ChannelLeft)->mutableData(); 292 vadd(sourceL, 1, sourceR, 1, destination, 1, length()); 293 float scale = 0.5; 294 vsmul(destination, 1, &scale, destination, 1, length()); 295 } else if (numberOfDestinationChannels == 6 && numberOfSourceChannels == 1) { 296 // Handle mono -> 5.1 case, copy mono channel to center. 297 channel(2)->copyFrom(sourceBus.channel(0)); 298 channel(0)->zero(); 299 channel(1)->zero(); 300 channel(3)->zero(); 301 channel(4)->zero(); 302 channel(5)->zero(); 303 } else if (numberOfDestinationChannels == 1 && numberOfSourceChannels == 6) { 304 // Handle 5.1 -> mono case. 305 zero(); 306 speakersSumFrom5_1_ToMono(sourceBus); 307 } else { 308 // Fallback for unknown combinations. 309 discreteCopyFrom(sourceBus); 310 } 311 } 312 313 void AudioBus::speakersSumFrom(const AudioBus& sourceBus) 314 { 315 // FIXME: Implement down mixing 5.1 to stereo. 316 // https://bugs.webkit.org/show_bug.cgi?id=79192 317 318 unsigned numberOfSourceChannels = sourceBus.numberOfChannels(); 319 unsigned numberOfDestinationChannels = numberOfChannels(); 320 321 if (numberOfDestinationChannels == 2 && numberOfSourceChannels == 1) { 322 // Handle mono -> stereo case (summing mono channel into both left and right). 323 const AudioChannel* sourceChannel = sourceBus.channel(0); 324 channel(0)->sumFrom(sourceChannel); 325 channel(1)->sumFrom(sourceChannel); 326 } else if (numberOfDestinationChannels == 1 && numberOfSourceChannels == 2) { 327 // Handle stereo -> mono case. output += 0.5 * (input.L + input.R). 328 AudioBus& sourceBusSafe = const_cast<AudioBus&>(sourceBus); 329 330 const float* sourceL = sourceBusSafe.channelByType(ChannelLeft)->data(); 331 const float* sourceR = sourceBusSafe.channelByType(ChannelRight)->data(); 332 333 float* destination = channelByType(ChannelLeft)->mutableData(); 334 float scale = 0.5; 335 vsma(sourceL, 1, &scale, destination, 1, length()); 336 vsma(sourceR, 1, &scale, destination, 1, length()); 337 } else if (numberOfDestinationChannels == 6 && numberOfSourceChannels == 1) { 338 // Handle mono -> 5.1 case, sum mono channel into center. 339 channel(2)->sumFrom(sourceBus.channel(0)); 340 } else if (numberOfDestinationChannels == 1 && numberOfSourceChannels == 6) { 341 // Handle 5.1 -> mono case. 342 speakersSumFrom5_1_ToMono(sourceBus); 343 } else { 344 // Fallback for unknown combinations. 345 discreteSumFrom(sourceBus); 346 } 347 } 348 349 void AudioBus::speakersSumFrom5_1_ToMono(const AudioBus& sourceBus) 350 { 351 AudioBus& sourceBusSafe = const_cast<AudioBus&>(sourceBus); 352 353 const float* sourceL = sourceBusSafe.channelByType(ChannelLeft)->data(); 354 const float* sourceR = sourceBusSafe.channelByType(ChannelRight)->data(); 355 const float* sourceC = sourceBusSafe.channelByType(ChannelCenter)->data(); 356 const float* sourceSL = sourceBusSafe.channelByType(ChannelSurroundLeft)->data(); 357 const float* sourceSR = sourceBusSafe.channelByType(ChannelSurroundRight)->data(); 358 359 float* destination = channelByType(ChannelLeft)->mutableData(); 360 361 AudioFloatArray temp(length()); 362 float* tempData = temp.data(); 363 364 // Sum in L and R. 365 vadd(sourceL, 1, sourceR, 1, tempData, 1, length()); 366 float scale = 0.7071; 367 vsmul(tempData, 1, &scale, tempData, 1, length()); 368 vadd(tempData, 1, destination, 1, destination, 1, length()); 369 370 // Sum in SL and SR. 371 vadd(sourceSL, 1, sourceSR, 1, tempData, 1, length()); 372 scale = 0.5; 373 vsmul(tempData, 1, &scale, tempData, 1, length()); 374 vadd(tempData, 1, destination, 1, destination, 1, length()); 375 376 // Sum in center. 377 vadd(sourceC, 1, destination, 1, destination, 1, length()); 378 } 379 380 void AudioBus::discreteCopyFrom(const AudioBus& sourceBus) 381 { 382 unsigned numberOfSourceChannels = sourceBus.numberOfChannels(); 383 unsigned numberOfDestinationChannels = numberOfChannels(); 384 385 if (numberOfDestinationChannels < numberOfSourceChannels) { 386 // Down-mix by copying channels and dropping the remaining. 387 for (unsigned i = 0; i < numberOfDestinationChannels; ++i) 388 channel(i)->copyFrom(sourceBus.channel(i)); 389 } else if (numberOfDestinationChannels > numberOfSourceChannels) { 390 // Up-mix by copying as many channels as we have, then zeroing remaining channels. 391 for (unsigned i = 0; i < numberOfSourceChannels; ++i) 392 channel(i)->copyFrom(sourceBus.channel(i)); 393 for (unsigned i = numberOfSourceChannels; i < numberOfDestinationChannels; ++i) 394 channel(i)->zero(); 395 } 396 } 397 398 void AudioBus::discreteSumFrom(const AudioBus& sourceBus) 399 { 400 unsigned numberOfSourceChannels = sourceBus.numberOfChannels(); 401 unsigned numberOfDestinationChannels = numberOfChannels(); 402 403 if (numberOfDestinationChannels < numberOfSourceChannels) { 404 // Down-mix by summing channels and dropping the remaining. 405 for (unsigned i = 0; i < numberOfDestinationChannels; ++i) 406 channel(i)->sumFrom(sourceBus.channel(i)); 407 } else if (numberOfDestinationChannels > numberOfSourceChannels) { 408 // Up-mix by summing as many channels as we have. 409 for (unsigned i = 0; i < numberOfSourceChannels; ++i) 410 channel(i)->sumFrom(sourceBus.channel(i)); 411 } 412 } 413 414 void AudioBus::copyWithGainFrom(const AudioBus &sourceBus, float* lastMixGain, float targetGain) 415 { 416 if (!topologyMatches(sourceBus)) { 417 ASSERT_NOT_REACHED(); 418 zero(); 419 return; 420 } 421 422 if (sourceBus.isSilent()) { 423 zero(); 424 return; 425 } 426 427 unsigned numberOfChannels = this->numberOfChannels(); 428 ASSERT(numberOfChannels <= MaxBusChannels); 429 if (numberOfChannels > MaxBusChannels) 430 return; 431 432 // If it is copying from the same bus and no need to change gain, just return. 433 if (this == &sourceBus && *lastMixGain == targetGain && targetGain == 1) 434 return; 435 436 AudioBus& sourceBusSafe = const_cast<AudioBus&>(sourceBus); 437 const float* sources[MaxBusChannels]; 438 float* destinations[MaxBusChannels]; 439 440 for (unsigned i = 0; i < numberOfChannels; ++i) { 441 sources[i] = sourceBusSafe.channel(i)->data(); 442 destinations[i] = channel(i)->mutableData(); 443 } 444 445 // We don't want to suddenly change the gain from mixing one time slice to the next, 446 // so we "de-zipper" by slowly changing the gain each sample-frame until we've achieved the target gain. 447 448 // Take master bus gain into account as well as the targetGain. 449 float totalDesiredGain = static_cast<float>(m_busGain * targetGain); 450 451 // First time, snap directly to totalDesiredGain. 452 float gain = static_cast<float>(m_isFirstTime ? totalDesiredGain : *lastMixGain); 453 m_isFirstTime = false; 454 455 const float DezipperRate = 0.005f; 456 unsigned framesToProcess = length(); 457 458 // If the gain is within epsilon of totalDesiredGain, we can skip dezippering. 459 // FIXME: this value may need tweaking. 460 const float epsilon = 0.001f; 461 float gainDiff = fabs(totalDesiredGain - gain); 462 463 // Number of frames to de-zipper before we are close enough to the target gain. 464 // FIXME: framesToDezipper could be smaller when target gain is close enough within this process loop. 465 unsigned framesToDezipper = (gainDiff < epsilon) ? 0 : framesToProcess; 466 467 if (framesToDezipper) { 468 if (!m_dezipperGainValues.get() || m_dezipperGainValues->size() < framesToDezipper) 469 m_dezipperGainValues = adoptPtr(new AudioFloatArray(framesToDezipper)); 470 471 float* gainValues = m_dezipperGainValues->data(); 472 for (unsigned i = 0; i < framesToDezipper; ++i) { 473 gain += (totalDesiredGain - gain) * DezipperRate; 474 475 // FIXME: If we are clever enough in calculating the framesToDezipper value, we can probably get 476 // rid of this DenormalDisabler::flushDenormalFloatToZero() call. 477 gain = DenormalDisabler::flushDenormalFloatToZero(gain); 478 *gainValues++ = gain; 479 } 480 481 for (unsigned channelIndex = 0; channelIndex < numberOfChannels; ++channelIndex) { 482 vmul(sources[channelIndex], 1, m_dezipperGainValues->data(), 1, destinations[channelIndex], 1, framesToDezipper); 483 sources[channelIndex] += framesToDezipper; 484 destinations[channelIndex] += framesToDezipper; 485 } 486 } else 487 gain = totalDesiredGain; 488 489 // Apply constant gain after de-zippering has converged on target gain. 490 if (framesToDezipper < framesToProcess) { 491 for (unsigned channelIndex = 0; channelIndex < numberOfChannels; ++channelIndex) 492 vsmul(sources[channelIndex], 1, &gain, destinations[channelIndex], 1, framesToProcess - framesToDezipper); 493 } 494 495 // Save the target gain as the starting point for next time around. 496 *lastMixGain = gain; 497 } 498 499 void AudioBus::copyWithSampleAccurateGainValuesFrom(const AudioBus &sourceBus, float* gainValues, unsigned numberOfGainValues) 500 { 501 // Make sure we're processing from the same type of bus. 502 // We *are* able to process from mono -> stereo 503 if (sourceBus.numberOfChannels() != 1 && !topologyMatches(sourceBus)) { 504 ASSERT_NOT_REACHED(); 505 return; 506 } 507 508 if (!gainValues || numberOfGainValues > sourceBus.length()) { 509 ASSERT_NOT_REACHED(); 510 return; 511 } 512 513 if (sourceBus.length() == numberOfGainValues && sourceBus.length() == length() && sourceBus.isSilent()) { 514 zero(); 515 return; 516 } 517 518 // We handle both the 1 -> N and N -> N case here. 519 const float* source = sourceBus.channel(0)->data(); 520 for (unsigned channelIndex = 0; channelIndex < numberOfChannels(); ++channelIndex) { 521 if (sourceBus.numberOfChannels() == numberOfChannels()) 522 source = sourceBus.channel(channelIndex)->data(); 523 float* destination = channel(channelIndex)->mutableData(); 524 vmul(source, 1, gainValues, 1, destination, 1, numberOfGainValues); 525 } 526 } 527 528 PassRefPtr<AudioBus> AudioBus::createBySampleRateConverting(const AudioBus* sourceBus, bool mixToMono, double newSampleRate) 529 { 530 // sourceBus's sample-rate must be known. 531 ASSERT(sourceBus && sourceBus->sampleRate()); 532 if (!sourceBus || !sourceBus->sampleRate()) 533 return nullptr; 534 535 double sourceSampleRate = sourceBus->sampleRate(); 536 double destinationSampleRate = newSampleRate; 537 double sampleRateRatio = sourceSampleRate / destinationSampleRate; 538 unsigned numberOfSourceChannels = sourceBus->numberOfChannels(); 539 540 if (numberOfSourceChannels == 1) 541 mixToMono = false; // already mono 542 543 if (sourceSampleRate == destinationSampleRate) { 544 // No sample-rate conversion is necessary. 545 if (mixToMono) 546 return AudioBus::createByMixingToMono(sourceBus); 547 548 // Return exact copy. 549 return AudioBus::createBufferFromRange(sourceBus, 0, sourceBus->length()); 550 } 551 552 if (sourceBus->isSilent()) { 553 RefPtr<AudioBus> silentBus = create(numberOfSourceChannels, sourceBus->length() / sampleRateRatio); 554 silentBus->setSampleRate(newSampleRate); 555 return silentBus; 556 } 557 558 // First, mix to mono (if necessary) then sample-rate convert. 559 const AudioBus* resamplerSourceBus; 560 RefPtr<AudioBus> mixedMonoBus; 561 if (mixToMono) { 562 mixedMonoBus = AudioBus::createByMixingToMono(sourceBus); 563 resamplerSourceBus = mixedMonoBus.get(); 564 } else { 565 // Directly resample without down-mixing. 566 resamplerSourceBus = sourceBus; 567 } 568 569 // Calculate destination length based on the sample-rates. 570 int sourceLength = resamplerSourceBus->length(); 571 int destinationLength = sourceLength / sampleRateRatio; 572 573 // Create destination bus with same number of channels. 574 unsigned numberOfDestinationChannels = resamplerSourceBus->numberOfChannels(); 575 RefPtr<AudioBus> destinationBus = create(numberOfDestinationChannels, destinationLength); 576 577 // Sample-rate convert each channel. 578 for (unsigned i = 0; i < numberOfDestinationChannels; ++i) { 579 const float* source = resamplerSourceBus->channel(i)->data(); 580 float* destination = destinationBus->channel(i)->mutableData(); 581 582 SincResampler resampler(sampleRateRatio); 583 resampler.process(source, destination, sourceLength); 584 } 585 586 destinationBus->clearSilentFlag(); 587 destinationBus->setSampleRate(newSampleRate); 588 return destinationBus; 589 } 590 591 PassRefPtr<AudioBus> AudioBus::createByMixingToMono(const AudioBus* sourceBus) 592 { 593 if (sourceBus->isSilent()) 594 return create(1, sourceBus->length()); 595 596 switch (sourceBus->numberOfChannels()) { 597 case 1: 598 // Simply create an exact copy. 599 return AudioBus::createBufferFromRange(sourceBus, 0, sourceBus->length()); 600 case 2: 601 { 602 unsigned n = sourceBus->length(); 603 RefPtr<AudioBus> destinationBus = create(1, n); 604 605 const float* sourceL = sourceBus->channel(0)->data(); 606 const float* sourceR = sourceBus->channel(1)->data(); 607 float* destination = destinationBus->channel(0)->mutableData(); 608 609 // Do the mono mixdown. 610 for (unsigned i = 0; i < n; ++i) 611 destination[i] = (sourceL[i] + sourceR[i]) / 2; 612 613 destinationBus->clearSilentFlag(); 614 destinationBus->setSampleRate(sourceBus->sampleRate()); 615 return destinationBus; 616 } 617 } 618 619 ASSERT_NOT_REACHED(); 620 return nullptr; 621 } 622 623 bool AudioBus::isSilent() const 624 { 625 for (size_t i = 0; i < m_channels.size(); ++i) { 626 if (!m_channels[i]->isSilent()) 627 return false; 628 } 629 return true; 630 } 631 632 void AudioBus::clearSilentFlag() 633 { 634 for (size_t i = 0; i < m_channels.size(); ++i) 635 m_channels[i]->clearSilentFlag(); 636 } 637 638 PassRefPtr<AudioBus> decodeAudioFileData(const char* data, size_t size) 639 { 640 WebAudioBus webAudioBus; 641 if (Platform::current()->loadAudioResource(&webAudioBus, data, size)) 642 return webAudioBus.release(); 643 return nullptr; 644 } 645 646 PassRefPtr<AudioBus> AudioBus::loadPlatformResource(const char* name, float sampleRate) 647 { 648 const WebData& resource = Platform::current()->loadResource(name); 649 if (resource.isEmpty()) 650 return nullptr; 651 652 RefPtr<AudioBus> audioBus = decodeAudioFileData(resource.data(), resource.size()); 653 654 if (!audioBus.get()) 655 return nullptr; 656 657 // If the bus is already at the requested sample-rate then return as is. 658 if (audioBus->sampleRate() == sampleRate) 659 return audioBus; 660 661 return AudioBus::createBySampleRateConverting(audioBus.get(), false, sampleRate); 662 } 663 664 PassRefPtr<AudioBus> createBusFromInMemoryAudioFile(const void* data, size_t dataSize, bool mixToMono, float sampleRate) 665 { 666 RefPtr<AudioBus> audioBus = decodeAudioFileData(static_cast<const char*>(data), dataSize); 667 if (!audioBus.get()) 668 return nullptr; 669 670 // If the bus needs no conversion then return as is. 671 if ((!mixToMono || audioBus->numberOfChannels() == 1) && audioBus->sampleRate() == sampleRate) 672 return audioBus; 673 674 return AudioBus::createBySampleRateConverting(audioBus.get(), mixToMono, sampleRate); 675 } 676 677 } // namespace blink 678 679 #endif // ENABLE(WEB_AUDIO) 680