Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 "media/audio/win/audio_low_latency_input_win.h" | 5 #include "media/audio/win/audio_low_latency_input_win.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
| 9 #include "base/utf_string_conversions.h" | 9 #include "base/utf_string_conversions.h" |
| 10 #include "media/audio/audio_util.h" | 10 #include "media/audio/audio_util.h" |
| 11 #include "media/audio/win/audio_manager_win.h" | 11 #include "media/audio/win/audio_manager_win.h" |
| 12 #include "media/audio/win/avrt_wrapper_win.h" | 12 #include "media/audio/win/avrt_wrapper_win.h" |
| 13 | 13 |
| 14 using base::win::ScopedComPtr; | 14 using base::win::ScopedComPtr; |
| 15 using base::win::ScopedCOMInitializer; | 15 using base::win::ScopedCOMInitializer; |
| 16 | 16 |
| 17 WASAPIAudioInputStream::WASAPIAudioInputStream( | 17 WASAPIAudioInputStream::WASAPIAudioInputStream( |
| 18 AudioManagerWin* manager, const AudioParameters& params, ERole device_role) | 18 AudioManagerWin* manager, const AudioParameters& params, |
| 19 const std::string& device_id) | |
| 19 : com_init_(ScopedCOMInitializer::kMTA), | 20 : com_init_(ScopedCOMInitializer::kMTA), |
| 20 manager_(manager), | 21 manager_(manager), |
| 21 capture_thread_(NULL), | 22 capture_thread_(NULL), |
| 22 opened_(false), | 23 opened_(false), |
| 23 started_(false), | 24 started_(false), |
| 24 endpoint_buffer_size_frames_(0), | 25 endpoint_buffer_size_frames_(0), |
| 25 device_role_(device_role), | 26 device_id_(device_id), |
| 26 sink_(NULL) { | 27 sink_(NULL) { |
| 27 DCHECK(manager_); | 28 DCHECK(manager_); |
| 28 | 29 |
| 29 // Load the Avrt DLL if not already loaded. Required to support MMCSS. | 30 // Load the Avrt DLL if not already loaded. Required to support MMCSS. |
| 30 bool avrt_init = avrt::Initialize(); | 31 bool avrt_init = avrt::Initialize(); |
| 31 DCHECK(avrt_init) << "Failed to load the Avrt.dll"; | 32 DCHECK(avrt_init) << "Failed to load the Avrt.dll"; |
| 32 | 33 |
| 33 // Set up the desired capture format specified by the client. | 34 // Set up the desired capture format specified by the client. |
| 34 format_.nSamplesPerSec = params.sample_rate; | 35 format_.nSamplesPerSec = params.sample_rate; |
| 35 format_.wFormatTag = WAVE_FORMAT_PCM; | 36 format_.wFormatTag = WAVE_FORMAT_PCM; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 71 } | 72 } |
| 72 } | 73 } |
| 73 | 74 |
| 74 WASAPIAudioInputStream::~WASAPIAudioInputStream() {} | 75 WASAPIAudioInputStream::~WASAPIAudioInputStream() {} |
| 75 | 76 |
| 76 bool WASAPIAudioInputStream::Open() { | 77 bool WASAPIAudioInputStream::Open() { |
| 77 // Verify that we are not already opened. | 78 // Verify that we are not already opened. |
| 78 if (opened_) | 79 if (opened_) |
| 79 return false; | 80 return false; |
| 80 | 81 |
| 81 // Obtain a reference to the IMMDevice interface of the default capturing | 82 // Obtain a reference to the IMMDevice interface of the capturing |
| 82 // device with the specified role. | 83 // device with the specified unique identifier or role. |
|
no longer working on chromium
2011/12/01 15:28:03
it only takes unique id. remove "or role".
henrika (OOO until Aug 14)
2011/12/01 16:02:38
But one of the IDs is "default" and that is a role
| |
| 83 HRESULT hr = SetCaptureDevice(device_role_); | 84 HRESULT hr = SetCaptureDevice(device_id_); |
| 84 if (FAILED(hr)) { | 85 if (FAILED(hr)) { |
| 85 return false; | 86 return false; |
| 86 } | 87 } |
| 87 | 88 |
| 88 // Obtain an IAudioClient interface which enables us to create and initialize | 89 // Obtain an IAudioClient interface which enables us to create and initialize |
| 89 // an audio stream between an audio application and the audio engine. | 90 // an audio stream between an audio application and the audio engine. |
| 90 hr = ActivateCaptureDevice(); | 91 hr = ActivateCaptureDevice(); |
| 91 if (FAILED(hr)) { | 92 if (FAILED(hr)) { |
| 92 return false; | 93 return false; |
| 93 } | 94 } |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 372 PLOG(WARNING) << "Failed to disable MMCSS"; | 373 PLOG(WARNING) << "Failed to disable MMCSS"; |
| 373 } | 374 } |
| 374 } | 375 } |
| 375 | 376 |
| 376 void WASAPIAudioInputStream::HandleError(HRESULT err) { | 377 void WASAPIAudioInputStream::HandleError(HRESULT err) { |
| 377 NOTREACHED() << "Error code: " << err; | 378 NOTREACHED() << "Error code: " << err; |
| 378 if (sink_) | 379 if (sink_) |
| 379 sink_->OnError(this, static_cast<int>(err)); | 380 sink_->OnError(this, static_cast<int>(err)); |
| 380 } | 381 } |
| 381 | 382 |
| 382 HRESULT WASAPIAudioInputStream::SetCaptureDevice(ERole device_role) { | 383 HRESULT WASAPIAudioInputStream::SetCaptureDevice(const std::string& device_id) { |
|
tommi (sloooow) - chröme
2011/12/01 14:11:03
Shouldn't we store this device_id in this function
henrika (OOO until Aug 14)
2011/12/01 16:02:38
Done.
| |
| 383 ScopedComPtr<IMMDeviceEnumerator> enumerator; | 384 ScopedComPtr<IMMDeviceEnumerator> enumerator; |
| 384 HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), | 385 HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), |
| 385 NULL, | 386 NULL, |
| 386 CLSCTX_INPROC_SERVER, | 387 CLSCTX_INPROC_SERVER, |
| 387 __uuidof(IMMDeviceEnumerator), | 388 __uuidof(IMMDeviceEnumerator), |
| 388 enumerator.ReceiveVoid()); | 389 enumerator.ReceiveVoid()); |
| 389 if (SUCCEEDED(hr)) { | 390 if (SUCCEEDED(hr)) { |
| 390 // Retrieve the default capture audio endpoint for the specified role. | 391 // Retrieve the IMMDevice by using the specified role or the specified |
| 391 // Note that, in Windows Vista, the MMDevice API supports device roles | 392 // unique endpoint device-identification string. |
| 392 // but the system-supplied user interface programs do not. | 393 // TODO(henrika): possibly add suport for the eCommunications as well. |
| 393 hr = enumerator->GetDefaultAudioEndpoint(eCapture, | 394 if (device_id == AudioManagerBase::kDefaultDeviceId) { |
| 394 device_role, | 395 // Retrieve the default capture audio endpoint for the specified role. |
| 395 endpoint_device_.Receive()); | 396 // Note that, in Windows Vista, the MMDevice API supports device roles |
| 397 // but the system-supplied user interface programs do not. | |
| 398 hr = enumerator->GetDefaultAudioEndpoint(eCapture, | |
| 399 eConsole, | |
| 400 endpoint_device_.Receive()); | |
| 401 } else { | |
| 402 // Retrieve a capture endpoint device that is specified by an endpoint | |
| 403 // device-identification string. | |
| 404 hr = enumerator->GetDevice(UTF8ToUTF16(device_id).c_str(), | |
| 405 endpoint_device_.Receive()); | |
| 406 } | |
| 396 | 407 |
| 397 // Verify that the audio endpoint device is active. That is, the audio | 408 if (FAILED(hr)) |
| 409 return hr; | |
| 410 | |
| 411 // Verify that the audio endpoint device is active, i.e., the audio | |
| 398 // adapter that connects to the endpoint device is present and enabled. | 412 // adapter that connects to the endpoint device is present and enabled. |
| 399 DWORD state = DEVICE_STATE_DISABLED; | 413 DWORD state = DEVICE_STATE_DISABLED; |
| 400 hr = endpoint_device_->GetState(&state); | 414 hr = endpoint_device_->GetState(&state); |
| 401 if (SUCCEEDED(hr)) { | 415 if (SUCCEEDED(hr)) { |
| 402 if (!(state & DEVICE_STATE_ACTIVE)) { | 416 if (!(state & DEVICE_STATE_ACTIVE)) { |
| 403 DLOG(ERROR) << "Selected capture device is not active."; | 417 DLOG(ERROR) << "Selected capture device is not active."; |
| 404 hr = E_ACCESSDENIED; | 418 hr = E_ACCESSDENIED; |
| 405 } | 419 } |
| 406 } | 420 } |
| 407 } | 421 } |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 499 hr = audio_client_->SetEventHandle(audio_samples_ready_event_.Get()); | 513 hr = audio_client_->SetEventHandle(audio_samples_ready_event_.Get()); |
| 500 if (FAILED(hr)) | 514 if (FAILED(hr)) |
| 501 return hr; | 515 return hr; |
| 502 | 516 |
| 503 // Get access to the IAudioCaptureClient interface. This interface | 517 // Get access to the IAudioCaptureClient interface. This interface |
| 504 // enables us to read input data from the capture endpoint buffer. | 518 // enables us to read input data from the capture endpoint buffer. |
| 505 hr = audio_client_->GetService(__uuidof(IAudioCaptureClient), | 519 hr = audio_client_->GetService(__uuidof(IAudioCaptureClient), |
| 506 audio_capture_client_.ReceiveVoid()); | 520 audio_capture_client_.ReceiveVoid()); |
| 507 return hr; | 521 return hr; |
| 508 } | 522 } |
| OLD | NEW |