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 * @see_also: pulsesrc, pulsesink
26 * This element lets you adjust sound input and output levels for the
27 * PulseAudio sound server. It supports the GstMixer interface, which can be
28 * used to obtain a list of available mixer tracks. Set the mixer element to
29 * READY state before using the GstMixer interface on it.
32 * <title>Example pipelines</title>
34 * pulsemixer can't be used in a sensible way in gst-launch.
46 #include "pulsemixer.h"
55 GST_DEBUG_CATEGORY_EXTERN (pulse_debug);
56 #define GST_CAT_DEFAULT pulse_debug
58 static void gst_pulsemixer_set_property (GObject * object, guint prop_id,
59 const GValue * value, GParamSpec * pspec);
60 static void gst_pulsemixer_get_property (GObject * object, guint prop_id,
61 GValue * value, GParamSpec * pspec);
62 static void gst_pulsemixer_finalize (GObject * object);
64 static GstStateChangeReturn gst_pulsemixer_change_state (GstElement * element,
65 GstStateChange transition);
67 static void gst_pulsemixer_init_interfaces (GType type);
69 GST_IMPLEMENT_PULSEMIXER_CTRL_METHODS (GstPulseMixer, gst_pulsemixer);
70 GST_IMPLEMENT_PULSEPROBE_METHODS (GstPulseMixer, gst_pulsemixer);
71 GST_BOILERPLATE_FULL (GstPulseMixer, gst_pulsemixer, GstElement,
72 GST_TYPE_ELEMENT, gst_pulsemixer_init_interfaces);
75 gst_pulsemixer_interface_supported (GstImplementsInterface
76 * iface, GType interface_type)
78 GstPulseMixer *this = GST_PULSEMIXER (iface);
80 if (interface_type == GST_TYPE_MIXER && this->mixer)
83 if (interface_type == GST_TYPE_PROPERTY_PROBE && this->probe)
90 gst_pulsemixer_implements_interface_init (GstImplementsInterfaceClass * klass)
92 klass->supported = gst_pulsemixer_interface_supported;
96 gst_pulsemixer_init_interfaces (GType type)
98 static const GInterfaceInfo implements_iface_info = {
99 (GInterfaceInitFunc) gst_pulsemixer_implements_interface_init,
103 static const GInterfaceInfo mixer_iface_info = {
104 (GInterfaceInitFunc) gst_pulsemixer_mixer_interface_init,
108 static const GInterfaceInfo probe_iface_info = {
109 (GInterfaceInitFunc) gst_pulsemixer_property_probe_interface_init,
114 g_type_add_interface_static (type, GST_TYPE_IMPLEMENTS_INTERFACE,
115 &implements_iface_info);
116 g_type_add_interface_static (type, GST_TYPE_MIXER, &mixer_iface_info);
117 g_type_add_interface_static (type, GST_TYPE_PROPERTY_PROBE,
122 gst_pulsemixer_base_init (gpointer g_class)
124 gst_element_class_set_details_simple (GST_ELEMENT_CLASS (g_class),
127 "Control sound input and output levels for PulseAudio",
128 "Lennart Poettering");
132 gst_pulsemixer_class_init (GstPulseMixerClass * g_class)
134 GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
135 GObjectClass *gobject_class = G_OBJECT_CLASS (g_class);
137 gstelement_class->change_state =
138 GST_DEBUG_FUNCPTR (gst_pulsemixer_change_state);
140 gobject_class->finalize = gst_pulsemixer_finalize;
141 gobject_class->get_property = gst_pulsemixer_get_property;
142 gobject_class->set_property = gst_pulsemixer_set_property;
144 g_object_class_install_property (gobject_class,
146 g_param_spec_string ("server", "Server",
147 "The PulseAudio server to connect to", NULL,
148 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
150 g_object_class_install_property (gobject_class,
152 g_param_spec_string ("device", "Device",
153 "The PulseAudio sink or source to control", NULL,
154 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
156 g_object_class_install_property (gobject_class,
158 g_param_spec_string ("device-name", "Device name",
159 "Human-readable name of the sound device", NULL,
160 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
164 gst_pulsemixer_init (GstPulseMixer * this, GstPulseMixerClass * g_class)
171 gst_pulseprobe_new (G_OBJECT (this), G_OBJECT_GET_CLASS (this),
172 PROP_DEVICE, this->device, TRUE, TRUE);
176 gst_pulsemixer_finalize (GObject * object)
178 GstPulseMixer *this = GST_PULSEMIXER (object);
180 g_free (this->server);
181 g_free (this->device);
184 gst_pulsemixer_ctrl_free (this->mixer);
189 gst_pulseprobe_free (this->probe);
193 G_OBJECT_CLASS (parent_class)->finalize (object);
197 gst_pulsemixer_set_property (GObject * object,
198 guint prop_id, const GValue * value, GParamSpec * pspec)
200 GstPulseMixer *this = GST_PULSEMIXER (object);
204 g_free (this->server);
205 this->server = g_value_dup_string (value);
208 gst_pulseprobe_set_server (this->probe, this->server);
213 g_free (this->device);
214 this->device = g_value_dup_string (value);
218 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
224 gst_pulsemixer_get_property (GObject * object,
225 guint prop_id, GValue * value, GParamSpec * pspec)
227 GstPulseMixer *this = GST_PULSEMIXER (object);
231 g_value_set_string (value, this->server);
234 g_value_set_string (value, this->device);
236 case PROP_DEVICE_NAME:
238 char *t = g_strdup_printf ("%s: %s",
239 this->mixer->type == GST_PULSEMIXER_SINK ? "Playback" : "Capture",
240 this->mixer->description);
241 g_value_take_string (value, t);
243 g_value_set_string (value, NULL);
246 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
251 static GstStateChangeReturn
252 gst_pulsemixer_change_state (GstElement * element, GstStateChange transition)
254 GstPulseMixer *this = GST_PULSEMIXER (element);
255 GstStateChangeReturn res;
257 switch (transition) {
258 case GST_STATE_CHANGE_NULL_TO_READY:
261 gst_pulsemixer_ctrl_new (G_OBJECT (this), this->server,
262 this->device, GST_PULSEMIXER_UNKNOWN);
268 res = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
270 switch (transition) {
271 case GST_STATE_CHANGE_READY_TO_NULL:
273 gst_pulsemixer_ctrl_free (this->mixer);