OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2010 Google Inc. All rights reserved. | 2 * Copyright (C) 2010 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 30 matching lines...) Expand all Loading... |
41 #include "core/platform/audio/VectorMath.h" | 41 #include "core/platform/audio/VectorMath.h" |
42 #include <wtf/OwnPtr.h> | 42 #include <wtf/OwnPtr.h> |
43 #include <wtf/PassOwnPtr.h> | 43 #include <wtf/PassOwnPtr.h> |
44 | 44 |
45 namespace WebCore { | 45 namespace WebCore { |
46 | 46 |
47 using namespace VectorMath; | 47 using namespace VectorMath; |
48 | 48 |
49 const unsigned MaxBusChannels = 32; | 49 const unsigned MaxBusChannels = 32; |
50 | 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 |
51 AudioBus::AudioBus(unsigned numberOfChannels, size_t length, bool allocate) | 60 AudioBus::AudioBus(unsigned numberOfChannels, size_t length, bool allocate) |
52 : m_length(length) | 61 : m_length(length) |
53 , m_busGain(1) | 62 , m_busGain(1) |
54 , m_isFirstTime(true) | 63 , m_isFirstTime(true) |
55 , m_sampleRate(0) | 64 , m_sampleRate(0) |
56 { | 65 { |
57 ASSERT(numberOfChannels <= MaxBusChannels); | |
58 if (numberOfChannels > MaxBusChannels) | |
59 return; | |
60 | |
61 m_channels.reserveInitialCapacity(numberOfChannels); | 66 m_channels.reserveInitialCapacity(numberOfChannels); |
62 | 67 |
63 for (unsigned i = 0; i < numberOfChannels; ++i) { | 68 for (unsigned i = 0; i < numberOfChannels; ++i) { |
64 PassOwnPtr<AudioChannel> channel = allocate ? adoptPtr(new AudioChannel(
length)) : adoptPtr(new AudioChannel(0, length)); | 69 PassOwnPtr<AudioChannel> channel = allocate ? adoptPtr(new AudioChannel(
length)) : adoptPtr(new AudioChannel(0, length)); |
65 m_channels.append(channel); | 70 m_channels.append(channel); |
66 } | 71 } |
67 | 72 |
68 m_layout = LayoutCanonical; // for now this is the only layout we define | 73 m_layout = LayoutCanonical; // for now this is the only layout we define |
69 } | 74 } |
70 | 75 |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 unsigned numberOfChannels = sourceBuffer->numberOfChannels(); | 175 unsigned numberOfChannels = sourceBuffer->numberOfChannels(); |
171 | 176 |
172 // Sanity checking | 177 // Sanity checking |
173 bool isRangeSafe = startFrame < endFrame && endFrame <= numberOfSourceFrames
; | 178 bool isRangeSafe = startFrame < endFrame && endFrame <= numberOfSourceFrames
; |
174 ASSERT(isRangeSafe); | 179 ASSERT(isRangeSafe); |
175 if (!isRangeSafe) | 180 if (!isRangeSafe) |
176 return 0; | 181 return 0; |
177 | 182 |
178 size_t rangeLength = endFrame - startFrame; | 183 size_t rangeLength = endFrame - startFrame; |
179 | 184 |
180 RefPtr<AudioBus> audioBus = adoptRef(new AudioBus(numberOfChannels, rangeLen
gth)); | 185 RefPtr<AudioBus> audioBus = create(numberOfChannels, rangeLength); |
181 audioBus->setSampleRate(sourceBuffer->sampleRate()); | 186 audioBus->setSampleRate(sourceBuffer->sampleRate()); |
182 | 187 |
183 for (unsigned i = 0; i < numberOfChannels; ++i) | 188 for (unsigned i = 0; i < numberOfChannels; ++i) |
184 audioBus->channel(i)->copyFromRange(sourceBuffer->channel(i), startFrame
, endFrame); | 189 audioBus->channel(i)->copyFromRange(sourceBuffer->channel(i), startFrame
, endFrame); |
185 | 190 |
186 return audioBus; | 191 return audioBus; |
187 } | 192 } |
188 | 193 |
189 float AudioBus::maxAbsValue() const | 194 float AudioBus::maxAbsValue() const |
190 { | 195 { |
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
536 if (sourceSampleRate == destinationSampleRate) { | 541 if (sourceSampleRate == destinationSampleRate) { |
537 // No sample-rate conversion is necessary. | 542 // No sample-rate conversion is necessary. |
538 if (mixToMono) | 543 if (mixToMono) |
539 return AudioBus::createByMixingToMono(sourceBus); | 544 return AudioBus::createByMixingToMono(sourceBus); |
540 | 545 |
541 // Return exact copy. | 546 // Return exact copy. |
542 return AudioBus::createBufferFromRange(sourceBus, 0, sourceBus->length()
); | 547 return AudioBus::createBufferFromRange(sourceBus, 0, sourceBus->length()
); |
543 } | 548 } |
544 | 549 |
545 if (sourceBus->isSilent()) { | 550 if (sourceBus->isSilent()) { |
546 RefPtr<AudioBus> silentBus = adoptRef(new AudioBus(numberOfSourceChannel
s, sourceBus->length() / sampleRateRatio)); | 551 RefPtr<AudioBus> silentBus = create(numberOfSourceChannels, sourceBus->l
ength() / sampleRateRatio); |
547 silentBus->setSampleRate(newSampleRate); | 552 silentBus->setSampleRate(newSampleRate); |
548 return silentBus; | 553 return silentBus; |
549 } | 554 } |
550 | 555 |
551 // First, mix to mono (if necessary) then sample-rate convert. | 556 // First, mix to mono (if necessary) then sample-rate convert. |
552 const AudioBus* resamplerSourceBus; | 557 const AudioBus* resamplerSourceBus; |
553 RefPtr<AudioBus> mixedMonoBus; | 558 RefPtr<AudioBus> mixedMonoBus; |
554 if (mixToMono) { | 559 if (mixToMono) { |
555 mixedMonoBus = AudioBus::createByMixingToMono(sourceBus); | 560 mixedMonoBus = AudioBus::createByMixingToMono(sourceBus); |
556 resamplerSourceBus = mixedMonoBus.get(); | 561 resamplerSourceBus = mixedMonoBus.get(); |
557 } else { | 562 } else { |
558 // Directly resample without down-mixing. | 563 // Directly resample without down-mixing. |
559 resamplerSourceBus = sourceBus; | 564 resamplerSourceBus = sourceBus; |
560 } | 565 } |
561 | 566 |
562 // Calculate destination length based on the sample-rates. | 567 // Calculate destination length based on the sample-rates. |
563 int sourceLength = resamplerSourceBus->length(); | 568 int sourceLength = resamplerSourceBus->length(); |
564 int destinationLength = sourceLength / sampleRateRatio; | 569 int destinationLength = sourceLength / sampleRateRatio; |
565 | 570 |
566 // Create destination bus with same number of channels. | 571 // Create destination bus with same number of channels. |
567 unsigned numberOfDestinationChannels = resamplerSourceBus->numberOfChannels(
); | 572 unsigned numberOfDestinationChannels = resamplerSourceBus->numberOfChannels(
); |
568 RefPtr<AudioBus> destinationBus(adoptRef(new AudioBus(numberOfDestinationCha
nnels, destinationLength))); | 573 RefPtr<AudioBus> destinationBus = create(numberOfDestinationChannels, destin
ationLength); |
569 | 574 |
570 // Sample-rate convert each channel. | 575 // Sample-rate convert each channel. |
571 for (unsigned i = 0; i < numberOfDestinationChannels; ++i) { | 576 for (unsigned i = 0; i < numberOfDestinationChannels; ++i) { |
572 const float* source = resamplerSourceBus->channel(i)->data(); | 577 const float* source = resamplerSourceBus->channel(i)->data(); |
573 float* destination = destinationBus->channel(i)->mutableData(); | 578 float* destination = destinationBus->channel(i)->mutableData(); |
574 | 579 |
575 SincResampler resampler(sampleRateRatio); | 580 SincResampler resampler(sampleRateRatio); |
576 resampler.process(source, destination, sourceLength); | 581 resampler.process(source, destination, sourceLength); |
577 } | 582 } |
578 | 583 |
579 destinationBus->clearSilentFlag(); | 584 destinationBus->clearSilentFlag(); |
580 destinationBus->setSampleRate(newSampleRate); | 585 destinationBus->setSampleRate(newSampleRate); |
581 return destinationBus; | 586 return destinationBus; |
582 } | 587 } |
583 | 588 |
584 PassRefPtr<AudioBus> AudioBus::createByMixingToMono(const AudioBus* sourceBus) | 589 PassRefPtr<AudioBus> AudioBus::createByMixingToMono(const AudioBus* sourceBus) |
585 { | 590 { |
586 if (sourceBus->isSilent()) | 591 if (sourceBus->isSilent()) |
587 return adoptRef(new AudioBus(1, sourceBus->length())); | 592 return create(1, sourceBus->length()); |
588 | 593 |
589 switch (sourceBus->numberOfChannels()) { | 594 switch (sourceBus->numberOfChannels()) { |
590 case 1: | 595 case 1: |
591 // Simply create an exact copy. | 596 // Simply create an exact copy. |
592 return AudioBus::createBufferFromRange(sourceBus, 0, sourceBus->length()
); | 597 return AudioBus::createBufferFromRange(sourceBus, 0, sourceBus->length()
); |
593 case 2: | 598 case 2: |
594 { | 599 { |
595 unsigned n = sourceBus->length(); | 600 unsigned n = sourceBus->length(); |
596 RefPtr<AudioBus> destinationBus(adoptRef(new AudioBus(1, n))); | 601 RefPtr<AudioBus> destinationBus = create(1, n); |
597 | 602 |
598 const float* sourceL = sourceBus->channel(0)->data(); | 603 const float* sourceL = sourceBus->channel(0)->data(); |
599 const float* sourceR = sourceBus->channel(1)->data(); | 604 const float* sourceR = sourceBus->channel(1)->data(); |
600 float* destination = destinationBus->channel(0)->mutableData(); | 605 float* destination = destinationBus->channel(0)->mutableData(); |
601 | 606 |
602 // Do the mono mixdown. | 607 // Do the mono mixdown. |
603 for (unsigned i = 0; i < n; ++i) | 608 for (unsigned i = 0; i < n; ++i) |
604 destination[i] = (sourceL[i] + sourceR[i]) / 2; | 609 destination[i] = (sourceL[i] + sourceR[i]) / 2; |
605 | 610 |
606 destinationBus->clearSilentFlag(); | 611 destinationBus->clearSilentFlag(); |
(...skipping 17 matching lines...) Expand all Loading... |
624 | 629 |
625 void AudioBus::clearSilentFlag() | 630 void AudioBus::clearSilentFlag() |
626 { | 631 { |
627 for (size_t i = 0; i < m_channels.size(); ++i) | 632 for (size_t i = 0; i < m_channels.size(); ++i) |
628 m_channels[i]->clearSilentFlag(); | 633 m_channels[i]->clearSilentFlag(); |
629 } | 634 } |
630 | 635 |
631 } // WebCore | 636 } // WebCore |
632 | 637 |
633 #endif // ENABLE(WEB_AUDIO) | 638 #endif // ENABLE(WEB_AUDIO) |
OLD | NEW |