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
47namespace blink {
48
49using namespace VectorMath;
50
51const unsigned MaxBusChannels = 32;
52
53PassRefPtr<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
62AudioBus::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
78void 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
86void 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
96void AudioBus::zero()
97{
98    for (unsigned i = 0; i < m_channels.size(); ++i)
99        m_channels[i]->zero();
100}
101
102AudioChannel* 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
156const 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.
162bool 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
174PassRefPtr<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
196float 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
207void AudioBus::normalize()
208{
209    float max = maxAbsValue();
210    if (max)
211        scale(1.0f / max);
212}
213
214void AudioBus::scale(float scale)
215{
216    for (unsigned i = 0; i < numberOfChannels(); ++i)
217        channel(i)->scale(scale);
218}
219
220void 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
245void 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
270void 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
313void 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
349void 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
380void 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
398void 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
414void 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
499void 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
528PassRefPtr<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
591PassRefPtr<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
623bool 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
632void AudioBus::clearSilentFlag()
633{
634    for (size_t i = 0; i < m_channels.size(); ++i)
635        m_channels[i]->clearSilentFlag();
636}
637
638PassRefPtr<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
646PassRefPtr<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
664PassRefPtr<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