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/core_audio_util_win.h" | 5 #include "media/audio/win/core_audio_util_win.h" |
6 | 6 |
7 #include <devicetopology.h> | 7 #include <devicetopology.h> |
8 #include <functiondiscoverykeys_devpkey.h> | 8 #include <functiondiscoverykeys_devpkey.h> |
9 | 9 |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
416 std::string controller_id; | 416 std::string controller_id; |
417 base::WideToUTF8(instance_id.get().pwszVal, | 417 base::WideToUTF8(instance_id.get().pwszVal, |
418 wcslen(instance_id.get().pwszVal), | 418 wcslen(instance_id.get().pwszVal), |
419 &controller_id); | 419 &controller_id); |
420 | 420 |
421 return controller_id; | 421 return controller_id; |
422 } | 422 } |
423 | 423 |
424 std::string CoreAudioUtil::GetMatchingOutputDeviceID( | 424 std::string CoreAudioUtil::GetMatchingOutputDeviceID( |
425 const std::string& input_device_id) { | 425 const std::string& input_device_id) { |
426 ScopedComPtr<IMMDevice> input_device(CreateDevice(input_device_id)); | 426 // Special handling for the default communications device. |
| 427 // We always treat the configured communications devices, as a pair. |
| 428 // If we didn't do that and the user has e.g. configured a mic of a headset |
| 429 // as the default comms input device and a different device (not the speakers |
| 430 // of the headset) as the default comms output device, then we would otherwise |
| 431 // here pick the headset as the matched output device. That's technically |
| 432 // correct, but the user experience would be that any audio played out to |
| 433 // the matched device, would get ducked since it's not the default comms |
| 434 // device. So here, we go with the user's configuration. |
| 435 if (input_device_id == AudioManagerBase::kCommunicationsDeviceId) |
| 436 return AudioManagerBase::kCommunicationsDeviceId; |
| 437 |
| 438 ScopedComPtr<IMMDevice> input_device; |
| 439 if (input_device_id.empty() || |
| 440 input_device_id == AudioManagerBase::kDefaultDeviceId) { |
| 441 input_device = CreateDefaultDevice(eCapture, eConsole); |
| 442 } else { |
| 443 input_device = CreateDevice(input_device_id); |
| 444 } |
| 445 |
427 if (!input_device.get()) | 446 if (!input_device.get()) |
428 return std::string(); | 447 return std::string(); |
429 | 448 |
430 // See if we can get id of the associated controller. | 449 // See if we can get id of the associated controller. |
431 ScopedComPtr<IMMDeviceEnumerator> enumerator(CreateDeviceEnumerator()); | 450 ScopedComPtr<IMMDeviceEnumerator> enumerator(CreateDeviceEnumerator()); |
432 std::string controller_id( | 451 std::string controller_id( |
433 GetAudioControllerID(input_device.get(), enumerator.get())); | 452 GetAudioControllerID(input_device.get(), enumerator.get())); |
434 if (controller_id.empty()) | 453 if (controller_id.empty()) |
435 return std::string(); | 454 return std::string(); |
436 | 455 |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
716 AudioParameters* params) { | 735 AudioParameters* params) { |
717 DCHECK(IsSupported()); | 736 DCHECK(IsSupported()); |
718 | 737 |
719 ScopedComPtr<IMMDevice> device; | 738 ScopedComPtr<IMMDevice> device; |
720 if (device_id == AudioManagerBase::kDefaultDeviceId) { | 739 if (device_id == AudioManagerBase::kDefaultDeviceId) { |
721 device = CoreAudioUtil::CreateDefaultDevice( | 740 device = CoreAudioUtil::CreateDefaultDevice( |
722 is_output_device ? eRender : eCapture, eConsole); | 741 is_output_device ? eRender : eCapture, eConsole); |
723 } else if (device_id == AudioManagerBase::kLoopbackInputDeviceId) { | 742 } else if (device_id == AudioManagerBase::kLoopbackInputDeviceId) { |
724 DCHECK(!is_output_device); | 743 DCHECK(!is_output_device); |
725 device = CoreAudioUtil::CreateDefaultDevice(eRender, eConsole); | 744 device = CoreAudioUtil::CreateDefaultDevice(eRender, eConsole); |
| 745 } else if (device_id == AudioManagerBase::kCommunicationsDeviceId) { |
| 746 device = CoreAudioUtil::CreateDefaultDevice( |
| 747 is_output_device ? eRender : eCapture, eCommunications); |
726 } else { | 748 } else { |
727 device = CreateDevice(device_id); | 749 device = CreateDevice(device_id); |
728 } | 750 } |
729 | 751 |
730 if (!device.get()) { | 752 if (!device.get()) { |
731 // Map NULL-pointer to new error code which can be different from the | 753 // Map NULL-pointer to new error code which can be different from the |
732 // actual error code. The exact value is not important here. | 754 // actual error code. The exact value is not important here. |
733 return AUDCLNT_E_DEVICE_INVALIDATED; | 755 return AUDCLNT_E_DEVICE_INVALIDATED; |
734 } | 756 } |
735 | 757 |
(...skipping 12 matching lines...) Expand all Loading... |
748 DCHECK(!is_output_device); | 770 DCHECK(!is_output_device); |
749 | 771 |
750 // TODO(dalecurtis): Old code rewrote != 1 channels to stereo, do we still | 772 // TODO(dalecurtis): Old code rewrote != 1 channels to stereo, do we still |
751 // need to do the same thing? | 773 // need to do the same thing? |
752 if (params->channels() != 1) { | 774 if (params->channels() != 1) { |
753 params->Reset(params->format(), CHANNEL_LAYOUT_STEREO, 2, | 775 params->Reset(params->format(), CHANNEL_LAYOUT_STEREO, 2, |
754 params->sample_rate(), params->bits_per_sample(), | 776 params->sample_rate(), params->bits_per_sample(), |
755 params->frames_per_buffer()); | 777 params->frames_per_buffer()); |
756 } | 778 } |
757 | 779 |
758 ScopedComPtr<IMMDevice> communications_device( | |
759 CreateDefaultDevice(eCapture, eCommunications)); | |
760 if (communications_device && | |
761 GetDeviceID(communications_device.get()) == GetDeviceID(device.get())) { | |
762 // Raise the 'DUCKING' flag for default communication devices. | |
763 *params = | |
764 AudioParameters(params->format(), params->channel_layout(), | |
765 params->channels(), params->sample_rate(), | |
766 params->bits_per_sample(), params->frames_per_buffer(), | |
767 params->effects() | AudioParameters::DUCKING); | |
768 } | |
769 | |
770 return hr; | 780 return hr; |
771 } | 781 } |
772 | 782 |
773 ChannelConfig CoreAudioUtil::GetChannelConfig(const std::string& device_id, | 783 ChannelConfig CoreAudioUtil::GetChannelConfig(const std::string& device_id, |
774 EDataFlow data_flow) { | 784 EDataFlow data_flow) { |
775 ScopedComPtr<IAudioClient> client( | 785 ScopedComPtr<IAudioClient> client( |
776 CreateClient(device_id, data_flow, eConsole)); | 786 CreateClient(device_id, data_flow, eConsole)); |
777 | 787 |
778 WAVEFORMATPCMEX format = {}; | 788 WAVEFORMATPCMEX format = {}; |
779 if (!client.get() || FAILED(GetSharedModeMixFormat(client.get(), &format))) | 789 if (!client.get() || FAILED(GetSharedModeMixFormat(client.get(), &format))) |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
892 return false; | 902 return false; |
893 | 903 |
894 // Using the AUDCLNT_BUFFERFLAGS_SILENT flag eliminates the need to | 904 // Using the AUDCLNT_BUFFERFLAGS_SILENT flag eliminates the need to |
895 // explicitly write silence data to the rendering buffer. | 905 // explicitly write silence data to the rendering buffer. |
896 DVLOG(2) << "filling up " << num_frames_to_fill << " frames with silence"; | 906 DVLOG(2) << "filling up " << num_frames_to_fill << " frames with silence"; |
897 return SUCCEEDED(render_client->ReleaseBuffer(num_frames_to_fill, | 907 return SUCCEEDED(render_client->ReleaseBuffer(num_frames_to_fill, |
898 AUDCLNT_BUFFERFLAGS_SILENT)); | 908 AUDCLNT_BUFFERFLAGS_SILENT)); |
899 } | 909 } |
900 | 910 |
901 } // namespace media | 911 } // namespace media |
OLD | NEW |