Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(306)

Side by Side Diff: media/audio/linux/audio_manager_linux.cc

Issue 7060011: Adding GetAudioInputDeviceNames to AudioManager, this function is supposed to do device enumerati... (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: '' Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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"
11 #include "base/process_util.h" 11 #include "base/process_util.h"
12 #include "base/stringprintf.h"
12 #include "media/audio/audio_output_dispatcher.h" 13 #include "media/audio/audio_output_dispatcher.h"
13 #include "media/audio/fake_audio_input_stream.h" 14 #include "media/audio/fake_audio_input_stream.h"
14 #include "media/audio/fake_audio_output_stream.h" 15 #include "media/audio/fake_audio_output_stream.h"
15 #include "media/audio/linux/alsa_input.h" 16 #include "media/audio/linux/alsa_input.h"
16 #include "media/audio/linux/alsa_output.h" 17 #include "media/audio/linux/alsa_output.h"
17 #include "media/audio/linux/alsa_wrapper.h" 18 #include "media/audio/linux/alsa_wrapper.h"
18 #include "media/base/limits.h" 19 #include "media/base/limits.h"
19 #include "media/base/media_switches.h" 20 #include "media/base/media_switches.h"
20 21
21 // Maximum number of output streams that can be open simultaneously. 22 // Maximum number of output streams that can be open simultaneously.
22 static const size_t kMaxOutputStreams = 50; 23 static const size_t kMaxOutputStreams = 50;
23 24
24 static const int kMaxInputChannels = 2; 25 static const int kMaxInputChannels = 2;
25 26
26 // Implementation of AudioManager. 27 // Implementation of AudioManager.
27 bool AudioManagerLinux::HasAudioOutputDevices() { 28 bool AudioManagerLinux::HasAudioOutputDevices() {
28 // TODO(ajwong): Make this actually query audio devices. 29 // TODO(ajwong): Make this actually query audio devices.
29 return true; 30 return true;
30 } 31 }
31 32
32 bool AudioManagerLinux::HasAudioInputDevices() { 33 bool AudioManagerLinux::HasAudioInputDevices() {
33 // TODO(satish): Make this actually query audio devices. 34 if (!initialized()) {
34 return true; 35 return false;
36 }
37
38 // Constants specified by the ALSA API for device hints.
39 static const int kGetAllDevices = -1;
40 static const char kPcmInterfaceName[] = "pcm";
41 bool has_device(false);
42 void **hints = NULL;
43
44 // Use the same approach to find the devices as in
45 // AlsaPcmOutputStream::FindDeviceForChannels
46 // Get Alsa device hints.
47 int error = wrapper_->DeviceNameHint(kGetAllDevices,
48 kPcmInterfaceName,
49 &hints);
50 if (error == 0) {
awong 2011/05/23 21:17:58 If you invert the control flow, you can indeed ear
xians 2011/05/24 13:50:27 Hold until the details here are sorted out. And I
awong 2011/05/24 23:30:32 Ah...I missed that hints might need to be freed.
51 // NOTE: Do not early return from inside this if statement. The
awong 2011/05/23 21:17:58 I think you can clean up the control flow of this
awong 2011/05/24 23:30:32 This comment is still out of date.
52 // hints above need to be freed.
53 has_device = HasAnyValidAudioInputDevice(hints);
54 } else {
55 LOG(ERROR) << "Unable to get device hints: " << wrapper_->StrError(error);
56 }
57
58 // Destory the hint now that we're done with it.
59 wrapper_->DeviceNameFreeHint(hints);
60 hints = NULL;
awong 2011/05/23 21:17:58 not necesasry to reset a local to NULL.
xians 2011/05/24 13:50:27 Done.
61 return has_device;
35 } 62 }
36 63
37 AudioOutputStream* AudioManagerLinux::MakeAudioOutputStream( 64 AudioOutputStream* AudioManagerLinux::MakeAudioOutputStream(
38 AudioParameters params) { 65 AudioParameters params) {
39 // Early return for testing hook. Do this before checking for 66 // Early return for testing hook. Do this before checking for
40 // |initialized_|. 67 // |initialized_|.
41 if (params.format == AudioParameters::AUDIO_MOCK) { 68 if (params.format == AudioParameters::AUDIO_MOCK) {
42 return FakeAudioOutputStream::MakeFakeStream(params); 69 return FakeAudioOutputStream::MakeFakeStream(params);
43 } 70 }
44 71
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 AlsaPcmInputStream* stream = new AlsaPcmInputStream( 116 AlsaPcmInputStream* stream = new AlsaPcmInputStream(
90 device_name, params, wrapper_.get()); 117 device_name, params, wrapper_.get());
91 118
92 return stream; 119 return stream;
93 } 120 }
94 121
95 AudioManagerLinux::AudioManagerLinux() { 122 AudioManagerLinux::AudioManagerLinux() {
96 } 123 }
97 124
98 AudioManagerLinux::~AudioManagerLinux() { 125 AudioManagerLinux::~AudioManagerLinux() {
99 // Make sure we stop the thread first. If we let the default destructor to 126 // Make sure we stop the thread first. If we let the default destructor to
awong 2011/05/23 21:17:58 "let the default destructor to destruct" -> "allow
xians 2011/05/24 13:50:27 Done.
100 // destruct the members, we may destroy audio streams before stopping the 127 // destruct the members, we may destroy audio streams before stopping the
101 // thread, resulting an unexpected behavior. 128 // thread, resulting an unexpected behavior.
102 // This way we make sure activities of the audio streams are all stopped 129 // This way we make sure activities of the audio streams are all stopped
103 // before we destroy them. 130 // before we destroy them.
104 audio_thread_.Stop(); 131 audio_thread_.Stop();
105 132
106 // Free output dispatchers, closing all remaining open streams. 133 // Free output dispatchers, closing all remaining open streams.
107 output_dispatchers_.clear(); 134 output_dispatchers_.clear();
108 135
109 active_streams_.clear(); 136 active_streams_.clear();
(...skipping 30 matching lines...) Expand all
140 167
141 void AudioManagerLinux::ShowAudioInputSettings() { 168 void AudioManagerLinux::ShowAudioInputSettings() {
142 scoped_ptr<base::Environment> env(base::Environment::Create()); 169 scoped_ptr<base::Environment> env(base::Environment::Create());
143 base::nix::DesktopEnvironment desktop = base::nix::GetDesktopEnvironment( 170 base::nix::DesktopEnvironment desktop = base::nix::GetDesktopEnvironment(
144 env.get()); 171 env.get());
145 std::string command((desktop == base::nix::DESKTOP_ENVIRONMENT_GNOME) ? 172 std::string command((desktop == base::nix::DESKTOP_ENVIRONMENT_GNOME) ?
146 "gnome-volume-control" : "kmix"); 173 "gnome-volume-control" : "kmix");
147 base::LaunchApp(CommandLine(FilePath(command)), false, false, NULL); 174 base::LaunchApp(CommandLine(FilePath(command)), false, false, NULL);
148 } 175 }
149 176
177 void AudioManagerLinux::GetAudioInputDeviceNames(
178 AudioDeviceNames* device_names) {
179 // TODO(xians): query a full list of valid devices.
180 if (HasAudioInputDevices()) {
181 // Add the default device to the list.
182 // We use (device_name)_(index) to make up the unique_ids to identify the
183 // devices. For default device, the index is 0, so its unique_id is
184 // Default_0.
185 AudioDeviceName name;
186 name.device_name = AudioManagerBase::kDefaultDeviceName;
187 name.unique_id = StringPrintf("%s_0", AudioManagerBase::kDefaultDeviceName);
188 device_names->push_back(name);
189 }
190 }
191
192 bool AudioManagerLinux::HasAnyValidAudioInputDevice(void** hints) {
193 static const char kIoHintName[] = "IOID";
194 static const char kNameHintName[] = "NAME";
195
196 // Since "default", "pulse" and "dmix" devices are virtual devices mapped to
197 // real devices, we remove them from the list to avoiding duplicate counting.
198 // In addition, note that we support no more than 2 channels for recording,
199 // hence surround devices are not stored in the list. Finally, output and
200 // null devices are not considered as valid devices for recording.
201 static const char kOutputDevice[] = "Output";
202 static const char KNotWantedDefaultDevice[] = "default";
203 static const char kNotWantedNullDevice[] = "null";
204 static const char kNotWantedPulseDevice[] = "pulse";
205 static const char kNotWantedDmixDevice[] = "dmix";
206 static const char kNotWantedSurroundDevice[] = "surround";
207
208 for (void** hint_iter = hints; *hint_iter != NULL; hint_iter++) {
209 // Only examine devices that are input capable.. Valid values are
210 // "Input", "Output", and NULL which means both input and output.
211 scoped_ptr_malloc<char> io(wrapper_->DeviceNameGetHint(*hint_iter,
212 kIoHintName));
213 // Wrong device type, skip it.
214 if (io != NULL &&
215 strncmp(kOutputDevice, io.get(), strlen(kOutputDevice)) == 0)
216 continue;
217
218 scoped_ptr_malloc<char> hint_device_name(
219 wrapper_->DeviceNameGetHint(*hint_iter, kNameHintName));
220 // Now check if if it is a valid device.
221 if (hint_device_name != NULL &&
222 strncmp(KNotWantedDefaultDevice,
223 hint_device_name.get(),
224 strlen(KNotWantedDefaultDevice)) != 0 &&
225 strncmp(kNotWantedNullDevice,
226 hint_device_name.get(),
227 strlen(kNotWantedNullDevice)) != 0 &&
228 strncmp(kNotWantedPulseDevice,
229 hint_device_name.get(),
230 strlen(kNotWantedPulseDevice)) != 0 &&
231 strncmp(kNotWantedDmixDevice,
232 hint_device_name.get(),
233 strlen(kNotWantedDmixDevice)) != 0 &&
234 strncmp(kNotWantedSurroundDevice,
235 hint_device_name.get(),
236 strlen(kNotWantedSurroundDevice)) != 0) {
237 return true;
238 }
239 }
240
241 // Did not find a valid device
242 return false;
243 }
244
150 // static 245 // static
151 AudioManager* AudioManager::CreateAudioManager() { 246 AudioManager* AudioManager::CreateAudioManager() {
152 return new AudioManagerLinux(); 247 return new AudioManagerLinux();
153 } 248 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698