| 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 <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
| 11 #include "base/trace_event/trace_event.h" | 11 #include "base/trace_event/trace_event.h" |
| 12 #include "media/audio/audio_device_description.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 #include "media/base/audio_bus.h" | 16 #include "media/base/audio_bus.h" |
| 16 | 17 |
| 17 using base::win::ScopedComPtr; | 18 using base::win::ScopedComPtr; |
| 18 using base::win::ScopedCOMInitializer; | 19 using base::win::ScopedCOMInitializer; |
| 19 | 20 |
| 20 namespace media { | 21 namespace media { |
| 21 | 22 |
| (...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 454 | 455 |
| 455 ScopedComPtr<IMMDeviceEnumerator> enumerator; | 456 ScopedComPtr<IMMDeviceEnumerator> enumerator; |
| 456 HRESULT hr = enumerator.CreateInstance(__uuidof(MMDeviceEnumerator), | 457 HRESULT hr = enumerator.CreateInstance(__uuidof(MMDeviceEnumerator), |
| 457 NULL, CLSCTX_INPROC_SERVER); | 458 NULL, CLSCTX_INPROC_SERVER); |
| 458 if (FAILED(hr)) | 459 if (FAILED(hr)) |
| 459 return hr; | 460 return hr; |
| 460 | 461 |
| 461 // Retrieve the IMMDevice by using the specified role or the specified | 462 // Retrieve the IMMDevice by using the specified role or the specified |
| 462 // unique endpoint device-identification string. | 463 // unique endpoint device-identification string. |
| 463 | 464 |
| 464 if (device_id_ == AudioManagerBase::kDefaultDeviceId) { | 465 if (device_id_ == AudioDeviceDescription::kDefaultDeviceId) { |
| 465 // Retrieve the default capture audio endpoint for the specified role. | 466 // Retrieve the default capture audio endpoint for the specified role. |
| 466 // Note that, in Windows Vista, the MMDevice API supports device roles | 467 // Note that, in Windows Vista, the MMDevice API supports device roles |
| 467 // but the system-supplied user interface programs do not. | 468 // but the system-supplied user interface programs do not. |
| 468 hr = enumerator->GetDefaultAudioEndpoint(eCapture, eConsole, | 469 hr = enumerator->GetDefaultAudioEndpoint(eCapture, eConsole, |
| 469 endpoint_device_.Receive()); | 470 endpoint_device_.Receive()); |
| 470 } else if (device_id_ == AudioManagerBase::kCommunicationsDeviceId) { | 471 } else if (device_id_ == AudioDeviceDescription::kCommunicationsDeviceId) { |
| 471 hr = enumerator->GetDefaultAudioEndpoint(eCapture, eCommunications, | 472 hr = enumerator->GetDefaultAudioEndpoint(eCapture, eCommunications, |
| 472 endpoint_device_.Receive()); | 473 endpoint_device_.Receive()); |
| 473 } else if (device_id_ == AudioManagerBase::kLoopbackInputDeviceId) { | 474 } else if (device_id_ == AudioDeviceDescription::kLoopbackInputDeviceId) { |
| 474 // Capture the default playback stream. | 475 // Capture the default playback stream. |
| 475 hr = enumerator->GetDefaultAudioEndpoint(eRender, eConsole, | 476 hr = enumerator->GetDefaultAudioEndpoint(eRender, eConsole, |
| 476 endpoint_device_.Receive()); | 477 endpoint_device_.Receive()); |
| 477 } else { | 478 } else { |
| 478 hr = enumerator->GetDevice(base::UTF8ToUTF16(device_id_).c_str(), | 479 hr = enumerator->GetDevice(base::UTF8ToUTF16(device_id_).c_str(), |
| 479 endpoint_device_.Receive()); | 480 endpoint_device_.Receive()); |
| 480 } | 481 } |
| 481 | 482 |
| 482 if (FAILED(hr)) | 483 if (FAILED(hr)) |
| 483 return hr; | 484 return hr; |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 564 DLOG_IF(ERROR, hr == S_FALSE) << "Format is not supported " | 565 DLOG_IF(ERROR, hr == S_FALSE) << "Format is not supported " |
| 565 << "but a closest match exists."; | 566 << "but a closest match exists."; |
| 566 return (hr == S_OK); | 567 return (hr == S_OK); |
| 567 } | 568 } |
| 568 | 569 |
| 569 HRESULT WASAPIAudioInputStream::InitializeAudioEngine() { | 570 HRESULT WASAPIAudioInputStream::InitializeAudioEngine() { |
| 570 DWORD flags; | 571 DWORD flags; |
| 571 // Use event-driven mode only fo regular input devices. For loopback the | 572 // Use event-driven mode only fo regular input devices. For loopback the |
| 572 // EVENTCALLBACK flag is specified when intializing | 573 // EVENTCALLBACK flag is specified when intializing |
| 573 // |audio_render_client_for_loopback_|. | 574 // |audio_render_client_for_loopback_|. |
| 574 if (device_id_ == AudioManagerBase::kLoopbackInputDeviceId) { | 575 if (device_id_ == AudioDeviceDescription::kLoopbackInputDeviceId) { |
| 575 flags = AUDCLNT_STREAMFLAGS_LOOPBACK | AUDCLNT_STREAMFLAGS_NOPERSIST; | 576 flags = AUDCLNT_STREAMFLAGS_LOOPBACK | AUDCLNT_STREAMFLAGS_NOPERSIST; |
| 576 } else { | 577 } else { |
| 577 flags = AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_NOPERSIST; | 578 flags = AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_NOPERSIST; |
| 578 } | 579 } |
| 579 | 580 |
| 580 // Initialize the audio stream between the client and the device. | 581 // Initialize the audio stream between the client and the device. |
| 581 // We connect indirectly through the audio engine by using shared mode. | 582 // We connect indirectly through the audio engine by using shared mode. |
| 582 // Note that, |hnsBufferDuration| is set of 0, which ensures that the | 583 // Note that, |hnsBufferDuration| is set of 0, which ensures that the |
| 583 // buffer is never smaller than the minimum buffer size needed to ensure | 584 // buffer is never smaller than the minimum buffer size needed to ensure |
| 584 // that glitches do not occur between the periodic processing passes. | 585 // that glitches do not occur between the periodic processing passes. |
| 585 // This setting should lead to lowest possible latency. | 586 // This setting should lead to lowest possible latency. |
| 586 HRESULT hr = audio_client_->Initialize( | 587 HRESULT hr = audio_client_->Initialize( |
| 587 AUDCLNT_SHAREMODE_SHARED, | 588 AUDCLNT_SHAREMODE_SHARED, flags, |
| 588 flags, | |
| 589 0, // hnsBufferDuration | 589 0, // hnsBufferDuration |
| 590 0, | 590 0, &format_, device_id_ == AudioDeviceDescription::kCommunicationsDeviceId |
| 591 &format_, | 591 ? &kCommunicationsSessionId |
| 592 device_id_ == AudioManagerBase::kCommunicationsDeviceId ? | 592 : nullptr); |
| 593 &kCommunicationsSessionId : nullptr); | |
| 594 | 593 |
| 595 if (FAILED(hr)) | 594 if (FAILED(hr)) |
| 596 return hr; | 595 return hr; |
| 597 | 596 |
| 598 // Retrieve the length of the endpoint buffer shared between the client | 597 // Retrieve the length of the endpoint buffer shared between the client |
| 599 // and the audio engine. The buffer length determines the maximum amount | 598 // and the audio engine. The buffer length determines the maximum amount |
| 600 // of capture data that the audio engine can read from the endpoint buffer | 599 // of capture data that the audio engine can read from the endpoint buffer |
| 601 // during a single processing pass. | 600 // during a single processing pass. |
| 602 // A typical value is 960 audio frames <=> 20ms @ 48kHz sample rate. | 601 // A typical value is 960 audio frames <=> 20ms @ 48kHz sample rate. |
| 603 hr = audio_client_->GetBufferSize(&endpoint_buffer_size_frames_); | 602 hr = audio_client_->GetBufferSize(&endpoint_buffer_size_frames_); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 640 // to MSDN: | 639 // to MSDN: |
| 641 // | 640 // |
| 642 // A pull-mode capture client does not receive any events when a stream is | 641 // A pull-mode capture client does not receive any events when a stream is |
| 643 // initialized with event-driven buffering and is loopback-enabled. To | 642 // initialized with event-driven buffering and is loopback-enabled. To |
| 644 // work around this, initialize a render stream in event-driven mode. Each | 643 // work around this, initialize a render stream in event-driven mode. Each |
| 645 // time the client receives an event for the render stream, it must signal | 644 // time the client receives an event for the render stream, it must signal |
| 646 // the capture client to run the capture thread that reads the next set of | 645 // the capture client to run the capture thread that reads the next set of |
| 647 // samples from the capture endpoint buffer. | 646 // samples from the capture endpoint buffer. |
| 648 // | 647 // |
| 649 // http://msdn.microsoft.com/en-us/library/windows/desktop/dd316551(v=vs.85).a
spx | 648 // http://msdn.microsoft.com/en-us/library/windows/desktop/dd316551(v=vs.85).a
spx |
| 650 if (device_id_ == AudioManagerBase::kLoopbackInputDeviceId) { | 649 if (device_id_ == AudioDeviceDescription::kLoopbackInputDeviceId) { |
| 651 hr = endpoint_device_->Activate( | 650 hr = endpoint_device_->Activate( |
| 652 __uuidof(IAudioClient), CLSCTX_INPROC_SERVER, NULL, | 651 __uuidof(IAudioClient), CLSCTX_INPROC_SERVER, NULL, |
| 653 audio_render_client_for_loopback_.ReceiveVoid()); | 652 audio_render_client_for_loopback_.ReceiveVoid()); |
| 654 if (FAILED(hr)) | 653 if (FAILED(hr)) |
| 655 return hr; | 654 return hr; |
| 656 | 655 |
| 657 hr = audio_render_client_for_loopback_->Initialize( | 656 hr = audio_render_client_for_loopback_->Initialize( |
| 658 AUDCLNT_SHAREMODE_SHARED, | 657 AUDCLNT_SHAREMODE_SHARED, |
| 659 AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_NOPERSIST, | 658 AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_NOPERSIST, |
| 660 0, 0, &format_, NULL); | 659 0, 0, &format_, NULL); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 678 return hr; | 677 return hr; |
| 679 | 678 |
| 680 // Obtain a reference to the ISimpleAudioVolume interface which enables | 679 // Obtain a reference to the ISimpleAudioVolume interface which enables |
| 681 // us to control the master volume level of an audio session. | 680 // us to control the master volume level of an audio session. |
| 682 hr = audio_client_->GetService(__uuidof(ISimpleAudioVolume), | 681 hr = audio_client_->GetService(__uuidof(ISimpleAudioVolume), |
| 683 simple_audio_volume_.ReceiveVoid()); | 682 simple_audio_volume_.ReceiveVoid()); |
| 684 return hr; | 683 return hr; |
| 685 } | 684 } |
| 686 | 685 |
| 687 } // namespace media | 686 } // namespace media |
| OLD | NEW |