ext/alsa/gstalsa.c: Small code cleanup.

Original commit message from CVS:
* ext/alsa/gstalsa.c: (gst_alsa_detect_rates),
(gst_alsa_detect_channels), (gst_alsa_probe_supported_formats):
Small code cleanup.
* ext/alsa/gstalsamixer.c: (gst_alsa_mixer_open),
(gst_alsa_mixer_new):
Remove hack that always set the device to hw:0*.
Properly find the card name for whatever device was configured.
Do some better debugging.
Fixes #350784.
* ext/alsa/gstalsamixerelement.c:
(gst_alsa_mixer_element_set_property),
(gst_alsa_mixer_element_change_state):
Cleanups.
Handle setting of a NULL device name better.
This commit is contained in:
Wim Taymans 2006-08-13 14:34:48 +00:00
parent 977f089d84
commit 5fd36709af
4 changed files with 85 additions and 55 deletions

View file

@ -1,3 +1,22 @@
2006-08-13 Wim Taymans <wim@fluendo.com>
* ext/alsa/gstalsa.c: (gst_alsa_detect_rates),
(gst_alsa_detect_channels), (gst_alsa_probe_supported_formats):
Small code cleanup.
* ext/alsa/gstalsamixer.c: (gst_alsa_mixer_open),
(gst_alsa_mixer_new):
Remove hack that always set the device to hw:0*.
Properly find the card name for whatever device was configured.
Do some better debugging.
Fixes #350784.
* ext/alsa/gstalsamixerelement.c:
(gst_alsa_mixer_element_set_property),
(gst_alsa_mixer_element_change_state):
Cleanups.
Handle setting of a NULL device name better.
2006-08-11 Wim Taymans <wim@fluendo.com> 2006-08-11 Wim Taymans <wim@fluendo.com>
* gst/adder/gstadder.c: * gst/adder/gstadder.c:

View file

@ -65,6 +65,7 @@ gst_alsa_detect_rates (GstObject * obj, snd_pcm_hw_params_t * hw_params,
return caps; return caps;
/* ERRORS */
min_rate_err: min_rate_err:
{ {
GST_ERROR_OBJECT (obj, "failed to query minimum sample rate: %s", GST_ERROR_OBJECT (obj, "failed to query minimum sample rate: %s",
@ -328,6 +329,7 @@ gst_alsa_detect_channels (GstObject * obj, snd_pcm_hw_params_t * hw_params,
return caps; return caps;
/* ERRORS */
min_chan_error: min_chan_error:
{ {
GST_ERROR_OBJECT (obj, "failed to query minimum channel count: %s", GST_ERROR_OBJECT (obj, "failed to query minimum channel count: %s",
@ -375,12 +377,12 @@ gst_alsa_probe_supported_formats (GstObject * obj, snd_pcm_t * handle,
return caps; return caps;
/* ERRORS */
error: error:
{ {
GST_ERROR_OBJECT (obj, "failed to query formats: %s", snd_strerror (err)); GST_ERROR_OBJECT (obj, "failed to query formats: %s", snd_strerror (err));
return NULL; return NULL;
} }
subroutine_error: subroutine_error:
{ {
GST_ERROR_OBJECT (obj, "failed to query formats"); GST_ERROR_OBJECT (obj, "failed to query formats");

View file

@ -44,76 +44,78 @@
/* First some utils, then the mixer implementation */ /* First some utils, then the mixer implementation */
static gboolean static gboolean
gst_alsa_mixer_open (GstAlsaMixer * mixer) gst_alsa_mixer_open (GstAlsaMixer * mixer)
{ {
gint err, devicenum; gint err;
snd_ctl_t *ctl;
snd_ctl_card_info_t *card_info;
g_return_val_if_fail (mixer->handle == NULL, FALSE); g_return_val_if_fail (mixer->handle == NULL, FALSE);
/* open and initialize the mixer device */ /* open and initialize the mixer device */
err = snd_mixer_open (&mixer->handle, 0); err = snd_mixer_open (&mixer->handle, 0);
if (err < 0 || mixer->handle == NULL) { if (err < 0 || mixer->handle == NULL)
GST_WARNING ("Cannot open empty mixer."); goto open_failed;
mixer->handle = NULL;
return FALSE;
}
/* hack hack hack hack hack!!!!! */
if (strncmp (mixer->device, "default", 7) == 0) {
/* hack! */
g_free (mixer->device);
mixer->device = g_strdup ("hw:0");
} else if (strncmp (mixer->device, "hw:", 3) == 0) {
/* ok */
} else if (strncmp (mixer->device, "plughw:", 7) == 0) {
gchar *freeme = mixer->device;
mixer->device = g_strdup (freeme + 4);
g_free (freeme);
} else {
goto error;
}
if (strchr (mixer->device, ','))
strchr (mixer->device, ',')[0] = '\0';
if ((err = snd_mixer_attach (mixer->handle, mixer->device)) < 0) { if ((err = snd_mixer_attach (mixer->handle, mixer->device)) < 0) {
GST_WARNING ("Cannot open mixer for sound device `%s'.", mixer->device); GST_WARNING ("Cannot open mixer for sound device '%s': %s", mixer->device,
snd_strerror (err));
goto error; goto error;
} }
if ((err = snd_mixer_selem_register (mixer->handle, NULL, NULL)) < 0) { if ((err = snd_mixer_selem_register (mixer->handle, NULL, NULL)) < 0) {
GST_WARNING ("Cannot register mixer elements."); GST_WARNING ("Cannot register mixer elements: %s", snd_strerror (err));
goto error; goto error;
} }
if ((err = snd_mixer_load (mixer->handle)) < 0) { if ((err = snd_mixer_load (mixer->handle)) < 0) {
GST_WARNING ("Cannot load mixer settings."); GST_WARNING ("Cannot load mixer settings: %s", snd_strerror (err));
goto error; goto error;
} }
/* I don't know how to get a device name from a mixer handle. So on
* to the ugly hacks here, then... */
if (sscanf (mixer->device, "hw:%d", &devicenum) == 1) {
gchar *name;
if (!snd_card_get_name (devicenum, &name)) { /* now get the device name, any of this is not fatal */
mixer->cardname = g_strdup (name); g_free (mixer->cardname);
free (name); if ((err = snd_ctl_open (&ctl, mixer->device, 0)) < 0) {
GST_DEBUG ("Card name = %s", GST_STR_NULL (mixer->cardname)); GST_WARNING ("Cannot open CTL: %s", snd_strerror (err));
} goto no_card_name;
} }
GST_INFO ("Successfully opened mixer for device `%s'.", mixer->device); snd_ctl_card_info_alloca (&card_info);
if ((err = snd_ctl_card_info (ctl, card_info)) < 0) {
GST_WARNING ("Cannot get card info: %s", snd_strerror (err));
snd_ctl_close (ctl);
goto no_card_name;
}
mixer->cardname = g_strdup (snd_ctl_card_info_get_name (card_info));
GST_DEBUG ("Card name = %s", GST_STR_NULL (mixer->cardname));
snd_ctl_close (ctl);
if (FALSE) {
no_card_name:
mixer->cardname = g_strdup ("Unknown");
GST_DEBUG ("Cannot find card name");
}
GST_INFO ("Successfully opened mixer for device '%s'.", mixer->device);
return TRUE; return TRUE;
/* ERROR */
open_failed:
{
GST_WARNING ("Cannot open mixer: %s", snd_strerror (err));
mixer->handle = NULL;
return FALSE;
}
error: error:
snd_mixer_close (mixer->handle); {
mixer->handle = NULL; snd_mixer_close (mixer->handle);
return FALSE; mixer->handle = NULL;
return FALSE;
}
} }
static void static void
@ -230,11 +232,12 @@ gst_alsa_mixer_new (const char *device, GstAlsaMixerDirection dir)
return ret; return ret;
/* ERRORS */
error: error:
if (ret) {
gst_alsa_mixer_free (ret); gst_alsa_mixer_free (ret);
return NULL;
return NULL; }
} }
void void

View file

@ -35,7 +35,6 @@ enum
PROP_DEVICE_NAME PROP_DEVICE_NAME
}; };
static const GstElementDetails gst_alsa_mixer_element_details = static const GstElementDetails gst_alsa_mixer_element_details =
GST_ELEMENT_DETAILS ("Alsa mixer", GST_ELEMENT_DETAILS ("Alsa mixer",
"Generic/Audio", "Generic/Audio",
@ -160,6 +159,10 @@ gst_alsa_mixer_element_set_property (GObject * object, guint prop_id,
GST_OBJECT_LOCK (this); GST_OBJECT_LOCK (this);
g_free (this->device); g_free (this->device);
this->device = g_value_dup_string (value); this->device = g_value_dup_string (value);
/* make sure we never set NULL, this is nice when we want to open the
* device. */
if (this->device == NULL)
this->device = g_strdup (DEFAULT_PROP_DEVICE);
GST_OBJECT_UNLOCK (this); GST_OBJECT_UNLOCK (this);
break; break;
} }
@ -208,14 +211,9 @@ gst_alsa_mixer_element_change_state (GstElement * element,
switch (transition) { switch (transition) {
case GST_STATE_CHANGE_NULL_TO_READY: case GST_STATE_CHANGE_NULL_TO_READY:
if (!this->mixer) { if (!this->mixer) {
const gchar *device = (this->device) ? this->device : "default"; this->mixer = gst_alsa_mixer_new (this->device, GST_ALSA_MIXER_ALL);
if (!this->mixer)
this->mixer = gst_alsa_mixer_new (device, GST_ALSA_MIXER_ALL); goto open_failed;
if (!this->mixer) {
GST_ELEMENT_ERROR (element, RESOURCE, OPEN_READ_WRITE, (NULL),
("Failed to open alsa mixer device '%s'", device));
return GST_STATE_CHANGE_FAILURE;
}
} }
break; break;
default: default:
@ -238,4 +236,12 @@ gst_alsa_mixer_element_change_state (GstElement * element,
} }
return ret; return ret;
/* ERRORS */
open_failed:
{
GST_ELEMENT_ERROR (element, RESOURCE, OPEN_READ_WRITE, (NULL),
("Failed to open alsa mixer device '%s'", this->device));
return GST_STATE_CHANGE_FAILURE;
}
} }