Chromium Code Reviews| Index: third_party/WebKit/Source/platform/audio/AudioRenderSink.cpp |
| diff --git a/third_party/WebKit/Source/platform/audio/AudioRenderSink.cpp b/third_party/WebKit/Source/platform/audio/AudioRenderSink.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..a2df6d4617b4fb03168c3a23169c0fb395dfca8e |
| --- /dev/null |
| +++ b/third_party/WebKit/Source/platform/audio/AudioRenderSink.cpp |
| @@ -0,0 +1,119 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "platform/audio/AudioRenderSink.h" |
| + |
| +#include "platform/audio/AudioPullFIFO.h" |
| +#include "public/platform/Platform.h" |
| +#include "public/platform/WebSecurityOrigin.h" |
| + |
| +namespace blink { |
| + |
| +// WebAudio engine's render quantum size. |
| +const unsigned kRenderQuantumSize = 128; |
| + |
| +// Default pulling FIFO size. |
| +const size_t kPullFifoSize = 8192; |
| + |
| +AudioRenderSink::AudioRenderSink(AudioIOCallback& callback, const String& inputDeviceId, unsigned numberOfInputChannels, unsigned numberOfOutputChannels, float sampleRate, const PassRefPtr<SecurityOrigin>& securityOrigin) |
| + : m_isRunning(false) |
| + , m_sampleRate(sampleRate) |
| + , m_numberOfOutputChannels(numberOfOutputChannels) |
| + , m_callback(callback) |
| + , m_inputBus(AudioBus::create(numberOfInputChannels, kRenderQuantumSize)) |
| + , m_outputBus(AudioBus::create(numberOfOutputChannels, kRenderQuantumSize, false)) |
| +{ |
| + // Use the optimal buffer size recommended by the audio stack. It differs |
| + // from the render quantum size and it varies across the platform. |
| + size_t recommendedBufferSize = Platform::current()->audioHardwareBufferSize(); |
| + m_callbackBufferSize = recommendedBufferSize; |
| + |
| + m_webAudioDevice = adoptPtr(Platform::current()->createAudioDevice(m_callbackBufferSize, numberOfInputChannels, numberOfOutputChannels, sampleRate, this, inputDeviceId, securityOrigin)); |
| + DCHECK(m_webAudioDevice); |
| + |
| + // TODO(hongchan): the ownership and the structure are weird. This |
| + // AudioRenderSink is also AudioSourceProvider, this can provide input for |
| + // its own FIFO. |
| + m_pullFifo = adoptPtr(new AudioPullFIFO(numberOfOutputChannels, kPullFifoSize, *this, kRenderQuantumSize)); |
| + |
| + LOG(INFO) << "WEBAUDIO: hardware buffer size = " << recommendedBufferSize; |
| +} |
| + |
| +AudioRenderSink::~AudioRenderSink() |
| +{ |
| + stop(); |
| +} |
| + |
| +PassOwnPtr<AudioRenderSink> AudioRenderSink::create(AudioIOCallback& callback, const String& inputDeviceId, unsigned numberOfInputChannels, unsigned numberOfOutputChannels, float sampleRate, const PassRefPtr<SecurityOrigin>& securityOrigin) |
| +{ |
| + return adoptPtr(new AudioRenderSink(callback, inputDeviceId, numberOfInputChannels, numberOfOutputChannels, sampleRate, securityOrigin)); |
| +} |
| + |
| +size_t AudioRenderSink::renderQuantumSize() |
| +{ |
| + return kRenderQuantumSize; |
| +} |
| + |
| +unsigned AudioRenderSink::audioHardwareBufferSize() |
| +{ |
| + return static_cast<unsigned>(Platform::current()->audioHardwareBufferSize()); |
| +} |
| + |
| +float AudioRenderSink::audioHardwareSampleRate() |
| +{ |
| + return static_cast<float>(Platform::current()->audioHardwareSampleRate()); |
| +} |
| + |
| +unsigned AudioRenderSink::audioHardwareChannelCount() |
| +{ |
| + return static_cast<unsigned>(Platform::current()->audioHardwareOutputChannels()); |
|
o1ka
2016/05/27 14:28:23
If WebAudioDevice provides all these information,
|
| +} |
| + |
| +void AudioRenderSink::start() |
| +{ |
| + if (!m_isRunning && m_webAudioDevice) { |
| + m_webAudioDevice->start(); |
| + m_isRunning = true; |
| + } |
| +} |
| + |
| +void AudioRenderSink::stop() |
| +{ |
| + if (m_isRunning && m_webAudioDevice) { |
| + m_webAudioDevice->stop(); |
| + m_isRunning = false; |
| + } |
| +} |
| + |
| +void AudioRenderSink::render(const WebVector<float*>& source, const WebVector<float*>& destination, size_t framesToProcess) |
| +{ |
| + // If the number of channels or the number of frames to process do not match |
| + // stop the render and return. |
| + if (!(destination.size() == m_numberOfOutputChannels) |
| + || !(framesToProcess == m_callbackBufferSize)) { |
| + NOTREACHED(); |
| + return; |
| + } |
| + |
| + // Fetch the input stream and make the data available in the input FIFO. |
| + if (source.size() >= 2) { |
| + // TODO: implement this. |
| + } |
| + |
| + for (unsigned i = 0; i < m_numberOfOutputChannels; ++i) |
| + m_outputBus->setChannelMemory(i, destination[i], framesToProcess); |
| + |
| + // Fill the destination buffer by consuming data in the pull FIFO. |
| + m_pullFifo->consume(m_outputBus.get(), framesToProcess); |
| + |
| + // LOG(INFO) << "AudioRenderSink::render" << framesToProcess; |
| +} |
| + |
| +void AudioRenderSink::provideInput(AudioBus* outputBus, size_t numberOfFrames) |
| +{ |
| + AudioBus* inputBus = m_inputBus.get(); |
| + m_callback.render(inputBus, outputBus, numberOfFrames); |
| +} |
| + |
| +} // namespace blink |