MediaStreamAudioSourceNode.cpp [plain text]
#include "config.h"
#if ENABLE(WEB_AUDIO) && ENABLE(MEDIA_STREAM)
#include "MediaStreamAudioSourceNode.h"
#include "AudioContext.h"
#include "AudioNodeOutput.h"
#include "Logging.h"
#include <wtf/Locker.h>
namespace WebCore {
Ref<MediaStreamAudioSourceNode> MediaStreamAudioSourceNode::create(AudioContext& context, MediaStream& mediaStream, MediaStreamTrack& audioTrack)
{
return adoptRef(*new MediaStreamAudioSourceNode(context, mediaStream, audioTrack));
}
MediaStreamAudioSourceNode::MediaStreamAudioSourceNode(AudioContext& context, MediaStream& mediaStream, MediaStreamTrack& audioTrack)
: AudioNode(context, context.sampleRate())
, m_mediaStream(mediaStream)
, m_audioTrack(audioTrack)
{
AudioSourceProvider* audioSourceProvider = m_audioTrack->audioSourceProvider();
ASSERT(audioSourceProvider);
audioSourceProvider->setClient(this);
addOutput(std::make_unique<AudioNodeOutput>(this, 2));
setNodeType(NodeTypeMediaStreamAudioSource);
initialize();
}
MediaStreamAudioSourceNode::~MediaStreamAudioSourceNode()
{
AudioSourceProvider* audioSourceProvider = m_audioTrack->audioSourceProvider();
ASSERT(audioSourceProvider);
audioSourceProvider->setClient(nullptr);
uninitialize();
}
void MediaStreamAudioSourceNode::setFormat(size_t numberOfChannels, float sourceSampleRate)
{
float sampleRate = this->sampleRate();
if (numberOfChannels == m_sourceNumberOfChannels && sourceSampleRate == sampleRate)
return;
if (!numberOfChannels || numberOfChannels > AudioContext::maxNumberOfChannels()) {
LOG(Media, "MediaStreamAudioSourceNode::setFormat(%u, %f) - unhandled format change", static_cast<unsigned>(numberOfChannels), sourceSampleRate);
m_sourceNumberOfChannels = 0;
return;
}
std::lock_guard<Lock> lock(m_processMutex);
m_sourceNumberOfChannels = numberOfChannels;
m_sourceSampleRate = sourceSampleRate;
if (sourceSampleRate == sampleRate)
m_multiChannelResampler = nullptr;
else {
double scaleFactor = sourceSampleRate / sampleRate;
m_multiChannelResampler = std::make_unique<MultiChannelResampler>(scaleFactor, numberOfChannels);
}
m_sourceNumberOfChannels = numberOfChannels;
{
AudioContext::AutoLocker contextLocker(context());
output(0)->setNumberOfChannels(numberOfChannels);
}
}
void MediaStreamAudioSourceNode::process(size_t numberOfFrames)
{
AudioBus* outputBus = output(0)->bus();
AudioSourceProvider* provider = m_audioTrack->audioSourceProvider();
if (!mediaStream() || !m_sourceNumberOfChannels || !m_sourceSampleRate || !provider) {
outputBus->zero();
return;
}
std::unique_lock<Lock> lock(m_processMutex, std::try_to_lock);
if (!lock.owns_lock()) {
outputBus->zero();
return;
}
if (m_multiChannelResampler.get()) {
ASSERT(m_sourceSampleRate != sampleRate());
m_multiChannelResampler->process(provider, outputBus, numberOfFrames);
} else {
ASSERT(m_sourceSampleRate == sampleRate());
provider->provideInput(outputBus, numberOfFrames);
}
}
}
#endif // ENABLE(WEB_AUDIO) && ENABLE(MEDIA_STREAM)