1604 lines
43 KiB
Diff
1604 lines
43 KiB
Diff
|
---
|
||
|
configure.ac.in | 18
|
||
|
libxfce4mixer/Makefile.am | 25
|
||
|
libxfce4mixer/audio.h | 8
|
||
|
libxfce4mixer/libxfce4mixer.c | 40 +
|
||
|
libxfce4mixer/libxfce4mixer.h | 2
|
||
|
libxfce4mixer/xfce-mixer-preferences.h | 3
|
||
|
libxfce4mixer/xfce-mixer-track-combo.c | 3
|
||
|
libxfce4mixer/xfce-mixer-track-combo.h | 3
|
||
|
libxfce4mixer/xfce-mixer-track-type.h | 2
|
||
|
libxfce4mixer/xfce4-mixer-alsa.c | 974 +++++++++++++++++++++++++++++++
|
||
|
libxfce4mixer/xfce4-mixer-alsa.h | 192 ++++++
|
||
|
panel-plugin/Makefile.am | 15
|
||
|
panel-plugin/xfce-plugin-dialog.c | 3
|
||
|
panel-plugin/xfce-plugin-dialog.h | 3
|
||
|
xfce4-mixer/Makefile.am | 11
|
||
|
xfce4-mixer/xfce-mixer-container.c | 3
|
||
|
xfce4-mixer/xfce-mixer-controls-dialog.c | 3
|
||
|
xfce4-mixer/xfce-mixer-option.c | 3
|
||
|
xfce4-mixer/xfce-mixer-switch.c | 3
|
||
|
xfce4-mixer/xfce-mixer-track.c | 3
|
||
|
xfce4-mixer/xfce-mixer-window.c | 4
|
||
|
21 files changed, 1278 insertions(+), 43 deletions(-)
|
||
|
|
||
|
--- a/libxfce4mixer/libxfce4mixer.c
|
||
|
+++ b/libxfce4mixer/libxfce4mixer.c
|
||
|
@@ -31,8 +31,7 @@
|
||
|
|
||
|
#include <dbus/dbus-glib.h>
|
||
|
|
||
|
-#include <gst/audio/mixerutils.h>
|
||
|
-#include <gst/interfaces/mixer.h>
|
||
|
+#include "audio.h"
|
||
|
|
||
|
#include <libxfce4util/libxfce4util.h>
|
||
|
|
||
|
@@ -40,8 +39,10 @@
|
||
|
|
||
|
|
||
|
|
||
|
+#ifndef XFCE4_MIXER_ALSA
|
||
|
static gboolean _xfce_mixer_filter_mixer (GstMixer *mixer,
|
||
|
gpointer user_data);
|
||
|
+#endif
|
||
|
static void _xfce_mixer_add_track_labels (gpointer data,
|
||
|
gpointer user_data);
|
||
|
static void _xfce_mixer_init_mixer (gpointer data,
|
||
|
@@ -88,7 +89,11 @@ xfce_mixer_init (void)
|
||
|
gtk_icon_theme_append_search_path (icon_theme, MIXER_DATADIR G_DIR_SEPARATOR_S "icons");
|
||
|
|
||
|
/* Get list of all available mixer devices */
|
||
|
+#ifdef XFCE4_MIXER_ALSA
|
||
|
+ mixers = gst_mixer_probe_devices ();
|
||
|
+#else
|
||
|
mixers = gst_audio_default_registry_mixer_filter (_xfce_mixer_filter_mixer, FALSE, &counter);
|
||
|
+#endif
|
||
|
|
||
|
/* Create a GstBus for notifications */
|
||
|
bus = gst_bus_new ();
|
||
|
@@ -396,6 +401,9 @@ xfce_mixer_get_max_volume (gint *volumes
|
||
|
|
||
|
|
||
|
|
||
|
+static void set_mixer_name (GstMixer *mixer, const gchar *name);
|
||
|
+
|
||
|
+#ifndef XFCE4_MIXER_ALSA
|
||
|
static gboolean
|
||
|
_xfce_mixer_filter_mixer (GstMixer *mixer,
|
||
|
gpointer user_data)
|
||
|
@@ -427,8 +435,24 @@ _xfce_mixer_filter_mixer (GstMixer *mixe
|
||
|
/* Free device name */
|
||
|
g_free (device_name);
|
||
|
|
||
|
+ set_mixer_name (mixer, name);
|
||
|
+ g_free (name);
|
||
|
+
|
||
|
+ /* Keep the mixer (we want all devices to be visible) */
|
||
|
+ return TRUE;
|
||
|
+}
|
||
|
+#endif /* !XFCE4_MIXER_ALSA */
|
||
|
+
|
||
|
+static void
|
||
|
+set_mixer_name (GstMixer *mixer, const gchar *name)
|
||
|
+{
|
||
|
+ gint length;
|
||
|
+ const gchar *p;
|
||
|
+ gchar *internal_name;
|
||
|
+
|
||
|
/* Set name to be used by xfce4-mixer */
|
||
|
- g_object_set_data_full (G_OBJECT (mixer), "xfce-mixer-name", name, (GDestroyNotify) g_free);
|
||
|
+ g_object_set_data_full (G_OBJECT (mixer), "xfce-mixer-name",
|
||
|
+ g_strdup (name), (GDestroyNotify) g_free);
|
||
|
|
||
|
/* Count alpha-numeric characters in the name */
|
||
|
for (length = 0, p = name; *p != '\0'; ++p)
|
||
|
@@ -442,15 +466,11 @@ _xfce_mixer_filter_mixer (GstMixer *mixe
|
||
|
internal_name[length++] = *p;
|
||
|
internal_name[length] = '\0';
|
||
|
|
||
|
- /* Remember name for use by xfce4-mixer */
|
||
|
+ /* Set name to be used by xfce4-mixer */
|
||
|
g_object_set_data_full (G_OBJECT (mixer), "xfce-mixer-internal-name", internal_name, (GDestroyNotify) g_free);
|
||
|
-
|
||
|
- /* Keep the mixer (we want all devices to be visible) */
|
||
|
- return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
-
|
||
|
static void
|
||
|
_xfce_mixer_add_track_labels (gpointer data,
|
||
|
gpointer user_data)
|
||
|
@@ -492,6 +512,10 @@ _xfce_mixer_init_mixer (gpointer data,
|
||
|
{
|
||
|
GstMixer *card = GST_MIXER (data);
|
||
|
|
||
|
+#ifdef XFCE4_MIXER_ALSA
|
||
|
+ set_mixer_name (card, gst_mixer_get_card_name (card));
|
||
|
+#endif
|
||
|
+
|
||
|
/* Add custom labels to all tracks */
|
||
|
_xfce_mixer_add_track_labels (card, NULL);
|
||
|
|
||
|
--- a/libxfce4mixer/libxfce4mixer.h
|
||
|
+++ b/libxfce4mixer/libxfce4mixer.h
|
||
|
@@ -26,7 +26,7 @@
|
||
|
|
||
|
#include <dbus/dbus-glib.h>
|
||
|
|
||
|
-#include <gst/interfaces/mixer.h>
|
||
|
+#include "audio.h"
|
||
|
|
||
|
#include "xfce-mixer-preferences.h"
|
||
|
#include "xfce-mixer-card-combo.h"
|
||
|
--- /dev/null
|
||
|
+++ b/libxfce4mixer/xfce4-mixer-alsa.h
|
||
|
@@ -0,0 +1,192 @@
|
||
|
+/*
|
||
|
+ * Simple alternative GstMixer implementation with ALSA-native API
|
||
|
+ */
|
||
|
+
|
||
|
+#ifndef __XFCE4_MIXER_ALSA_H
|
||
|
+#define __XFCE4_MIXER_ALSA_H
|
||
|
+
|
||
|
+G_BEGIN_DECLS
|
||
|
+
|
||
|
+/*
|
||
|
+ * GstMixer
|
||
|
+ */
|
||
|
+
|
||
|
+GType gst_mixer_get_type (void);
|
||
|
+
|
||
|
+#define GST_TYPE_MIXER \
|
||
|
+ (gst_mixer_get_type ())
|
||
|
+#define GST_MIXER(obj) \
|
||
|
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MIXER, GstMixer))
|
||
|
+#define GST_MIXER_CLASS(klass) \
|
||
|
+ (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_MIXER, GstMixerClass))
|
||
|
+#define GST_IS_MIXER(obj) \
|
||
|
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MIXER))
|
||
|
+#define GST_IS_MIXER_CLASS(klass) \
|
||
|
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MIXER))
|
||
|
+#define GST_MIXER_GET_CLASS(inst) \
|
||
|
+ (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GST_TYPE_MIXER, GstMixerClass))
|
||
|
+
|
||
|
+typedef struct _GstMixer GstMixer;
|
||
|
+typedef struct _GstMixerClass GstMixerClass;
|
||
|
+
|
||
|
+typedef enum {
|
||
|
+ GST_MIXER_FLAG_NONE = 0,
|
||
|
+ GST_MIXER_FLAG_AUTO_NOTIFICATIONS = (1<<0),
|
||
|
+ GST_MIXER_FLAG_HAS_WHITELIST = (1<<1),
|
||
|
+ GST_MIXER_FLAG_GROUPING = (1<<2),
|
||
|
+} GstMixerFlags;
|
||
|
+
|
||
|
+typedef enum {
|
||
|
+ GST_MIXER_MESSAGE_INVALID,
|
||
|
+ GST_MIXER_MESSAGE_MUTE_TOGGLED,
|
||
|
+ GST_MIXER_MESSAGE_RECORD_TOGGLED,
|
||
|
+ GST_MIXER_MESSAGE_VOLUME_CHANGED,
|
||
|
+ GST_MIXER_MESSAGE_OPTION_CHANGED,
|
||
|
+ GST_MIXER_MESSAGE_OPTIONS_LIST_CHANGED,
|
||
|
+ GST_MIXER_MESSAGE_MIXER_CHANGED
|
||
|
+} GstMixerMessageType;
|
||
|
+
|
||
|
+struct _GstMixer {
|
||
|
+ GstElement element;
|
||
|
+ GList *tracklist;
|
||
|
+ void *handle; /* snd_mixer_t */
|
||
|
+ const char *name;
|
||
|
+ const gchar *card_name;
|
||
|
+ GSource *src;
|
||
|
+};
|
||
|
+
|
||
|
+struct _GstMixerClass {
|
||
|
+ GstElementClass parent_class;
|
||
|
+};
|
||
|
+
|
||
|
+const GList *gst_mixer_list_tracks (GstMixer *mixer);
|
||
|
+
|
||
|
+static inline GstMixerFlags
|
||
|
+gst_mixer_get_mixer_flags (GstMixer * mixer)
|
||
|
+{
|
||
|
+ return GST_MIXER_FLAG_AUTO_NOTIFICATIONS;
|
||
|
+}
|
||
|
+
|
||
|
+GstMixerMessageType gst_mixer_message_get_type (GstMessage *message);
|
||
|
+
|
||
|
+int gst_mixer_new (const char *name, GstMixer **mixer_ret);
|
||
|
+GList *gst_mixer_probe_devices (void);
|
||
|
+const gchar *gst_mixer_get_card_name (GstMixer *mixer);
|
||
|
+
|
||
|
+/*
|
||
|
+ * GstMixerTrack
|
||
|
+ */
|
||
|
+
|
||
|
+GType gst_mixer_track_get_type (void);
|
||
|
+
|
||
|
+#define GST_TYPE_MIXER_TRACK \
|
||
|
+ (gst_mixer_track_get_type ())
|
||
|
+#define GST_MIXER_TRACK(obj) \
|
||
|
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MIXER_TRACK, \
|
||
|
+ GstMixerTrack))
|
||
|
+#define GST_MIXER_TRACK_CLASS(klass) \
|
||
|
+ (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_MIXER_TRACK, \
|
||
|
+ GstMixerTrackClass))
|
||
|
+#define GST_IS_MIXER_TRACK(obj) \
|
||
|
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MIXER_TRACK))
|
||
|
+#define GST_IS_MIXER_TRACK_CLASS(klass) \
|
||
|
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MIXER_TRACK))
|
||
|
+
|
||
|
+typedef struct _GstMixerTrack GstMixerTrack;
|
||
|
+typedef struct _GstMixerTrackClass GstMixerTrackClass;
|
||
|
+
|
||
|
+typedef enum {
|
||
|
+ GST_MIXER_TRACK_INPUT = (1<<0),
|
||
|
+ GST_MIXER_TRACK_OUTPUT = (1<<1),
|
||
|
+ GST_MIXER_TRACK_MUTE = (1<<2),
|
||
|
+ GST_MIXER_TRACK_RECORD = (1<<3),
|
||
|
+ GST_MIXER_TRACK_MASTER = (1<<4),
|
||
|
+ GST_MIXER_TRACK_SOFTWARE = (1<<5),
|
||
|
+ GST_MIXER_TRACK_NO_RECORD = (1<<6),
|
||
|
+ GST_MIXER_TRACK_NO_MUTE = (1<<7),
|
||
|
+ GST_MIXER_TRACK_WHITELIST = (1<<8),
|
||
|
+ GST_MIXER_TRACK_READONLY = (1<<9),
|
||
|
+ GST_MIXER_TRACK_WRITEONLY = (1<<10)
|
||
|
+} GstMixerTrackFlags;
|
||
|
+
|
||
|
+struct _GstMixerTrack {
|
||
|
+ GObject parent;
|
||
|
+ void *element;
|
||
|
+ gchar *label;
|
||
|
+ gchar *untranslated_label;
|
||
|
+ guint index;
|
||
|
+ GstMixerTrackFlags flags;
|
||
|
+ gint num_channels;
|
||
|
+ gint *volumes;
|
||
|
+ gint min_volume;
|
||
|
+ gint max_volume;
|
||
|
+ GstMixerTrack *shared_mute;
|
||
|
+ gboolean has_volume;
|
||
|
+ gboolean has_switch;
|
||
|
+};
|
||
|
+
|
||
|
+struct _GstMixerTrackClass {
|
||
|
+ GObjectClass parent;
|
||
|
+};
|
||
|
+
|
||
|
+#define GST_MIXER_TRACK_HAS_FLAG(track, flag) ((track)->flags & (flag))
|
||
|
+
|
||
|
+void gst_mixer_get_volume (GstMixer *mixer, GstMixerTrack *track, gint *volumes);
|
||
|
+void gst_mixer_set_volume (GstMixer *mixer, GstMixerTrack *track, gint *volumes);
|
||
|
+void gst_mixer_set_mute (GstMixer *mixer, GstMixerTrack *track, gboolean mute);
|
||
|
+void gst_mixer_set_record (GstMixer *mixer, GstMixerTrack *track, gboolean record);
|
||
|
+
|
||
|
+void gst_mixer_message_parse_mute_toggled (GstMessage *message,
|
||
|
+ GstMixerTrack **track,
|
||
|
+ gboolean *mute);
|
||
|
+void gst_mixer_message_parse_record_toggled (GstMessage *message,
|
||
|
+ GstMixerTrack **track,
|
||
|
+ gboolean *record);
|
||
|
+void gst_mixer_message_parse_volume_changed (GstMessage *message,
|
||
|
+ GstMixerTrack **track,
|
||
|
+ gint **volumes,
|
||
|
+ gint *num_channels);
|
||
|
+
|
||
|
+/*
|
||
|
+ * GstMixerOptions
|
||
|
+ */
|
||
|
+
|
||
|
+GType gst_mixer_options_get_type (void);
|
||
|
+
|
||
|
+#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))
|
||
|
+#define GST_MIXER_OPTIONS_GET_CLASS(inst) \
|
||
|
+ (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GST_TYPE_MIXER_OPTIONS, GstMixerOptionsClass))
|
||
|
+
|
||
|
+typedef struct _GstMixerOptions GstMixerOptions;
|
||
|
+typedef struct _GstMixerOptionsClass GstMixerOptionsClass;
|
||
|
+
|
||
|
+struct _GstMixerOptions {
|
||
|
+ GstMixerTrack parent;
|
||
|
+ GList *values;
|
||
|
+};
|
||
|
+
|
||
|
+struct _GstMixerOptionsClass {
|
||
|
+ GstMixerTrackClass parent;
|
||
|
+};
|
||
|
+
|
||
|
+void gst_mixer_set_option (GstMixer * mixer, GstMixerOptions * opts, gchar * value);
|
||
|
+const gchar * gst_mixer_get_option (GstMixer * mixer, GstMixerOptions * opts);
|
||
|
+GList * gst_mixer_options_get_values (GstMixerOptions *mixer_options);
|
||
|
+void gst_mixer_message_parse_option_changed (GstMessage *message,
|
||
|
+ GstMixerOptions ** options,
|
||
|
+ const gchar **value);
|
||
|
+void gst_mixer_message_parse_options_list_changed (GstMessage *message,
|
||
|
+ GstMixerOptions **options);
|
||
|
+
|
||
|
+G_END_DECLS
|
||
|
+
|
||
|
+#endif /* __XFCE4_MIXER_ALSA_H */
|
||
|
--- a/libxfce4mixer/xfce-mixer-preferences.h
|
||
|
+++ b/libxfce4mixer/xfce-mixer-preferences.h
|
||
|
@@ -24,8 +24,7 @@
|
||
|
|
||
|
#include <glib-object.h>
|
||
|
|
||
|
-#include <gst/gst.h>
|
||
|
-#include <gst/interfaces/mixer.h>
|
||
|
+#include "audio.h"
|
||
|
|
||
|
G_BEGIN_DECLS
|
||
|
|
||
|
--- a/libxfce4mixer/xfce-mixer-track-combo.c
|
||
|
+++ b/libxfce4mixer/xfce-mixer-track-combo.c
|
||
|
@@ -27,8 +27,7 @@
|
||
|
|
||
|
#include <gtk/gtk.h>
|
||
|
|
||
|
-#include <gst/gst.h>
|
||
|
-#include <gst/interfaces/mixer.h>
|
||
|
+#include "audio.h"
|
||
|
|
||
|
#include "libxfce4mixer.h"
|
||
|
#include "xfce-mixer-track-type.h"
|
||
|
--- a/libxfce4mixer/xfce-mixer-track-combo.h
|
||
|
+++ b/libxfce4mixer/xfce-mixer-track-combo.h
|
||
|
@@ -24,8 +24,7 @@
|
||
|
|
||
|
#include <gtk/gtk.h>
|
||
|
|
||
|
-#include <gst/gst.h>
|
||
|
-#include <gst/interfaces/mixer.h>
|
||
|
+#include "audio.h"
|
||
|
|
||
|
G_BEGIN_DECLS
|
||
|
|
||
|
--- a/libxfce4mixer/xfce-mixer-track-type.h
|
||
|
+++ b/libxfce4mixer/xfce-mixer-track-type.h
|
||
|
@@ -22,7 +22,7 @@
|
||
|
#define __XFCE_TRACK_TYPE_H__
|
||
|
|
||
|
#include <glib-object.h>
|
||
|
-#include <gst/interfaces/mixer.h>
|
||
|
+#include "audio.h"
|
||
|
|
||
|
G_BEGIN_DECLS
|
||
|
|
||
|
--- /dev/null
|
||
|
+++ b/libxfce4mixer/xfce4-mixer-alsa.c
|
||
|
@@ -0,0 +1,974 @@
|
||
|
+/*
|
||
|
+ * Simple alternative GstMixer implementation with ALSA-native API
|
||
|
+ */
|
||
|
+
|
||
|
+#include "config.h"
|
||
|
+#include "audio.h"
|
||
|
+
|
||
|
+#include <alsa/asoundlib.h>
|
||
|
+
|
||
|
+#define GST_MIXER_MESSAGE_NAME "gst-mixer-message"
|
||
|
+
|
||
|
+/*
|
||
|
+ * GstMixer
|
||
|
+ */
|
||
|
+
|
||
|
+G_DEFINE_TYPE (GstMixer, gst_mixer, GST_TYPE_ELEMENT);
|
||
|
+
|
||
|
+static void gst_mixer_init (GstMixer *mixer)
|
||
|
+{
|
||
|
+}
|
||
|
+
|
||
|
+static void gst_mixer_dispose (GObject * object)
|
||
|
+{
|
||
|
+ GstMixer *mixer = GST_MIXER (object);
|
||
|
+
|
||
|
+ if (mixer->src) {
|
||
|
+ g_source_destroy (mixer->src);
|
||
|
+ mixer->src = NULL;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (mixer->handle) {
|
||
|
+ snd_mixer_close (mixer->handle);
|
||
|
+ mixer->handle = NULL;
|
||
|
+ }
|
||
|
+
|
||
|
+ g_list_free_full (mixer->tracklist, g_object_unref);
|
||
|
+ mixer->tracklist = NULL;
|
||
|
+
|
||
|
+ g_free ((gpointer *) mixer->name);
|
||
|
+ mixer->name = NULL;
|
||
|
+
|
||
|
+ g_free ((gpointer *) mixer->card_name);
|
||
|
+ mixer->card_name = NULL;
|
||
|
+
|
||
|
+ G_OBJECT_CLASS (gst_mixer_parent_class)->dispose (object);
|
||
|
+}
|
||
|
+
|
||
|
+static void gst_mixer_class_init (GstMixerClass *klass)
|
||
|
+{
|
||
|
+ GstElementClass *element_klass = GST_ELEMENT_CLASS (klass);
|
||
|
+ GObjectClass *object_klass = G_OBJECT_CLASS (klass);
|
||
|
+
|
||
|
+ gst_element_class_set_static_metadata (element_klass,
|
||
|
+ "ALSA mixer", "Generic/Audio",
|
||
|
+ "Control audio mixer via ALSA API",
|
||
|
+ "Takashi Iwai <tiwai@suse.de>");
|
||
|
+
|
||
|
+ object_klass->dispose = gst_mixer_dispose;
|
||
|
+}
|
||
|
+
|
||
|
+/*
|
||
|
+ * GstMixerTrack
|
||
|
+ */
|
||
|
+
|
||
|
+G_DEFINE_TYPE (GstMixerTrack, gst_mixer_track, G_TYPE_OBJECT);
|
||
|
+
|
||
|
+static void gst_mixer_track_init (GstMixerTrack *track)
|
||
|
+{
|
||
|
+}
|
||
|
+
|
||
|
+static void notify_mute_change (GstMixer *mixer, GstMixerTrack *track,
|
||
|
+ gboolean mute)
|
||
|
+{
|
||
|
+ GstStructure *s;
|
||
|
+ GstMessage *m;
|
||
|
+
|
||
|
+ s = gst_structure_new (GST_MIXER_MESSAGE_NAME,
|
||
|
+ "type", G_TYPE_STRING, "mute-toggled",
|
||
|
+ "track", GST_TYPE_MIXER_TRACK, track,
|
||
|
+ "mute", G_TYPE_BOOLEAN, mute,
|
||
|
+ NULL);
|
||
|
+ m = gst_message_new_element (GST_OBJECT (mixer), s);
|
||
|
+ gst_element_post_message (GST_ELEMENT (mixer), m);
|
||
|
+}
|
||
|
+
|
||
|
+static void update_mute (GstMixer *mixer, GstMixerTrack *track, gboolean mute)
|
||
|
+{
|
||
|
+ int old_flag = track->flags & GST_MIXER_TRACK_MUTE;
|
||
|
+
|
||
|
+ if (mute) {
|
||
|
+ track->flags |= GST_MIXER_TRACK_MUTE;
|
||
|
+ if (track->shared_mute)
|
||
|
+ track->shared_mute->flags |= GST_MIXER_TRACK_MUTE;
|
||
|
+ } else {
|
||
|
+ track->flags &= ~GST_MIXER_TRACK_MUTE;
|
||
|
+ if (track->shared_mute)
|
||
|
+ track->shared_mute->flags &= ~GST_MIXER_TRACK_MUTE;
|
||
|
+ }
|
||
|
+
|
||
|
+ if ((track->flags & GST_MIXER_TRACK_MUTE) != old_flag)
|
||
|
+ notify_mute_change (mixer, track, mute);
|
||
|
+}
|
||
|
+
|
||
|
+static void notify_recording_change (GstMixer *mixer, GstMixerTrack *track,
|
||
|
+ gboolean recording)
|
||
|
+{
|
||
|
+ GstStructure *s;
|
||
|
+ GstMessage *m;
|
||
|
+
|
||
|
+ s = gst_structure_new (GST_MIXER_MESSAGE_NAME,
|
||
|
+ "type", G_TYPE_STRING, "record-toggled",
|
||
|
+ "track", GST_TYPE_MIXER_TRACK, track,
|
||
|
+ "record", G_TYPE_BOOLEAN, recording,
|
||
|
+ NULL);
|
||
|
+ m = gst_message_new_element (GST_OBJECT (mixer), s);
|
||
|
+ gst_element_post_message (GST_ELEMENT (mixer), m);
|
||
|
+}
|
||
|
+
|
||
|
+static void update_recording (GstMixer *mixer, GstMixerTrack *track,
|
||
|
+ gboolean recording)
|
||
|
+{
|
||
|
+ int old_flag = track->flags & GST_MIXER_TRACK_RECORD;
|
||
|
+
|
||
|
+ if (recording)
|
||
|
+ track->flags |= GST_MIXER_TRACK_RECORD;
|
||
|
+ else
|
||
|
+ track->flags &= ~GST_MIXER_TRACK_RECORD;
|
||
|
+
|
||
|
+ if ((track->flags & GST_MIXER_TRACK_RECORD) != old_flag)
|
||
|
+ notify_recording_change (mixer, track, recording);
|
||
|
+}
|
||
|
+
|
||
|
+static void notify_volume_change (GstMixer *mixer, GstMixerTrack *track)
|
||
|
+{
|
||
|
+ GstStructure *s;
|
||
|
+ GstMessage *m;
|
||
|
+ GValue l = { 0, };
|
||
|
+ GValue v = { 0, };
|
||
|
+ int i;
|
||
|
+
|
||
|
+ s = gst_structure_new (GST_MIXER_MESSAGE_NAME,
|
||
|
+ "type", G_TYPE_STRING, "volume-changed",
|
||
|
+ "track", GST_TYPE_MIXER_TRACK, track,
|
||
|
+ NULL);
|
||
|
+ g_value_init (&l, GST_TYPE_ARRAY);
|
||
|
+ g_value_init (&v, G_TYPE_INT);
|
||
|
+
|
||
|
+ for (i = 0; i < track->num_channels; i++) {
|
||
|
+ g_value_set_int (&v, track->volumes[i]);
|
||
|
+ gst_value_array_append_value (&l, &v);
|
||
|
+ }
|
||
|
+
|
||
|
+ gst_structure_set_value (s, "volumes", &l);
|
||
|
+ g_value_unset (&v);
|
||
|
+ g_value_unset (&l);
|
||
|
+
|
||
|
+ m = gst_message_new_element (GST_OBJECT (mixer), s);
|
||
|
+ gst_element_post_message (GST_ELEMENT (mixer), m);
|
||
|
+}
|
||
|
+
|
||
|
+static void track_update (GstMixer *mixer, GstMixerTrack *track)
|
||
|
+{
|
||
|
+ gboolean vol_changed = FALSE;
|
||
|
+ int i;
|
||
|
+
|
||
|
+ if (track->flags & GST_MIXER_TRACK_OUTPUT) {
|
||
|
+ int audible = 0;
|
||
|
+ if (track->has_switch) {
|
||
|
+ for (i = 0; i < track->num_channels; i++) {
|
||
|
+ int v = 0;
|
||
|
+ snd_mixer_selem_get_playback_switch (track->element, i, &v);
|
||
|
+ if (v)
|
||
|
+ audible = 1;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ if (track->has_volume) {
|
||
|
+ for (i = 0; i < track->num_channels; i++) {
|
||
|
+ long vol = 0;
|
||
|
+ snd_mixer_selem_get_playback_volume (track->element, i, &vol);
|
||
|
+ if (track->volumes[i] != vol)
|
||
|
+ vol_changed = TRUE;
|
||
|
+ track->volumes[i] = vol;
|
||
|
+ if (!track->has_switch &&
|
||
|
+ vol > track->min_volume)
|
||
|
+ audible = 1;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ update_mute (mixer, track, !audible);
|
||
|
+ }
|
||
|
+
|
||
|
+ if (track->flags & GST_MIXER_TRACK_INPUT) {
|
||
|
+ int recording = 0;
|
||
|
+ if (track->has_switch) {
|
||
|
+ for (i = 0; i < track->num_channels; i++) {
|
||
|
+ int v = 0;
|
||
|
+ snd_mixer_selem_get_capture_switch (track->element, i, &v);
|
||
|
+ if (v)
|
||
|
+ recording = 1;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ if (track->has_volume) {
|
||
|
+ for (i = 0; i < track->num_channels; i++) {
|
||
|
+ long vol = 0;
|
||
|
+ snd_mixer_selem_get_capture_volume (track->element, i, &vol);
|
||
|
+ if (track->volumes[i] != vol)
|
||
|
+ vol_changed = TRUE;
|
||
|
+ track->volumes[i] = vol;
|
||
|
+ if (!track->has_switch &&
|
||
|
+ vol > track->min_volume)
|
||
|
+ recording = 1;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ update_recording (mixer, track, recording);
|
||
|
+ }
|
||
|
+
|
||
|
+ if (vol_changed)
|
||
|
+ notify_volume_change (mixer, track);
|
||
|
+}
|
||
|
+
|
||
|
+static GstMixerTrack *track_new (snd_mixer_elem_t *element, int num,
|
||
|
+ int flags, gboolean append_capture)
|
||
|
+{
|
||
|
+ GstMixerTrack *track;
|
||
|
+ const char *name;
|
||
|
+
|
||
|
+ track = (GstMixerTrack *) g_object_new (GST_TYPE_MIXER_TRACK, NULL);
|
||
|
+ track->index = snd_mixer_selem_get_index (element);
|
||
|
+ track->element = element;
|
||
|
+ track->flags = flags;
|
||
|
+
|
||
|
+ if (flags & GST_MIXER_TRACK_OUTPUT) {
|
||
|
+ while (snd_mixer_selem_has_playback_channel (element,
|
||
|
+ track->num_channels))
|
||
|
+ track->num_channels++;
|
||
|
+ } else if (flags & GST_MIXER_TRACK_INPUT) {
|
||
|
+ while (snd_mixer_selem_has_capture_channel (element,
|
||
|
+ track->num_channels))
|
||
|
+ track->num_channels++;
|
||
|
+ }
|
||
|
+
|
||
|
+ track->volumes = g_new (gint, track->num_channels);
|
||
|
+
|
||
|
+ name = snd_mixer_selem_get_name (element);
|
||
|
+ track->untranslated_label = g_strdup (name);
|
||
|
+
|
||
|
+ if (!num)
|
||
|
+ track->label = g_strdup_printf ("%s%s", name,
|
||
|
+ append_capture ? " Capture" : "");
|
||
|
+ else
|
||
|
+ track->label = g_strdup_printf ("%s%s %d", name,
|
||
|
+ append_capture ? " Capture" : "",
|
||
|
+ num);
|
||
|
+
|
||
|
+ return track;
|
||
|
+}
|
||
|
+
|
||
|
+enum {
|
||
|
+ ARG_0,
|
||
|
+ ARG_LABEL,
|
||
|
+ ARG_UNTRANSLATED_LABEL,
|
||
|
+ ARG_INDEX,
|
||
|
+};
|
||
|
+
|
||
|
+static void gst_mixer_track_get_property (GObject *object, guint prop_id,
|
||
|
+ GValue *value, GParamSpec *pspec)
|
||
|
+{
|
||
|
+ GstMixerTrack *track = GST_MIXER_TRACK (object);
|
||
|
+
|
||
|
+ switch (prop_id) {
|
||
|
+ case ARG_LABEL:
|
||
|
+ g_value_set_string (value, track->label);
|
||
|
+ break;
|
||
|
+ case ARG_UNTRANSLATED_LABEL:
|
||
|
+ g_value_set_string (value, track->untranslated_label);
|
||
|
+ break;
|
||
|
+ case ARG_INDEX:
|
||
|
+ g_value_set_uint (value, track->index);
|
||
|
+ break;
|
||
|
+ default:
|
||
|
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||
|
+ break;
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+static void gst_mixer_track_set_property (GObject *object,
|
||
|
+ guint prop_id,
|
||
|
+ const GValue *value,
|
||
|
+ GParamSpec * pspec)
|
||
|
+{
|
||
|
+ GstMixerTrack *track;
|
||
|
+
|
||
|
+ track = GST_MIXER_TRACK (object);
|
||
|
+
|
||
|
+ switch (prop_id) {
|
||
|
+ case ARG_LABEL:
|
||
|
+ g_free (track->label);
|
||
|
+ track->label = g_value_dup_string (value);
|
||
|
+ break;
|
||
|
+ case ARG_UNTRANSLATED_LABEL:
|
||
|
+ g_free (track->untranslated_label);
|
||
|
+ track->untranslated_label = g_value_dup_string (value);
|
||
|
+ break;
|
||
|
+ case ARG_INDEX:
|
||
|
+ track->index = g_value_get_uint (value);
|
||
|
+ break;
|
||
|
+ default:
|
||
|
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||
|
+ break;
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+static void gst_mixer_track_dispose (GObject * object)
|
||
|
+{
|
||
|
+ GstMixerTrack *track = GST_MIXER_TRACK (object);
|
||
|
+
|
||
|
+ if (track->label) {
|
||
|
+ g_free (track->label);
|
||
|
+ track->label = NULL;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (track->untranslated_label) {
|
||
|
+ g_free (track->untranslated_label);
|
||
|
+ track->untranslated_label = NULL;
|
||
|
+ }
|
||
|
+
|
||
|
+ G_OBJECT_CLASS (gst_mixer_track_parent_class)->dispose (object);
|
||
|
+}
|
||
|
+
|
||
|
+static void gst_mixer_track_class_init (GstMixerTrackClass * klass)
|
||
|
+{
|
||
|
+ GObjectClass *object_klass = G_OBJECT_CLASS (klass);
|
||
|
+
|
||
|
+ object_klass->get_property = gst_mixer_track_get_property;
|
||
|
+ object_klass->set_property = gst_mixer_track_set_property;
|
||
|
+
|
||
|
+ g_object_class_install_property (object_klass, ARG_UNTRANSLATED_LABEL,
|
||
|
+ g_param_spec_string ("untranslated-label",
|
||
|
+ "Untranslated track label",
|
||
|
+ "The untranslated label assigned to the track (since 0.10.13)",
|
||
|
+ NULL,
|
||
|
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
||
|
+
|
||
|
+ g_object_class_install_property (object_klass, ARG_LABEL,
|
||
|
+ g_param_spec_string ("label", "Track label",
|
||
|
+ "The label assigned to the track (may be translated)",
|
||
|
+ NULL,
|
||
|
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS | G_PARAM_STATIC_STRINGS));
|
||
|
+
|
||
|
+ g_object_class_install_property (object_klass, ARG_INDEX,
|
||
|
+ g_param_spec_uint ("index", "Index",
|
||
|
+ "Track index",
|
||
|
+ 0, G_MAXUINT, 0,
|
||
|
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||
|
+
|
||
|
+ object_klass->dispose = gst_mixer_track_dispose;
|
||
|
+}
|
||
|
+
|
||
|
+static void get_playback_min_max (GstMixerTrack *track)
|
||
|
+{
|
||
|
+ if (track->has_volume) {
|
||
|
+ long min = 0, max = 0;
|
||
|
+ snd_mixer_selem_get_playback_volume_range (track->element, &min, &max);
|
||
|
+ track->min_volume = min;
|
||
|
+ track->max_volume = max;
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+static void get_capture_min_max (GstMixerTrack *track)
|
||
|
+{
|
||
|
+ if (track->has_volume) {
|
||
|
+ long min = 0, max = 0;
|
||
|
+ snd_mixer_selem_get_capture_volume_range (track->element, &min, &max);
|
||
|
+ track->min_volume = min;
|
||
|
+ track->max_volume = max;
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+static GstMixerTrack *get_named_playback_track (GstMixer *mixer,
|
||
|
+ const char *name)
|
||
|
+{
|
||
|
+ GList *item;
|
||
|
+ GstMixerTrack *track;
|
||
|
+
|
||
|
+ for (item = mixer->tracklist; item; item = item->next) {
|
||
|
+ track = GST_MIXER_TRACK (item->data);
|
||
|
+ if (! (track->flags & GST_MIXER_TRACK_OUTPUT))
|
||
|
+ continue;
|
||
|
+ if (!strcmp (track->label, name))
|
||
|
+ return track;
|
||
|
+ }
|
||
|
+ return NULL;
|
||
|
+}
|
||
|
+
|
||
|
+static void mark_master_track (GstMixer *mixer)
|
||
|
+{
|
||
|
+ GList *item;
|
||
|
+ GstMixerTrack *track;
|
||
|
+
|
||
|
+ if ((track = get_named_playback_track (mixer, "Master")) ||
|
||
|
+ (track = get_named_playback_track (mixer, "Front")) ||
|
||
|
+ (track = get_named_playback_track (mixer, "PCM")) ||
|
||
|
+ (track = get_named_playback_track (mixer, "Speaker")))
|
||
|
+ goto found;
|
||
|
+
|
||
|
+ /* If not found, take a mono track with both volume and switch */
|
||
|
+ for (item = mixer->tracklist; item; item = item->next) {
|
||
|
+ track = GST_MIXER_TRACK (item->data);
|
||
|
+ if (! (track->flags & GST_MIXER_TRACK_OUTPUT))
|
||
|
+ continue;
|
||
|
+ if (track->has_volume && track->has_switch &&
|
||
|
+ track->num_channels == 1)
|
||
|
+ goto found;
|
||
|
+ }
|
||
|
+
|
||
|
+ /* If not found, take any track with both volume and switch */
|
||
|
+ for (item = mixer->tracklist; item; item = item->next) {
|
||
|
+ track = GST_MIXER_TRACK (item->data);
|
||
|
+ if (! (track->flags & GST_MIXER_TRACK_OUTPUT))
|
||
|
+ continue;
|
||
|
+ if (track->has_volume && track->has_switch)
|
||
|
+ goto found;
|
||
|
+ }
|
||
|
+
|
||
|
+ /* If not found, take any track with volume */
|
||
|
+ for (item = mixer->tracklist; item; item = item->next) {
|
||
|
+ track = GST_MIXER_TRACK (item->data);
|
||
|
+ if (! (track->flags & GST_MIXER_TRACK_OUTPUT))
|
||
|
+ continue;
|
||
|
+ if (track->has_volume)
|
||
|
+ goto found;
|
||
|
+ }
|
||
|
+
|
||
|
+ return;
|
||
|
+
|
||
|
+ found:
|
||
|
+ track->flags |= GST_MIXER_TRACK_MASTER;
|
||
|
+ return;
|
||
|
+}
|
||
|
+
|
||
|
+static int mixer_elem_callback (snd_mixer_elem_t *elem, unsigned int mask)
|
||
|
+{
|
||
|
+ GstMixer *mixer = snd_mixer_elem_get_callback_private (elem);
|
||
|
+ GList *item;
|
||
|
+
|
||
|
+ for (item = mixer->tracklist; item; item = item->next) {
|
||
|
+ GstMixerTrack *track = GST_MIXER_TRACK (item->data);
|
||
|
+ if (track->element == elem)
|
||
|
+ track_update (mixer, track);
|
||
|
+ }
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static int mixer_callback (snd_mixer_t *ctl, unsigned int mask,
|
||
|
+ snd_mixer_elem_t *elem)
|
||
|
+{
|
||
|
+ GstMixer *mixer = snd_mixer_get_callback_private (ctl);
|
||
|
+
|
||
|
+ snd_mixer_handle_events (mixer->handle);
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+const GList *gst_mixer_list_tracks (GstMixer *mixer)
|
||
|
+{
|
||
|
+ return mixer->tracklist;
|
||
|
+}
|
||
|
+
|
||
|
+static gboolean same_volumes (gint num_channels, const gint *volumes)
|
||
|
+{
|
||
|
+ gint i;
|
||
|
+
|
||
|
+ for (i = 1; i < num_channels; i++) {
|
||
|
+ if (volumes[0] != volumes[i])
|
||
|
+ return FALSE;
|
||
|
+ }
|
||
|
+
|
||
|
+ return TRUE;
|
||
|
+}
|
||
|
+
|
||
|
+void gst_mixer_set_volume (GstMixer *mixer, GstMixerTrack *track, gint *volumes)
|
||
|
+{
|
||
|
+ gint i;
|
||
|
+
|
||
|
+ track_update (mixer, track);
|
||
|
+
|
||
|
+ if (!track->has_volume)
|
||
|
+ return;
|
||
|
+
|
||
|
+ for (i = 0; i < track->num_channels; i++)
|
||
|
+ track->volumes[i] = volumes[i];
|
||
|
+
|
||
|
+ if (track->flags & GST_MIXER_TRACK_OUTPUT) {
|
||
|
+ if (!track->has_switch && (track->flags & GST_MIXER_TRACK_MUTE))
|
||
|
+ return;
|
||
|
+ if (same_volumes (track->num_channels, volumes)) {
|
||
|
+ snd_mixer_selem_set_playback_volume_all (track->element,
|
||
|
+ volumes[0]);
|
||
|
+ } else {
|
||
|
+ for (i = 0; i < track->num_channels; i++)
|
||
|
+ snd_mixer_selem_set_playback_volume (track->element, i,
|
||
|
+ volumes[i]);
|
||
|
+ }
|
||
|
+ } else {
|
||
|
+ if (!track->has_switch && ! (track->flags & GST_MIXER_TRACK_RECORD))
|
||
|
+ return;
|
||
|
+ if (same_volumes (track->num_channels, volumes)) {
|
||
|
+ snd_mixer_selem_set_capture_volume_all (track->element,
|
||
|
+ volumes[0]);
|
||
|
+ } else {
|
||
|
+ for (i = 0; i < track->num_channels; i++)
|
||
|
+ snd_mixer_selem_set_capture_volume (track->element, i,
|
||
|
+ volumes[i]);
|
||
|
+ }
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+void gst_mixer_get_volume (GstMixer *mixer, GstMixerTrack *track, gint *volumes)
|
||
|
+{
|
||
|
+ int i;
|
||
|
+
|
||
|
+ if (!track->has_volume)
|
||
|
+ return;
|
||
|
+
|
||
|
+ track_update (mixer, track);
|
||
|
+ for (i = 0; i < track->num_channels; i++)
|
||
|
+ volumes[i] = track->volumes[i];
|
||
|
+}
|
||
|
+
|
||
|
+void gst_mixer_set_mute (GstMixer *mixer, GstMixerTrack *track, gboolean mute)
|
||
|
+{
|
||
|
+ int i;
|
||
|
+
|
||
|
+ if (track->flags & GST_MIXER_TRACK_INPUT) {
|
||
|
+ if (track->shared_mute)
|
||
|
+ track = track->shared_mute;
|
||
|
+ else
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+ track_update (mixer, track);
|
||
|
+
|
||
|
+ mute = !!mute;
|
||
|
+ if (mute == !! (track->flags & GST_MIXER_TRACK_MUTE))
|
||
|
+ return;
|
||
|
+
|
||
|
+ update_mute (mixer, track, mute);
|
||
|
+
|
||
|
+ if (track->has_switch) {
|
||
|
+ snd_mixer_selem_set_playback_switch_all (track->element, !mute);
|
||
|
+ } else {
|
||
|
+ for (i = 0; i < track->num_channels; i++) {
|
||
|
+ long vol = mute ? track->min_volume : track->volumes[i];
|
||
|
+ snd_mixer_selem_set_playback_volume (track->element, i, vol);
|
||
|
+ }
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+void gst_mixer_set_record (GstMixer * mixer, GstMixerTrack *track, gboolean record)
|
||
|
+{
|
||
|
+ int i;
|
||
|
+
|
||
|
+ if (! (track->flags & GST_MIXER_TRACK_INPUT))
|
||
|
+ return;
|
||
|
+
|
||
|
+ track_update (mixer, track);
|
||
|
+
|
||
|
+ record = !!record;
|
||
|
+ if (record == !! (track->flags & GST_MIXER_TRACK_RECORD))
|
||
|
+ return;
|
||
|
+
|
||
|
+ if (record)
|
||
|
+ track->flags |= GST_MIXER_TRACK_RECORD;
|
||
|
+ else
|
||
|
+ track->flags &= ~GST_MIXER_TRACK_RECORD;
|
||
|
+
|
||
|
+ if (track->has_switch) {
|
||
|
+ snd_mixer_selem_set_capture_switch_all (track->element, record);
|
||
|
+ } else {
|
||
|
+ for (i = 0; i < track->num_channels; i++) {
|
||
|
+ long vol = record ? track->volumes[i] : track->min_volume;
|
||
|
+ snd_mixer_selem_set_capture_volume (track->element, i, vol);
|
||
|
+ }
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+GstMixerMessageType
|
||
|
+gst_mixer_message_get_type (GstMessage * message)
|
||
|
+{
|
||
|
+ const GstStructure *s;
|
||
|
+ const gchar *m_type;
|
||
|
+
|
||
|
+ s = gst_message_get_structure (message);
|
||
|
+ m_type = gst_structure_get_string (s, "type");
|
||
|
+ if (!m_type)
|
||
|
+ return GST_MIXER_MESSAGE_INVALID;
|
||
|
+
|
||
|
+ if (g_str_equal (m_type, "mute-toggled"))
|
||
|
+ return GST_MIXER_MESSAGE_MUTE_TOGGLED;
|
||
|
+ else if (g_str_equal (m_type, "record-toggled"))
|
||
|
+ return GST_MIXER_MESSAGE_RECORD_TOGGLED;
|
||
|
+ else if (g_str_equal (m_type, "volume-changed"))
|
||
|
+ return GST_MIXER_MESSAGE_VOLUME_CHANGED;
|
||
|
+ else if (g_str_equal (m_type, "option-changed"))
|
||
|
+ return GST_MIXER_MESSAGE_OPTION_CHANGED;
|
||
|
+ else if (g_str_equal (m_type, "options-list-changed"))
|
||
|
+ return GST_MIXER_MESSAGE_OPTIONS_LIST_CHANGED;
|
||
|
+ else if (g_str_equal (m_type, "mixer-changed"))
|
||
|
+ return GST_MIXER_MESSAGE_MIXER_CHANGED;
|
||
|
+
|
||
|
+ return GST_MIXER_MESSAGE_INVALID;
|
||
|
+}
|
||
|
+
|
||
|
+static void message_parse_track (const GstStructure *s, GstMixerTrack **track)
|
||
|
+{
|
||
|
+ if (track) {
|
||
|
+ const GValue *v = gst_structure_get_value (s, "track");
|
||
|
+ *track = (GstMixerTrack *)g_value_get_object (v);
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+void gst_mixer_message_parse_mute_toggled (GstMessage *message,
|
||
|
+ GstMixerTrack **track,
|
||
|
+ gboolean *mute)
|
||
|
+{
|
||
|
+ const GstStructure *s = gst_message_get_structure (message);
|
||
|
+
|
||
|
+ message_parse_track (s, track);
|
||
|
+ if (mute)
|
||
|
+ gst_structure_get_boolean (s, "mute", mute);
|
||
|
+}
|
||
|
+
|
||
|
+void gst_mixer_message_parse_record_toggled (GstMessage *message,
|
||
|
+ GstMixerTrack **track,
|
||
|
+ gboolean *record)
|
||
|
+{
|
||
|
+ const GstStructure *s = gst_message_get_structure (message);
|
||
|
+
|
||
|
+ message_parse_track (s, track);
|
||
|
+ if (record)
|
||
|
+ gst_structure_get_boolean (s, "record", record);
|
||
|
+}
|
||
|
+
|
||
|
+void gst_mixer_message_parse_volume_changed (GstMessage *message,
|
||
|
+ GstMixerTrack **track,
|
||
|
+ gint **volumes,
|
||
|
+ gint *num_channels)
|
||
|
+{
|
||
|
+ const GstStructure *s = gst_message_get_structure (message);
|
||
|
+
|
||
|
+ message_parse_track (s, track);
|
||
|
+ if (volumes || num_channels) {
|
||
|
+ gint n_chans, i;
|
||
|
+ const GValue *v = gst_structure_get_value (s, "volumes");
|
||
|
+
|
||
|
+ n_chans = gst_value_array_get_size (v);
|
||
|
+ if (num_channels)
|
||
|
+ *num_channels = n_chans;
|
||
|
+
|
||
|
+ if (volumes) {
|
||
|
+ *volumes = g_new (gint, n_chans);
|
||
|
+ for (i = 0; i < n_chans; i++) {
|
||
|
+ const GValue *e = gst_value_array_get_value (v, i);
|
||
|
+
|
||
|
+ (*volumes)[i] = g_value_get_int (e);
|
||
|
+ }
|
||
|
+ }
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+/*
|
||
|
+ * GstMixerOptions
|
||
|
+ */
|
||
|
+
|
||
|
+G_DEFINE_TYPE (GstMixerOptions, gst_mixer_options, GST_TYPE_MIXER_TRACK);
|
||
|
+
|
||
|
+static GstMixerOptions *
|
||
|
+mixer_options_new (snd_mixer_elem_t *element, int num)
|
||
|
+{
|
||
|
+ GstMixerOptions *opt;
|
||
|
+ GstMixerTrack *track;
|
||
|
+ const char *label;
|
||
|
+ int i;
|
||
|
+
|
||
|
+ label = snd_mixer_selem_get_name (element);
|
||
|
+ opt = g_object_new (GST_TYPE_MIXER_OPTIONS,
|
||
|
+ "untranslated-label", label,
|
||
|
+ "index", snd_mixer_selem_get_index (element),
|
||
|
+ NULL);
|
||
|
+ track = GST_MIXER_TRACK (opt);
|
||
|
+ track->element = element;
|
||
|
+ if (!num)
|
||
|
+ track->label = g_strdup (label);
|
||
|
+ else
|
||
|
+ track->label = g_strdup_printf ("%s %d", label, num);
|
||
|
+
|
||
|
+ num = snd_mixer_selem_get_enum_items (element);
|
||
|
+ for (i = 0; i < num; i++) {
|
||
|
+ char str[256];
|
||
|
+ if (snd_mixer_selem_get_enum_item_name (element, i, sizeof(str), str) < 0)
|
||
|
+ break;
|
||
|
+ opt->values = g_list_append (opt->values, g_strdup (str));
|
||
|
+ }
|
||
|
+
|
||
|
+ return opt;
|
||
|
+}
|
||
|
+
|
||
|
+static void gst_mixer_options_dispose (GObject * object)
|
||
|
+{
|
||
|
+ GstMixerOptions *opt = GST_MIXER_OPTIONS (object);
|
||
|
+
|
||
|
+ g_list_free_full (opt->values, g_free);
|
||
|
+ opt->values = NULL;
|
||
|
+
|
||
|
+ G_OBJECT_CLASS (gst_mixer_options_parent_class)->dispose (object);
|
||
|
+}
|
||
|
+
|
||
|
+static void gst_mixer_options_init (GstMixerOptions *opt)
|
||
|
+{
|
||
|
+}
|
||
|
+
|
||
|
+static void gst_mixer_options_class_init (GstMixerOptionsClass * klass)
|
||
|
+{
|
||
|
+ GObjectClass *object_klass = G_OBJECT_CLASS (klass);
|
||
|
+
|
||
|
+ object_klass->dispose = gst_mixer_options_dispose;
|
||
|
+}
|
||
|
+
|
||
|
+const gchar *gst_mixer_get_option (GstMixer *mixer, GstMixerOptions *opt)
|
||
|
+{
|
||
|
+ unsigned int idx;
|
||
|
+
|
||
|
+ if (snd_mixer_selem_get_enum_item (opt->parent.element, 0, &idx) < 0)
|
||
|
+ return "error";
|
||
|
+ return g_list_nth_data (opt->values, idx);
|
||
|
+}
|
||
|
+
|
||
|
+void gst_mixer_set_option (GstMixer *mixer, GstMixerOptions *opt,
|
||
|
+ gchar *value)
|
||
|
+{
|
||
|
+ int n = 0;
|
||
|
+ GList *item;
|
||
|
+
|
||
|
+ for (item = opt->values; item; item = item->next, n++) {
|
||
|
+ if (!strcmp (item->data, value)) {
|
||
|
+ snd_mixer_selem_set_enum_item (opt->parent.element, 0, n);
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+GList *gst_mixer_options_get_values (GstMixerOptions *opt)
|
||
|
+{
|
||
|
+ return opt->values;
|
||
|
+}
|
||
|
+
|
||
|
+static void message_parse_options (const GstStructure *s,
|
||
|
+ GstMixerOptions ** options)
|
||
|
+{
|
||
|
+ if (options) {
|
||
|
+ const GValue *v = gst_structure_get_value (s, "options");
|
||
|
+ *options = (GstMixerOptions *) g_value_get_object (v);
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+void gst_mixer_message_parse_option_changed (GstMessage *message,
|
||
|
+ GstMixerOptions ** options,
|
||
|
+ const gchar **value)
|
||
|
+{
|
||
|
+ const GstStructure *s = gst_message_get_structure (message);
|
||
|
+
|
||
|
+ message_parse_options (s, options);
|
||
|
+ if (value)
|
||
|
+ *value = gst_structure_get_string (s, "value");
|
||
|
+}
|
||
|
+
|
||
|
+void gst_mixer_message_parse_options_list_changed (GstMessage *message,
|
||
|
+ GstMixerOptions **options)
|
||
|
+{
|
||
|
+ const GstStructure *s = gst_message_get_structure (message);
|
||
|
+
|
||
|
+ message_parse_options (s, options);
|
||
|
+}
|
||
|
+
|
||
|
+/*
|
||
|
+ */
|
||
|
+
|
||
|
+static void create_track_list (GstMixer *mixer)
|
||
|
+{
|
||
|
+ snd_mixer_elem_t *element, *temp;
|
||
|
+ GList *item;
|
||
|
+
|
||
|
+ if (mixer->tracklist)
|
||
|
+ return;
|
||
|
+
|
||
|
+ for (element = snd_mixer_first_elem (mixer->handle); element;
|
||
|
+ element = snd_mixer_elem_next (element)) {
|
||
|
+ GstMixerTrack *play_track = NULL;
|
||
|
+ GstMixerTrack *cap_track = NULL;
|
||
|
+ const gchar *name = snd_mixer_selem_get_name (element);
|
||
|
+ int index = 0;
|
||
|
+ int has_volume, has_switch;
|
||
|
+
|
||
|
+ for (item = mixer->tracklist; item; item = item->next) {
|
||
|
+ temp = GST_MIXER_TRACK (item->data)->element;
|
||
|
+ if (strcmp (name, snd_mixer_selem_get_name (temp)) == 0)
|
||
|
+ index++;
|
||
|
+ }
|
||
|
+
|
||
|
+ has_volume = snd_mixer_selem_has_playback_volume (element);
|
||
|
+ has_switch = snd_mixer_selem_has_playback_switch (element);
|
||
|
+ if (has_volume || has_switch) {
|
||
|
+ play_track = track_new (element, index,
|
||
|
+ GST_MIXER_TRACK_OUTPUT, FALSE);
|
||
|
+ play_track->has_volume = has_volume;
|
||
|
+ play_track->has_switch = has_switch;
|
||
|
+ get_playback_min_max (play_track);
|
||
|
+ }
|
||
|
+
|
||
|
+ has_volume = snd_mixer_selem_has_capture_volume (element);
|
||
|
+ has_switch = snd_mixer_selem_has_capture_switch (element);
|
||
|
+ if (play_track && snd_mixer_selem_has_common_volume (element))
|
||
|
+ has_volume = 0;
|
||
|
+ if (play_track && snd_mixer_selem_has_common_switch (element))
|
||
|
+ has_switch = 0;
|
||
|
+ if (has_volume || has_switch) {
|
||
|
+ cap_track = track_new (element, index,
|
||
|
+ GST_MIXER_TRACK_INPUT,
|
||
|
+ play_track != NULL);
|
||
|
+ cap_track->has_volume = has_volume;
|
||
|
+ cap_track->has_switch = has_switch;
|
||
|
+ get_capture_min_max (cap_track);
|
||
|
+ }
|
||
|
+
|
||
|
+ if (play_track && cap_track) {
|
||
|
+ play_track->shared_mute = cap_track;
|
||
|
+ cap_track->shared_mute = play_track;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (play_track) {
|
||
|
+ track_update (mixer, play_track);
|
||
|
+ mixer->tracklist = g_list_append (mixer->tracklist, play_track);
|
||
|
+ }
|
||
|
+
|
||
|
+ if (cap_track) {
|
||
|
+ track_update (mixer, cap_track);
|
||
|
+ mixer->tracklist = g_list_append (mixer->tracklist, cap_track);
|
||
|
+ }
|
||
|
+
|
||
|
+ if (snd_mixer_selem_is_enumerated (element)) {
|
||
|
+ mixer->tracklist = g_list_append (mixer->tracklist,
|
||
|
+ mixer_options_new (element, index));
|
||
|
+ }
|
||
|
+
|
||
|
+ snd_mixer_elem_set_callback_private (element, mixer);
|
||
|
+ snd_mixer_elem_set_callback (element, mixer_elem_callback);
|
||
|
+ }
|
||
|
+
|
||
|
+ mark_master_track (mixer);
|
||
|
+}
|
||
|
+
|
||
|
+static gboolean mixer_src_callback (gpointer user_data)
|
||
|
+{
|
||
|
+ GstMixer *mixer = (GstMixer *)user_data;
|
||
|
+
|
||
|
+ snd_mixer_handle_events (mixer->handle);
|
||
|
+ return TRUE;
|
||
|
+}
|
||
|
+
|
||
|
+static gboolean mixer_src_dispatch (GSource *source,
|
||
|
+ GSourceFunc callback,
|
||
|
+ gpointer user_data)
|
||
|
+{
|
||
|
+ return callback (user_data);
|
||
|
+}
|
||
|
+
|
||
|
+static void mixer_src_attach (GstMixer *mixer)
|
||
|
+{
|
||
|
+ static GSourceFuncs func = {
|
||
|
+ .dispatch = mixer_src_dispatch,
|
||
|
+ };
|
||
|
+ struct pollfd pfd;
|
||
|
+
|
||
|
+ if (snd_mixer_poll_descriptors (mixer->handle, &pfd, 1) != 1)
|
||
|
+ return;
|
||
|
+
|
||
|
+ mixer->src = g_source_new (&func, sizeof (*mixer->src));
|
||
|
+ g_source_add_unix_fd (mixer->src, pfd.fd, G_IO_IN | G_IO_ERR);
|
||
|
+ g_source_set_callback (mixer->src, mixer_src_callback, mixer, NULL);
|
||
|
+ g_source_attach (mixer->src, g_main_context_default ());
|
||
|
+}
|
||
|
+
|
||
|
+/*
|
||
|
+ * These are new functions that didn't exist in the original gstreamer API;
|
||
|
+ * instead of lengthy probing using factory, just provide a simpler method
|
||
|
+ */
|
||
|
+
|
||
|
+int gst_mixer_new (const char *name, GstMixer **mixer_ret)
|
||
|
+{
|
||
|
+ GstMixer *mixer;
|
||
|
+ snd_hctl_t *hctl;
|
||
|
+ int err;
|
||
|
+
|
||
|
+ mixer = (GstMixer *) g_object_new (GST_TYPE_MIXER, NULL);
|
||
|
+ mixer->name = g_strdup (name);
|
||
|
+
|
||
|
+ err = snd_mixer_open ((snd_mixer_t **) &mixer->handle, 0);
|
||
|
+ if (err < 0)
|
||
|
+ return err;
|
||
|
+
|
||
|
+ err = snd_mixer_attach (mixer->handle, name);
|
||
|
+ if (err < 0)
|
||
|
+ goto error;
|
||
|
+
|
||
|
+ err = snd_mixer_selem_register (mixer->handle, NULL, NULL);
|
||
|
+ if (err < 0)
|
||
|
+ goto error;
|
||
|
+
|
||
|
+ err = snd_mixer_load (mixer->handle);
|
||
|
+ if (err < 0)
|
||
|
+ goto error;
|
||
|
+
|
||
|
+ snd_mixer_get_hctl (mixer->handle, name, &hctl);
|
||
|
+ {
|
||
|
+ snd_ctl_card_info_t *info;
|
||
|
+
|
||
|
+ snd_ctl_card_info_alloca (&info);
|
||
|
+ snd_ctl_card_info (snd_hctl_ctl (hctl), info);
|
||
|
+ mixer->card_name = g_strdup_printf ("%s (Alsa mixer)",
|
||
|
+ snd_ctl_card_info_get_name (info));
|
||
|
+ }
|
||
|
+
|
||
|
+ snd_mixer_set_callback_private (mixer->handle, mixer);
|
||
|
+ snd_mixer_set_callback (mixer->handle, mixer_callback);
|
||
|
+
|
||
|
+ create_track_list (mixer);
|
||
|
+
|
||
|
+ mixer_src_attach (mixer);
|
||
|
+
|
||
|
+ *mixer_ret = mixer;
|
||
|
+ return 0;
|
||
|
+
|
||
|
+ error:
|
||
|
+ gst_object_unref (mixer);
|
||
|
+ return err;
|
||
|
+}
|
||
|
+
|
||
|
+GList *gst_mixer_probe_devices (void)
|
||
|
+{
|
||
|
+ int card = -1;
|
||
|
+ GList *card_list = NULL;
|
||
|
+
|
||
|
+ while (snd_card_next(&card) >= 0 && card >= 0) {
|
||
|
+ GstMixer *mixer;
|
||
|
+ char name [16];
|
||
|
+ int err;
|
||
|
+
|
||
|
+ sprintf (name, "hw:%d", card);
|
||
|
+ err = gst_mixer_new (name, &mixer);
|
||
|
+ if (err < 0)
|
||
|
+ continue;
|
||
|
+ card_list = g_list_append (card_list, mixer);
|
||
|
+ }
|
||
|
+
|
||
|
+ return card_list;
|
||
|
+}
|
||
|
+
|
||
|
+const gchar *gst_mixer_get_card_name (GstMixer *mixer)
|
||
|
+{
|
||
|
+ return mixer->card_name;
|
||
|
+}
|
||
|
--- a/panel-plugin/xfce-plugin-dialog.c
|
||
|
+++ b/panel-plugin/xfce-plugin-dialog.c
|
||
|
@@ -25,8 +25,7 @@
|
||
|
|
||
|
#include <gtk/gtk.h>
|
||
|
|
||
|
-#include <gst/gst.h>
|
||
|
-#include <gst/interfaces/mixer.h>
|
||
|
+#include "../libxfce4mixer/audio.h"
|
||
|
|
||
|
#include <libxfce4ui/libxfce4ui.h>
|
||
|
#include <libxfce4panel/libxfce4panel.h>
|
||
|
--- a/panel-plugin/xfce-plugin-dialog.h
|
||
|
+++ b/panel-plugin/xfce-plugin-dialog.h
|
||
|
@@ -24,8 +24,7 @@
|
||
|
|
||
|
#include <gtk/gtk.h>
|
||
|
|
||
|
-#include <gst/gst.h>
|
||
|
-#include <gst/interfaces/mixer.h>
|
||
|
+#include "../libxfce4mixer/audio.h"
|
||
|
|
||
|
G_BEGIN_DECLS
|
||
|
|
||
|
--- a/xfce4-mixer/xfce-mixer-container.c
|
||
|
+++ b/xfce4-mixer/xfce-mixer-container.c
|
||
|
@@ -23,8 +23,7 @@
|
||
|
#include <config.h>
|
||
|
#endif
|
||
|
|
||
|
-#include <gst/gst.h>
|
||
|
-#include <gst/interfaces/mixer.h>
|
||
|
+#include "../libxfce4mixer/audio.h"
|
||
|
|
||
|
#include <libxfce4util/libxfce4util.h>
|
||
|
#include <libxfce4ui/libxfce4ui.h>
|
||
|
--- a/xfce4-mixer/xfce-mixer-controls-dialog.c
|
||
|
+++ b/xfce4-mixer/xfce-mixer-controls-dialog.c
|
||
|
@@ -23,8 +23,7 @@
|
||
|
#include <config.h>
|
||
|
#endif
|
||
|
|
||
|
-#include <gst/gst.h>
|
||
|
-#include <gst/interfaces/mixer.h>
|
||
|
+#include "../libxfce4mixer/audio.h"
|
||
|
|
||
|
#include <libxfce4util/libxfce4util.h>
|
||
|
#include <libxfce4ui/libxfce4ui.h>
|
||
|
--- a/xfce4-mixer/xfce-mixer-option.c
|
||
|
+++ b/xfce4-mixer/xfce-mixer-option.c
|
||
|
@@ -23,8 +23,7 @@
|
||
|
#include <config.h>
|
||
|
#endif
|
||
|
|
||
|
-#include <gst/gst.h>
|
||
|
-#include <gst/interfaces/mixer.h>
|
||
|
+#include "../libxfce4mixer/audio.h"
|
||
|
|
||
|
#include <libxfce4util/libxfce4util.h>
|
||
|
#include <libxfce4ui/libxfce4ui.h>
|
||
|
--- a/xfce4-mixer/xfce-mixer-switch.c
|
||
|
+++ b/xfce4-mixer/xfce-mixer-switch.c
|
||
|
@@ -23,8 +23,7 @@
|
||
|
#include <config.h>
|
||
|
#endif
|
||
|
|
||
|
-#include <gst/gst.h>
|
||
|
-#include <gst/interfaces/mixer.h>
|
||
|
+#include "../libxfce4mixer/audio.h"
|
||
|
|
||
|
#include <libxfce4util/libxfce4util.h>
|
||
|
#include <libxfce4ui/libxfce4ui.h>
|
||
|
--- a/xfce4-mixer/xfce-mixer-track.c
|
||
|
+++ b/xfce4-mixer/xfce-mixer-track.c
|
||
|
@@ -27,8 +27,7 @@
|
||
|
#include <math.h>
|
||
|
#endif
|
||
|
|
||
|
-#include <gst/gst.h>
|
||
|
-#include <gst/interfaces/mixer.h>
|
||
|
+#include "../libxfce4mixer/audio.h"
|
||
|
|
||
|
#include <libxfce4util/libxfce4util.h>
|
||
|
#include <libxfce4ui/libxfce4ui.h>
|
||
|
--- a/xfce4-mixer/xfce-mixer-window.c
|
||
|
+++ b/xfce4-mixer/xfce-mixer-window.c
|
||
|
@@ -23,9 +23,7 @@
|
||
|
#include <config.h>
|
||
|
#endif
|
||
|
|
||
|
-#include <gst/gst.h>
|
||
|
-#include <gst/audio/mixerutils.h>
|
||
|
-#include <gst/interfaces/mixer.h>
|
||
|
+#include "../libxfce4mixer/audio.h"
|
||
|
|
||
|
#include <libxfce4util/libxfce4util.h>
|
||
|
#include <libxfce4ui/libxfce4ui.h>
|
||
|
--- a/libxfce4mixer/Makefile.am
|
||
|
+++ b/libxfce4mixer/Makefile.am
|
||
|
@@ -17,7 +17,14 @@ libxfce4mixer_la_SOURCES = \
|
||
|
xfce-mixer-preferences.h \
|
||
|
xfce-mixer-preferences.c \
|
||
|
xfce-mixer-debug.h \
|
||
|
- xfce-mixer-debug.c
|
||
|
+ xfce-mixer-debug.c \
|
||
|
+ audio.h
|
||
|
+
|
||
|
+if XFCE4_MIXER_ALSA
|
||
|
+libxfce4mixer_la_SOURCES += \
|
||
|
+ xfce4-mixer-alsa.h \
|
||
|
+ xfce4-mixer-alsa.c
|
||
|
+endif
|
||
|
|
||
|
libxfce4mixer_la_CPPFLAGS = \
|
||
|
-I$(top_builddir) \
|
||
|
@@ -35,7 +42,12 @@ libxfce4mixer_la_CFLAGS = \
|
||
|
$(LIBXFCE4UI_CFLAGS) \
|
||
|
$(XFCONF_CFLAGS) \
|
||
|
$(DBUS_GLIB_CFLAGS) \
|
||
|
- $(GST_PLUGINS_BASE_CFLAGS)
|
||
|
+ $(GST_CFLAGS)
|
||
|
+
|
||
|
+if XFCE4_MIXER_ALSA
|
||
|
+libxfce4mixer_la_CFLAGS += \
|
||
|
+ $(ALSA_CFLAGS)
|
||
|
+endif
|
||
|
|
||
|
libxfce4mixer_la_LDFLAGS = \
|
||
|
-no-undefined
|
||
|
@@ -48,6 +60,13 @@ libxfce4mixer_la_LIBADD = \
|
||
|
$(LIBXFCE4UI_LIBS) \
|
||
|
$(XFCONF_LIBS) \
|
||
|
$(DBUS_GLIB_LIBS) \
|
||
|
- $(GST_PLUGINS_BASE_LIBS) \
|
||
|
+ $(GST_LIBS)
|
||
|
+
|
||
|
+if XFCE4_MIXER_ALSA
|
||
|
+libxfce4mixer_la_LIBADD += \
|
||
|
+ $(ALSA_LIBS)
|
||
|
+else
|
||
|
+libxfce4mixer_la_LIBADD += \
|
||
|
-lgstaudio-0.10 \
|
||
|
-lgstinterfaces-0.10
|
||
|
+endif
|
||
|
--- a/panel-plugin/Makefile.am
|
||
|
+++ b/panel-plugin/Makefile.am
|
||
|
@@ -27,7 +27,7 @@ libmixer_la_CFLAGS = \
|
||
|
$(LIBXFCE4UI_CFLAGS) \
|
||
|
$(LIBXFCE4PANEL_CFLAGS) \
|
||
|
$(XFCONF_CFLAGS) \
|
||
|
- $(GST_PLUGINS_BASE_CFLAGS) \
|
||
|
+ $(GST_CFLAGS) \
|
||
|
$(KEYBINDER_CFLAGS)
|
||
|
|
||
|
libmixer_la_DEPENDENCIES = \
|
||
|
@@ -48,11 +48,18 @@ libmixer_la_LIBADD = \
|
||
|
$(LIBXFCE4UI_LIBS) \
|
||
|
$(LIBXFCE4PANEL_LIBS) \
|
||
|
$(XFCONF_LIBS) \
|
||
|
- $(GST_PLUGINS_BASE_LIBS) \
|
||
|
- -lgstaudio-0.10 \
|
||
|
- -lgstinterfaces-0.10 \
|
||
|
+ $(GST_LIBS) \
|
||
|
$(KEYBINDER_LIBS)
|
||
|
|
||
|
+if XFCE4_MIXER_ALSA
|
||
|
+libmixer_la_LIBADD += \
|
||
|
+ $(ALSA_LIBS)
|
||
|
+else
|
||
|
+libmixer_la_LIBADD += \
|
||
|
+ -lgstaudio-0.10 \
|
||
|
+ -lgstinterfaces-0.10
|
||
|
+endif
|
||
|
+
|
||
|
desktopdir = $(datadir)/xfce4/panel/plugins
|
||
|
|
||
|
desktop_in_files = mixer.desktop.in
|
||
|
--- a/xfce4-mixer/Makefile.am
|
||
|
+++ b/xfce4-mixer/Makefile.am
|
||
|
@@ -34,7 +34,7 @@ xfce4_mixer_CFLAGS = \
|
||
|
$(LIBXFCE4UTIL_CFLAGS) \
|
||
|
$(LIBXFCE4UI_CFLAGS) \
|
||
|
$(XFCONF_CFLAGS) \
|
||
|
- $(GST_PLUGINS_BASE_CFLAGS)
|
||
|
+ $(GST_CFLAGS)
|
||
|
|
||
|
xfce4_mixer_DEPENDENCIES = \
|
||
|
$(top_builddir)/libxfce4mixer/libxfce4mixer.la
|
||
|
@@ -47,9 +47,16 @@ xfce4_mixer_LDFLAGS = \
|
||
|
$(LIBXFCE4UTIL_LIBS) \
|
||
|
$(LIBXFCE4UI_LIBS) \
|
||
|
$(XFCONF_LIBS) \
|
||
|
- $(GST_PLUGINS_BASE_LIBS) \
|
||
|
+ $(GST_LIBS)
|
||
|
+
|
||
|
+if XFCE4_MIXER_ALSA
|
||
|
+xfce4_mixer_LDFLAGS += \
|
||
|
+ $(ALSA_LIBS)
|
||
|
+else
|
||
|
+xfce4_mixer_LDFLAGS += \
|
||
|
-lgstaudio-0.10 \
|
||
|
-lgstinterfaces-0.10
|
||
|
+endif
|
||
|
|
||
|
dist_man_MANS = xfce4-mixer.1
|
||
|
|
||
|
--- /dev/null
|
||
|
+++ b/libxfce4mixer/audio.h
|
||
|
@@ -0,0 +1,8 @@
|
||
|
+#ifdef XFCE4_MIXER_ALSA
|
||
|
+#include <gst/gst.h>
|
||
|
+#include "xfce4-mixer-alsa.h"
|
||
|
+#else
|
||
|
+#include <gst/gst.h>
|
||
|
+#include <gst/interfaces/mixer.h>
|
||
|
+#include <gst/audio/mixerutils.h>
|
||
|
+#endif
|
||
|
--- a/configure.ac.in
|
||
|
+++ b/configure.ac.in
|
||
|
@@ -96,13 +96,29 @@ dnl ***********************************
|
||
|
XDT_CHECK_PACKAGE([GLIB], [glib-2.0], [2.42.0])
|
||
|
XDT_CHECK_PACKAGE([GTHREAD], [gthread-2.0], [2.42.0])
|
||
|
XDT_CHECK_PACKAGE([DBUS_GLIB], [dbus-glib-1], [0.84])
|
||
|
-XDT_CHECK_PACKAGE([GST_PLUGINS_BASE], [gstreamer-plugins-base-0.10], [0.10.25])
|
||
|
XDT_CHECK_PACKAGE([GTK], [gtk+-3.0], [3.14.0])
|
||
|
XDT_CHECK_PACKAGE([LIBXFCE4UTIL], [libxfce4util-1.0], [4.12.0])
|
||
|
XDT_CHECK_PACKAGE([LIBXFCE4UI], [libxfce4ui-2], [4.12.0])
|
||
|
XDT_CHECK_PACKAGE([LIBXFCE4PANEL], [libxfce4panel-2.0], [4.12.0])
|
||
|
XDT_CHECK_PACKAGE([XFCONF], [libxfconf-0], [4.12.0])
|
||
|
|
||
|
+AC_MSG_CHECKING(for audio engine)
|
||
|
+AC_ARG_WITH(audio,
|
||
|
+ AS_HELP_STRING([--with-audio],
|
||
|
+ [audio engine, either gstmixer or alsa (default)]),
|
||
|
+ audio="$withval", audio="alsa")
|
||
|
+
|
||
|
+if test "$audio" = "gstmixer"; then
|
||
|
+ AC_MSG_RESULT(gstreamer-0.10 native mixer)
|
||
|
+ XDT_CHECK_PACKAGE([GST], [gstreamer-plugins-base-0.10], [0.10.25])
|
||
|
+else
|
||
|
+ AC_MSG_RESULT(gstreamer-1.0 ALSA mixer)
|
||
|
+ XDT_CHECK_PACKAGE([GST], [gstreamer-1.0], [1.0])
|
||
|
+ XDT_CHECK_PACKAGE([ALSA], [alsa], [0.9])
|
||
|
+ AC_DEFINE([XFCE4_MIXER_ALSA], 1, [Built-in ALSA-based gstreamer mixer i/f])
|
||
|
+fi
|
||
|
+AM_CONDITIONAL([XFCE4_MIXER_ALSA], [test x"$audio" != x"gstmixer"])
|
||
|
+
|
||
|
dnl ***********************************
|
||
|
dnl *** Check for optional packages ***
|
||
|
dnl
|