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 |