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