Skip to content

Commit

Permalink
Revert 106513 - The first step to add device selection to linux.
Browse files Browse the repository at this point in the history
This patch will loop through the soundcard and return a list of available devices when the AudioInputDeviceManager does the device enumeration.
Previously, only default device will be returned.

Reverted because this CL caused the Linux/Windows (shared) builds to fail.

Review URL: http://codereview.chromium.org/8162015

TBR=xians@chromium.org
Review URL: http://codereview.chromium.org/8362004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@106517 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
garykac@chromium.org committed Oct 20, 2011
1 parent 4e4e45c commit d308625
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 168 deletions.
17 changes: 0 additions & 17 deletions media/audio/audio_device_name.cc

This file was deleted.

5 changes: 1 addition & 4 deletions media/audio/audio_device_name.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@
namespace media {

struct AudioDeviceName {
AudioDeviceName();
AudioDeviceName(std::string device_name, std::string unique_id);

std::string device_name; // Friendly name of the device.
std::string device_name; // Name and also display name of the device.
std::string unique_id; // Unique identifier for the device.
};

Expand Down
4 changes: 2 additions & 2 deletions media/audio/audio_input_device_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ TEST(AudioInputDeviceTest, EnumerateDevices) {

// Other devices should have non-empty name and id.
while (it != device_names.end()) {
EXPECT_NE("", it->device_name);
EXPECT_NE("", it->unique_id);
EXPECT_EQ("", it->device_name);
EXPECT_EQ("", it->unique_id);
++it;
}
}
Expand Down
185 changes: 57 additions & 128 deletions media/audio/linux/audio_manager_linux.cc
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,54 @@ static const char* kInvalidAudioInputDevices[] = {
"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() {
return HasAnyAlsaAudioDevice(kStreamPlayback);
// TODO(ajwong): Make this actually query audio devices.
return true;
}

bool AudioManagerLinux::HasAudioInputDevices() {
return HasAnyAlsaAudioDevice(kStreamCapture);
if (!initialized()) {
return false;
}

// Constants specified by the ALSA API for device hints.
static const char kPcmInterfaceName[] = "pcm";
bool has_device = false;
void** hints = NULL;
int card = -1;

// Loop through the sound cards to get Alsa device hints.
// Don't use snd_device_name_hint(-1,..) since there is a access violation
// inside this ALSA API with libasound.so.2.0.0.
while (!wrapper_->CardNext(&card) && (card >= 0) && !has_device) {
int error = wrapper_->DeviceNameHint(card,
kPcmInterfaceName,
&hints);
if (error == 0) {
has_device = HasAnyValidAudioInputDevice(hints);

// Destroy the hints now that we're done with it.
wrapper_->DeviceNameFreeHint(hints);
hints = NULL;
} else {
LOG(ERROR) << "Unable to get device hints: " << wrapper_->StrError(error);
}
}

return has_device;
}

AudioOutputStream* AudioManagerLinux::MakeAudioOutputStream(
Expand Down Expand Up @@ -100,7 +141,6 @@ AudioInputStream* AudioManagerLinux::MakeAudioInputStream(
if (!initialized())
return NULL;

// TODO(xians): Pass the device name From AudioInputController instead.
std::string device_name = AlsaPcmOutputStream::kAutoSelectDevice;
if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAlsaInputDevice)) {
device_name = CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
Expand Down Expand Up @@ -173,47 +213,21 @@ void AudioManagerLinux::ShowAudioInputSettings() {

void AudioManagerLinux::GetAudioInputDeviceNames(
media::AudioDeviceNames* device_names) {
device_names->clear();

GetAlsaAudioInputDevices(device_names);

if (!device_names->empty()) {
// Prepend the default device to the list since we always want it to be
// on the top of the list for all platforms. There is no duplicate
// counting here since the default device has been abstracted out before.
// We use index 0 to make up the unique_id to identify the default device.
device_names->push_front(media::AudioDeviceName(
AudioManagerBase::kDefaultDeviceName, "0"));
}
}

void AudioManagerLinux::GetAlsaAudioInputDevices(
media::AudioDeviceNames* device_names) {
// Constants specified by the ALSA API for device hints.
static const char kPcmInterfaceName[] = "pcm";
int card = -1;

// Loop through the sound cards to get ALSA device hints.
while (!wrapper_->CardNext(&card) && (card >= 0)) {
void** hints = NULL;
int error = wrapper_->DeviceNameHint(card, kPcmInterfaceName, &hints);
if (!error) {
GetAlsaDevicesInfo(hints, device_names);

// Destroy the hints now that we're done with it.
wrapper_->DeviceNameFreeHint(hints);
} else {
DLOG(WARNING) << "GetAudioInputDevices: unable to get device hints: "
<< wrapper_->StrError(error);
}
// 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);
}
}

void AudioManagerLinux::GetAlsaDevicesInfo(
void** hints, media::AudioDeviceNames* device_names) {
bool AudioManagerLinux::HasAnyValidAudioInputDevice(void** hints) {
static const char kIoHintName[] = "IOID";
static const char kNameHintName[] = "NAME";
static const char kDescriptionHintName[] = "DESC";
static const char kOutputDevice[] = "Output";

for (void** hint_iter = hints; *hint_iter != NULL; hint_iter++) {
Expand All @@ -224,98 +238,13 @@ void AudioManagerLinux::GetAlsaDevicesInfo(
if (io != NULL && strcmp(kOutputDevice, io.get()) == 0)
continue;

// Get the unique device name for the device.
scoped_ptr_malloc<char> unique_device_name(
scoped_ptr_malloc<char> hint_device_name(
wrapper_->DeviceNameGetHint(*hint_iter, kNameHintName));

// Find out if the device is available.
if (IsAlsaDeviceAvailable(unique_device_name.get())) {
// Get the description for the device.
scoped_ptr_malloc<char> desc(wrapper_->DeviceNameGetHint(
*hint_iter, kDescriptionHintName));

media::AudioDeviceName name;
name.unique_id = unique_device_name.get();
if (desc.get()) {
// Use the more user friendly description as name.
// Replace '\n' with '-'.
char* pret = strchr(desc.get(), '\n');
if (pret)
*pret = '-';
name.device_name = desc.get();
} else {
// Virtual devices don't necessarily have descriptions.
// Use their names instead.
name.device_name = unique_device_name.get();
}

// Store the device information.
device_names->push_back(name);
}
if (IsValidAudioInputDevice(hint_device_name.get()))
return true;
}
}

bool AudioManagerLinux::IsAlsaDeviceAvailable(const char* device_name) {
if (!device_name)
return false;

// Check if the device is in the list of invalid devices.
for (size_t i = 0; i < arraysize(kInvalidAudioInputDevices); ++i) {
if (!strncmp(kInvalidAudioInputDevices[i], device_name,
strlen(kInvalidAudioInputDevices[i])))
return false;
}

// The only way to check if the device is available is to open/close the
// device. Return false if it fails either of operations.
snd_pcm_t* device_handle = NULL;
if (wrapper_->PcmOpen(
&device_handle, device_name, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK))
return false;
if (wrapper_->PcmClose(device_handle))
return false;

return true;
}

bool AudioManagerLinux::HasAnyAlsaAudioDevice(StreamType stream) {
static const char kPcmInterfaceName[] = "pcm";
static const char kIoHintName[] = "IOID";
const char* kNotWantedDevice =
(stream == kStreamPlayback ? "Input" : "Output");
void** hints = NULL;
bool has_device = false;
int card = -1;

// Loop through the sound cards.
// Don't use snd_device_name_hint(-1,..) since there is a access violation
// inside this ALSA API with libasound.so.2.0.0.
while (!wrapper_->CardNext(&card) && (card >= 0) && !has_device) {
int error = wrapper_->DeviceNameHint(card, kPcmInterfaceName, &hints);
if (!error) {
for (void** hint_iter = hints; *hint_iter != NULL; hint_iter++) {
// Only examine devices that are |stream| 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(kNotWantedDevice, io.get()) == 0)
continue; // Wrong type, skip the device.

// Found an input device.
has_device = true;
break;
}

// Destroy the hints now that we're done with it.
wrapper_->DeviceNameFreeHint(hints);
hints = NULL;
} else {
DLOG(WARNING) << "HasAnyAudioDevice: unable to get device hints: "
<< wrapper_->StrError(error);
}
}

return has_device;
return false;
}

// static
Expand Down
18 changes: 2 additions & 16 deletions media/audio/linux/audio_manager_linux.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,22 +42,8 @@ class MEDIA_EXPORT AudioManagerLinux : public AudioManagerBase {
virtual ~AudioManagerLinux();

private:
enum StreamType {
kStreamPlayback = 0,
kStreamCapture,
};

// Gets a list of available ALSA input devices.
void GetAlsaAudioInputDevices(media::AudioDeviceNames* device_names);

// Gets the ALSA devices' names and ids.
void GetAlsaDevicesInfo(void** hint, media::AudioDeviceNames* device_names);

// Checks if the specific ALSA device is available.
bool IsAlsaDeviceAvailable(const char* device_name);

// Returns true if a device is present for the given stream type.
bool HasAnyAlsaAudioDevice(StreamType stream);
// Helper method to query if there is any valid input device
bool HasAnyValidAudioInputDevice(void** hint);

scoped_ptr<AlsaWrapper> wrapper_;

Expand Down
1 change: 0 additions & 1 deletion media/media.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
'audio/audio_io.h',
'audio/audio_input_controller.cc',
'audio/audio_input_controller.h',
'audio/audio_device_name.cc',
'audio/audio_device_name.h',
'audio/audio_manager.cc',
'audio/audio_manager.h',
Expand Down

0 comments on commit d308625

Please sign in to comment.