ext/alsa/gstalsa.*: Add propertyprobe interface implementation, add some device-name property, all this so that it lo...

Original commit message from CVS:
* ext/alsa/gstalsa.c: (gst_alsa_get_type), (gst_alsa_class_init),
(gst_alsa_get_property), (gst_alsa_probe_get_properties),
(gst_alsa_class_probe_devices), (gst_alsa_class_list_devices),
(gst_alsa_probe_probe_property), (gst_alsa_probe_needs_probe),
(gst_alsa_probe_get_values), (gst_alsa_probe_interface_init),
(gst_alsa_open_audio), (gst_alsa_close_audio):
* ext/alsa/gstalsa.h:
Add propertyprobe interface implementation, add some device-name
property, all this so that it looks good in gnome-volume-control.
This commit is contained in:
Ronald S. Bultje 2004-03-13 04:44:50 +00:00
parent a518507a47
commit 23d142d276
3 changed files with 181 additions and 0 deletions

View file

@ -1,3 +1,15 @@
2004-03-12 Ronald Bultje <rbultje@ronald.bitfreak.net>
* ext/alsa/gstalsa.c: (gst_alsa_get_type), (gst_alsa_class_init),
(gst_alsa_get_property), (gst_alsa_probe_get_properties),
(gst_alsa_class_probe_devices), (gst_alsa_class_list_devices),
(gst_alsa_probe_probe_property), (gst_alsa_probe_needs_probe),
(gst_alsa_probe_get_values), (gst_alsa_probe_interface_init),
(gst_alsa_open_audio), (gst_alsa_close_audio):
* ext/alsa/gstalsa.h:
Add propertyprobe interface implementation, add some device-name
property, all this so that it looks good in gnome-volume-control.
2004-03-12 David Schleef <ds@schleef.org>
* configure.ac: the Hermes library controls hermescolorspace, not

View file

@ -26,6 +26,7 @@
#include <sys/time.h>
#include "gst/gst-i18n-plugin.h"
#include "gst/propertyprobe/propertyprobe.h"
#include "gstalsa.h"
#include "gstalsaclock.h"
#include "gstalsamixer.h"
@ -44,6 +45,9 @@ static void gst_alsa_get_property (GObject * object,
GValue * value,
GParamSpec * pspec);
/* interface */
static void gst_alsa_probe_interface_init (GstPropertyProbeInterface *iface);
/* GStreamer functions for pads and state changing */
static GstPad * gst_alsa_request_new_pad (GstElement * element,
GstPadTemplate * templ,
@ -109,8 +113,17 @@ gst_alsa_get_type (void)
0,
(GInstanceInitFunc) gst_alsa_init,
};
static const GInterfaceInfo alsa_probe_info = {
(GInterfaceInitFunc) gst_alsa_probe_interface_init,
NULL,
NULL
};
alsa_type = g_type_register_static (GST_TYPE_ELEMENT, "GstAlsa", &alsa_info, 0);
g_type_add_interface_static (alsa_type,
GST_TYPE_PROPERTY_PROBE,
&alsa_probe_info);
}
return alsa_type;
@ -122,6 +135,7 @@ enum
{
ARG_0,
ARG_DEVICE,
ARG_DEVICE_NAME,
ARG_PERIODCOUNT,
ARG_PERIODSIZE,
ARG_BUFFERSIZE,
@ -154,6 +168,10 @@ gst_alsa_class_init (gpointer g_class, gpointer class_data)
g_param_spec_string ("device", "Device",
"ALSA device, as defined in an asoundrc",
"default", G_PARAM_READWRITE));
g_object_class_install_property (object_class, ARG_DEVICE_NAME,
g_param_spec_string ("device_name", "Device name",
"Name of the device",
NULL, G_PARAM_READABLE));
g_object_class_install_property (object_class, ARG_PERIODCOUNT,
g_param_spec_int ("period-count", "Period count",
"Number of hardware buffers to use",
@ -268,6 +286,13 @@ gst_alsa_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec
case ARG_DEVICE:
g_value_set_string (value, this->device);
break;
case ARG_DEVICE_NAME:
if (GST_STATE (this) != GST_STATE_NULL) {
g_value_set_string (value, snd_pcm_info_get_name (this->info));
} else {
g_value_set_string (value, NULL);
}
break;
case ARG_PERIODCOUNT:
g_value_set_int (value, this->period_count);
break;
@ -292,6 +317,141 @@ gst_alsa_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec
}
}
static const GList *
gst_alsa_probe_get_properties (GstPropertyProbe *probe)
{
GObjectClass *klass = G_OBJECT_GET_CLASS (probe);
static GList *list = NULL;
if (!list) {
list = g_list_append (NULL, g_object_class_find_property (klass, "device")); }
return list;
}
static gboolean
gst_alsa_class_probe_devices (GstAlsaClass *klass,
gboolean check)
{
static gboolean init = FALSE;
/* I'm pretty sure ALSA has a good way to do this. However, their cool
* auto-generated documentation is pretty much useless if you try to
* do function-wise look-ups. */
if (!init && !check) {
#define MAX_DEVICES 16 /* random number */
gint num, res;
gchar *dev;
snd_pcm_t *pcm;
for (num = 0; num < MAX_DEVICES; num++) {
dev = g_strdup_printf ("hw:%d", num);
printf ("Trying to open %s\n", dev);
if (!(res = snd_pcm_open (&pcm, dev, 0, 0))) {
klass->devices = g_list_append (klass->devices, dev);
printf ("success\n");
snd_pcm_close (pcm);
} else {
printf ("failure=%d (%s)\n", res, snd_strerror (res));
g_free (dev);
}
}
init = TRUE;
}
return init;
}
static GValueArray *
gst_alsa_class_list_devices (GstAlsaClass *klass)
{
GValueArray *array;
GValue value = { 0 };
GList *item;
if (!klass->devices)
return NULL;
array = g_value_array_new (g_list_length (klass->devices));
g_value_init (&value, G_TYPE_STRING);
for (item = klass->devices; item != NULL; item = item->next) {
g_value_set_string (&value, item->data);
g_value_array_append (array, &value);
}
g_value_unset (&value);
return array;
}
static void
gst_alsa_probe_probe_property (GstPropertyProbe *probe,
guint prop_id,
const GParamSpec *pspec)
{
GstAlsaClass *klass = GST_ALSA_GET_CLASS (probe);
switch (prop_id) {
case ARG_DEVICE:
gst_alsa_class_probe_devices (klass, FALSE);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec);
break;
}
}
static gboolean
gst_alsa_probe_needs_probe (GstPropertyProbe *probe,
guint prop_id,
const GParamSpec *pspec)
{
GstAlsaClass *klass = GST_ALSA_GET_CLASS (probe);
gboolean ret = FALSE;
switch (prop_id) {
case ARG_DEVICE:
ret = !gst_alsa_class_probe_devices (klass, TRUE);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec);
break;
}
return ret;
}
static GValueArray *
gst_alsa_probe_get_values (GstPropertyProbe *probe,
guint prop_id,
const GParamSpec *pspec)
{
GstAlsaClass *klass = GST_ALSA_GET_CLASS (probe);
GValueArray *array = NULL;
switch (prop_id) {
case ARG_DEVICE:
array = gst_alsa_class_list_devices (klass);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec);
break;
}
return array;
}
static void
gst_alsa_probe_interface_init (GstPropertyProbeInterface *iface)
{
iface->get_properties = gst_alsa_probe_get_properties;
iface->probe_property = gst_alsa_probe_probe_property;
iface->needs_probe = gst_alsa_probe_needs_probe;
iface->get_values = gst_alsa_probe_get_values;
}
/*** GSTREAMER PAD / QUERY / CONVERSION / STATE FUNCTIONS *********************/
static GstPad *
@ -947,6 +1107,9 @@ gst_alsa_open_audio (GstAlsa *this)
return FALSE;
}
snd_pcm_info_malloc (&this->info);
snd_pcm_info (this->handle, this->info);
GST_FLAG_SET (this, GST_ALSA_OPEN);
return TRUE;
}
@ -1159,9 +1322,11 @@ gst_alsa_close_audio (GstAlsa *this)
g_return_val_if_fail (this != NULL, FALSE);
g_return_val_if_fail (this->handle != NULL, FALSE);
snd_pcm_info_free (this->info);
ERROR_CHECK (snd_pcm_close (this->handle), "Error closing device: %s");
this->handle = NULL;
this->info = NULL;
GST_FLAG_UNSET (this, GST_ALSA_OPEN);
return TRUE;

View file

@ -134,6 +134,7 @@ struct _GstAlsa {
gchar * device;
snd_pcm_t * handle;
snd_pcm_info_t * info;
guint pcm_caps; /* capabilities of the pcm device, see GstAlsaPcmCaps */
snd_output_t * out;
@ -167,6 +168,9 @@ struct _GstAlsaClass {
/* different transmit functions */
GstAlsaTransmitFunction transmit_mmap;
GstAlsaTransmitFunction transmit_rw;
/* autodetected devices available */
GList *devices;
};
GType gst_alsa_get_type (void);