summaryrefslogtreecommitdiffstats
path: root/media/audio/linux
diff options
context:
space:
mode:
authorscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-01 17:15:57 +0000
committerscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-01 17:15:57 +0000
commita6e6910a717353139ce540da41ded6986c004ee3 (patch)
tree881ca6e0889a7873402512da1d8ec8e99b06692d /media/audio/linux
parentb2ab4efc5aca698fa6a8f6c518b2cab54eb4f28d (diff)
downloadchromium_src-a6e6910a717353139ce540da41ded6986c004ee3.zip
chromium_src-a6e6910a717353139ce540da41ded6986c004ee3.tar.gz
chromium_src-a6e6910a717353139ce540da41ded6986c004ee3.tar.bz2
Adding GetAudioInputDeviceNames() to AudioManager, which allows for device enumeration.
The current version only supports the default device and isn't fully implemented for Mac/Windows yet. Patch by xians@chromium.org: http://codereview.chromium.org/7060011/ BUG=none TEST=media_unittests git-svn-id: svn://svn.chromium.org/chrome/trunk/src@87493 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/audio/linux')
-rw-r--r--media/audio/linux/audio_manager_linux.cc91
-rw-r--r--media/audio/linux/audio_manager_linux.h4
2 files changed, 91 insertions, 4 deletions
diff --git a/media/audio/linux/audio_manager_linux.cc b/media/audio/linux/audio_manager_linux.cc
index b1108be..58b4c0e 100644
--- a/media/audio/linux/audio_manager_linux.cc
+++ b/media/audio/linux/audio_manager_linux.cc
@@ -23,6 +23,30 @@ static const size_t kMaxOutputStreams = 50;
static const int kMaxInputChannels = 2;
+// Since "default", "pulse" and "dmix" devices are virtual devices mapped to
+// real devices, we remove them from the list to avoiding duplicate counting.
+// In addition, note that we support no more than 2 channels for recording,
+// hence surround devices are not stored in the list.
+static const char* kInvalidAudioInputDevices[] = {
+ "default",
+ "null",
+ "pulse",
+ "dmix",
+ "surround",
+};
+
+static bool IsValidAudioInputDevice(const char* device_name) {
+ if (!device_name)
+ return false;
+
+ for (size_t i = 0; i < arraysize(kInvalidAudioInputDevices); ++i) {
+ if (strcmp(kInvalidAudioInputDevices[i], device_name) == 0)
+ return false;
+ }
+
+ return true;
+}
+
// Implementation of AudioManager.
bool AudioManagerLinux::HasAudioOutputDevices() {
// TODO(ajwong): Make this actually query audio devices.
@@ -30,8 +54,31 @@ bool AudioManagerLinux::HasAudioOutputDevices() {
}
bool AudioManagerLinux::HasAudioInputDevices() {
- // TODO(satish): Make this actually query audio devices.
- return true;
+ if (!initialized()) {
+ return false;
+ }
+
+ // Constants specified by the ALSA API for device hints.
+ static const int kGetAllDevices = -1;
+ static const char kPcmInterfaceName[] = "pcm";
+ bool has_device = false;
+ void** hints = NULL;
+
+ // Use the same approach to find the devices as in
+ // AlsaPcmOutputStream::FindDeviceForChannels
+ // Get Alsa device hints.
+ int error = wrapper_->DeviceNameHint(kGetAllDevices,
+ kPcmInterfaceName,
+ &hints);
+ if (error == 0) {
+ has_device = HasAnyValidAudioInputDevice(hints);
+ } else {
+ LOG(ERROR) << "Unable to get device hints: " << wrapper_->StrError(error);
+ }
+
+ // Destroy the hint now that we're done with it.
+ wrapper_->DeviceNameFreeHint(hints);
+ return has_device;
}
AudioOutputStream* AudioManagerLinux::MakeAudioOutputStream(
@@ -96,8 +143,8 @@ AudioManagerLinux::AudioManagerLinux() {
}
AudioManagerLinux::~AudioManagerLinux() {
- // Make sure we stop the thread first. If we let the default destructor to
- // destruct the members, we may destroy audio streams before stopping the
+ // Make sure we stop the thread first. If we allow the default destructor to
+ // destroy the members, we may destroy audio streams before stopping the
// thread, resulting an unexpected behavior.
// This way we make sure activities of the audio streams are all stopped
// before we destroy them.
@@ -147,6 +194,42 @@ void AudioManagerLinux::ShowAudioInputSettings() {
base::LaunchApp(CommandLine(FilePath(command)), false, false, NULL);
}
+void AudioManagerLinux::GetAudioInputDeviceNames(
+ media::AudioDeviceNames* device_names) {
+ // TODO(xians): query a full list of valid devices.
+ if (HasAudioInputDevices()) {
+ // Add the default device to the list.
+ // We use index 0 to make up the unique_id to identify the
+ // default devices.
+ media::AudioDeviceName name;
+ name.device_name = AudioManagerBase::kDefaultDeviceName;
+ name.unique_id = "0";
+ device_names->push_back(name);
+ }
+}
+
+bool AudioManagerLinux::HasAnyValidAudioInputDevice(void** hints) {
+ static const char kIoHintName[] = "IOID";
+ static const char kNameHintName[] = "NAME";
+ static const char kOutputDevice[] = "Output";
+
+ for (void** hint_iter = hints; *hint_iter != NULL; hint_iter++) {
+ // Only examine devices that are input capable. Valid values are
+ // "Input", "Output", and NULL which means both input and output.
+ scoped_ptr_malloc<char> io(wrapper_->DeviceNameGetHint(*hint_iter,
+ kIoHintName));
+ if (io != NULL && strcmp(kOutputDevice, io.get()) == 0)
+ continue;
+
+ scoped_ptr_malloc<char> hint_device_name(
+ wrapper_->DeviceNameGetHint(*hint_iter, kNameHintName));
+ if (IsValidAudioInputDevice(hint_device_name.get()))
+ return true;
+ }
+
+ return false;
+}
+
// static
AudioManager* AudioManager::CreateAudioManager() {
return new AudioManagerLinux();
diff --git a/media/audio/linux/audio_manager_linux.h b/media/audio/linux/audio_manager_linux.h
index b7d43f0..6a5d287 100644
--- a/media/audio/linux/audio_manager_linux.h
+++ b/media/audio/linux/audio_manager_linux.h
@@ -30,6 +30,7 @@ class AudioManagerLinux : public AudioManagerBase {
virtual AudioInputStream* MakeAudioInputStream(AudioParameters params);
virtual bool CanShowAudioInputSettings();
virtual void ShowAudioInputSettings();
+ virtual void GetAudioInputDeviceNames(media::AudioDeviceNames* device_names);
virtual void MuteAll();
virtual void UnMuteAll();
@@ -40,6 +41,9 @@ class AudioManagerLinux : public AudioManagerBase {
virtual ~AudioManagerLinux();
private:
+ // Helper method to query if there is any valid input device
+ bool HasAnyValidAudioInputDevice(void** hint);
+
scoped_ptr<AlsaWrapper> wrapper_;
base::Lock lock_;