2 * Copyright (C) 2011 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
33 #include "platform/audio/MultiChannelResampler.h"
35 #include "platform/audio/AudioBus.h"
41 // ChannelProvider provides a single channel of audio data (one channel at a time) for each channel
42 // of data provided to us in a multi-channel provider.
44 class ChannelProvider final
: public AudioSourceProvider
{
46 ChannelProvider(AudioSourceProvider
* multiChannelProvider
, unsigned numberOfChannels
)
47 : m_multiChannelProvider(multiChannelProvider
)
48 , m_numberOfChannels(numberOfChannels
)
50 , m_framesToProcess(0)
54 // provideInput() will be called once for each channel, starting with the first channel.
55 // Each time it's called, it will provide the next channel of data.
56 void provideInput(AudioBus
* bus
, size_t framesToProcess
) override
58 bool isBusGood
= bus
&& bus
->numberOfChannels() == 1;
63 // Get the data from the multi-channel provider when the first channel asks for it.
64 // For subsequent channels, we can just dish out the channel data from that (stored in m_multiChannelBus).
65 if (!m_currentChannel
) {
66 m_framesToProcess
= framesToProcess
;
67 m_multiChannelBus
= AudioBus::create(m_numberOfChannels
, framesToProcess
);
68 m_multiChannelProvider
->provideInput(m_multiChannelBus
.get(), framesToProcess
);
71 // All channels must ask for the same amount. This should always be the case, but let's just make sure.
72 bool isGood
= m_multiChannelBus
.get() && framesToProcess
== m_framesToProcess
;
77 // Copy the channel data from what we received from m_multiChannelProvider.
78 ASSERT(m_currentChannel
<= m_numberOfChannels
);
79 if (m_currentChannel
< m_numberOfChannels
) {
80 memcpy(bus
->channel(0)->mutableData(), m_multiChannelBus
->channel(m_currentChannel
)->data(), sizeof(float) * framesToProcess
);
86 AudioSourceProvider
* m_multiChannelProvider
;
87 RefPtr
<AudioBus
> m_multiChannelBus
;
88 unsigned m_numberOfChannels
;
89 unsigned m_currentChannel
;
90 size_t m_framesToProcess
; // Used to verify that all channels ask for the same amount.
95 MultiChannelResampler::MultiChannelResampler(double scaleFactor
, unsigned numberOfChannels
)
96 : m_numberOfChannels(numberOfChannels
)
98 // Create each channel's resampler.
99 for (unsigned channelIndex
= 0; channelIndex
< numberOfChannels
; ++channelIndex
)
100 m_kernels
.append(adoptPtr(new SincResampler(scaleFactor
)));
103 void MultiChannelResampler::process(AudioSourceProvider
* provider
, AudioBus
* destination
, size_t framesToProcess
)
105 // The provider can provide us with multi-channel audio data. But each of our single-channel resamplers (kernels)
106 // below requires a provider which provides a single unique channel of data.
107 // channelProvider wraps the original multi-channel provider and dishes out one channel at a time.
108 ChannelProvider
channelProvider(provider
, m_numberOfChannels
);
110 for (unsigned channelIndex
= 0; channelIndex
< m_numberOfChannels
; ++channelIndex
) {
111 // Depending on the sample-rate scale factor, and the internal buffering used in a SincResampler
112 // kernel, this call to process() will only sometimes call provideInput() on the channelProvider.
113 // However, if it calls provideInput() for the first channel, then it will call it for the remaining
114 // channels, since they all buffer in the same way and are processing the same number of frames.
115 m_kernels
[channelIndex
]->process(&channelProvider
,
116 destination
->channel(channelIndex
)->mutableData(),
123 #endif // ENABLE(WEB_AUDIO)