diff options
author | scherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-01 17:15:57 +0000 |
---|---|---|
committer | scherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-01 17:15:57 +0000 |
commit | a6e6910a717353139ce540da41ded6986c004ee3 (patch) | |
tree | 881ca6e0889a7873402512da1d8ec8e99b06692d /media/audio/linux | |
parent | b2ab4efc5aca698fa6a8f6c518b2cab54eb4f28d (diff) | |
download | chromium_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.cc | 91 | ||||
-rw-r--r-- | media/audio/linux/audio_manager_linux.h | 4 |
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_; |