Separate Simple Backend creation from initialization.
[chromium-blink-merge.git] / webkit / media / webaudiosourceprovider_impl.cc
blob3d2bfb1cd48d743bad46499d23bd352cc9815185
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "webkit/media/webaudiosourceprovider_impl.h"
7 #include <vector>
9 #include "base/logging.h"
10 #include "third_party/WebKit/Source/WebKit/chromium/public/WebAudioSourceProviderClient.h"
12 using WebKit::WebVector;
14 namespace webkit_media {
16 WebAudioSourceProviderImpl::WebAudioSourceProviderImpl(
17 const scoped_refptr<media::AudioRendererSink>& sink)
18 : is_initialized_(false),
19 channels_(0),
20 sample_rate_(0),
21 is_running_(false),
22 renderer_(NULL),
23 client_(NULL),
24 sink_(sink) {
27 WebAudioSourceProviderImpl::~WebAudioSourceProviderImpl() {}
29 void WebAudioSourceProviderImpl::setClient(
30 WebKit::WebAudioSourceProviderClient* client) {
31 base::AutoLock auto_lock(sink_lock_);
33 if (client && client != client_) {
34 // Detach the audio renderer from normal playback.
35 sink_->Stop();
37 // The client will now take control by calling provideInput() periodically.
38 client_ = client;
40 if (is_initialized_) {
41 // The client needs to be notified of the audio format, if available.
42 // If the format is not yet available, we'll be notified later
43 // when Initialize() is called.
45 // Inform WebKit about the audio stream format.
46 client->setFormat(channels_, sample_rate_);
48 } else if (!client && client_) {
49 // Restore normal playback.
50 client_ = NULL;
51 // TODO(crogers): We should call sink_->Play() if we're
52 // in the playing state.
56 void WebAudioSourceProviderImpl::provideInput(
57 const WebVector<float*>& audio_data, size_t number_of_frames) {
58 DCHECK(client_);
60 if (renderer_ && is_initialized_ && is_running_) {
61 // Wrap WebVector as std::vector.
62 std::vector<float*> v(audio_data.size());
63 for (size_t i = 0; i < audio_data.size(); ++i)
64 v[i] = audio_data[i];
66 scoped_ptr<media::AudioBus> audio_bus = media::AudioBus::WrapVector(
67 number_of_frames, v);
69 // TODO(crogers): figure out if we should volume scale here or in common
70 // WebAudio code. In any case we need to take care of volume.
71 renderer_->Render(audio_bus.get(), 0);
72 return;
75 // Provide silence if the source is not running.
76 for (size_t i = 0; i < audio_data.size(); ++i)
77 memset(audio_data[i], 0, sizeof(*audio_data[0]) * number_of_frames);
80 void WebAudioSourceProviderImpl::Start() {
81 base::AutoLock auto_lock(sink_lock_);
82 if (!client_)
83 sink_->Start();
84 is_running_ = true;
87 void WebAudioSourceProviderImpl::Stop() {
88 base::AutoLock auto_lock(sink_lock_);
89 if (!client_)
90 sink_->Stop();
91 is_running_ = false;
94 void WebAudioSourceProviderImpl::Play() {
95 base::AutoLock auto_lock(sink_lock_);
96 if (!client_)
97 sink_->Play();
98 is_running_ = true;
101 void WebAudioSourceProviderImpl::Pause(bool flush) {
102 base::AutoLock auto_lock(sink_lock_);
103 if (!client_)
104 sink_->Pause(flush);
105 is_running_ = false;
108 bool WebAudioSourceProviderImpl::SetVolume(double volume) {
109 base::AutoLock auto_lock(sink_lock_);
110 if (!client_)
111 sink_->SetVolume(volume);
112 return true;
115 void WebAudioSourceProviderImpl::Initialize(
116 const media::AudioParameters& params,
117 RenderCallback* renderer) {
118 base::AutoLock auto_lock(sink_lock_);
119 CHECK(!is_initialized_);
120 renderer_ = renderer;
122 sink_->Initialize(params, renderer);
124 // Keep track of the format in case the client hasn't yet been set.
125 channels_ = params.channels();
126 sample_rate_ = params.sample_rate();
128 if (client_) {
129 // Inform WebKit about the audio stream format.
130 client_->setFormat(channels_, sample_rate_);
133 is_initialized_ = true;
136 } // namespace webkit_media