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/mac/audio_manager_mac.h" | 5 #include "media/audio/mac/audio_manager_mac.h" |
6 | 6 |
7 #include <CoreAudio/AudioHardware.h> | 7 #include <CoreAudio/AudioHardware.h> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
637 stream = new AUAudioInputStream(this, params, output_params, | 637 stream = new AUAudioInputStream(this, params, output_params, |
638 audio_device_id); | 638 audio_device_id); |
639 } | 639 } |
640 | 640 |
641 return stream; | 641 return stream; |
642 } | 642 } |
643 | 643 |
644 AudioParameters AudioManagerMac::GetPreferredOutputStreamParameters( | 644 AudioParameters AudioManagerMac::GetPreferredOutputStreamParameters( |
645 const std::string& output_device_id, | 645 const std::string& output_device_id, |
646 const AudioParameters& input_params) { | 646 const AudioParameters& input_params) { |
647 AudioDeviceID device = GetAudioDeviceIdByUId(false, output_device_id); | 647 const AudioDeviceID device = GetAudioDeviceIdByUId(false, output_device_id); |
648 if (device == kAudioObjectUnknown) { | 648 if (device == kAudioObjectUnknown) { |
649 DLOG(ERROR) << "Invalid output device " << output_device_id; | 649 DLOG(ERROR) << "Invalid output device " << output_device_id; |
650 return input_params.IsValid() ? input_params : AudioParameters( | 650 return input_params.IsValid() ? input_params : AudioParameters( |
651 AudioParameters::AUDIO_PCM_LOW_LATENCY, CHANNEL_LAYOUT_STEREO, | 651 AudioParameters::AUDIO_PCM_LOW_LATENCY, CHANNEL_LAYOUT_STEREO, |
652 kFallbackSampleRate, 16, ChooseBufferSize(kFallbackSampleRate)); | 652 kFallbackSampleRate, 16, ChooseBufferSize(kFallbackSampleRate)); |
653 } | 653 } |
654 | 654 |
655 int hardware_channels = 2; | 655 const bool has_valid_input_params = input_params.IsValid(); |
| 656 const int hardware_sample_rate = HardwareSampleRateForDevice(device); |
| 657 const int buffer_size = ChooseBufferSize(hardware_sample_rate); |
| 658 |
| 659 int hardware_channels; |
656 if (!GetDeviceChannels(device, kAudioDevicePropertyScopeOutput, | 660 if (!GetDeviceChannels(device, kAudioDevicePropertyScopeOutput, |
657 &hardware_channels)) { | 661 &hardware_channels)) { |
658 // Fallback to stereo. | |
659 hardware_channels = 2; | 662 hardware_channels = 2; |
660 } | 663 } |
661 | 664 |
662 ChannelLayout channel_layout = GuessChannelLayout(hardware_channels); | 665 // Use the input channel count and channel layout if possible. Let OSX take |
663 | 666 // care of remapping the channels; this lets user specified channel layouts |
664 const int hardware_sample_rate = HardwareSampleRateForDevice(device); | 667 // work correctly. |
665 const int buffer_size = ChooseBufferSize(hardware_sample_rate); | 668 int output_channels = input_params.channels(); |
666 | 669 ChannelLayout channel_layout = input_params.channel_layout(); |
667 int input_channels = 0; | 670 if (!has_valid_input_params || output_channels > hardware_channels) { |
668 if (input_params.IsValid()) { | 671 output_channels = hardware_channels; |
669 input_channels = input_params.input_channels(); | 672 channel_layout = GuessChannelLayout(output_channels); |
670 | 673 if (channel_layout == CHANNEL_LAYOUT_UNSUPPORTED) |
671 if (input_channels > 0) { | 674 channel_layout = CHANNEL_LAYOUT_DISCRETE; |
672 // TODO(xians): given the limitations of the AudioOutputStream | |
673 // back-ends used with synchronized I/O, we hard-code to stereo. | |
674 // Specifically, this is a limitation of AudioSynchronizedStream which | |
675 // can be removed as part of the work to consolidate these back-ends. | |
676 channel_layout = CHANNEL_LAYOUT_STEREO; | |
677 } | |
678 } | 675 } |
679 | 676 |
680 if (channel_layout == CHANNEL_LAYOUT_UNSUPPORTED) | 677 const int input_channels = |
681 channel_layout = CHANNEL_LAYOUT_DISCRETE; | 678 has_valid_input_params ? input_params.input_channels() : 0; |
682 else | 679 if (input_channels > 0) { |
683 hardware_channels = ChannelLayoutToChannelCount(channel_layout); | 680 // TODO(xians): given the limitations of the AudioOutputStream |
| 681 // back-ends used with synchronized I/O, we hard-code to stereo. |
| 682 // Specifically, this is a limitation of AudioSynchronizedStream which |
| 683 // can be removed as part of the work to consolidate these back-ends. |
| 684 channel_layout = CHANNEL_LAYOUT_STEREO; |
| 685 } |
684 | 686 |
685 AudioParameters params( | 687 return AudioParameters( |
686 AudioParameters::AUDIO_PCM_LOW_LATENCY, | 688 AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, output_channels, |
687 channel_layout, | 689 input_channels, hardware_sample_rate, 16, buffer_size, |
688 hardware_channels, | |
689 input_channels, | |
690 hardware_sample_rate, | |
691 16, | |
692 buffer_size, | |
693 AudioParameters::NO_EFFECTS); | 690 AudioParameters::NO_EFFECTS); |
694 | |
695 return params; | |
696 } | 691 } |
697 | 692 |
698 void AudioManagerMac::CreateDeviceListener() { | 693 void AudioManagerMac::CreateDeviceListener() { |
699 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); | 694 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); |
700 | 695 |
701 // Get a baseline for the sample-rate and current device, | 696 // Get a baseline for the sample-rate and current device, |
702 // so we can intelligently handle device notifications only when necessary. | 697 // so we can intelligently handle device notifications only when necessary. |
703 current_sample_rate_ = HardwareSampleRate(); | 698 current_sample_rate_ = HardwareSampleRate(); |
704 if (!GetDefaultOutputDevice(¤t_output_device_)) | 699 if (!GetDefaultOutputDevice(¤t_output_device_)) |
705 current_output_device_ = kAudioDeviceUnknown; | 700 current_output_device_ = kAudioDeviceUnknown; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
748 } | 743 } |
749 | 744 |
750 return buffer_size; | 745 return buffer_size; |
751 } | 746 } |
752 | 747 |
753 AudioManager* CreateAudioManager(AudioLogFactory* audio_log_factory) { | 748 AudioManager* CreateAudioManager(AudioLogFactory* audio_log_factory) { |
754 return new AudioManagerMac(audio_log_factory); | 749 return new AudioManagerMac(audio_log_factory); |
755 } | 750 } |
756 | 751 |
757 } // namespace media | 752 } // namespace media |
OLD | NEW |