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 <algorithm> | 7 #include <algorithm> |
8 #include <limits> | 8 #include <limits> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 16 matching lines...) Expand all Loading... |
27 #include "media/base/bind_to_current_loop.h" | 27 #include "media/base/bind_to_current_loop.h" |
28 #include "media/base/channel_layout.h" | 28 #include "media/base/channel_layout.h" |
29 #include "media/base/limits.h" | 29 #include "media/base/limits.h" |
30 #include "media/base/media_switches.h" | 30 #include "media/base/media_switches.h" |
31 | 31 |
32 namespace media { | 32 namespace media { |
33 | 33 |
34 // Maximum number of output streams that can be open simultaneously. | 34 // Maximum number of output streams that can be open simultaneously. |
35 static const int kMaxOutputStreams = 50; | 35 static const int kMaxOutputStreams = 50; |
36 | 36 |
37 // Define bounds for for low-latency input and output streams. | |
38 static const int kMinimumInputOutputBufferSize = 128; | |
39 static const int kMaximumInputOutputBufferSize = 4096; | |
40 | |
41 // Default sample-rate on most Apple hardware. | 37 // Default sample-rate on most Apple hardware. |
42 static const int kFallbackSampleRate = 44100; | 38 static const int kFallbackSampleRate = 44100; |
43 | 39 |
44 // Helper method to construct AudioObjectPropertyAddress structure given | 40 // Helper method to construct AudioObjectPropertyAddress structure given |
45 // property selector and scope. The property element is always set to | 41 // property selector and scope. The property element is always set to |
46 // kAudioObjectPropertyElementMaster. | 42 // kAudioObjectPropertyElementMaster. |
47 static AudioObjectPropertyAddress GetAudioObjectPropertyAddress( | 43 static AudioObjectPropertyAddress GetAudioObjectPropertyAddress( |
48 AudioObjectPropertySelector selector, | 44 AudioObjectPropertySelector selector, |
49 bool is_input) { | 45 bool is_input) { |
50 AudioObjectPropertyScope scope = is_input ? kAudioObjectPropertyScopeInput | 46 AudioObjectPropertyScope scope = is_input ? kAudioObjectPropertyScopeInput |
(...skipping 780 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
831 } | 827 } |
832 | 828 |
833 const bool has_valid_input_params = input_params.IsValid(); | 829 const bool has_valid_input_params = input_params.IsValid(); |
834 const int hardware_sample_rate = HardwareSampleRateForDevice(device); | 830 const int hardware_sample_rate = HardwareSampleRateForDevice(device); |
835 | 831 |
836 // Allow pass through buffer sizes. If concurrent input and output streams | 832 // Allow pass through buffer sizes. If concurrent input and output streams |
837 // exist, they will use the smallest buffer size amongst them. As such, each | 833 // exist, they will use the smallest buffer size amongst them. As such, each |
838 // stream must be able to FIFO requests appropriately when this happens. | 834 // stream must be able to FIFO requests appropriately when this happens. |
839 int buffer_size = ChooseBufferSize(false, hardware_sample_rate); | 835 int buffer_size = ChooseBufferSize(false, hardware_sample_rate); |
840 if (has_valid_input_params) { | 836 if (has_valid_input_params) { |
841 buffer_size = | 837 buffer_size = std::min( |
842 std::min(kMaximumInputOutputBufferSize, | 838 AudioLatency::GetMaximumAudioBufferSize(hardware_sample_rate), |
843 std::max(input_params.frames_per_buffer(), buffer_size)); | 839 std::max( |
| 840 input_params.frames_per_buffer(), |
| 841 AudioLatency::GetMinimumAudioBufferSize(hardware_sample_rate))); |
844 } | 842 } |
845 | 843 |
846 int hardware_channels; | 844 int hardware_channels; |
847 if (!GetDeviceChannels(device, AUElement::OUTPUT, &hardware_channels)) | 845 if (!GetDeviceChannels(device, AUElement::OUTPUT, &hardware_channels)) |
848 hardware_channels = 2; | 846 hardware_channels = 2; |
849 | 847 |
850 // Use the input channel count and channel layout if possible. Let OSX take | 848 // Use the input channel count and channel layout if possible. Let OSX take |
851 // care of remapping the channels; this lets user specified channel layouts | 849 // care of remapping the channels; this lets user specified channel layouts |
852 // work correctly. | 850 // work correctly. |
853 int output_channels = input_params.channels(); | 851 int output_channels = input_params.channels(); |
(...skipping 26 matching lines...) Expand all Loading... |
880 current_output_device_ == new_output_device) { | 878 current_output_device_ == new_output_device) { |
881 return; | 879 return; |
882 } | 880 } |
883 | 881 |
884 current_sample_rate_ = new_sample_rate; | 882 current_sample_rate_ = new_sample_rate; |
885 current_output_device_ = new_output_device; | 883 current_output_device_ = new_output_device; |
886 NotifyAllOutputDeviceChangeListeners(); | 884 NotifyAllOutputDeviceChangeListeners(); |
887 } | 885 } |
888 | 886 |
889 int AudioManagerMac::ChooseBufferSize(bool is_input, int sample_rate) { | 887 int AudioManagerMac::ChooseBufferSize(bool is_input, int sample_rate) { |
890 // kMinimumInputOutputBufferSize is too small for the output side because | |
891 // CoreAudio can get into under-run if the renderer fails delivering data | |
892 // to the browser within the allowed time by the OS. The workaround is to | |
893 // use 256 samples as the default output buffer size for sample rates | |
894 // smaller than 96KHz. | |
895 // TODO(xians): Remove this workaround after WebAudio supports user defined | |
896 // buffer size. See https://github.com/WebAudio/web-audio-api/issues/348 | |
897 // for details. | |
898 int buffer_size = is_input ? | |
899 kMinimumInputOutputBufferSize : 2 * kMinimumInputOutputBufferSize; | |
900 const int user_buffer_size = GetUserBufferSize(); | 888 const int user_buffer_size = GetUserBufferSize(); |
901 if (user_buffer_size) { | 889 if (user_buffer_size) |
902 buffer_size = user_buffer_size; | 890 return user_buffer_size; |
903 } else if (sample_rate > 48000) { | 891 return AudioLatency::GetDefaultAudioBufferSize(is_input, sample_rate); |
904 // The default buffer size is too small for higher sample rates and may lead | |
905 // to glitching. Adjust upwards by multiples of the default size. | |
906 if (sample_rate <= 96000) | |
907 buffer_size = 2 * kMinimumInputOutputBufferSize; | |
908 else if (sample_rate <= 192000) | |
909 buffer_size = 4 * kMinimumInputOutputBufferSize; | |
910 } | |
911 | |
912 return buffer_size; | |
913 } | 892 } |
914 | 893 |
915 bool AudioManagerMac::IsSuspending() const { | 894 bool AudioManagerMac::IsSuspending() const { |
916 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); | 895 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); |
917 return power_observer_->IsSuspending(); | 896 return power_observer_->IsSuspending(); |
918 } | 897 } |
919 | 898 |
920 bool AudioManagerMac::ShouldDeferStreamStart() const { | 899 bool AudioManagerMac::ShouldDeferStreamStart() const { |
921 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); | 900 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); |
922 return power_observer_->ShouldDeferStreamStart(); | 901 return power_observer_->ShouldDeferStreamStart(); |
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1183 } | 1162 } |
1184 | 1163 |
1185 std::unique_ptr<AudioManager> CreateAudioManager( | 1164 std::unique_ptr<AudioManager> CreateAudioManager( |
1186 std::unique_ptr<AudioThread> audio_thread, | 1165 std::unique_ptr<AudioThread> audio_thread, |
1187 AudioLogFactory* audio_log_factory) { | 1166 AudioLogFactory* audio_log_factory) { |
1188 return base::MakeUnique<AudioManagerMac>(std::move(audio_thread), | 1167 return base::MakeUnique<AudioManagerMac>(std::move(audio_thread), |
1189 audio_log_factory); | 1168 audio_log_factory); |
1190 } | 1169 } |
1191 | 1170 |
1192 } // namespace media | 1171 } // namespace media |
OLD | NEW |