2 * GStreamer pulseaudio plugin
4 * Copyright (c) 2004-2008 Lennart Poettering
6 * gst-pulse is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as
8 * published by the Free Software Foundation; either version 2.1 of the
9 * License, or (at your option) any later version.
11 * gst-pulse is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with gst-pulse; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
23 * SECTION:element-pulsemixer
24 * @short_description: Element to control sound input and output levels for the PulseAudio sound server
25 * @see_also: pulsesrc, pulsesink
29 * This element lets you adjust sound input and output levels for the
30 * PulseAudio sound server. It supports the GstMixer interface, which can be
31 * used to obtain a list of available mixer tracks. Set the mixer element to
32 * READY state before using the GstMixer interface on it.
34 * <title>Example pipelines</title>
36 * pulsemixer can't be used in a sensible way in gst-launch.
48 #include "pulsemixer.h"
57 GST_DEBUG_CATEGORY_EXTERN (pulse_debug);
58 #define GST_CAT_DEFAULT pulse_debug
60 static void gst_pulsemixer_set_property (GObject * object, guint prop_id,
61 const GValue * value, GParamSpec * pspec);
62 static void gst_pulsemixer_get_property (GObject * object, guint prop_id,
63 GValue * value, GParamSpec * pspec);
64 static void gst_pulsemixer_finalize (GObject * object);
66 static GstStateChangeReturn gst_pulsemixer_change_state (GstElement * element,
67 GstStateChange transition);
69 static void gst_pulsemixer_init_interfaces (GType type);
71 GST_IMPLEMENT_PULSEMIXER_CTRL_METHODS (GstPulseMixer, gst_pulsemixer);
72 GST_IMPLEMENT_PULSEPROBE_METHODS (GstPulseMixer, gst_pulsemixer);
73 GST_BOILERPLATE_FULL (GstPulseMixer, gst_pulsemixer, GstElement,
74 GST_TYPE_ELEMENT, gst_pulsemixer_init_interfaces);
77 gst_pulsemixer_interface_supported (GstImplementsInterface
78 * iface, GType interface_type)
80 GstPulseMixer *this = GST_PULSEMIXER (iface);
82 if (interface_type == GST_TYPE_MIXER && this->mixer)
85 if (interface_type == GST_TYPE_PROPERTY_PROBE && this->probe)
92 gst_pulsemixer_implements_interface_init (GstImplementsInterfaceClass * klass)
94 klass->supported = gst_pulsemixer_interface_supported;
98 gst_pulsemixer_init_interfaces (GType type)
100 static const GInterfaceInfo implements_iface_info = {
101 (GInterfaceInitFunc) gst_pulsemixer_implements_interface_init,
105 static const GInterfaceInfo mixer_iface_info = {
106 (GInterfaceInitFunc) gst_pulsemixer_mixer_interface_init,
110 static const GInterfaceInfo probe_iface_info = {
111 (GInterfaceInitFunc) gst_pulsemixer_property_probe_interface_init,
116 g_type_add_interface_static (type, GST_TYPE_IMPLEMENTS_INTERFACE,
117 &implements_iface_info);
118 g_type_add_interface_static (type, GST_TYPE_MIXER, &mixer_iface_info);
119 g_type_add_interface_static (type, GST_TYPE_PROPERTY_PROBE,
124 gst_pulsemixer_base_init (gpointer g_class)
127 static const GstElementDetails details =
128 GST_ELEMENT_DETAILS ("PulseAudio Mixer",
130 "Control sound input and output levels for PulseAudio",
131 "Lennart Poettering");
133 gst_element_class_set_details (GST_ELEMENT_CLASS (g_class), &details);
137 gst_pulsemixer_class_init (GstPulseMixerClass * g_class)
139 GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
141 GObjectClass *gobject_class = G_OBJECT_CLASS (g_class);
143 gstelement_class->change_state =
144 GST_DEBUG_FUNCPTR (gst_pulsemixer_change_state);
146 gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_pulsemixer_finalize);
147 gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_pulsemixer_get_property);
148 gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_pulsemixer_set_property);
150 g_object_class_install_property (gobject_class,
152 g_param_spec_string ("server", "Server",
153 "The PulseAudio server to connect to", NULL, G_PARAM_READWRITE));
155 g_object_class_install_property (gobject_class,
157 g_param_spec_string ("device", "Sink/Source",
158 "The PulseAudio sink or source to control", NULL, G_PARAM_READWRITE));
160 g_object_class_install_property (gobject_class,
162 g_param_spec_string ("device-name", "Device name",
163 "Human-readable name of the sound device", NULL, G_PARAM_READABLE));
167 gst_pulsemixer_init (GstPulseMixer * this, GstPulseMixerClass * g_class)
174 gst_pulseprobe_new (G_OBJECT_GET_CLASS (this), PROP_DEVICE, this->device,
179 gst_pulsemixer_finalize (GObject * object)
181 GstPulseMixer *this = GST_PULSEMIXER (object);
183 g_free (this->server);
184 g_free (this->device);
187 gst_pulsemixer_ctrl_free (this->mixer);
192 gst_pulseprobe_free (this->probe);
196 G_OBJECT_CLASS (parent_class)->finalize (object);
200 gst_pulsemixer_set_property (GObject * object,
201 guint prop_id, const GValue * value, GParamSpec * pspec)
204 GstPulseMixer *this = GST_PULSEMIXER (object);
208 g_free (this->server);
209 this->server = g_value_dup_string (value);
213 g_free (this->device);
214 this->device = g_value_dup_string (value);
217 gst_pulseprobe_set_server (this->probe, this->device);
222 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
228 gst_pulsemixer_get_property (GObject * object,
229 guint prop_id, GValue * value, GParamSpec * pspec)
232 GstPulseMixer *this = GST_PULSEMIXER (object);
237 g_value_set_string (value, this->server);
241 g_value_set_string (value, this->device);
244 case PROP_DEVICE_NAME:
247 char *t = g_strdup_printf ("%s: %s",
248 this->mixer->type == GST_PULSEMIXER_SINK ? "Playback" : "Capture",
249 this->mixer->description);
251 g_value_set_string (value, t);
254 g_value_set_string (value, NULL);
259 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
264 static GstStateChangeReturn
265 gst_pulsemixer_change_state (GstElement * element, GstStateChange transition)
267 GstPulseMixer *this = GST_PULSEMIXER (element);
269 switch (transition) {
270 case GST_STATE_CHANGE_NULL_TO_READY:
274 gst_pulsemixer_ctrl_new (this->server, this->device,
275 GST_PULSEMIXER_UNKNOWN);
279 case GST_STATE_CHANGE_READY_TO_NULL:
282 gst_pulsemixer_ctrl_free (this->mixer);
292 if (GST_ELEMENT_CLASS (parent_class)->change_state)
293 return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
295 return GST_STATE_CHANGE_SUCCESS;