Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(203)

Side by Side Diff: content/renderer/media/audio_renderer_impl.cc

Issue 8980008: Integrate HTMLMediaElement with Web Audio API's MediaElementAudioSourceNode (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/renderer/media/audio_renderer_impl.h" 5 #include "content/renderer/media/audio_renderer_impl.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 10
(...skipping 20 matching lines...) Expand all
31 if (sample_rate <= 48000) 31 if (sample_rate <= 48000)
32 return kNominalBufferSize; 32 return kNominalBufferSize;
33 else if (sample_rate <= 96000) 33 else if (sample_rate <= 96000)
34 return kNominalBufferSize * 2; 34 return kNominalBufferSize * 2;
35 return kNominalBufferSize * 4; 35 return kNominalBufferSize * 4;
36 } 36 }
37 37
38 AudioRendererImpl::AudioRendererImpl() 38 AudioRendererImpl::AudioRendererImpl()
39 : AudioRendererBase(), 39 : AudioRendererBase(),
40 bytes_per_second_(0), 40 bytes_per_second_(0),
41 stopped_(false) { 41 stopped_(false),
42 is_initialized_(false) {
42 // We create the AudioDevice here because it must be created in the 43 // We create the AudioDevice here because it must be created in the
43 // main thread. But we don't yet know the audio format (sample-rate, etc.) 44 // main thread. But we don't yet know the audio format (sample-rate, etc.)
44 // at this point. Later, when OnInitialize() is called, we have 45 // at this point. Later, when OnInitialize() is called, we have
45 // the audio format information and call the AudioDevice::Initialize() 46 // the audio format information and call the AudioDevice::Initialize()
46 // method to fully initialize it. 47 // method to fully initialize it.
47 audio_device_ = new AudioDevice(); 48 audio_device_ = new AudioDevice();
49
50 // Assign the AudioDevice as the default audio sink.
51 sink_ = audio_device_.get();
48 } 52 }
49 53
50 AudioRendererImpl::~AudioRendererImpl() { 54 AudioRendererImpl::~AudioRendererImpl() {
51 } 55 }
52 56
53 base::TimeDelta AudioRendererImpl::ConvertToDuration(int bytes) { 57 base::TimeDelta AudioRendererImpl::ConvertToDuration(int bytes) {
54 if (bytes_per_second_) { 58 if (bytes_per_second_) {
55 return base::TimeDelta::FromMicroseconds( 59 return base::TimeDelta::FromMicroseconds(
56 base::Time::kMicrosecondsPerSecond * bytes / bytes_per_second_); 60 base::Time::kMicrosecondsPerSecond * bytes / bytes_per_second_);
57 } 61 }
(...skipping 25 matching lines...) Expand all
83 // Please see: http://code.google.com/p/chromium/issues/detail?id=103627 87 // Please see: http://code.google.com/p/chromium/issues/detail?id=103627
84 // for more details. 88 // for more details.
85 audio_parameters_ = AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 89 audio_parameters_ = AudioParameters(AudioParameters::AUDIO_PCM_LINEAR,
86 channel_layout, 90 channel_layout,
87 sample_rate, 91 sample_rate,
88 bits_per_channel, 92 bits_per_channel,
89 0); 93 0);
90 94
91 bytes_per_second_ = audio_parameters_.GetBytesPerSecond(); 95 bytes_per_second_ = audio_parameters_.GetBytesPerSecond();
92 96
93 DCHECK(audio_device_.get()); 97 base::AutoLock auto_lock(sink_lock_);
94 98
95 if (!audio_device_->IsInitialized()) { 99 DCHECK(sink_);
96 audio_device_->Initialize( 100
101 if (!is_initialized_) {
102 sink_->Initialize(
97 GetBufferSizeForSampleRate(sample_rate), 103 GetBufferSizeForSampleRate(sample_rate),
98 audio_parameters_.channels, 104 audio_parameters_.channels,
99 audio_parameters_.sample_rate, 105 audio_parameters_.sample_rate,
100 audio_parameters_.format, 106 audio_parameters_.format,
101 this); 107 this);
102 108
103 audio_device_->Start(); 109 sink_->Start();
110 is_initialized_ = true;
104 } 111 }
105 112
106 return true; 113 return true;
107 } 114 }
108 115
109 void AudioRendererImpl::OnStop() { 116 void AudioRendererImpl::OnStop() {
110 if (stopped_) 117 if (stopped_)
111 return; 118 return;
112 119
113 DCHECK(audio_device_.get()); 120 base::AutoLock auto_lock(sink_lock_);
114 audio_device_->Stop(); 121 DCHECK(sink_);
122 sink_->Stop();
115 123
116 stopped_ = true; 124 stopped_ = true;
117 } 125 }
118 126
119 void AudioRendererImpl::SetPlaybackRate(float rate) { 127 void AudioRendererImpl::SetPlaybackRate(float rate) {
120 DCHECK_LE(0.0f, rate); 128 DCHECK_LE(0.0f, rate);
121 129
122 // Handle the case where we stopped due to IO message loop dying. 130 // Handle the case where we stopped due to IO message loop dying.
123 if (stopped_) { 131 if (stopped_) {
124 AudioRendererBase::SetPlaybackRate(rate); 132 AudioRendererBase::SetPlaybackRate(rate);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 if (GetPlaybackRate() != 0.0f) { 170 if (GetPlaybackRate() != 0.0f) {
163 DoPlay(); 171 DoPlay();
164 } else { 172 } else {
165 DoPause(); 173 DoPause();
166 } 174 }
167 } 175 }
168 176
169 void AudioRendererImpl::SetVolume(float volume) { 177 void AudioRendererImpl::SetVolume(float volume) {
170 if (stopped_) 178 if (stopped_)
171 return; 179 return;
172 DCHECK(audio_device_.get()); 180 base::AutoLock auto_lock(sink_lock_);
173 audio_device_->SetVolume(volume); 181 DCHECK(sink_);
182 sink_->SetVolume(volume);
174 } 183 }
175 184
176 void AudioRendererImpl::DoPlay() { 185 void AudioRendererImpl::DoPlay() {
177 earliest_end_time_ = base::Time::Now(); 186 earliest_end_time_ = base::Time::Now();
178 DCHECK(audio_device_.get()); 187 base::AutoLock auto_lock(sink_lock_);
179 audio_device_->Play(); 188 DCHECK(sink_);
189 sink_->Play();
180 } 190 }
181 191
182 void AudioRendererImpl::DoPause() { 192 void AudioRendererImpl::DoPause() {
183 DCHECK(audio_device_.get()); 193 base::AutoLock auto_lock(sink_lock_);
184 audio_device_->Pause(false); 194 DCHECK(sink_);
195 sink_->Pause(false);
185 } 196 }
186 197
187 void AudioRendererImpl::DoSeek() { 198 void AudioRendererImpl::DoSeek() {
188 earliest_end_time_ = base::Time::Now(); 199 earliest_end_time_ = base::Time::Now();
189 200
190 // Pause and flush the stream when we seek to a new location. 201 // Pause and flush the stream when we seek to a new location.
191 DCHECK(audio_device_.get()); 202 base::AutoLock auto_lock(sink_lock_);
192 audio_device_->Pause(true); 203 DCHECK(sink_);
204 sink_->Pause(true);
193 } 205 }
194 206
195 void AudioRendererImpl::Render(const std::vector<float*>& audio_data, 207 void AudioRendererImpl::Render(const std::vector<float*>& audio_data,
196 size_t number_of_frames, 208 size_t number_of_frames,
197 size_t audio_delay_milliseconds) { 209 size_t audio_delay_milliseconds) {
198 if (stopped_ || GetPlaybackRate() == 0.0f) { 210 if (stopped_ || GetPlaybackRate() == 0.0f) {
199 // Output silence if stopped. 211 // Output silence if stopped.
200 for (size_t i = 0; i < audio_data.size(); ++i) 212 for (size_t i = 0; i < audio_data.size(); ++i)
201 memset(audio_data[i], 0, sizeof(float) * number_of_frames); 213 memset(audio_data[i], 0, sizeof(float) * number_of_frames);
202 return; 214 return;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 bytes_per_frame / channels, 250 bytes_per_frame / channels,
239 filled_frames); 251 filled_frames);
240 252
241 // If FillBuffer() didn't give us enough data then zero out the remainder. 253 // If FillBuffer() didn't give us enough data then zero out the remainder.
242 if (filled_frames < number_of_frames) { 254 if (filled_frames < number_of_frames) {
243 int frames_to_zero = number_of_frames - filled_frames; 255 int frames_to_zero = number_of_frames - filled_frames;
244 memset(audio_data[channel_index], 0, sizeof(float) * frames_to_zero); 256 memset(audio_data[channel_index], 0, sizeof(float) * frames_to_zero);
245 } 257 }
246 } 258 }
247 } 259 }
260
261 void AudioRendererImpl::SetAudioRendererSink(media::AudioRendererSink* sink) {
262 // NULL should be passed in to use the default AudioDevice sink.
263 DCHECK_NE(sink, audio_device_.get());
264
265 // Synchronize with other uses of sink_ since we're messing with it here.
266 base::AutoLock auto_lock(sink_lock_);
267
268 if (sink && sink != sink_) {
269 // We're switching rendering to a different sink than the AudioDevice.
270
271 // Since we're no longer rendering to the AudioDevice, we don't want
272 // it to make callbacks to us any more.
tommi (sloooow) - chröme 2011/12/19 15:26:24 nit: anymore
Chris Rogers 2011/12/19 21:40:35 Done.
273 if (sink_ == audio_device_.get())
274 audio_device_->Pause(true);
275
276 sink_ = sink;
277 if (is_initialized_) {
278 // The sink needs to be notified of the audio format, if available.
279 // If the format is not yet available, it will later be called
280 // in OnInitialize().
281 sink_->Initialize(
282 GetBufferSizeForSampleRate(audio_parameters_.sample_rate),
283 audio_parameters_.channels,
284 audio_parameters_.sample_rate,
285 audio_parameters_.format,
286 this);
287 }
288 } else if (!sink && sink_ != audio_device_.get()) {
289 // Use default sink.
290 sink_ = audio_device_.get();
291
292 // !!!!! should only call Play() if we're in the playing state.
tommi (sloooow) - chröme 2011/12/19 15:26:24 will you fix this or is it a todo? do we need to c
Chris Rogers 2011/12/19 21:40:35 Actually, for now I think it's better to do nothin
tommi (sloooow) - chröme 2011/12/20 15:05:46 sounds good.
293 audio_device_->Play();
294 }
295 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698