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