OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/linux/audio_manager_linux.h" | 5 #include "media/audio/linux/audio_manager_linux.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/environment.h" | 8 #include "base/environment.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/nix/xdg_util.h" | 10 #include "base/nix/xdg_util.h" |
(...skipping 18 matching lines...) Expand all Loading... |
29 | 29 |
30 // Since "default", "pulse" and "dmix" devices are virtual devices mapped to | 30 // Since "default", "pulse" and "dmix" devices are virtual devices mapped to |
31 // real devices, we remove them from the list to avoiding duplicate counting. | 31 // real devices, we remove them from the list to avoiding duplicate counting. |
32 // In addition, note that we support no more than 2 channels for recording, | 32 // In addition, note that we support no more than 2 channels for recording, |
33 // hence surround devices are not stored in the list. | 33 // hence surround devices are not stored in the list. |
34 static const char* kInvalidAudioInputDevices[] = { | 34 static const char* kInvalidAudioInputDevices[] = { |
35 "default", | 35 "default", |
36 "null", | 36 "null", |
37 "pulse", | 37 "pulse", |
38 "dmix", | 38 "dmix", |
39 "surround", | |
40 }; | 39 }; |
41 | 40 |
42 // Implementation of AudioManager. | 41 // Implementation of AudioManager. |
43 bool AudioManagerLinux::HasAudioOutputDevices() { | 42 bool AudioManagerLinux::HasAudioOutputDevices() { |
44 return HasAnyAlsaAudioDevice(kStreamPlayback); | 43 return HasAnyAlsaAudioDevice(kStreamPlayback); |
45 } | 44 } |
46 | 45 |
47 bool AudioManagerLinux::HasAudioInputDevices() { | 46 bool AudioManagerLinux::HasAudioInputDevices() { |
48 return HasAnyAlsaAudioDevice(kStreamCapture); | 47 return HasAnyAlsaAudioDevice(kStreamCapture); |
49 } | 48 } |
(...skipping 30 matching lines...) Expand all Loading... |
80 stream = new AlsaPcmOutputStream(device_name, params, wrapper_.get(), this, | 79 stream = new AlsaPcmOutputStream(device_name, params, wrapper_.get(), this, |
81 GetMessageLoop()); | 80 GetMessageLoop()); |
82 #if defined(USE_PULSEAUDIO) | 81 #if defined(USE_PULSEAUDIO) |
83 } | 82 } |
84 #endif | 83 #endif |
85 active_streams_.insert(stream); | 84 active_streams_.insert(stream); |
86 return stream; | 85 return stream; |
87 } | 86 } |
88 | 87 |
89 AudioInputStream* AudioManagerLinux::MakeAudioInputStream( | 88 AudioInputStream* AudioManagerLinux::MakeAudioInputStream( |
90 const AudioParameters& params) { | 89 const AudioParameters& params, const std::string& device_id) { |
91 if (!params.IsValid() || params.channels > kMaxInputChannels) | 90 if (!params.IsValid() || params.channels > kMaxInputChannels || |
| 91 device_id.empty()) |
92 return NULL; | 92 return NULL; |
93 | 93 |
94 if (params.format == AudioParameters::AUDIO_MOCK) { | 94 if (params.format == AudioParameters::AUDIO_MOCK) { |
95 return FakeAudioInputStream::MakeFakeStream(params); | 95 return FakeAudioInputStream::MakeFakeStream(params); |
96 } else if (params.format != AudioParameters::AUDIO_PCM_LINEAR) { | 96 } else if (params.format != AudioParameters::AUDIO_PCM_LINEAR) { |
97 return NULL; | 97 return NULL; |
98 } | 98 } |
99 | 99 |
100 if (!initialized()) | 100 if (!initialized()) |
101 return NULL; | 101 return NULL; |
102 | 102 |
103 // TODO(xians): Pass the device name From AudioInputController instead. | 103 std::string device_name; |
104 std::string device_name = AlsaPcmOutputStream::kAutoSelectDevice; | 104 if (device_id == AudioManagerBase::kDefaultDeviceId) |
| 105 device_name = AlsaPcmInputStream::kAutoSelectDevice; |
| 106 else |
| 107 device_name = device_id; |
105 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAlsaInputDevice)) { | 108 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAlsaInputDevice)) { |
106 device_name = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 109 device_name = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
107 switches::kAlsaInputDevice); | 110 switches::kAlsaInputDevice); |
108 } | 111 } |
109 | 112 |
110 AlsaPcmInputStream* stream = new AlsaPcmInputStream( | 113 AlsaPcmInputStream* stream = new AlsaPcmInputStream( |
111 device_name, params, wrapper_.get()); | 114 device_name, params, wrapper_.get()); |
112 | 115 |
113 return stream; | 116 return stream; |
114 } | 117 } |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 DCHECK(device_names->empty()); | 179 DCHECK(device_names->empty()); |
177 | 180 |
178 GetAlsaAudioInputDevices(device_names); | 181 GetAlsaAudioInputDevices(device_names); |
179 | 182 |
180 if (!device_names->empty()) { | 183 if (!device_names->empty()) { |
181 // Prepend the default device to the list since we always want it to be | 184 // Prepend the default device to the list since we always want it to be |
182 // on the top of the list for all platforms. There is no duplicate | 185 // on the top of the list for all platforms. There is no duplicate |
183 // counting here since the default device has been abstracted out before. | 186 // counting here since the default device has been abstracted out before. |
184 // We use index 0 to make up the unique_id to identify the default device. | 187 // We use index 0 to make up the unique_id to identify the default device. |
185 device_names->push_front(media::AudioDeviceName( | 188 device_names->push_front(media::AudioDeviceName( |
186 AudioManagerBase::kDefaultDeviceName, "0")); | 189 AudioManagerBase::kDefaultDeviceName, |
| 190 AudioManagerBase::kDefaultDeviceId)); |
187 } | 191 } |
188 } | 192 } |
189 | 193 |
190 void AudioManagerLinux::GetAlsaAudioInputDevices( | 194 void AudioManagerLinux::GetAlsaAudioInputDevices( |
191 media::AudioDeviceNames* device_names) { | 195 media::AudioDeviceNames* device_names) { |
192 // Constants specified by the ALSA API for device hints. | 196 // Constants specified by the ALSA API for device hints. |
193 static const char kPcmInterfaceName[] = "pcm"; | 197 static const char kPcmInterfaceName[] = "pcm"; |
194 int card = -1; | 198 int card = -1; |
195 | 199 |
196 // Loop through the sound cards to get ALSA device hints. | 200 // Loop through the sound cards to get ALSA device hints. |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
249 name.device_name = unique_device_name.get(); | 253 name.device_name = unique_device_name.get(); |
250 } | 254 } |
251 | 255 |
252 // Store the device information. | 256 // Store the device information. |
253 device_names->push_back(name); | 257 device_names->push_back(name); |
254 } | 258 } |
255 } | 259 } |
256 } | 260 } |
257 | 261 |
258 bool AudioManagerLinux::IsAlsaDeviceAvailable(const char* device_name) { | 262 bool AudioManagerLinux::IsAlsaDeviceAvailable(const char* device_name) { |
| 263 static const char kNotWantedSurroundDevices[] = "surround"; |
| 264 |
259 if (!device_name) | 265 if (!device_name) |
260 return false; | 266 return false; |
261 | 267 |
262 // Check if the device is in the list of invalid devices. | 268 // Check if the device is in the list of invalid devices. |
263 for (size_t i = 0; i < arraysize(kInvalidAudioInputDevices); ++i) { | 269 for (size_t i = 0; i < arraysize(kInvalidAudioInputDevices); ++i) { |
264 if (!strncmp(kInvalidAudioInputDevices[i], device_name, | 270 if ((strcmp(kInvalidAudioInputDevices[i], device_name) == 0) || |
265 strlen(kInvalidAudioInputDevices[i]))) | 271 (strncmp(kNotWantedSurroundDevices, device_name, |
| 272 arraysize(kNotWantedSurroundDevices) - 1) == 0)) |
266 return false; | 273 return false; |
267 } | 274 } |
268 | 275 |
269 // The only way to check if the device is available is to open/close the | 276 // The only way to check if the device is available is to open/close the |
270 // device. Return false if it fails either of operations. | 277 // device. Return false if it fails either of operations. |
271 snd_pcm_t* device_handle = NULL; | 278 snd_pcm_t* device_handle = NULL; |
272 if (wrapper_->PcmOpen(&device_handle, | 279 if (wrapper_->PcmOpen(&device_handle, |
273 device_name, | 280 device_name, |
274 SND_PCM_STREAM_CAPTURE, | 281 SND_PCM_STREAM_CAPTURE, |
275 SND_PCM_NONBLOCK)) | 282 SND_PCM_NONBLOCK)) |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 } | 324 } |
318 } | 325 } |
319 | 326 |
320 return has_device; | 327 return has_device; |
321 } | 328 } |
322 | 329 |
323 // static | 330 // static |
324 AudioManager* AudioManager::CreateAudioManager() { | 331 AudioManager* AudioManager::CreateAudioManager() { |
325 return new AudioManagerLinux(); | 332 return new AudioManagerLinux(); |
326 } | 333 } |
OLD | NEW |