| OLD | NEW |
| 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_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/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
| 10 #include "media/audio/win/audio_manager_win.h" | 10 #include "media/audio/win/audio_manager_win.h" |
| 11 #include "media/audio/win/avrt_wrapper_win.h" | 11 #include "media/audio/win/avrt_wrapper_win.h" |
| 12 #include "media/audio/win/core_audio_util_win.h" |
| 12 #include "media/base/audio_bus.h" | 13 #include "media/base/audio_bus.h" |
| 13 | 14 |
| 14 using base::win::ScopedComPtr; | 15 using base::win::ScopedComPtr; |
| 15 using base::win::ScopedCOMInitializer; | 16 using base::win::ScopedCOMInitializer; |
| 16 | 17 |
| 17 namespace media { | 18 namespace media { |
| 18 namespace { | 19 namespace { |
| 19 | 20 |
| 20 // Returns true if |device| represents the default communication capture device. | 21 // Returns true if |device| represents the default communication capture device. |
| 21 bool IsDefaultCommunicationDevice(IMMDeviceEnumerator* enumerator, | 22 bool IsDefaultCommunicationDevice(IMMDeviceEnumerator* enumerator, |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 | 91 |
| 91 LARGE_INTEGER performance_frequency; | 92 LARGE_INTEGER performance_frequency; |
| 92 if (QueryPerformanceFrequency(&performance_frequency)) { | 93 if (QueryPerformanceFrequency(&performance_frequency)) { |
| 93 perf_count_to_100ns_units_ = | 94 perf_count_to_100ns_units_ = |
| 94 (10000000.0 / static_cast<double>(performance_frequency.QuadPart)); | 95 (10000000.0 / static_cast<double>(performance_frequency.QuadPart)); |
| 95 } else { | 96 } else { |
| 96 DLOG(ERROR) << "High-resolution performance counters are not supported."; | 97 DLOG(ERROR) << "High-resolution performance counters are not supported."; |
| 97 } | 98 } |
| 98 } | 99 } |
| 99 | 100 |
| 100 WASAPIAudioInputStream::~WASAPIAudioInputStream() {} | 101 WASAPIAudioInputStream::~WASAPIAudioInputStream() { |
| 102 DCHECK(CalledOnValidThread()); |
| 103 } |
| 101 | 104 |
| 102 bool WASAPIAudioInputStream::Open() { | 105 bool WASAPIAudioInputStream::Open() { |
| 103 DCHECK(CalledOnValidThread()); | 106 DCHECK(CalledOnValidThread()); |
| 104 // Verify that we are not already opened. | 107 // Verify that we are not already opened. |
| 105 if (opened_) | 108 if (opened_) |
| 106 return false; | 109 return false; |
| 107 | 110 |
| 108 // Obtain a reference to the IMMDevice interface of the capturing | 111 // Obtain a reference to the IMMDevice interface of the capturing |
| 109 // device with the specified unique identifier or role which was | 112 // device with the specified unique identifier or role which was |
| 110 // set at construction. | 113 // set at construction. |
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 505 // to be valid matches. | 508 // to be valid matches. |
| 506 hr = enumerator->GetDefaultAudioEndpoint(eCapture, eCommunications, | 509 hr = enumerator->GetDefaultAudioEndpoint(eCapture, eCommunications, |
| 507 endpoint_device_.Receive()); | 510 endpoint_device_.Receive()); |
| 508 if (endpoint_device_ && device_id_ != AudioManagerBase::kDefaultDeviceId) { | 511 if (endpoint_device_ && device_id_ != AudioManagerBase::kDefaultDeviceId) { |
| 509 base::win::ScopedCoMem<WCHAR> communications_id; | 512 base::win::ScopedCoMem<WCHAR> communications_id; |
| 510 endpoint_device_->GetId(&communications_id); | 513 endpoint_device_->GetId(&communications_id); |
| 511 if (device_id_ != | 514 if (device_id_ != |
| 512 base::WideToUTF8(static_cast<WCHAR*>(communications_id))) { | 515 base::WideToUTF8(static_cast<WCHAR*>(communications_id))) { |
| 513 DLOG(WARNING) << "Ducking has been requested for a non-default device." | 516 DLOG(WARNING) << "Ducking has been requested for a non-default device." |
| 514 "Not supported."; | 517 "Not supported."; |
| 518 // We can't honor the requested effect flag, so turn it off and |
| 519 // continue. We'll check this flag later to see if we've actually |
| 520 // opened up the communications device, so it's important that it |
| 521 // reflects the active state. |
| 522 effects_ &= ~AudioParameters::DUCKING; |
| 515 endpoint_device_.Release(); // Fall back on code below. | 523 endpoint_device_.Release(); // Fall back on code below. |
| 516 } | 524 } |
| 517 } | 525 } |
| 518 } | 526 } |
| 519 | 527 |
| 520 if (!endpoint_device_) { | 528 if (!endpoint_device_) { |
| 521 if (device_id_ == AudioManagerBase::kDefaultDeviceId) { | 529 if (device_id_ == AudioManagerBase::kDefaultDeviceId) { |
| 522 // Retrieve the default capture audio endpoint for the specified role. | 530 // Retrieve the default capture audio endpoint for the specified role. |
| 523 // Note that, in Windows Vista, the MMDevice API supports device roles | 531 // Note that, in Windows Vista, the MMDevice API supports device roles |
| 524 // but the system-supplied user interface programs do not. | 532 // but the system-supplied user interface programs do not. |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 632 flags = | 640 flags = |
| 633 AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_NOPERSIST; | 641 AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_NOPERSIST; |
| 634 } | 642 } |
| 635 | 643 |
| 636 // Initialize the audio stream between the client and the device. | 644 // Initialize the audio stream between the client and the device. |
| 637 // We connect indirectly through the audio engine by using shared mode. | 645 // We connect indirectly through the audio engine by using shared mode. |
| 638 // Note that, |hnsBufferDuration| is set of 0, which ensures that the | 646 // Note that, |hnsBufferDuration| is set of 0, which ensures that the |
| 639 // buffer is never smaller than the minimum buffer size needed to ensure | 647 // buffer is never smaller than the minimum buffer size needed to ensure |
| 640 // that glitches do not occur between the periodic processing passes. | 648 // that glitches do not occur between the periodic processing passes. |
| 641 // This setting should lead to lowest possible latency. | 649 // This setting should lead to lowest possible latency. |
| 642 HRESULT hr = audio_client_->Initialize(AUDCLNT_SHAREMODE_SHARED, | 650 HRESULT hr = audio_client_->Initialize( |
| 643 flags, | 651 AUDCLNT_SHAREMODE_SHARED, |
| 644 0, // hnsBufferDuration | 652 flags, |
| 645 0, | 653 0, // hnsBufferDuration |
| 646 &format_, | 654 0, |
| 647 NULL); | 655 &format_, |
| 656 (effects_ & AudioParameters::DUCKING) ? &kCommunicationsSessionId : NULL); |
| 657 |
| 648 if (FAILED(hr)) | 658 if (FAILED(hr)) |
| 649 return hr; | 659 return hr; |
| 650 | 660 |
| 651 // Retrieve the length of the endpoint buffer shared between the client | 661 // Retrieve the length of the endpoint buffer shared between the client |
| 652 // and the audio engine. The buffer length determines the maximum amount | 662 // and the audio engine. The buffer length determines the maximum amount |
| 653 // of capture data that the audio engine can read from the endpoint buffer | 663 // of capture data that the audio engine can read from the endpoint buffer |
| 654 // during a single processing pass. | 664 // during a single processing pass. |
| 655 // A typical value is 960 audio frames <=> 20ms @ 48kHz sample rate. | 665 // A typical value is 960 audio frames <=> 20ms @ 48kHz sample rate. |
| 656 hr = audio_client_->GetBufferSize(&endpoint_buffer_size_frames_); | 666 hr = audio_client_->GetBufferSize(&endpoint_buffer_size_frames_); |
| 657 if (FAILED(hr)) | 667 if (FAILED(hr)) |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 731 return hr; | 741 return hr; |
| 732 | 742 |
| 733 // Obtain a reference to the ISimpleAudioVolume interface which enables | 743 // Obtain a reference to the ISimpleAudioVolume interface which enables |
| 734 // us to control the master volume level of an audio session. | 744 // us to control the master volume level of an audio session. |
| 735 hr = audio_client_->GetService(__uuidof(ISimpleAudioVolume), | 745 hr = audio_client_->GetService(__uuidof(ISimpleAudioVolume), |
| 736 simple_audio_volume_.ReceiveVoid()); | 746 simple_audio_volume_.ReceiveVoid()); |
| 737 return hr; | 747 return hr; |
| 738 } | 748 } |
| 739 | 749 |
| 740 } // namespace media | 750 } // namespace media |
| OLD | NEW |