Make GstMixerTrack a GObject. I also want to make it emit several signals, starting work is in here but it's not full...

Original commit message from CVS:
Make GstMixerTrack a GObject. I also want to make it emit several signals, starting work is in here but it's not fully implemented yet. for OSS, this will cause issues, but for ALSA, this is all automated.
This commit is contained in:
Ronald S. Bultje 2003-10-10 12:24:20 +00:00
parent c5c78205bc
commit 4506e60ea0
4 changed files with 171 additions and 56 deletions

View file

@ -40,6 +40,7 @@ enum {
ARG_0,
ARG_DEVICE,
ARG_MIXERDEV,
ARG_DEVICE_NAME,
};
/* elementfactory information */
@ -124,12 +125,15 @@ gst_osselement_class_init (GstOssElementClass *klass)
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_DEVICE,
g_param_spec_string ("device", "device", "oss device (/dev/dspN usually)",
g_param_spec_string ("device", "Device", "OSS device (/dev/dspN usually)",
"default", G_PARAM_READWRITE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_MIXERDEV,
g_param_spec_string ("mixerdev", "mixer device",
"oss mixer device (/dev/mixerN usually)",
g_param_spec_string ("mixerdev", "Mixer device",
"OSS mixer device (/dev/mixerN usually)",
"default", G_PARAM_READWRITE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_MIXERDEV,
g_param_spec_string ("device_name", "Device name", "Name of the device",
NULL, G_PARAM_READABLE));
gobject_class->set_property = gst_osselement_set_property;
gobject_class->get_property = gst_osselement_get_property;
@ -146,6 +150,7 @@ gst_osselement_init (GstOssElement *oss)
oss->fd = -1;
oss->mixer_fd = -1;
oss->tracklist = NULL;
oss->device_name = NULL;
gst_osselement_reset (oss);
}
@ -632,6 +637,9 @@ gst_osselement_get_property (GObject *object,
case ARG_MIXERDEV:
g_value_set_string (value, oss->mixer_dev);
break;
case ARG_DEVICE_NAME:
g_value_set_string (value, oss->device_name);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;

View file

@ -82,6 +82,7 @@ struct _GstOssElement
recmask,
mixcaps;
gint mixer_fd;
gchar *device_name;
};
struct _GstOssElementClass {

View file

@ -1,7 +1,7 @@
/* GStreamer OSS Mixer implementation
* Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
*
* gstossmixer.h: mixer interface implementation for OSS
* gstossmixer.c: mixer interface implementation for OSS
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@ -37,26 +37,72 @@
#define MASK_BIT_IS_SET(mask, bit) \
(mask & (1 << bit))
static gboolean gst_ossmixer_supported (GstInterface *iface,
GType iface_type);
static void gst_ossmixer_track_class_init (GstOssMixerTrackClass *klass);
static void gst_ossmixer_track_init (GstOssMixerTrack *track);
static const GList * gst_ossmixer_list_tracks (GstMixer *ossmixer);
static gboolean gst_ossmixer_supported (GstInterface *iface,
GType iface_type);
static const GList *
gst_ossmixer_list_tracks (GstMixer *ossmixer);
static void gst_ossmixer_set_volume (GstMixer *ossmixer,
GstMixerTrack *track,
gint *volumes);
static void gst_ossmixer_get_volume (GstMixer *ossmixer,
GstMixerTrack *track,
gint *volumes);
static void gst_ossmixer_set_volume (GstMixer *ossmixer,
GstMixerTrack *track,
gint *volumes);
static void gst_ossmixer_get_volume (GstMixer *ossmixer,
GstMixerTrack *track,
gint *volumes);
static void gst_ossmixer_set_record (GstMixer *ossmixer,
GstMixerTrack *track,
gboolean record);
static void gst_ossmixer_set_mute (GstMixer *ossmixer,
GstMixerTrack *track,
gboolean mute);
static void gst_ossmixer_set_record (GstMixer *ossmixer,
GstMixerTrack *track,
gboolean record);
static void gst_ossmixer_set_mute (GstMixer *ossmixer,
GstMixerTrack *track,
gboolean mute);
static const gchar *labels[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_LABELS;
static GstMixerTrackClass *parent_class = NULL;
GType
gst_ossmixer_track_get_type (void)
{
static GType gst_ossmixer_track_type = 0;
if (!gst_ossmixer_track_type) {
static const GTypeInfo ossmixer_track_info = {
sizeof (GstOssMixerTrackClass),
NULL,
NULL,
(GClassInitFunc) gst_ossmixer_track_class_init,
NULL,
NULL,
sizeof (GstOssMixerTrack),
0,
(GInstanceInitFunc) gst_ossmixer_track_init,
NULL
};
gst_ossmixer_track_type =
g_type_register_static (GST_TYPE_MIXER_TRACK,
"GstOssMixerTrack",
&ossmixer_track_info, 0);
}
return gst_ossmixer_track_type;
}
static void
gst_ossmixer_track_class_init (GstOssMixerTrackClass *klass)
{
parent_class = g_type_class_ref (GST_TYPE_MIXER_TRACK);
}
static void
gst_ossmixer_track_init (GstOssMixerTrack *track)
{
track->lvol = track->rvol = 0;
track->track_num = 0;
}
GstMixerTrack *
gst_ossmixer_track_new (GstOssElement *oss,
@ -64,34 +110,28 @@ gst_ossmixer_track_new (GstOssElement *oss,
gint max_chans,
gint flags)
{
GstMixerTrack *track = (GstMixerTrack *) g_new (GstOssMixerTrack, 1);
GstOssMixerTrack *osstrack;
GstMixerTrack *track;
gint volumes[2];
osstrack = g_object_new (GST_TYPE_OSSMIXER_TRACK, NULL);
track = GST_MIXER_TRACK (osstrack);
track->label = g_strdup (labels[track_num]);
track->num_channels = max_chans;
track->flags = flags;
track->min_volume = 0;
track->max_volume = 100;
((GstOssMixerTrack *) track)->track_num = track_num;
osstrack->track_num = track_num;
/* volume */
gst_ossmixer_get_volume (GST_MIXER (oss), track, volumes);
if (max_chans == 1) {
volumes[1] = 0;
}
((GstOssMixerTrack *) track)->lvol = volumes[0];
((GstOssMixerTrack *) track)->rvol = volumes[1];
osstrack->lvol = volumes[0];
if (max_chans == 2)
osstrack->rvol = volumes[1];
return track;
}
void
gst_ossmixer_track_free (GstMixerTrack *track)
{
g_free (track->label);
g_free (track);
}
void
gst_oss_interface_init (GstInterfaceClass *klass)
{
@ -119,13 +159,22 @@ gst_ossmixer_supported (GstInterface *iface,
return (GST_OSSELEMENT (iface)->mixer_fd != -1);
}
static gboolean
gst_ossmixer_contains_track (GstOssElement *oss,
GstOssMixerTrack *osstrack)
{
const GList *item;
for (item = oss->tracklist; item != NULL; item = item->next)
if (item->data == osstrack)
return TRUE;
return FALSE;
}
static const GList *
gst_ossmixer_list_tracks (GstMixer *mixer)
{
GstOssElement *oss = GST_OSSELEMENT (mixer);
g_return_val_if_fail (oss->mixer_fd != -1, NULL);
return (const GList *) GST_OSSELEMENT (mixer)->tracklist;
}
@ -136,9 +185,11 @@ gst_ossmixer_get_volume (GstMixer *mixer,
{
gint volume;
GstOssElement *oss = GST_OSSELEMENT (mixer);
GstOssMixerTrack *osstrack = (GstOssMixerTrack *) track;
GstOssMixerTrack *osstrack = GST_OSSMIXER_TRACK (track);
/* assert that we're opened and that we're using a known item */
g_return_if_fail (oss->mixer_fd != -1);
g_return_if_fail (gst_ossmixer_contains_track (oss, osstrack));
if (track->flags & GST_MIXER_TRACK_MUTE) {
volumes[0] = osstrack->lvol;
@ -167,9 +218,11 @@ gst_ossmixer_set_volume (GstMixer *mixer,
{
gint volume;
GstOssElement *oss = GST_OSSELEMENT (mixer);
GstOssMixerTrack *osstrack = (GstOssMixerTrack *) track;
GstOssMixerTrack *osstrack = GST_OSSMIXER_TRACK (track);
/* assert that we're opened and that we're using a known item */
g_return_if_fail (oss->mixer_fd != -1);
g_return_if_fail (gst_ossmixer_contains_track (oss, osstrack));
/* prepare the value for ioctl() */
if (!(track->flags & GST_MIXER_TRACK_MUTE)) {
@ -199,9 +252,11 @@ gst_ossmixer_set_mute (GstMixer *mixer,
{
int volume;
GstOssElement *oss = GST_OSSELEMENT (mixer);
GstOssMixerTrack *osstrack = (GstOssMixerTrack *) track;
GstOssMixerTrack *osstrack = GST_OSSMIXER_TRACK (track);
/* assert that we're opened and that we're using a known item */
g_return_if_fail (oss->mixer_fd != -1);
g_return_if_fail (gst_ossmixer_contains_track (oss, osstrack));
if (mute) {
volume = 0;
@ -231,9 +286,11 @@ gst_ossmixer_set_record (GstMixer *mixer,
gboolean record)
{
GstOssElement *oss = GST_OSSELEMENT (mixer);
GstOssMixerTrack *osstrack = (GstOssMixerTrack *) track;
GstOssMixerTrack *osstrack = GST_OSSMIXER_TRACK (track);
/* assert that we're opened and that we're using a known item */
g_return_if_fail (oss->mixer_fd != -1);
g_return_if_fail (gst_ossmixer_contains_track (oss, osstrack));
/* if we're exclusive, then we need to unset the current one(s) */
if (oss->mixcaps & SOUND_CAP_EXCL_INPUT) {
@ -270,22 +327,40 @@ void
gst_ossmixer_build_list (GstOssElement *oss)
{
gint i, devmask;
const GList *pads = gst_element_get_pad_list (GST_ELEMENT (oss));
GstPadDirection dir = GST_PAD_UNKNOWN;
struct mixer_info minfo;
g_return_if_fail (oss->mixer_fd == -1);
oss->mixer_fd = open (oss->mixer_dev, O_RDWR);
if (oss->mixer_fd == -1) {
g_warning ("Failed to open mixer device %s, mixing disabled: %s",
/* this is valid. OSS devices don't need to expose a mixer */
GST_DEBUG ("Failed to open mixer device %s, mixing disabled: %s",
oss->mixer_dev, strerror (errno));
return;
}
/* get direction */
if (pads && g_list_length ((GList *) pads) == 1)
dir = GST_PAD_DIRECTION (GST_PAD (pads->data));
/* get masks */
ioctl (oss->mixer_fd, SOUND_MIXER_READ_RECMASK, &oss->recmask);
ioctl (oss->mixer_fd, SOUND_MIXER_READ_RECSRC, &oss->recdevs);
ioctl (oss->mixer_fd, SOUND_MIXER_READ_STEREODEVS, &oss->stereomask);
ioctl (oss->mixer_fd, SOUND_MIXER_READ_DEVMASK, &devmask);
ioctl (oss->mixer_fd, SOUND_MIXER_READ_CAPS, &oss->mixcaps);
if (ioctl (oss->mixer_fd, SOUND_MIXER_READ_RECMASK, &oss->recmask) < 0 ||
ioctl (oss->mixer_fd, SOUND_MIXER_READ_RECSRC, &oss->recdevs) < 0 ||
ioctl (oss->mixer_fd, SOUND_MIXER_READ_STEREODEVS, &oss->stereomask) < 0 ||
ioctl (oss->mixer_fd, SOUND_MIXER_READ_DEVMASK, &devmask) < 0 ||
ioctl (oss->mixer_fd, SOUND_MIXER_READ_CAPS, &oss->mixcaps) < 0) {
GST_DEBUG ("Failed to get device masks - disabling mixer");
close (oss->mixer_fd);
oss->mixer_fd = -1;
return;
}
/* get name */
if (ioctl (oss->mixer_fd, SOUND_MIXER_INFO, &minfo) == 0) {
oss->device_name = g_strdup (minfo.name);
}
/* build track list */
for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
@ -301,11 +376,16 @@ gst_ossmixer_build_list (GstOssElement *oss)
if (MASK_BIT_IS_SET (oss->recdevs, i))
record = TRUE;
/* do we want this in our list? */
if ((dir == GST_PAD_SRC && input == FALSE) ||
(dir == GST_PAD_SINK && i == SOUND_MIXER_PCM))
continue;
/* add track to list */
track = gst_ossmixer_track_new (oss, i, stereo ? 2 : 1,
(record ? GST_MIXER_TRACK_RECORD : 0) |
(input ? GST_MIXER_TRACK_INPUT :
GST_MIXER_TRACK_OUTPUT));
(record ? GST_MIXER_TRACK_RECORD : 0) |
(input ? GST_MIXER_TRACK_INPUT :
GST_MIXER_TRACK_OUTPUT));
oss->tracklist = g_list_append (oss->tracklist, track);
}
}
@ -314,12 +394,18 @@ gst_ossmixer_build_list (GstOssElement *oss)
void
gst_ossmixer_free_list (GstOssElement *oss)
{
g_return_if_fail (oss->mixer_fd != -1);
if (oss->mixer_fd == -1)
return;
g_list_foreach (oss->tracklist, (GFunc) gst_ossmixer_track_free, NULL);
g_list_foreach (oss->tracklist, (GFunc) g_object_unref, NULL);
g_list_free (oss->tracklist);
oss->tracklist = NULL;
if (oss->device_name) {
g_free (oss->device_name);
oss->device_name = NULL;
}
close (oss->mixer_fd);
oss->mixer_fd = -1;
}

View file

@ -28,16 +28,36 @@
G_BEGIN_DECLS
#define GST_TYPE_OSSMIXER_TRACK \
(gst_ossmixer_track_get_type ())
#define GST_OSSMIXER_TRACK(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_OSSMIXER_TRACK, \
GstOssMixerTrack))
#define GST_OSSMIXER_TRACK_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_OSSMIXER_TRACK, \
GstOssMixerTrackClass))
#define GST_IS_OSSMIXER_TRACK(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_OSSMIXER_TRACK))
#define GST_IS_OSSMIXER_TRACK_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_OSSMIXER_TRACK))
typedef struct _GstOssMixerTrack {
GstMixerTrack parent;
gint lvol, rvol;
gint track_num;
} GstOssMixerTrack;
void gst_ossmixer_interface_init (GstMixerClass *klass);
void gst_oss_interface_init (GstInterfaceClass *klass);
void gst_ossmixer_build_list (GstOssElement *oss);
void gst_ossmixer_free_list (GstOssElement *oss);
typedef struct _GstOssMixerTrackClass {
GstMixerTrackClass parent;
} GstOssMixerTrackClass;
GType gst_ossmixer_track_get_type (void);
void gst_ossmixer_interface_init (GstMixerClass *klass);
void gst_oss_interface_init (GstInterfaceClass *klass);
void gst_ossmixer_build_list (GstOssElement *oss);
void gst_ossmixer_free_list (GstOssElement *oss);
G_END_DECLS