Skip to content

Commit 6dbc720

Browse files
author
crogers@google.com
committed
Implement MediaElementAudioSourceNode::setFormat() so numberOfChannels and sampleRate are accounted for
https://bugs.webkit.org/show_bug.cgi?id=75057 Reviewed by Eric Carlson. * GNUmakefile.list.am: * WebCore.gypi: * WebCore.xcodeproj/project.pbxproj: Add MultiChannelResampler source files to makefiles. * platform/audio/MultiChannelResampler.cpp: Added. (WebCore::MultiChannelResampler::MultiChannelResampler): (WebCore::MultiChannelResampler::process): * platform/audio/MultiChannelResampler.h: Added. Add MultiChannelResampler implementation which uses one SincResampler per channel. * webaudio/MediaElementAudioSourceNode.cpp: (WebCore::MediaElementAudioSourceNode::create): (WebCore::MediaElementAudioSourceNode::MediaElementAudioSourceNode): (WebCore::MediaElementAudioSourceNode::setFormat): (WebCore::MediaElementAudioSourceNode::process): Implement MediaElementAudioSourceNode::setFormat() so that we can properly setup a sample-rate converter and set the number of channels of the MediaElementAudioSourceNode output. * webaudio/MediaElementAudioSourceNode.h: git-svn-id: svn://svn.chromium.org/blink/trunk@103581 bbb929c8-8fbe-4397-9dbb-9b2b20218538
1 parent 7dc24ff commit 6dbc720

File tree

8 files changed

+289
-11
lines changed

8 files changed

+289
-11
lines changed

third_party/WebKit/Source/WebCore/ChangeLog

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,29 @@
1+
2011-12-22 Chris Rogers <crogers@google.com>
2+
3+
Implement MediaElementAudioSourceNode::setFormat() so numberOfChannels and sampleRate are accounted for
4+
https://bugs.webkit.org/show_bug.cgi?id=75057
5+
6+
Reviewed by Eric Carlson.
7+
8+
* GNUmakefile.list.am:
9+
* WebCore.gypi:
10+
* WebCore.xcodeproj/project.pbxproj:
11+
Add MultiChannelResampler source files to makefiles.
12+
* platform/audio/MultiChannelResampler.cpp: Added.
13+
(WebCore::MultiChannelResampler::MultiChannelResampler):
14+
(WebCore::MultiChannelResampler::process):
15+
* platform/audio/MultiChannelResampler.h: Added.
16+
Add MultiChannelResampler implementation which uses one SincResampler per channel.
17+
* webaudio/MediaElementAudioSourceNode.cpp:
18+
(WebCore::MediaElementAudioSourceNode::create):
19+
(WebCore::MediaElementAudioSourceNode::MediaElementAudioSourceNode):
20+
(WebCore::MediaElementAudioSourceNode::setFormat):
21+
(WebCore::MediaElementAudioSourceNode::process):
22+
Implement MediaElementAudioSourceNode::setFormat() so that we can
23+
properly setup a sample-rate converter and set the number of channels
24+
of the MediaElementAudioSourceNode output.
25+
* webaudio/MediaElementAudioSourceNode.h:
26+
127
2011-12-22 Chris Fleizach <cfleizach@apple.com>
228

329
AX: WebKit should ignore ARIA role=presentation on focusable elements

third_party/WebKit/Source/WebCore/GNUmakefile.list.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4829,6 +4829,8 @@ webcore_sources += \
48294829
Source/WebCore/platform/audio/HRTFKernel.h \
48304830
Source/WebCore/platform/audio/HRTFPanner.cpp \
48314831
Source/WebCore/platform/audio/HRTFPanner.h \
4832+
Source/WebCore/platform/audio/MultiChannelResampler.cpp \
4833+
Source/WebCore/platform/audio/MultiChannelResampler.h \
48324834
Source/WebCore/platform/audio/Panner.cpp \
48334835
Source/WebCore/platform/audio/Panner.h \
48344836
Source/WebCore/platform/audio/ReverbAccumulationBuffer.cpp \

third_party/WebKit/Source/WebCore/WebCore.gypi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3217,6 +3217,8 @@
32173217
'platform/audio/HRTFKernel.h',
32183218
'platform/audio/HRTFPanner.cpp',
32193219
'platform/audio/HRTFPanner.h',
3220+
'platform/audio/MultiChannelResampler.cpp',
3221+
'platform/audio/MultiChannelResampler.h',
32203222
'platform/audio/Panner.cpp',
32213223
'platform/audio/Panner.h',
32223224
'platform/audio/Reverb.cpp',

third_party/WebKit/Source/WebCore/WebCore.xcodeproj/project.pbxproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6371,6 +6371,8 @@
63716371
FDA3E95A134A49EF008D4B5A /* OfflineAudioCompletionEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = FDA3E956134A49EF008D4B5A /* OfflineAudioCompletionEvent.h */; };
63726372
FDA3E95B134A49EF008D4B5A /* OfflineAudioDestinationNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FDA3E957134A49EF008D4B5A /* OfflineAudioDestinationNode.cpp */; };
63736373
FDA3E95C134A49EF008D4B5A /* OfflineAudioDestinationNode.h in Headers */ = {isa = PBXBuildFile; fileRef = FDA3E958134A49EF008D4B5A /* OfflineAudioDestinationNode.h */; };
6374+
FDB1700514A2BAB200A2B5D9 /* MultiChannelResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FDB1700314A2BAB200A2B5D9 /* MultiChannelResampler.cpp */; };
6375+
FDB1700614A2BAB200A2B5D9 /* MultiChannelResampler.h in Headers */ = {isa = PBXBuildFile; fileRef = FDB1700414A2BAB200A2B5D9 /* MultiChannelResampler.h */; };
63746376
FDC54F041399B0DA008D9117 /* BiquadFilterNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FDC54F011399B0DA008D9117 /* BiquadFilterNode.cpp */; };
63756377
FDC54F051399B0DA008D9117 /* BiquadFilterNode.h in Headers */ = {isa = PBXBuildFile; fileRef = FDC54F021399B0DA008D9117 /* BiquadFilterNode.h */; };
63766378
FDEAAAF312B02EE400DCF33B /* JSAudioBufferSourceNodeCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FDEAAAEF12B02EE400DCF33B /* JSAudioBufferSourceNodeCustom.cpp */; };
@@ -13843,6 +13845,8 @@
1384313845
FDA3E957134A49EF008D4B5A /* OfflineAudioDestinationNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OfflineAudioDestinationNode.cpp; sourceTree = "<group>"; };
1384413846
FDA3E958134A49EF008D4B5A /* OfflineAudioDestinationNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OfflineAudioDestinationNode.h; sourceTree = "<group>"; };
1384513847
FDA3E95D134A49FF008D4B5A /* OfflineAudioCompletionEvent.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = OfflineAudioCompletionEvent.idl; sourceTree = "<group>"; };
13848+
FDB1700314A2BAB200A2B5D9 /* MultiChannelResampler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MultiChannelResampler.cpp; sourceTree = "<group>"; };
13849+
FDB1700414A2BAB200A2B5D9 /* MultiChannelResampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MultiChannelResampler.h; sourceTree = "<group>"; };
1384613850
FDC54F011399B0DA008D9117 /* BiquadFilterNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BiquadFilterNode.cpp; sourceTree = "<group>"; };
1384713851
FDC54F021399B0DA008D9117 /* BiquadFilterNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BiquadFilterNode.h; sourceTree = "<group>"; };
1384813852
FDC54F031399B0DA008D9117 /* BiquadFilterNode.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = BiquadFilterNode.idl; sourceTree = "<group>"; };
@@ -21757,6 +21761,8 @@
2175721761
FD31606912B026F700C1A359 /* HRTFKernel.h */,
2175821762
FD31606A12B026F700C1A359 /* HRTFPanner.cpp */,
2175921763
FD31606B12B026F700C1A359 /* HRTFPanner.h */,
21764+
FDB1700314A2BAB200A2B5D9 /* MultiChannelResampler.cpp */,
21765+
FDB1700414A2BAB200A2B5D9 /* MultiChannelResampler.h */,
2176021766
FD31606C12B026F700C1A359 /* Panner.cpp */,
2176121767
FD31606D12B026F700C1A359 /* Panner.h */,
2176221768
FD31606E12B026F700C1A359 /* Reverb.cpp */,
@@ -24954,6 +24960,7 @@
2495424960
1AA7160B149BC4DB0016EC19 /* TileCache.h in Headers */,
2495524961
C37CDEBD149EF2030042090D /* ColorChooserClient.h in Headers */,
2495624962
1AC6926A14A1253200BD85F1 /* ScrollableAreaClient.h in Headers */,
24963+
FDB1700614A2BAB200A2B5D9 /* MultiChannelResampler.h in Headers */,
2495724964
);
2495824965
runOnlyForDeploymentPostprocessing = 0;
2495924966
};
@@ -27858,6 +27865,7 @@
2785827865
A80A9423149F225E00989291 /* JSDOMWindowWebAudioCustom.cpp in Sources */,
2785927866
A80A9425149F227100989291 /* JSDOMWindowWebSocketCustom.cpp in Sources */,
2786027867
52F52E1114A0134F00ACC397 /* NSScrollerImpDetails.mm in Sources */,
27868+
FDB1700514A2BAB200A2B5D9 /* MultiChannelResampler.cpp in Sources */,
2786127869
);
2786227870
runOnlyForDeploymentPostprocessing = 0;
2786327871
};
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/*
2+
* Copyright (C) 2011 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 "MultiChannelResampler.h"
34+
35+
#include "AudioBus.h"
36+
37+
namespace WebCore {
38+
39+
namespace {
40+
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.
43+
44+
class ChannelProvider : public AudioSourceProvider {
45+
public:
46+
ChannelProvider(AudioSourceProvider* multiChannelProvider, unsigned numberOfChannels)
47+
: m_multiChannelProvider(multiChannelProvider)
48+
, m_numberOfChannels(numberOfChannels)
49+
, m_currentChannel(0)
50+
, m_framesToProcess(0)
51+
{
52+
}
53+
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+
virtual void provideInput(AudioBus* bus, size_t framesToProcess)
57+
{
58+
bool isBusGood = bus && bus->numberOfChannels() == 1;
59+
ASSERT(isBusGood);
60+
if (!isBusGood)
61+
return;
62+
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 = adoptPtr(new AudioBus(m_numberOfChannels, framesToProcess));
68+
m_multiChannelProvider->provideInput(m_multiChannelBus.get(), framesToProcess);
69+
}
70+
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;
73+
ASSERT(isGood);
74+
if (!isGood)
75+
return;
76+
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)->data(), m_multiChannelBus->channel(m_currentChannel)->data(), sizeof(float) * framesToProcess);
81+
++m_currentChannel;
82+
}
83+
}
84+
85+
private:
86+
AudioSourceProvider* m_multiChannelProvider;
87+
OwnPtr<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.
91+
};
92+
93+
} // namespace
94+
95+
MultiChannelResampler::MultiChannelResampler(double scaleFactor, unsigned numberOfChannels)
96+
: m_numberOfChannels(numberOfChannels)
97+
{
98+
// Create each channel's resampler.
99+
for (unsigned channelIndex = 0; channelIndex < numberOfChannels; ++channelIndex)
100+
m_kernels.append(adoptPtr(new SincResampler(scaleFactor)));
101+
}
102+
103+
void MultiChannelResampler::process(AudioSourceProvider* provider, AudioBus* destination, size_t framesToProcess)
104+
{
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);
109+
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)->data(),
117+
framesToProcess);
118+
}
119+
}
120+
121+
} // namespace WebCore
122+
123+
#endif // ENABLE(WEB_AUDIO)
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright (C) 2011 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+
#ifndef MultiChannelResampler_h
30+
#define MultiChannelResampler_h
31+
32+
#include "SincResampler.h"
33+
#include <wtf/OwnPtr.h>
34+
35+
namespace WebCore {
36+
37+
class AudioBus;
38+
39+
class MultiChannelResampler {
40+
public:
41+
MultiChannelResampler(double scaleFactor, unsigned numberOfChannels);
42+
43+
// Process given AudioSourceProvider for streaming applications.
44+
void process(AudioSourceProvider*, AudioBus* destination, size_t framesToProcess);
45+
46+
private:
47+
// FIXME: the mac port can have a more highly optimized implementation based on CoreAudio
48+
// instead of SincResampler. For now the default implementation will be used on all ports.
49+
// https://bugs.webkit.org/show_bug.cgi?id=75118
50+
51+
// Each channel will be resampled using a high-quality SincResampler.
52+
Vector<OwnPtr<SincResampler> > m_kernels;
53+
54+
unsigned m_numberOfChannels;
55+
};
56+
57+
} // namespace WebCore
58+
59+
#endif // MultiChannelResampler_h

third_party/WebKit/Source/WebCore/webaudio/MediaElementAudioSourceNode.cpp

Lines changed: 62 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,22 +30,30 @@
3030

3131
#include "AudioContext.h"
3232
#include "AudioNodeOutput.h"
33+
#include "Locker.h"
34+
#include "Logging.h"
3335
#include "MediaPlayer.h"
3436

37+
// These are somewhat arbitrary limits, but we need to do some kind of sanity-checking.
38+
const unsigned minSampleRate = 8000;
39+
const unsigned maxSampleRate = 192000;
40+
3541
namespace WebCore {
3642

3743
PassRefPtr<MediaElementAudioSourceNode> MediaElementAudioSourceNode::create(AudioContext* context, HTMLMediaElement* mediaElement)
3844
{
39-
return adoptRef(new MediaElementAudioSourceNode(context, mediaElement));
45+
return adoptRef(new MediaElementAudioSourceNode(context, mediaElement));
4046
}
4147

4248
MediaElementAudioSourceNode::MediaElementAudioSourceNode(AudioContext* context, HTMLMediaElement* mediaElement)
4349
: AudioSourceNode(context, context->sampleRate())
4450
, m_mediaElement(mediaElement)
51+
, m_sourceNumberOfChannels(0)
52+
, m_sourceSampleRate(0)
4553
{
4654
// Default to stereo. This could change depending on what the media element .src is set to.
4755
addOutput(adoptPtr(new AudioNodeOutput(this, 2)));
48-
56+
4957
setNodeType(NodeTypeMediaElementAudioSource);
5058

5159
initialize();
@@ -57,32 +65,75 @@ MediaElementAudioSourceNode::~MediaElementAudioSourceNode()
5765
uninitialize();
5866
}
5967

60-
void MediaElementAudioSourceNode::setFormat(size_t, float)
68+
void MediaElementAudioSourceNode::setFormat(size_t numberOfChannels, float sourceSampleRate)
6169
{
62-
// FIXME: setup a sample-rate converter if necessary to convert to the AudioContext sample-rate.
63-
ASSERT_NOT_REACHED();
70+
if (numberOfChannels != m_sourceNumberOfChannels || sourceSampleRate != m_sourceSampleRate) {
71+
// FIXME: implement multi-channel greater than stereo.
72+
// https://bugs.webkit.org/show_bug.cgi?id=75119
73+
if (!numberOfChannels || numberOfChannels > 2 || sourceSampleRate < minSampleRate || sourceSampleRate > maxSampleRate) {
74+
// process() will generate silence for these uninitialized values.
75+
LOG(Media, "MediaElementAudioSourceNode::setFormat(%u, %f) - unhandled format change", static_cast<unsigned>(numberOfChannels), sourceSampleRate);
76+
m_sourceNumberOfChannels = 0;
77+
m_sourceSampleRate = 0;
78+
return;
79+
}
80+
81+
m_sourceNumberOfChannels = numberOfChannels;
82+
m_sourceSampleRate = sourceSampleRate;
83+
84+
// Synchronize with process().
85+
Locker<MediaElementAudioSourceNode> locker(*this);
86+
87+
if (sourceSampleRate != sampleRate()) {
88+
double scaleFactor = sourceSampleRate / sampleRate();
89+
m_multiChannelResampler = adoptPtr(new MultiChannelResampler(scaleFactor, numberOfChannels));
90+
} else {
91+
// Bypass resampling.
92+
m_multiChannelResampler.clear();
93+
}
94+
95+
{
96+
// The context must be locked when changing the number of output channels.
97+
AudioContext::AutoLocker contextLocker(context());
98+
99+
// Do any necesssary re-configuration to the output's number of channels.
100+
output(0)->setNumberOfChannels(numberOfChannels);
101+
}
102+
}
64103
}
65104

66105
void MediaElementAudioSourceNode::process(size_t numberOfFrames)
67106
{
68107
AudioBus* outputBus = output(0)->bus();
69108

70-
if (!mediaElement()) {
109+
if (!mediaElement() || !m_sourceNumberOfChannels || !m_sourceSampleRate) {
71110
outputBus->zero();
72111
return;
73112
}
74-
113+
75114
// Use a tryLock() to avoid contention in the real-time audio thread.
76115
// If we fail to acquire the lock then the HTMLMediaElement must be in the middle of
77116
// reconfiguring its playback engine, so we output silence in this case.
78117
if (m_processLock.tryLock()) {
79-
if (AudioSourceProvider* provider = mediaElement()->audioSourceProvider())
80-
provider->provideInput(outputBus, numberOfFrames);
81-
else
118+
if (AudioSourceProvider* provider = mediaElement()->audioSourceProvider()) {
119+
if (m_multiChannelResampler.get()) {
120+
ASSERT(m_sourceSampleRate != sampleRate());
121+
m_multiChannelResampler->process(provider, outputBus, numberOfFrames);
122+
} else {
123+
// Bypass the resampler completely if the source is at the context's sample-rate.
124+
ASSERT(m_sourceSampleRate == sampleRate());
125+
provider->provideInput(outputBus, numberOfFrames);
126+
}
127+
} else {
128+
// Either this port doesn't yet support HTMLMediaElement audio stream access,
129+
// or the stream is not yet available.
82130
outputBus->zero();
131+
}
83132
m_processLock.unlock();
84-
} else
133+
} else {
134+
// We failed to acquire the lock.
85135
outputBus->zero();
136+
}
86137
}
87138

88139
void MediaElementAudioSourceNode::reset()

0 commit comments

Comments
 (0)