| 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 <endpointvolume.h> |
| 7 #include <memory> | 8 #include <memory> |
| 8 | 9 |
| 9 #include "base/logging.h" | 10 #include "base/logging.h" |
| 10 #include "base/strings/utf_string_conversions.h" | 11 #include "base/strings/utf_string_conversions.h" |
| 11 #include "base/trace_event/trace_event.h" | 12 #include "base/trace_event/trace_event.h" |
| 12 #include "media/audio/audio_device_description.h" | 13 #include "media/audio/audio_device_description.h" |
| 13 #include "media/audio/win/audio_manager_win.h" | 14 #include "media/audio/win/audio_manager_win.h" |
| 14 #include "media/audio/win/avrt_wrapper_win.h" | 15 #include "media/audio/win/avrt_wrapper_win.h" |
| 15 #include "media/audio/win/core_audio_util_win.h" | 16 #include "media/audio/win/core_audio_util_win.h" |
| 16 #include "media/base/audio_bus.h" | 17 #include "media/base/audio_bus.h" |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 158 | 159 |
| 159 started_ = SUCCEEDED(hr); | 160 started_ = SUCCEEDED(hr); |
| 160 } | 161 } |
| 161 | 162 |
| 162 void WASAPIAudioInputStream::Stop() { | 163 void WASAPIAudioInputStream::Stop() { |
| 163 DCHECK(CalledOnValidThread()); | 164 DCHECK(CalledOnValidThread()); |
| 164 DVLOG(1) << "WASAPIAudioInputStream::Stop()"; | 165 DVLOG(1) << "WASAPIAudioInputStream::Stop()"; |
| 165 if (!started_) | 166 if (!started_) |
| 166 return; | 167 return; |
| 167 | 168 |
| 169 if (device_id_ == AudioDeviceDescription::kLoopbackWithMuteDeviceId) { |
| 170 IAudioEndpointVolume* pVolume = NULL; |
| 171 HRESULT hr = |
| 172 endpoint_device_->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_ALL, |
| 173 NULL, reinterpret_cast<void**>(&pVolume)); |
| 174 hr = pVolume->SetMute(false, NULL); |
| 175 } |
| 168 // Stops periodic AGC microphone measurements. | 176 // Stops periodic AGC microphone measurements. |
| 169 StopAgc(); | 177 StopAgc(); |
| 170 | 178 |
| 171 // Shut down the capture thread. | 179 // Shut down the capture thread. |
| 172 if (stop_capture_event_.IsValid()) { | 180 if (stop_capture_event_.IsValid()) { |
| 173 SetEvent(stop_capture_event_.Get()); | 181 SetEvent(stop_capture_event_.Get()); |
| 174 } | 182 } |
| 175 | 183 |
| 176 // Stop the input audio streaming. | 184 // Stop the input audio streaming. |
| 177 HRESULT hr = audio_client_->Stop(); | 185 HRESULT hr = audio_client_->Stop(); |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 464 | 472 |
| 465 if (device_id_ == AudioDeviceDescription::kDefaultDeviceId) { | 473 if (device_id_ == AudioDeviceDescription::kDefaultDeviceId) { |
| 466 // Retrieve the default capture audio endpoint for the specified role. | 474 // Retrieve the default capture audio endpoint for the specified role. |
| 467 // Note that, in Windows Vista, the MMDevice API supports device roles | 475 // Note that, in Windows Vista, the MMDevice API supports device roles |
| 468 // but the system-supplied user interface programs do not. | 476 // but the system-supplied user interface programs do not. |
| 469 hr = enumerator->GetDefaultAudioEndpoint(eCapture, eConsole, | 477 hr = enumerator->GetDefaultAudioEndpoint(eCapture, eConsole, |
| 470 endpoint_device_.Receive()); | 478 endpoint_device_.Receive()); |
| 471 } else if (device_id_ == AudioDeviceDescription::kCommunicationsDeviceId) { | 479 } else if (device_id_ == AudioDeviceDescription::kCommunicationsDeviceId) { |
| 472 hr = enumerator->GetDefaultAudioEndpoint(eCapture, eCommunications, | 480 hr = enumerator->GetDefaultAudioEndpoint(eCapture, eCommunications, |
| 473 endpoint_device_.Receive()); | 481 endpoint_device_.Receive()); |
| 482 } else if (device_id_ == AudioDeviceDescription::kLoopbackWithMuteDeviceId) { |
| 483 // Capture the default playback stream. |
| 484 hr = enumerator->GetDefaultAudioEndpoint(eRender, eConsole, |
| 485 endpoint_device_.Receive()); |
| 486 |
| 487 IAudioEndpointVolume* pVolume = NULL; |
| 488 HRESULT hr2 = |
| 489 endpoint_device_->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_ALL, |
| 490 NULL, reinterpret_cast<void**>(&pVolume)); |
| 491 hr2 = pVolume->SetMute(true, NULL); |
| 474 } else if (device_id_ == AudioDeviceDescription::kLoopbackInputDeviceId) { | 492 } else if (device_id_ == AudioDeviceDescription::kLoopbackInputDeviceId) { |
| 475 // Capture the default playback stream. | 493 // Capture the default playback stream. |
| 476 hr = enumerator->GetDefaultAudioEndpoint(eRender, eConsole, | 494 hr = enumerator->GetDefaultAudioEndpoint(eRender, eConsole, |
| 477 endpoint_device_.Receive()); | 495 endpoint_device_.Receive()); |
| 478 } else { | 496 } else { |
| 479 hr = enumerator->GetDevice(base::UTF8ToUTF16(device_id_).c_str(), | 497 hr = enumerator->GetDevice(base::UTF8ToUTF16(device_id_).c_str(), |
| 480 endpoint_device_.Receive()); | 498 endpoint_device_.Receive()); |
| 481 } | 499 } |
| 482 | 500 |
| 483 if (FAILED(hr)) | 501 if (FAILED(hr)) |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 565 DLOG_IF(ERROR, hr == S_FALSE) << "Format is not supported " | 583 DLOG_IF(ERROR, hr == S_FALSE) << "Format is not supported " |
| 566 << "but a closest match exists."; | 584 << "but a closest match exists."; |
| 567 return (hr == S_OK); | 585 return (hr == S_OK); |
| 568 } | 586 } |
| 569 | 587 |
| 570 HRESULT WASAPIAudioInputStream::InitializeAudioEngine() { | 588 HRESULT WASAPIAudioInputStream::InitializeAudioEngine() { |
| 571 DWORD flags; | 589 DWORD flags; |
| 572 // Use event-driven mode only fo regular input devices. For loopback the | 590 // Use event-driven mode only fo regular input devices. For loopback the |
| 573 // EVENTCALLBACK flag is specified when intializing | 591 // EVENTCALLBACK flag is specified when intializing |
| 574 // |audio_render_client_for_loopback_|. | 592 // |audio_render_client_for_loopback_|. |
| 575 if (device_id_ == AudioDeviceDescription::kLoopbackInputDeviceId) { | 593 if (device_id_ == AudioDeviceDescription::kLoopbackInputDeviceId || |
| 594 device_id_ == AudioDeviceDescription::kLoopbackWithMuteDeviceId) { |
| 576 flags = AUDCLNT_STREAMFLAGS_LOOPBACK | AUDCLNT_STREAMFLAGS_NOPERSIST; | 595 flags = AUDCLNT_STREAMFLAGS_LOOPBACK | AUDCLNT_STREAMFLAGS_NOPERSIST; |
| 577 } else { | 596 } else { |
| 578 flags = AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_NOPERSIST; | 597 flags = AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_NOPERSIST; |
| 579 } | 598 } |
| 580 | 599 |
| 581 // Initialize the audio stream between the client and the device. | 600 // Initialize the audio stream between the client and the device. |
| 582 // We connect indirectly through the audio engine by using shared mode. | 601 // We connect indirectly through the audio engine by using shared mode. |
| 583 // Note that, |hnsBufferDuration| is set of 0, which ensures that the | 602 // Note that, |hnsBufferDuration| is set of 0, which ensures that the |
| 584 // buffer is never smaller than the minimum buffer size needed to ensure | 603 // buffer is never smaller than the minimum buffer size needed to ensure |
| 585 // that glitches do not occur between the periodic processing passes. | 604 // that glitches do not occur between the periodic processing passes. |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 639 // to MSDN: | 658 // to MSDN: |
| 640 // | 659 // |
| 641 // A pull-mode capture client does not receive any events when a stream is | 660 // A pull-mode capture client does not receive any events when a stream is |
| 642 // initialized with event-driven buffering and is loopback-enabled. To | 661 // initialized with event-driven buffering and is loopback-enabled. To |
| 643 // work around this, initialize a render stream in event-driven mode. Each | 662 // work around this, initialize a render stream in event-driven mode. Each |
| 644 // time the client receives an event for the render stream, it must signal | 663 // time the client receives an event for the render stream, it must signal |
| 645 // the capture client to run the capture thread that reads the next set of | 664 // the capture client to run the capture thread that reads the next set of |
| 646 // samples from the capture endpoint buffer. | 665 // samples from the capture endpoint buffer. |
| 647 // | 666 // |
| 648 // http://msdn.microsoft.com/en-us/library/windows/desktop/dd316551(v=vs.85).a
spx | 667 // http://msdn.microsoft.com/en-us/library/windows/desktop/dd316551(v=vs.85).a
spx |
| 649 if (device_id_ == AudioDeviceDescription::kLoopbackInputDeviceId) { | 668 if (device_id_ == AudioDeviceDescription::kLoopbackInputDeviceId || |
| 669 device_id_ == AudioDeviceDescription::kLoopbackWithMuteDeviceId) { |
| 650 hr = endpoint_device_->Activate( | 670 hr = endpoint_device_->Activate( |
| 651 __uuidof(IAudioClient), CLSCTX_INPROC_SERVER, NULL, | 671 __uuidof(IAudioClient), CLSCTX_INPROC_SERVER, NULL, |
| 652 audio_render_client_for_loopback_.ReceiveVoid()); | 672 audio_render_client_for_loopback_.ReceiveVoid()); |
| 653 if (FAILED(hr)) | 673 if (FAILED(hr)) |
| 654 return hr; | 674 return hr; |
| 655 | 675 |
| 656 hr = audio_render_client_for_loopback_->Initialize( | 676 hr = audio_render_client_for_loopback_->Initialize( |
| 657 AUDCLNT_SHAREMODE_SHARED, | 677 AUDCLNT_SHAREMODE_SHARED, |
| 658 AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_NOPERSIST, | 678 AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_NOPERSIST, |
| 659 0, 0, &format_, NULL); | 679 0, 0, &format_, NULL); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 677 return hr; | 697 return hr; |
| 678 | 698 |
| 679 // Obtain a reference to the ISimpleAudioVolume interface which enables | 699 // Obtain a reference to the ISimpleAudioVolume interface which enables |
| 680 // us to control the master volume level of an audio session. | 700 // us to control the master volume level of an audio session. |
| 681 hr = audio_client_->GetService(__uuidof(ISimpleAudioVolume), | 701 hr = audio_client_->GetService(__uuidof(ISimpleAudioVolume), |
| 682 simple_audio_volume_.ReceiveVoid()); | 702 simple_audio_volume_.ReceiveVoid()); |
| 683 return hr; | 703 return hr; |
| 684 } | 704 } |
| 685 | 705 |
| 686 } // namespace media | 706 } // namespace media |
| OLD | NEW |