ext/alsa/: Add enumerations (as GstMixerOptions). Make correct distinction between...
authorRonald S. Bultje <rbultje@ronald.bitfreak.net>
Thu, 27 May 2004 03:36:17 +0000 (03:36 +0000)
committerRonald S. Bultje <rbultje@ronald.bitfreak.net>
Thu, 27 May 2004 03:36:17 +0000 (03:36 +0000)
Original commit message from CVS:
* ext/alsa/Makefile.am:
* ext/alsa/gstalsamixer.c: (gst_alsa_mixer_interface_init),
(gst_alsa_mixer_build_list), (gst_alsa_mixer_get_volume),
(gst_alsa_mixer_set_volume), (gst_alsa_mixer_set_mute),
(gst_alsa_mixer_set_record), (gst_alsa_mixer_set_option),
(gst_alsa_mixer_get_option):
* ext/alsa/gstalsamixer.h:
* ext/alsa/gstalsamixeroptions.c:
(gst_alsa_mixer_options_get_type),
(gst_alsa_mixer_options_class_init), (gst_alsa_mixer_options_init),
(gst_alsa_mixer_options_new):
* ext/alsa/gstalsamixeroptions.h:
* ext/alsa/gstalsamixertrack.c: (gst_alsa_mixer_track_new):
* ext/alsa/gstalsamixertrack.h:
Add enumerations (as GstMixerOptions). Make correct distinction
between input/output tracks. Add capture/playback private flag.
Use flag to decide on whether to set capture or playback volumes
or switches. Use playback and record switches.
* gst-libs/gst/mixer/Makefile.am:
* gst-libs/gst/mixer/mixer-marshal.list:
* gst-libs/gst/mixer/mixer.c: (gst_mixer_class_init),
(gst_mixer_set_option), (gst_mixer_get_option),
(gst_mixer_mute_toggled), (gst_mixer_record_toggled),
(gst_mixer_volume_changed), (gst_mixer_option_changed):
* gst-libs/gst/mixer/mixer.h:
* gst-libs/gst/mixer/mixeroptions.c: (gst_mixer_options_get_type),
(gst_mixer_options_class_init), (gst_mixer_options_init),
(gst_mixer_options_dispose):
* gst-libs/gst/mixer/mixeroptions.h:
Add GstMixerOptions.
* sys/oss/gstosselement.c: (gst_osselement_class_probe_devices):
Rename Audio Mixer to OSS Mixer (similar to Alsa Mixer). Fix
broken device detection on computers with multiple OSS sound
cards.

18 files changed:
ChangeLog
ext/alsa/Makefile.am
ext/alsa/gstalsamixer.c
ext/alsa/gstalsamixer.h
ext/alsa/gstalsamixeroptions.c [new file with mode: 0644]
ext/alsa/gstalsamixeroptions.h [new file with mode: 0644]
ext/alsa/gstalsamixertrack.c
ext/alsa/gstalsamixertrack.h
gst-libs/gst/interfaces/mixer.c
gst-libs/gst/interfaces/mixer.h
gst-libs/gst/interfaces/mixeroptions.c [new file with mode: 0644]
gst-libs/gst/interfaces/mixeroptions.h [new file with mode: 0644]
gst-libs/gst/mixer/Makefile.am
gst-libs/gst/mixer/mixer-marshal.list
gst-libs/gst/mixer/mixer.c
gst-libs/gst/mixer/mixer.h
gst-libs/gst/mixer/mixeroptions.c [new file with mode: 0644]
gst-libs/gst/mixer/mixeroptions.h [new file with mode: 0644]

index 4588480..f394526 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,40 @@
+2004-05-26  Ronald Bultje  <rbultje@ronald.bitfreak.net>
+
+       * ext/alsa/Makefile.am:
+       * ext/alsa/gstalsamixer.c: (gst_alsa_mixer_interface_init),
+       (gst_alsa_mixer_build_list), (gst_alsa_mixer_get_volume),
+       (gst_alsa_mixer_set_volume), (gst_alsa_mixer_set_mute),
+       (gst_alsa_mixer_set_record), (gst_alsa_mixer_set_option),
+       (gst_alsa_mixer_get_option):
+       * ext/alsa/gstalsamixer.h:
+       * ext/alsa/gstalsamixeroptions.c:
+       (gst_alsa_mixer_options_get_type),
+       (gst_alsa_mixer_options_class_init), (gst_alsa_mixer_options_init),
+       (gst_alsa_mixer_options_new):
+       * ext/alsa/gstalsamixeroptions.h:
+       * ext/alsa/gstalsamixertrack.c: (gst_alsa_mixer_track_new):
+       * ext/alsa/gstalsamixertrack.h:
+         Add enumerations (as GstMixerOptions). Make correct distinction
+         between input/output tracks. Add capture/playback private flag.
+         Use flag to decide on whether to set capture or playback volumes
+         or switches. Use playback and record switches.
+       * gst-libs/gst/mixer/Makefile.am:
+       * gst-libs/gst/mixer/mixer-marshal.list:
+       * gst-libs/gst/mixer/mixer.c: (gst_mixer_class_init),
+       (gst_mixer_set_option), (gst_mixer_get_option),
+       (gst_mixer_mute_toggled), (gst_mixer_record_toggled),
+       (gst_mixer_volume_changed), (gst_mixer_option_changed):
+       * gst-libs/gst/mixer/mixer.h:
+       * gst-libs/gst/mixer/mixeroptions.c: (gst_mixer_options_get_type),
+       (gst_mixer_options_class_init), (gst_mixer_options_init),
+       (gst_mixer_options_dispose):
+       * gst-libs/gst/mixer/mixeroptions.h:
+         Add GstMixerOptions.
+       * sys/oss/gstosselement.c: (gst_osselement_class_probe_devices):
+         Rename Audio Mixer to OSS Mixer (similar to Alsa Mixer). Fix
+         broken device detection on computers with multiple OSS sound
+         cards.
+
 2004-05-26  Benjamin Otte  <in7y118@public.uni-hamburg.de>
 
        * gst/audioconvert/gstaudioconvert.c: (gst_audio_convert_fixate):
index a65bd37..882456e 100644 (file)
@@ -1,9 +1,15 @@
 
 plugin_LTLIBRARIES = libgstalsa.la
 
-libgstalsa_la_SOURCES = gstalsaplugin.c \
-  gstalsa.c gstalsaclock.c gstalsasink.c gstalsasrc.c \
-  gstalsamixer.c gstalsamixertrack.c
+libgstalsa_la_SOURCES = \
+       gstalsaplugin.c \
+       gstalsa.c \
+       gstalsaclock.c \
+       gstalsasink.c \
+       gstalsasrc.c \
+       gstalsamixer.c \
+       gstalsamixertrack.c \
+       gstalsamixeroptions.c
 
 libgstalsa_la_CFLAGS = $(GST_CFLAGS) $(ALSA_CFLAGS)
 libgstalsa_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
@@ -11,5 +17,10 @@ libgstalsa_la_LIBADD = $(ALSA_LIBS) \
   ${top_builddir}/gst-libs/gst/libgstinterfaces-@GST_MAJORMINOR@.la
 
 noinst_HEADERS = \
-  gstalsa.h gstalsaclock.h gstalsasink.h gstalsasrc.h \
-  gstalsamixer.h gstalsamixertrack.h
+       gstalsa.h \
+       gstalsaclock.h \
+       gstalsasink.h \
+       gstalsasrc.h \
+       gstalsamixer.h \
+       gstalsamixertrack.h \
+       gstalsamixeroptions.h
index 12f6769..ab7d533 100644 (file)
@@ -57,6 +57,11 @@ static void gst_alsa_mixer_set_record (GstMixer * mixer,
 static void gst_alsa_mixer_set_mute (GstMixer * mixer,
     GstMixerTrack * track, gboolean mute);
 
+static void gst_alsa_mixer_set_option (GstMixer * mixer,
+    GstMixerOptions * opts, gchar * value);
+static const gchar *gst_alsa_mixer_get_option (GstMixer * mixer,
+    GstMixerOptions * opts);
+
 /*** GOBJECT STUFF ************************************************************/
 
 static GstAlsa *parent_class = NULL;
@@ -223,6 +228,8 @@ gst_alsa_mixer_interface_init (GstMixerClass * klass)
   klass->get_volume = gst_alsa_mixer_get_volume;
   klass->set_mute = gst_alsa_mixer_set_mute;
   klass->set_record = gst_alsa_mixer_set_record;
+  klass->set_option = gst_alsa_mixer_set_option;
+  klass->get_option = gst_alsa_mixer_get_option;
 }
 
 gboolean
@@ -239,6 +246,7 @@ gst_alsa_mixer_build_list (GstAlsaMixer * mixer)
   gint i, count;
   snd_mixer_elem_t *element;
   GstMixerTrack *track;
+  GstMixerOptions *opts;
   const GList *templates;
   GstPadDirection dir = GST_PAD_UNKNOWN;
 
@@ -254,42 +262,40 @@ gst_alsa_mixer_build_list (GstAlsaMixer * mixer)
   element = snd_mixer_first_elem (mixer->mixer_handle);
 
   /* build track list */
-
   for (i = 0; i < count; i++) {
     gint channels = 0;
+    gint flags = GST_MIXER_TRACK_OUTPUT;
+
+    if (snd_mixer_selem_has_capture_switch (element)) {
+      if (dir != GST_PAD_SRC && dir != GST_PAD_UNKNOWN)
+        continue;
+      flags = GST_MIXER_TRACK_INPUT;
+    } else {
+      if (dir != GST_PAD_SINK && dir != GST_PAD_UNKNOWN)
+        continue;
+    }
 
-    if (!snd_mixer_selem_is_active (element))
-      continue;
-
-    /* find out if this element can be an input */
-    if ((dir == GST_PAD_SRC || dir == GST_PAD_UNKNOWN) &&
-        (snd_mixer_selem_has_capture_channel (element, 0) ||
-            snd_mixer_selem_has_capture_switch (element) ||
-            snd_mixer_selem_is_capture_mono (element))) {
+    if (snd_mixer_selem_has_capture_volume (element)) {
       while (snd_mixer_selem_has_capture_channel (element, channels))
         channels++;
-
-      track = gst_alsa_mixer_track_new
-          (element, i, channels, GST_MIXER_TRACK_INPUT);
+      track = gst_alsa_mixer_track_new (element, i, channels,
+          flags, GST_ALSA_MIXER_TRACK_CAPTURE);
       mixer->tracklist = g_list_append (mixer->tracklist, track);
     }
 
-    /* find out if this element can also be an output */
-
-    channels = 0;
-
-    if ((dir == GST_PAD_SINK || dir == GST_PAD_UNKNOWN) &&
-        (snd_mixer_selem_has_playback_channel (element, 0) ||
-            snd_mixer_selem_has_playback_switch (element) ||
-            snd_mixer_selem_is_playback_mono (element))) {
+    if (snd_mixer_selem_has_playback_volume (element)) {
       while (snd_mixer_selem_has_playback_channel (element, channels))
         channels++;
-
-      track = gst_alsa_mixer_track_new
-          (element, i, channels, GST_MIXER_TRACK_OUTPUT);
+      track = gst_alsa_mixer_track_new (element, i, channels,
+          flags, GST_ALSA_MIXER_TRACK_PLAYBACK);
       mixer->tracklist = g_list_append (mixer->tracklist, track);
     }
 
+    if (snd_mixer_selem_is_enumerated (element)) {
+      opts = gst_alsa_mixer_options_new (element, i);
+      mixer->tracklist = g_list_append (mixer->tracklist, opts);
+    }
+
     element = snd_mixer_elem_next (element);
   }
 }
@@ -358,20 +364,20 @@ gst_alsa_mixer_get_volume (GstMixer * mixer,
 
   g_return_if_fail (alsa_mixer->mixer_handle != NULL);
 
-  if (track->flags & GST_MIXER_TRACK_MUTE) {
+  if (track->flags & GST_MIXER_TRACK_MUTE &&
+      !snd_mixer_selem_has_playback_switch (alsa_track->element)) {
     for (i = 0; i < track->num_channels; i++)
       volumes[i] = alsa_track->volumes[i];
   } else {
     for (i = 0; i < track->num_channels; i++) {
-      long tmp;
+      long tmp = 0;
 
-      if (snd_mixer_selem_has_playback_channel (alsa_track->element, i)) {
+      if (alsa_track->alsa_flags & GST_ALSA_MIXER_TRACK_PLAYBACK) {
         snd_mixer_selem_get_playback_volume (alsa_track->element, i, &tmp);
-        volumes[i] = (gint) tmp;
-      } else if (snd_mixer_selem_has_capture_channel (alsa_track->element, i)) {
+      } else if (alsa_track->alsa_flags & GST_ALSA_MIXER_TRACK_CAPTURE) {
         snd_mixer_selem_get_capture_volume (alsa_track->element, i, &tmp);
-        volumes[i] = (gint) tmp;
       }
+      volumes[i] = (gint) tmp;
     }
   }
 }
@@ -387,19 +393,20 @@ gst_alsa_mixer_set_volume (GstMixer * mixer,
   g_return_if_fail (alsa_mixer->mixer_handle != NULL);
 
   /* only set the volume with ALSA lib if the track isn't muted. */
-  if (!(track->flags & GST_MIXER_TRACK_MUTE)) {
-    for (i = 0; i < track->num_channels; i++) {
-      if (snd_mixer_selem_has_playback_channel (alsa_track->element, i))
+  for (i = 0; i < track->num_channels; i++) {
+    alsa_track->volumes[i] = volumes[i];
+
+    if (!(track->flags & GST_MIXER_TRACK_MUTE) ||
+        snd_mixer_selem_has_playback_switch (alsa_track->element)) {
+      if (alsa_track->alsa_flags & GST_ALSA_MIXER_TRACK_PLAYBACK) {
         snd_mixer_selem_set_playback_volume (alsa_track->element, i,
             (long) volumes[i]);
-      else if (snd_mixer_selem_has_capture_channel (alsa_track->element, i))
+      } else if (alsa_track->alsa_flags & GST_ALSA_MIXER_TRACK_CAPTURE) {
         snd_mixer_selem_set_capture_volume (alsa_track->element, i,
             (long) volumes[i]);
+      }
     }
   }
-
-  for (i = 0; i < track->num_channels; i++)
-    alsa_track->volumes[i] = volumes[i];
 }
 
 static void
@@ -413,23 +420,21 @@ gst_alsa_mixer_set_mute (GstMixer * mixer, GstMixerTrack * track, gboolean mute)
 
   if (mute) {
     track->flags |= GST_MIXER_TRACK_MUTE;
-
-    for (i = 0; i < track->num_channels; i++) {
-      if (snd_mixer_selem_has_capture_channel (alsa_track->element, i))
-        snd_mixer_selem_set_capture_volume (alsa_track->element, i, 0);
-      else if (snd_mixer_selem_has_playback_channel (alsa_track->element, i))
-        snd_mixer_selem_set_playback_volume (alsa_track->element, i, 0);
-    }
   } else {
     track->flags &= ~GST_MIXER_TRACK_MUTE;
+  }
 
+  if (snd_mixer_selem_has_playback_switch (alsa_track->element)) {
+    snd_mixer_selem_set_playback_switch_all (alsa_track->element, mute ? 0 : 1);
+  } else {
     for (i = 0; i < track->num_channels; i++) {
-      if (snd_mixer_selem_has_capture_channel (alsa_track->element, i))
-        snd_mixer_selem_set_capture_volume (alsa_track->element, i,
-            alsa_track->volumes[i]);
-      else if (snd_mixer_selem_has_playback_channel (alsa_track->element, i))
-        snd_mixer_selem_set_playback_volume (alsa_track->element, i,
-            alsa_track->volumes[i]);
+      long vol = mute ? 0 : alsa_track->volumes[i];
+
+      if (alsa_track->alsa_flags & GST_ALSA_MIXER_TRACK_CAPTURE) {
+        snd_mixer_selem_set_capture_volume (alsa_track->element, i, vol);
+      } else if (alsa_track->alsa_flags & GST_ALSA_MIXER_TRACK_PLAYBACK) {
+        snd_mixer_selem_set_playback_volume (alsa_track->element, i, vol);
+      }
     }
   }
 }
@@ -439,6 +444,7 @@ gst_alsa_mixer_set_record (GstMixer * mixer,
     GstMixerTrack * track, gboolean record)
 {
   GstAlsaMixer *alsa_mixer = GST_ALSA_MIXER (mixer);
+  GstAlsaMixerTrack *alsa_track = (GstAlsaMixerTrack *) track;
 
   g_return_if_fail (alsa_mixer->mixer_handle != NULL);
 
@@ -447,4 +453,43 @@ gst_alsa_mixer_set_record (GstMixer * mixer,
   } else {
     track->flags &= ~GST_MIXER_TRACK_RECORD;
   }
+
+  snd_mixer_selem_set_capture_switch_all (alsa_track->element, record ? 1 : 0);
+}
+
+static void
+gst_alsa_mixer_set_option (GstMixer * mixer,
+    GstMixerOptions * opts, gchar * value)
+{
+  gint idx = -1, n = 0;
+  GList *item;
+  GstAlsaMixer *alsa_mixer = (GstAlsaMixer *) mixer;
+  GstAlsaMixerOptions *alsa_opts = (GstAlsaMixerOptions *) opts;
+
+  g_return_if_fail (alsa_mixer->mixer_handle != NULL);
+
+  for (item = opts->values; item != NULL; item = item->next, n++) {
+    if (!strcmp (item->data, value)) {
+      idx = n;
+      break;
+    }
+  }
+  if (idx == -1)
+    return;
+
+  snd_mixer_selem_set_enum_item (alsa_opts->element, 0, idx);
+}
+
+static const gchar *
+gst_alsa_mixer_get_option (GstMixer * mixer, GstMixerOptions * opts)
+{
+  GstAlsaMixer *alsa_mixer = (GstAlsaMixer *) mixer;
+  GstAlsaMixerOptions *alsa_opts = (GstAlsaMixerOptions *) opts;
+  gint idx = -1;
+
+  g_return_val_if_fail (alsa_mixer->mixer_handle != NULL, NULL);
+
+  snd_mixer_selem_get_enum_item (alsa_opts->element, 0, &idx);
+
+  return g_list_nth_data (opts->values, idx);
 }
index a612eaa..4a54d63 100644 (file)
@@ -20,6 +20,7 @@
 #define __GST_ALSA_MIXER_H__
 
 #include "gstalsa.h"
+#include "gstalsamixeroptions.h"
 #include "gstalsamixertrack.h"
 #include <gst/mixer/mixer.h>
 
diff --git a/ext/alsa/gstalsamixeroptions.c b/ext/alsa/gstalsamixeroptions.c
new file mode 100644 (file)
index 0000000..09ff949
--- /dev/null
@@ -0,0 +1,98 @@
+/* ALSA mixer object implementation.
+ * Copyright (C) 2003 Leif Johnson <leif@ambient.2y.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "gstalsamixeroptions.h"
+
+static void gst_alsa_mixer_options_init (GstAlsaMixerOptions * alsa_opts);
+static void gst_alsa_mixer_options_class_init (gpointer g_class,
+    gpointer class_data);
+
+static GstMixerOptionsClass *parent_class = NULL;
+
+GType
+gst_alsa_mixer_options_get_type (void)
+{
+  static GType opts_type = 0;
+
+  if (!opts_type) {
+    static const GTypeInfo opts_info = {
+      sizeof (GstAlsaMixerOptionsClass),
+      NULL,
+      NULL,
+      gst_alsa_mixer_options_class_init,
+      NULL,
+      NULL,
+      sizeof (GstAlsaMixerOptions),
+      0,
+      (GInstanceInitFunc) gst_alsa_mixer_options_init,
+    };
+
+    opts_type =
+        g_type_register_static (GST_TYPE_MIXER_OPTIONS, "GstAlsaMixerOptions",
+        &opts_info, 0);
+  }
+
+  return opts_type;
+}
+
+static void
+gst_alsa_mixer_options_class_init (gpointer g_class, gpointer class_data)
+{
+  if (parent_class == NULL)
+    parent_class = g_type_class_ref (GST_TYPE_MIXER_TRACK);
+}
+
+static void
+gst_alsa_mixer_options_init (GstAlsaMixerOptions * alsa_opts)
+{
+}
+
+GstMixerOptions *
+gst_alsa_mixer_options_new (snd_mixer_elem_t * element, gint track_num)
+{
+  GstMixerOptions *opts = g_object_new (GST_ALSA_MIXER_OPTIONS_TYPE, NULL);
+  GstAlsaMixerOptions *alsa_opts = (GstAlsaMixerOptions *) opts;
+  GstMixerTrack *track = (GstMixerTrack *) opts;
+  gint num, i;
+  gchar str[256];
+
+  /* set basic information */
+  track->label = g_strdup (snd_mixer_selem_get_name (element));
+  track->num_channels = 0;
+  track->flags = 0;
+  alsa_opts->element = element;
+  alsa_opts->track_num = track_num;
+
+  /* get enumerations for switch/options object */
+  num = snd_mixer_selem_get_enum_items (element);
+  for (i = 0; i < num; i++) {
+    if (snd_mixer_selem_get_enum_item_name (element, i, 255, str) < 0) {
+      g_object_unref (G_OBJECT (alsa_opts));
+      return NULL;
+    }
+
+    opts->values = g_list_append (opts->values, g_strdup (str));
+  }
+
+  return opts;
+}
diff --git a/ext/alsa/gstalsamixeroptions.h b/ext/alsa/gstalsamixeroptions.h
new file mode 100644 (file)
index 0000000..80a6152
--- /dev/null
@@ -0,0 +1,53 @@
+/* ALSA mixer options object.
+ * Copyright (C) 2003 Leif Johnson <leif@ambient.2y.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __GST_ALSA_MIXER_OPTIONS_H__
+#define __GST_ALSA_MIXER_OPTIONS_H__
+
+#include "gstalsa.h"
+#include <gst/mixer/mixeroptions.h>
+
+G_BEGIN_DECLS
+
+#define GST_ALSA_MIXER_OPTIONS_TYPE            (gst_alsa_mixer_options_get_type ())
+#define GST_ALSA_MIXER_OPTIONS(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ALSA_MIXER_OPTIONS,GstAlsaMixerOptions))
+#define GST_ALSA_MIXER_OPTIONS_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ALSA_MIXER_OPTIONS,GstAlsaMixerOptionsClass))
+#define GST_IS_ALSA_MIXER_OPTIONS(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ALSA_MIXER_OPTIONS))
+#define GST_IS_ALSA_MIXER_OPTIONS_CLASS(obj)   (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ALSA_MIXER_OPTIONS))
+#define GST_TYPE_ALSA_MIXER_OPTIONS            (gst_alsa_mixer_options_get_type())
+
+typedef struct _GstAlsaMixerOptions GstAlsaMixerOptions;
+typedef struct _GstAlsaMixerOptionsClass GstAlsaMixerOptionsClass;
+
+struct _GstAlsaMixerOptions {
+  GstMixerOptions       parent;
+  snd_mixer_elem_t     *element; /* the ALSA mixer element for this track */
+  gint                 track_num;
+};
+
+struct _GstAlsaMixerOptionsClass {
+  GstMixerOptionsClass parent;
+};
+
+GType          gst_alsa_mixer_options_get_type (void);
+GstMixerOptions *gst_alsa_mixer_options_new    (snd_mixer_elem_t *     element,
+                                                gint                   track_num);
+
+G_END_DECLS
+
+#endif /* __GST_ALSA_MIXER_OPTIONS_H__ */
index df3d2f1..c6a8f14 100644 (file)
@@ -69,10 +69,10 @@ gst_alsa_mixer_track_init (GstAlsaMixerTrack * alsa_track)
 
 GstMixerTrack *
 gst_alsa_mixer_track_new (snd_mixer_elem_t * element,
-    gint track_num, gint channels, gint flags)
+    gint track_num, gint channels, gint flags, gint alsa_flags)
 {
   gint i;
-  long min, max;
+  long min = 0, max = 0;
 
   GstMixerTrack *track = g_object_new (GST_ALSA_MIXER_TRACK_TYPE, NULL);
   GstAlsaMixerTrack *alsa_track = (GstAlsaMixerTrack *) track;
@@ -82,27 +82,43 @@ gst_alsa_mixer_track_new (snd_mixer_elem_t * element,
   track->num_channels = channels;
   track->flags = flags;
   alsa_track->element = element;
+  alsa_track->alsa_flags = alsa_flags;
   alsa_track->track_num = track_num;
 
   /* set volume information */
-  snd_mixer_selem_get_playback_volume_range (element, &min, &max);
+  if (alsa_flags & GST_ALSA_MIXER_TRACK_PLAYBACK) {
+    snd_mixer_selem_get_playback_volume_range (element, &min, &max);
+  } else if (alsa_flags & GST_ALSA_MIXER_TRACK_CAPTURE) {
+    snd_mixer_selem_get_capture_volume_range (element, &min, &max);
+  }
   track->min_volume = (gint) min;
   track->max_volume = (gint) max;
 
-  snd_mixer_selem_get_capture_volume_range (element, &min, &max);
-  alsa_track->min_rec_volume = (gint) min;
-  alsa_track->max_rec_volume = (gint) max;
-
   for (i = 0; i < channels; i++) {
-    long tmp;
+    long tmp = 0;
 
-    if (snd_mixer_selem_has_playback_channel (element, i)) {
+    if (alsa_flags & GST_ALSA_MIXER_TRACK_PLAYBACK) {
       snd_mixer_selem_get_playback_volume (element, i, &tmp);
-      alsa_track->volumes[i] = (gint) tmp;
-    } else if (snd_mixer_selem_has_capture_channel (element, i)) {
+    } else if (alsa_flags & GST_ALSA_MIXER_TRACK_CAPTURE) {
       snd_mixer_selem_get_capture_volume (element, i, &tmp);
-      alsa_track->volumes[i] = (gint) tmp;
     }
+    alsa_track->volumes[i] = (gint) tmp;
+  }
+
+  if (snd_mixer_selem_has_playback_switch (element)) {
+    int val = 1;
+
+    snd_mixer_selem_get_playback_switch (element, 0, &val);
+    if (!val)
+      track->flags |= GST_MIXER_TRACK_MUTE;
+  }
+
+  if (flags & GST_MIXER_TRACK_INPUT) {
+    int val = 0;
+
+    snd_mixer_selem_get_capture_switch (element, 0, &val);
+    if (val)
+      track->flags |= GST_MIXER_TRACK_RECORD;
   }
 
   return track;
index 339b3ba..02500c8 100644 (file)
@@ -34,11 +34,14 @@ G_BEGIN_DECLS
 typedef struct _GstAlsaMixerTrack GstAlsaMixerTrack;
 typedef struct _GstAlsaMixerTrackClass GstAlsaMixerTrackClass;
 
+#define GST_ALSA_MIXER_TRACK_CAPTURE  (1<<0)
+#define GST_ALSA_MIXER_TRACK_PLAYBACK (1<<1)
+
 struct _GstAlsaMixerTrack {
   GstMixerTrack                 parent;
   snd_mixer_elem_t     *element; /* the ALSA mixer element for this track */
   gint                 track_num;
-  gint                 min_rec_volume, max_rec_volume;
+  gint                 alsa_flags;
   gint                 volumes[GST_ALSA_MAX_CHANNELS];
 };
 
@@ -50,7 +53,8 @@ GType         gst_alsa_mixer_track_get_type   (void);
 GstMixerTrack *        gst_alsa_mixer_track_new        (snd_mixer_elem_t *     element,
                                                 gint                   track_num,
                                                 gint                   channels,
-                                                gint                   flags);
+                                                gint                   flags,
+                                                gint                   alsa_flags);
 
 G_END_DECLS
 
index 1db3d6a..dcae874 100644 (file)
 
 enum
 {
-  MUTE_TOGGLED,
-  RECORD_TOGGLED,
-  VOLUME_CHANGED,
+  SIGNAL_MUTE_TOGGLED,
+  SIGNAL_RECORD_TOGGLED,
+  SIGNAL_VOLUME_CHANGED,
+  SIGNAL_OPTION_CHANGED,
   LAST_SIGNAL
 };
 
@@ -71,27 +72,34 @@ gst_mixer_class_init (GstMixerClass * klass)
   static gboolean initialized = FALSE;
 
   if (!initialized) {
-    gst_mixer_signals[RECORD_TOGGLED] =
+    gst_mixer_signals[SIGNAL_RECORD_TOGGLED] =
         g_signal_new ("record-toggled",
         GST_TYPE_MIXER, G_SIGNAL_RUN_LAST,
         G_STRUCT_OFFSET (GstMixerClass, record_toggled),
         NULL, NULL,
         gst_mixer_marshal_VOID__OBJECT_BOOLEAN, G_TYPE_NONE, 2,
         GST_TYPE_MIXER_TRACK, G_TYPE_BOOLEAN);
-    gst_mixer_signals[MUTE_TOGGLED] =
+    gst_mixer_signals[SIGNAL_MUTE_TOGGLED] =
         g_signal_new ("mute-toggled",
         GST_TYPE_MIXER, G_SIGNAL_RUN_LAST,
         G_STRUCT_OFFSET (GstMixerClass, mute_toggled),
         NULL, NULL,
         gst_mixer_marshal_VOID__OBJECT_BOOLEAN, G_TYPE_NONE, 2,
         GST_TYPE_MIXER_TRACK, G_TYPE_BOOLEAN);
-    gst_mixer_signals[VOLUME_CHANGED] =
+    gst_mixer_signals[SIGNAL_VOLUME_CHANGED] =
         g_signal_new ("volume-changed",
         GST_TYPE_MIXER, G_SIGNAL_RUN_LAST,
         G_STRUCT_OFFSET (GstMixerClass, volume_changed),
         NULL, NULL,
         gst_mixer_marshal_VOID__OBJECT_POINTER, G_TYPE_NONE, 2,
         GST_TYPE_MIXER_TRACK, G_TYPE_POINTER);
+    gst_mixer_signals[SIGNAL_OPTION_CHANGED] =
+        g_signal_new ("option-changed",
+        GST_TYPE_MIXER, G_SIGNAL_RUN_LAST,
+        G_STRUCT_OFFSET (GstMixerClass, option_changed),
+        NULL, NULL,
+        gst_mixer_marshal_VOID__OBJECT_STRING, G_TYPE_NONE, 2,
+        GST_TYPE_MIXER_OPTIONS, G_TYPE_STRING);
 
     initialized = TRUE;
   }
@@ -104,6 +112,8 @@ gst_mixer_class_init (GstMixerClass * klass)
   klass->get_volume = NULL;
   klass->set_mute = NULL;
   klass->set_record = NULL;
+  klass->set_option = NULL;
+  klass->get_option = NULL;
 }
 
 /**
@@ -226,11 +236,52 @@ gst_mixer_set_record (GstMixer * mixer, GstMixerTrack * track, gboolean record)
   }
 }
 
+/**
+ * gst_mixer_set_option:
+ * @mixer: The #GstMixer (a #GstElement) that owns the optionlist.
+ * @opts: The #GstMixerOptions that we operate on.
+ * @value: The requested new option value.
+ *
+ * Sets a name/value option in the mixer to the requested value.
+ */
+
+void
+gst_mixer_set_option (GstMixer * mixer, GstMixerOptions * opts, gchar * value)
+{
+  GstMixerClass *klass = GST_MIXER_GET_CLASS (mixer);
+
+  if (klass->set_option) {
+    klass->set_option (mixer, opts, value);
+  }
+}
+
+/**
+ * gst_mixer_g_option:
+ * @mixer: The #GstMixer (a #GstElement) that owns the optionlist.
+ * @opts: The #GstMixerOptions that we operate on.
+ *
+ * Get the current value of a name/value option in the mixer.
+ *
+ * Returns: current value of the name/value option.
+ */
+
+const gchar *
+gst_mixer_get_option (GstMixer * mixer, GstMixerOptions * opts)
+{
+  GstMixerClass *klass = GST_MIXER_GET_CLASS (mixer);
+
+  if (klass->get_option) {
+    return klass->get_option (mixer, opts);
+  }
+
+  return NULL;
+}
+
 void
 gst_mixer_mute_toggled (GstMixer * mixer, GstMixerTrack * track, gboolean mute)
 {
   g_signal_emit (G_OBJECT (mixer),
-      gst_mixer_signals[MUTE_TOGGLED], 0, track, mute);
+      gst_mixer_signals[SIGNAL_MUTE_TOGGLED], 0, track, mute);
 
   g_signal_emit_by_name (G_OBJECT (track), "mute_toggled", mute);
 }
@@ -240,7 +291,7 @@ gst_mixer_record_toggled (GstMixer * mixer,
     GstMixerTrack * track, gboolean record)
 {
   g_signal_emit (G_OBJECT (mixer),
-      gst_mixer_signals[RECORD_TOGGLED], 0, track, record);
+      gst_mixer_signals[SIGNAL_RECORD_TOGGLED], 0, track, record);
 
   g_signal_emit_by_name (G_OBJECT (track), "record_toggled", record);
 }
@@ -250,7 +301,17 @@ gst_mixer_volume_changed (GstMixer * mixer,
     GstMixerTrack * track, gint * volumes)
 {
   g_signal_emit (G_OBJECT (mixer),
-      gst_mixer_signals[VOLUME_CHANGED], 0, track, volumes);
+      gst_mixer_signals[SIGNAL_VOLUME_CHANGED], 0, track, volumes);
 
   g_signal_emit_by_name (G_OBJECT (track), "volume_changed", volumes);
 }
+
+void
+gst_mixer_option_changed (GstMixer * mixer,
+    GstMixerOptions * opts, gchar * value)
+{
+  g_signal_emit (G_OBJECT (mixer),
+      gst_mixer_signals[SIGNAL_OPTION_CHANGED], 0, opts, value);
+
+  g_signal_emit_by_name (G_OBJECT (opts), "value_changed", value);
+}
index 50ba3fd..2cb326d 100644 (file)
@@ -23,6 +23,7 @@
 #define __GST_MIXER_H__
 
 #include <gst/gst.h>
+#include <gst/mixer/mixeroptions.h>
 #include <gst/mixer/mixertrack.h>
 #include <gst/mixer/mixer-enumtypes.h>
 
@@ -84,7 +85,18 @@ typedef struct _GstMixerClass {
                           GstMixerTrack *channel,
                           gint          *volumes);
 
-  gpointer _gst_reserved[GST_PADDING];
+  /* use padding */
+  void         (* set_option)     (GstMixer      *mixer,
+                                   GstMixerOptions *opts,
+                                   gchar         *value);
+  const gchar *        (* get_option)     (GstMixer      *mixer,
+                                   GstMixerOptions *opts);
+
+  void (* option_changed) (GstMixer      *mixer,
+                          GstMixerOptions *opts,
+                          gchar         *option);
+
+  gpointer _gst_reserved[GST_PADDING-3];
 } GstMixerClass;
 
 GType          gst_mixer_get_type      (void);
@@ -103,6 +115,11 @@ void               gst_mixer_set_mute       (GstMixer      *mixer,
 void           gst_mixer_set_record     (GstMixer      *mixer,
                                          GstMixerTrack *track,
                                          gboolean       record);
+void           gst_mixer_set_option     (GstMixer      *mixer,
+                                         GstMixerOptions *opts,
+                                         gchar         *value);
+const gchar *  gst_mixer_get_option     (GstMixer      *mixer,
+                                         GstMixerOptions *opts);
 
 /* trigger signals */
 void           gst_mixer_mute_toggled   (GstMixer      *mixer,
@@ -114,6 +131,9 @@ void                gst_mixer_record_toggled (GstMixer      *mixer,
 void           gst_mixer_volume_changed (GstMixer      *mixer,
                                          GstMixerTrack *track,
                                          gint          *volumes);
+void           gst_mixer_option_changed (GstMixer      *mixer,
+                                         GstMixerOptions *opts,
+                                         gchar         *value);
 
 G_END_DECLS
 
diff --git a/gst-libs/gst/interfaces/mixeroptions.c b/gst-libs/gst/interfaces/mixeroptions.c
new file mode 100644 (file)
index 0000000..5e79a41
--- /dev/null
@@ -0,0 +1,103 @@
+/* GStreamer Mixer
+ * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
+ *
+ * mixeroptions.c: mixer track options object design
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "mixeroptions.h"
+
+enum
+{
+  /* FILL ME */
+  SIGNAL_OPTION_CHANGED,
+  LAST_SIGNAL
+};
+
+static void gst_mixer_options_class_init (GstMixerOptionsClass * klass);
+static void gst_mixer_options_init (GstMixerOptions * mixer);
+static void gst_mixer_options_dispose (GObject * object);
+
+static GObjectClass *parent_class = NULL;
+static guint signals[LAST_SIGNAL] = { 0 };
+
+GType
+gst_mixer_options_get_type (void)
+{
+  static GType gst_mixer_options_type = 0;
+
+  if (!gst_mixer_options_type) {
+    static const GTypeInfo mixer_options_info = {
+      sizeof (GstMixerOptionsClass),
+      NULL,
+      NULL,
+      (GClassInitFunc) gst_mixer_options_class_init,
+      NULL,
+      NULL,
+      sizeof (GstMixerOptions),
+      0,
+      (GInstanceInitFunc) gst_mixer_options_init,
+      NULL
+    };
+
+    gst_mixer_options_type =
+        g_type_register_static (GST_TYPE_MIXER_TRACK,
+        "GstMixerOptions", &mixer_options_info, 0);
+  }
+
+  return gst_mixer_options_type;
+}
+
+static void
+gst_mixer_options_class_init (GstMixerOptionsClass * klass)
+{
+  GObjectClass *object_klass = (GObjectClass *) klass;
+
+  parent_class = g_type_class_ref (GST_TYPE_MIXER_TRACK);
+
+  signals[SIGNAL_OPTION_CHANGED] =
+      g_signal_new ("option_changed", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST,
+      G_STRUCT_OFFSET (GstMixerOptionsClass, option_changed),
+      NULL, NULL, g_cclosure_marshal_VOID__STRING,
+      G_TYPE_NONE, 1, G_TYPE_STRING);
+
+  object_klass->dispose = gst_mixer_options_dispose;
+}
+
+static void
+gst_mixer_options_init (GstMixerOptions * channel)
+{
+  channel->values = NULL;
+}
+
+static void
+gst_mixer_options_dispose (GObject * object)
+{
+  GstMixerOptions *opts = GST_MIXER_OPTIONS (object);
+
+  g_list_foreach (opts->values, (GFunc) g_free, NULL);
+  g_list_free (opts->values);
+  opts->values = NULL;
+
+  if (parent_class->dispose)
+    parent_class->dispose (object);
+}
diff --git a/gst-libs/gst/interfaces/mixeroptions.h b/gst-libs/gst/interfaces/mixeroptions.h
new file mode 100644 (file)
index 0000000..586c9e4
--- /dev/null
@@ -0,0 +1,67 @@
+/* GStreamer Mixer
+ * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
+ *
+ * mixeroptions.h: mixer track options object
+ * This should be a subclass of MixerItem, along with MixerOptions,
+ * but that's not possible because of API/ABI in 0.8.x. FIXME.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GST_MIXER_OPTIONS_H__
+#define __GST_MIXER_OPTIONS_H__
+
+#include <gst/gst.h>
+#include <gst/mixer/mixertrack.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_MIXER_OPTIONS \
+  (gst_mixer_options_get_type ())
+#define GST_MIXER_OPTIONS(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MIXER_OPTIONS, \
+                              GstMixerOptions))
+#define GST_MIXER_OPTIONS_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_MIXER_OPTIONS, \
+                           GstMixerOptionsClass))
+#define GST_IS_MIXER_OPTIONS(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MIXER_OPTIONS))
+#define GST_IS_MIXER_OPTIONS_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MIXER_OPTIONS))
+
+typedef struct _GstMixerOptions {
+  GstMixerTrack parent;
+
+  /* list of strings */
+  GList        *values;
+
+  gpointer _gst_reserved[GST_PADDING];
+} GstMixerOptions;
+
+typedef struct _GstMixerOptionsClass {
+  GstMixerTrackClass parent;
+
+  void (* option_changed) (GstMixerOptions *opts,
+                          gchar           *value);
+
+  gpointer _gst_reserved[GST_PADDING];
+} GstMixerOptionsClass;
+
+GType          gst_mixer_options_get_type      (void);
+
+G_END_DECLS
+
+#endif /* __GST_MIXER_OPTIONS_H__ */
index a77936c..e556ab0 100644 (file)
@@ -9,6 +9,7 @@ libgstmixerincludedir = \
 
 mixer_headers = \
        mixer.h \
+       mixeroptions.h \
        mixertrack.h
 
 built_sources = \
@@ -27,7 +28,9 @@ noinst_LTLIBRARIES = libgstmixer.la
 
 libgstmixer_la_SOURCES = \
        mixer.c \
+       mixeroptions.c \
        mixertrack.c
+
 nodist_libgstmixer_la_SOURCES = \
        mixer-marshal.h \
        $(built_sources)
index ac2cd6b..3bcfd83 100644 (file)
@@ -1,2 +1,3 @@
 VOID:OBJECT,BOOLEAN
 VOID:OBJECT,POINTER
+VOID:OBJECT,STRING
index 1db3d6a..dcae874 100644 (file)
 
 enum
 {
-  MUTE_TOGGLED,
-  RECORD_TOGGLED,
-  VOLUME_CHANGED,
+  SIGNAL_MUTE_TOGGLED,
+  SIGNAL_RECORD_TOGGLED,
+  SIGNAL_VOLUME_CHANGED,
+  SIGNAL_OPTION_CHANGED,
   LAST_SIGNAL
 };
 
@@ -71,27 +72,34 @@ gst_mixer_class_init (GstMixerClass * klass)
   static gboolean initialized = FALSE;
 
   if (!initialized) {
-    gst_mixer_signals[RECORD_TOGGLED] =
+    gst_mixer_signals[SIGNAL_RECORD_TOGGLED] =
         g_signal_new ("record-toggled",
         GST_TYPE_MIXER, G_SIGNAL_RUN_LAST,
         G_STRUCT_OFFSET (GstMixerClass, record_toggled),
         NULL, NULL,
         gst_mixer_marshal_VOID__OBJECT_BOOLEAN, G_TYPE_NONE, 2,
         GST_TYPE_MIXER_TRACK, G_TYPE_BOOLEAN);
-    gst_mixer_signals[MUTE_TOGGLED] =
+    gst_mixer_signals[SIGNAL_MUTE_TOGGLED] =
         g_signal_new ("mute-toggled",
         GST_TYPE_MIXER, G_SIGNAL_RUN_LAST,
         G_STRUCT_OFFSET (GstMixerClass, mute_toggled),
         NULL, NULL,
         gst_mixer_marshal_VOID__OBJECT_BOOLEAN, G_TYPE_NONE, 2,
         GST_TYPE_MIXER_TRACK, G_TYPE_BOOLEAN);
-    gst_mixer_signals[VOLUME_CHANGED] =
+    gst_mixer_signals[SIGNAL_VOLUME_CHANGED] =
         g_signal_new ("volume-changed",
         GST_TYPE_MIXER, G_SIGNAL_RUN_LAST,
         G_STRUCT_OFFSET (GstMixerClass, volume_changed),
         NULL, NULL,
         gst_mixer_marshal_VOID__OBJECT_POINTER, G_TYPE_NONE, 2,
         GST_TYPE_MIXER_TRACK, G_TYPE_POINTER);
+    gst_mixer_signals[SIGNAL_OPTION_CHANGED] =
+        g_signal_new ("option-changed",
+        GST_TYPE_MIXER, G_SIGNAL_RUN_LAST,
+        G_STRUCT_OFFSET (GstMixerClass, option_changed),
+        NULL, NULL,
+        gst_mixer_marshal_VOID__OBJECT_STRING, G_TYPE_NONE, 2,
+        GST_TYPE_MIXER_OPTIONS, G_TYPE_STRING);
 
     initialized = TRUE;
   }
@@ -104,6 +112,8 @@ gst_mixer_class_init (GstMixerClass * klass)
   klass->get_volume = NULL;
   klass->set_mute = NULL;
   klass->set_record = NULL;
+  klass->set_option = NULL;
+  klass->get_option = NULL;
 }
 
 /**
@@ -226,11 +236,52 @@ gst_mixer_set_record (GstMixer * mixer, GstMixerTrack * track, gboolean record)
   }
 }
 
+/**
+ * gst_mixer_set_option:
+ * @mixer: The #GstMixer (a #GstElement) that owns the optionlist.
+ * @opts: The #GstMixerOptions that we operate on.
+ * @value: The requested new option value.
+ *
+ * Sets a name/value option in the mixer to the requested value.
+ */
+
+void
+gst_mixer_set_option (GstMixer * mixer, GstMixerOptions * opts, gchar * value)
+{
+  GstMixerClass *klass = GST_MIXER_GET_CLASS (mixer);
+
+  if (klass->set_option) {
+    klass->set_option (mixer, opts, value);
+  }
+}
+
+/**
+ * gst_mixer_g_option:
+ * @mixer: The #GstMixer (a #GstElement) that owns the optionlist.
+ * @opts: The #GstMixerOptions that we operate on.
+ *
+ * Get the current value of a name/value option in the mixer.
+ *
+ * Returns: current value of the name/value option.
+ */
+
+const gchar *
+gst_mixer_get_option (GstMixer * mixer, GstMixerOptions * opts)
+{
+  GstMixerClass *klass = GST_MIXER_GET_CLASS (mixer);
+
+  if (klass->get_option) {
+    return klass->get_option (mixer, opts);
+  }
+
+  return NULL;
+}
+
 void
 gst_mixer_mute_toggled (GstMixer * mixer, GstMixerTrack * track, gboolean mute)
 {
   g_signal_emit (G_OBJECT (mixer),
-      gst_mixer_signals[MUTE_TOGGLED], 0, track, mute);
+      gst_mixer_signals[SIGNAL_MUTE_TOGGLED], 0, track, mute);
 
   g_signal_emit_by_name (G_OBJECT (track), "mute_toggled", mute);
 }
@@ -240,7 +291,7 @@ gst_mixer_record_toggled (GstMixer * mixer,
     GstMixerTrack * track, gboolean record)
 {
   g_signal_emit (G_OBJECT (mixer),
-      gst_mixer_signals[RECORD_TOGGLED], 0, track, record);
+      gst_mixer_signals[SIGNAL_RECORD_TOGGLED], 0, track, record);
 
   g_signal_emit_by_name (G_OBJECT (track), "record_toggled", record);
 }
@@ -250,7 +301,17 @@ gst_mixer_volume_changed (GstMixer * mixer,
     GstMixerTrack * track, gint * volumes)
 {
   g_signal_emit (G_OBJECT (mixer),
-      gst_mixer_signals[VOLUME_CHANGED], 0, track, volumes);
+      gst_mixer_signals[SIGNAL_VOLUME_CHANGED], 0, track, volumes);
 
   g_signal_emit_by_name (G_OBJECT (track), "volume_changed", volumes);
 }
+
+void
+gst_mixer_option_changed (GstMixer * mixer,
+    GstMixerOptions * opts, gchar * value)
+{
+  g_signal_emit (G_OBJECT (mixer),
+      gst_mixer_signals[SIGNAL_OPTION_CHANGED], 0, opts, value);
+
+  g_signal_emit_by_name (G_OBJECT (opts), "value_changed", value);
+}
index 50ba3fd..2cb326d 100644 (file)
@@ -23,6 +23,7 @@
 #define __GST_MIXER_H__
 
 #include <gst/gst.h>
+#include <gst/mixer/mixeroptions.h>
 #include <gst/mixer/mixertrack.h>
 #include <gst/mixer/mixer-enumtypes.h>
 
@@ -84,7 +85,18 @@ typedef struct _GstMixerClass {
                           GstMixerTrack *channel,
                           gint          *volumes);
 
-  gpointer _gst_reserved[GST_PADDING];
+  /* use padding */
+  void         (* set_option)     (GstMixer      *mixer,
+                                   GstMixerOptions *opts,
+                                   gchar         *value);
+  const gchar *        (* get_option)     (GstMixer      *mixer,
+                                   GstMixerOptions *opts);
+
+  void (* option_changed) (GstMixer      *mixer,
+                          GstMixerOptions *opts,
+                          gchar         *option);
+
+  gpointer _gst_reserved[GST_PADDING-3];
 } GstMixerClass;
 
 GType          gst_mixer_get_type      (void);
@@ -103,6 +115,11 @@ void               gst_mixer_set_mute       (GstMixer      *mixer,
 void           gst_mixer_set_record     (GstMixer      *mixer,
                                          GstMixerTrack *track,
                                          gboolean       record);
+void           gst_mixer_set_option     (GstMixer      *mixer,
+                                         GstMixerOptions *opts,
+                                         gchar         *value);
+const gchar *  gst_mixer_get_option     (GstMixer      *mixer,
+                                         GstMixerOptions *opts);
 
 /* trigger signals */
 void           gst_mixer_mute_toggled   (GstMixer      *mixer,
@@ -114,6 +131,9 @@ void                gst_mixer_record_toggled (GstMixer      *mixer,
 void           gst_mixer_volume_changed (GstMixer      *mixer,
                                          GstMixerTrack *track,
                                          gint          *volumes);
+void           gst_mixer_option_changed (GstMixer      *mixer,
+                                         GstMixerOptions *opts,
+                                         gchar         *value);
 
 G_END_DECLS
 
diff --git a/gst-libs/gst/mixer/mixeroptions.c b/gst-libs/gst/mixer/mixeroptions.c
new file mode 100644 (file)
index 0000000..5e79a41
--- /dev/null
@@ -0,0 +1,103 @@
+/* GStreamer Mixer
+ * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
+ *
+ * mixeroptions.c: mixer track options object design
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "mixeroptions.h"
+
+enum
+{
+  /* FILL ME */
+  SIGNAL_OPTION_CHANGED,
+  LAST_SIGNAL
+};
+
+static void gst_mixer_options_class_init (GstMixerOptionsClass * klass);
+static void gst_mixer_options_init (GstMixerOptions * mixer);
+static void gst_mixer_options_dispose (GObject * object);
+
+static GObjectClass *parent_class = NULL;
+static guint signals[LAST_SIGNAL] = { 0 };
+
+GType
+gst_mixer_options_get_type (void)
+{
+  static GType gst_mixer_options_type = 0;
+
+  if (!gst_mixer_options_type) {
+    static const GTypeInfo mixer_options_info = {
+      sizeof (GstMixerOptionsClass),
+      NULL,
+      NULL,
+      (GClassInitFunc) gst_mixer_options_class_init,
+      NULL,
+      NULL,
+      sizeof (GstMixerOptions),
+      0,
+      (GInstanceInitFunc) gst_mixer_options_init,
+      NULL
+    };
+
+    gst_mixer_options_type =
+        g_type_register_static (GST_TYPE_MIXER_TRACK,
+        "GstMixerOptions", &mixer_options_info, 0);
+  }
+
+  return gst_mixer_options_type;
+}
+
+static void
+gst_mixer_options_class_init (GstMixerOptionsClass * klass)
+{
+  GObjectClass *object_klass = (GObjectClass *) klass;
+
+  parent_class = g_type_class_ref (GST_TYPE_MIXER_TRACK);
+
+  signals[SIGNAL_OPTION_CHANGED] =
+      g_signal_new ("option_changed", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST,
+      G_STRUCT_OFFSET (GstMixerOptionsClass, option_changed),
+      NULL, NULL, g_cclosure_marshal_VOID__STRING,
+      G_TYPE_NONE, 1, G_TYPE_STRING);
+
+  object_klass->dispose = gst_mixer_options_dispose;
+}
+
+static void
+gst_mixer_options_init (GstMixerOptions * channel)
+{
+  channel->values = NULL;
+}
+
+static void
+gst_mixer_options_dispose (GObject * object)
+{
+  GstMixerOptions *opts = GST_MIXER_OPTIONS (object);
+
+  g_list_foreach (opts->values, (GFunc) g_free, NULL);
+  g_list_free (opts->values);
+  opts->values = NULL;
+
+  if (parent_class->dispose)
+    parent_class->dispose (object);
+}
diff --git a/gst-libs/gst/mixer/mixeroptions.h b/gst-libs/gst/mixer/mixeroptions.h
new file mode 100644 (file)
index 0000000..586c9e4
--- /dev/null
@@ -0,0 +1,67 @@
+/* GStreamer Mixer
+ * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
+ *
+ * mixeroptions.h: mixer track options object
+ * This should be a subclass of MixerItem, along with MixerOptions,
+ * but that's not possible because of API/ABI in 0.8.x. FIXME.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GST_MIXER_OPTIONS_H__
+#define __GST_MIXER_OPTIONS_H__
+
+#include <gst/gst.h>
+#include <gst/mixer/mixertrack.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_MIXER_OPTIONS \
+  (gst_mixer_options_get_type ())
+#define GST_MIXER_OPTIONS(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MIXER_OPTIONS, \
+                              GstMixerOptions))
+#define GST_MIXER_OPTIONS_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_MIXER_OPTIONS, \
+                           GstMixerOptionsClass))
+#define GST_IS_MIXER_OPTIONS(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MIXER_OPTIONS))
+#define GST_IS_MIXER_OPTIONS_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MIXER_OPTIONS))
+
+typedef struct _GstMixerOptions {
+  GstMixerTrack parent;
+
+  /* list of strings */
+  GList        *values;
+
+  gpointer _gst_reserved[GST_PADDING];
+} GstMixerOptions;
+
+typedef struct _GstMixerOptionsClass {
+  GstMixerTrackClass parent;
+
+  void (* option_changed) (GstMixerOptions *opts,
+                          gchar           *value);
+
+  gpointer _gst_reserved[GST_PADDING];
+} GstMixerOptionsClass;
+
+GType          gst_mixer_options_get_type      (void);
+
+G_END_DECLS
+
+#endif /* __GST_MIXER_OPTIONS_H__ */