Chromium Code Reviews| Index: webkit/media/webaudiosourceprovider_impl.cc |
| diff --git a/webkit/media/webaudiosourceprovider_impl.cc b/webkit/media/webaudiosourceprovider_impl.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..3d2bfb1cd48d743bad46499d23bd352cc9815185 |
| --- /dev/null |
| +++ b/webkit/media/webaudiosourceprovider_impl.cc |
| @@ -0,0 +1,136 @@ |
| +// Copyright (c) 2013 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 "webkit/media/webaudiosourceprovider_impl.h" |
| + |
| +#include <vector> |
| + |
| +#include "base/logging.h" |
| +#include "third_party/WebKit/Source/WebKit/chromium/public/WebAudioSourceProviderClient.h" |
| + |
| +using WebKit::WebVector; |
| + |
| +namespace webkit_media { |
| + |
| +WebAudioSourceProviderImpl::WebAudioSourceProviderImpl( |
| + const scoped_refptr<media::AudioRendererSink>& sink) |
| + : is_initialized_(false), |
| + channels_(0), |
| + sample_rate_(0), |
| + is_running_(false), |
| + renderer_(NULL), |
| + client_(NULL), |
| + sink_(sink) { |
| +} |
| + |
| +WebAudioSourceProviderImpl::~WebAudioSourceProviderImpl() {} |
| + |
| +void WebAudioSourceProviderImpl::setClient( |
| + WebKit::WebAudioSourceProviderClient* client) { |
| + base::AutoLock auto_lock(sink_lock_); |
| + |
| + if (client && client != client_) { |
| + // Detach the audio renderer from normal playback. |
| + sink_->Stop(); |
| + |
| + // The client will now take control by calling provideInput() periodically. |
| + client_ = client; |
| + |
| + if (is_initialized_) { |
| + // The client needs to be notified of the audio format, if available. |
| + // If the format is not yet available, we'll be notified later |
| + // when Initialize() is called. |
| + |
| + // Inform WebKit about the audio stream format. |
| + client->setFormat(channels_, sample_rate_); |
| + } |
| + } else if (!client && client_) { |
| + // Restore normal playback. |
| + client_ = NULL; |
| + // TODO(crogers): We should call sink_->Play() if we're |
| + // in the playing state. |
| + } |
| +} |
| + |
| +void WebAudioSourceProviderImpl::provideInput( |
| + const WebVector<float*>& audio_data, size_t number_of_frames) { |
| + DCHECK(client_); |
| + |
| + if (renderer_ && is_initialized_ && is_running_) { |
| + // Wrap WebVector as std::vector. |
| + std::vector<float*> v(audio_data.size()); |
| + for (size_t i = 0; i < audio_data.size(); ++i) |
| + v[i] = audio_data[i]; |
| + |
| + scoped_ptr<media::AudioBus> audio_bus = media::AudioBus::WrapVector( |
| + number_of_frames, v); |
| + |
| + // TODO(crogers): figure out if we should volume scale here or in common |
| + // WebAudio code. In any case we need to take care of volume. |
| + renderer_->Render(audio_bus.get(), 0); |
| + return; |
| + } |
| + |
| + // Provide silence if the source is not running. |
| + for (size_t i = 0; i < audio_data.size(); ++i) |
| + memset(audio_data[i], 0, sizeof(*audio_data[0]) * number_of_frames); |
| +} |
| + |
| +void WebAudioSourceProviderImpl::Start() { |
| + base::AutoLock auto_lock(sink_lock_); |
| + if (!client_) |
| + sink_->Start(); |
| + is_running_ = true; |
|
miu
2013/01/09 18:48:35
Weirdness in existing code (not part of your chang
scherkus (not reviewing)
2013/01/09 23:16:06
Discussed offline, ARS::Start() does indeed start
|
| +} |
| + |
| +void WebAudioSourceProviderImpl::Stop() { |
| + base::AutoLock auto_lock(sink_lock_); |
| + if (!client_) |
| + sink_->Stop(); |
| + is_running_ = false; |
| +} |
| + |
| +void WebAudioSourceProviderImpl::Play() { |
| + base::AutoLock auto_lock(sink_lock_); |
| + if (!client_) |
| + sink_->Play(); |
| + is_running_ = true; |
| +} |
| + |
| +void WebAudioSourceProviderImpl::Pause(bool flush) { |
| + base::AutoLock auto_lock(sink_lock_); |
| + if (!client_) |
| + sink_->Pause(flush); |
| + is_running_ = false; |
| +} |
| + |
| +bool WebAudioSourceProviderImpl::SetVolume(double volume) { |
| + base::AutoLock auto_lock(sink_lock_); |
| + if (!client_) |
| + sink_->SetVolume(volume); |
| + return true; |
| +} |
| + |
| +void WebAudioSourceProviderImpl::Initialize( |
| + const media::AudioParameters& params, |
| + RenderCallback* renderer) { |
| + base::AutoLock auto_lock(sink_lock_); |
| + CHECK(!is_initialized_); |
| + renderer_ = renderer; |
| + |
| + sink_->Initialize(params, renderer); |
| + |
| + // Keep track of the format in case the client hasn't yet been set. |
| + channels_ = params.channels(); |
| + sample_rate_ = params.sample_rate(); |
| + |
| + if (client_) { |
| + // Inform WebKit about the audio stream format. |
| + client_->setFormat(channels_, sample_rate_); |
| + } |
| + |
| + is_initialized_ = true; |
| +} |
| + |
| +} // namespace webkit_media |