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

Side by Side Diff: media/audio/win/audio_unified_win.cc

Issue 12049070: Avoids irregular OnMoreData callbacks on Windows using Core Audio (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed audio glitch at startup Created 7 years, 10 months 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "media/audio/win/audio_unified_win.h" 5 #include "media/audio/win/audio_unified_win.h"
6 6
7 #include <Functiondiscoverykeys_devpkey.h> 7 #include <Functiondiscoverykeys_devpkey.h>
8 8
9 #include "base/debug/trace_event.h" 9 #include "base/debug/trace_event.h"
10 #include "base/time.h" 10 #include "base/time.h"
11 #include "base/win/scoped_com_initializer.h" 11 #include "base/win/scoped_com_initializer.h"
12 #include "media/audio/audio_util.h"
12 #include "media/audio/win/audio_manager_win.h" 13 #include "media/audio/win/audio_manager_win.h"
13 #include "media/audio/win/avrt_wrapper_win.h" 14 #include "media/audio/win/avrt_wrapper_win.h"
14 #include "media/audio/win/core_audio_util_win.h" 15 #include "media/audio/win/core_audio_util_win.h"
15 16
16 using base::win::ScopedComPtr; 17 using base::win::ScopedComPtr;
17 using base::win::ScopedCOMInitializer; 18 using base::win::ScopedCOMInitializer;
18 using base::win::ScopedCoMem; 19 using base::win::ScopedCoMem;
19 20
20 // Time in milliseconds between two successive delay measurements. 21 // Time in milliseconds between two successive delay measurements.
21 // We save resources by not updating the delay estimates for each capture 22 // We save resources by not updating the delay estimates for each capture
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 70
70 namespace media { 71 namespace media {
71 72
72 WASAPIUnifiedStream::WASAPIUnifiedStream(AudioManagerWin* manager, 73 WASAPIUnifiedStream::WASAPIUnifiedStream(AudioManagerWin* manager,
73 const AudioParameters& params) 74 const AudioParameters& params)
74 : creating_thread_id_(base::PlatformThread::CurrentId()), 75 : creating_thread_id_(base::PlatformThread::CurrentId()),
75 manager_(manager), 76 manager_(manager),
76 share_mode_(CoreAudioUtil::GetShareMode()), 77 share_mode_(CoreAudioUtil::GetShareMode()),
77 audio_io_thread_(NULL), 78 audio_io_thread_(NULL),
78 opened_(false), 79 opened_(false),
80 volume_(1.0),
79 endpoint_render_buffer_size_frames_(0), 81 endpoint_render_buffer_size_frames_(0),
80 endpoint_capture_buffer_size_frames_(0), 82 endpoint_capture_buffer_size_frames_(0),
81 num_written_frames_(0), 83 num_written_frames_(0),
82 total_delay_ms_(0.0), 84 total_delay_ms_(0.0),
83 source_(NULL), 85 source_(NULL),
84 capture_bus_(AudioBus::Create(params)), 86 capture_bus_(AudioBus::Create(params)),
85 render_bus_(AudioBus::Create(params)) { 87 render_bus_(AudioBus::Create(params)) {
86 DCHECK(manager_); 88 DCHECK(manager_);
87 89
88 DVLOG_IF(1, !HasUnifiedDefaultIO()) << "Unified audio I/O is not supported."; 90 DVLOG_IF(1, !HasUnifiedDefaultIO()) << "Unified audio I/O is not supported.";
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 } 241 }
240 242
241 // Start input streaming data between the endpoint buffer and the audio 243 // Start input streaming data between the endpoint buffer and the audio
242 // engine. 244 // engine.
243 HRESULT hr = audio_input_client_->Start(); 245 HRESULT hr = audio_input_client_->Start();
244 if (FAILED(hr)) { 246 if (FAILED(hr)) {
245 StopAndJoinThread(hr); 247 StopAndJoinThread(hr);
246 return; 248 return;
247 } 249 }
248 250
249 // Reset the counter for number of rendered frames taking into account the 251 // Ensure that the endpoint buffer is prepared with silence.
250 // fact that we always initialize the render side with silence. 252 if (share_mode_ == AUDCLNT_SHAREMODE_SHARED) {
251 UINT32 num_queued_frames = 0; 253 if (!CoreAudioUtil::FillRenderEndpointBufferWithSilence(
252 audio_output_client_->GetCurrentPadding(&num_queued_frames); 254 audio_output_client_, audio_render_client_)) {
253 DCHECK_EQ(num_queued_frames, endpoint_render_buffer_size_frames_); 255 DLOG(WARNING) << "Failed to prepare endpoint buffers with silence.";
254 num_written_frames_ = num_queued_frames; 256 return;
257 }
258 }
259 num_written_frames_ = endpoint_render_buffer_size_frames_;
255 260
256 // Start output streaming data between the endpoint buffer and the audio 261 // Start output streaming data between the endpoint buffer and the audio
257 // engine. 262 // engine.
258 hr = audio_output_client_->Start(); 263 hr = audio_output_client_->Start();
259 if (FAILED(hr)) { 264 if (FAILED(hr)) {
260 StopAndJoinThread(hr); 265 StopAndJoinThread(hr);
261 return; 266 return;
262 } 267 }
263 } 268 }
264 269
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
321 // It is valid to call Close() before calling open or Start(). 326 // It is valid to call Close() before calling open or Start().
322 // It is also valid to call Close() after Start() has been called. 327 // It is also valid to call Close() after Start() has been called.
323 Stop(); 328 Stop();
324 329
325 // Inform the audio manager that we have been closed. This will cause our 330 // Inform the audio manager that we have been closed. This will cause our
326 // destruction. 331 // destruction.
327 manager_->ReleaseOutputStream(this); 332 manager_->ReleaseOutputStream(this);
328 } 333 }
329 334
330 void WASAPIUnifiedStream::SetVolume(double volume) { 335 void WASAPIUnifiedStream::SetVolume(double volume) {
331 NOTIMPLEMENTED(); 336 DVLOG(1) << "SetVolume(volume=" << volume << ")";
337 float volume_float = static_cast<float>(volume);
tommi (sloooow) - chröme 2013/02/01 11:57:53 prefer to consistently use double for volume.
henrika (OOO until Aug 14) 2013/02/01 12:23:52 Done.
338 if (volume_float < 0.0f || volume_float > 1.0f) {
tommi (sloooow) - chröme 2013/02/01 11:57:53 no {}
henrika (OOO until Aug 14) 2013/02/01 12:23:52 Done.
339 return;
340 }
341 volume_ = volume_float;
332 } 342 }
333 343
334 void WASAPIUnifiedStream::GetVolume(double* volume) { 344 void WASAPIUnifiedStream::GetVolume(double* volume) {
335 NOTIMPLEMENTED(); 345 DVLOG(1) << "GetVolume()";
346 *volume = static_cast<double>(volume_);
336 } 347 }
337 348
338 // static 349 // static
339 bool WASAPIUnifiedStream::HasUnifiedDefaultIO() { 350 bool WASAPIUnifiedStream::HasUnifiedDefaultIO() {
340 AudioParameters in_params; 351 AudioParameters in_params;
341 HRESULT hr = CoreAudioUtil::GetPreferredAudioParameters(eCapture, eConsole, 352 HRESULT hr = CoreAudioUtil::GetPreferredAudioParameters(eCapture, eConsole,
342 &in_params); 353 &in_params);
343 if (FAILED(hr)) 354 if (FAILED(hr))
344 return false; 355 return false;
345 356
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
516 if (FAILED(hr)) { 527 if (FAILED(hr)) {
517 DLOG(ERROR) << "Failed to access render buffer"; 528 DLOG(ERROR) << "Failed to access render buffer";
518 continue; 529 continue;
519 } 530 }
520 531
521 // Convert the audio bus content to interleaved integer data using 532 // Convert the audio bus content to interleaved integer data using
522 // |audio_data| as destination. 533 // |audio_data| as destination.
523 render_bus_->ToInterleaved( 534 render_bus_->ToInterleaved(
524 packet_size_frames_, bytes_per_sample, audio_data); 535 packet_size_frames_, bytes_per_sample, audio_data);
525 536
537 // Perform in-place, software-volume adjustments.
538 media::AdjustVolume(audio_data,
539 frames_filled * format_.Format.nBlockAlign,
540 render_bus_->channels(),
541 bytes_per_sample,
542 volume_);
543
526 // Release the buffer space acquired in the GetBuffer() call. 544 // Release the buffer space acquired in the GetBuffer() call.
527 audio_render_client_->ReleaseBuffer(packet_size_frames_, 0); 545 audio_render_client_->ReleaseBuffer(packet_size_frames_, 0);
528 DLOG_IF(ERROR, FAILED(hr)) << "Failed to release render buffer"; 546 DLOG_IF(ERROR, FAILED(hr)) << "Failed to release render buffer";
529 } 547 }
530 break; 548 break;
531 default: 549 default:
532 error = true; 550 error = true;
533 break; 551 break;
534 } 552 }
535 } 553 }
(...skipping 24 matching lines...) Expand all
560 void WASAPIUnifiedStream::StopAndJoinThread(HRESULT err) { 578 void WASAPIUnifiedStream::StopAndJoinThread(HRESULT err) {
561 CHECK(GetCurrentThreadId() == creating_thread_id_); 579 CHECK(GetCurrentThreadId() == creating_thread_id_);
562 DCHECK(audio_io_thread_.get()); 580 DCHECK(audio_io_thread_.get());
563 SetEvent(stop_streaming_event_.Get()); 581 SetEvent(stop_streaming_event_.Get());
564 audio_io_thread_->Join(); 582 audio_io_thread_->Join();
565 audio_io_thread_.reset(); 583 audio_io_thread_.reset();
566 HandleError(err); 584 HandleError(err);
567 } 585 }
568 586
569 } // namespace media 587 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698