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
create(unsigned numberOfChannels,size_t length,bool allocate)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
AudioBus(unsigned numberOfChannels,size_t length,bool allocate)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
setChannelMemory(unsigned channelIndex,float * storage,size_t length)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
resizeSmaller(size_t newLength)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
zero()93 void AudioBus::zero()
94 {
95 for (unsigned i = 0; i < m_channels.size(); ++i)
96 m_channels[i]->zero();
97 }
98
channelByType(unsigned channelType)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
channelByType(unsigned type) const153 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.
topologyMatches(const AudioBus & bus) const159 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
createBufferFromRange(const AudioBus * sourceBuffer,unsigned startFrame,unsigned endFrame)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
maxAbsValue() const193 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
normalize()204 void AudioBus::normalize()
205 {
206 float max = maxAbsValue();
207 if (max)
208 scale(1.0f / max);
209 }
210
scale(float scale)211 void AudioBus::scale(float scale)
212 {
213 for (unsigned i = 0; i < numberOfChannels(); ++i)
214 channel(i)->scale(scale);
215 }
216
copyFrom(const AudioBus & sourceBus,ChannelInterpretation channelInterpretation)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
sumFrom(const AudioBus & sourceBus,ChannelInterpretation channelInterpretation)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
speakersCopyFrom(const AudioBus & sourceBus)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
speakersSumFrom(const AudioBus & sourceBus)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
speakersSumFrom5_1_ToMono(const AudioBus & sourceBus)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
discreteCopyFrom(const AudioBus & sourceBus)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
discreteSumFrom(const AudioBus & sourceBus)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
copyWithGainFrom(const AudioBus & sourceBus,float * lastMixGain,float targetGain)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
copyWithSampleAccurateGainValuesFrom(const AudioBus & sourceBus,float * gainValues,unsigned numberOfGainValues)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
createBySampleRateConverting(const AudioBus * sourceBus,bool mixToMono,double newSampleRate)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
createByMixingToMono(const AudioBus * sourceBus)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
isSilent() const620 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
clearSilentFlag()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