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
29 #include "pulsemixer.h"
38 GST_DEBUG_CATEGORY_EXTERN (pulse_debug);
39 #define GST_CAT_DEFAULT pulse_debug
41 static void gst_pulsemixer_set_property (GObject * object, guint prop_id,
42 const GValue * value, GParamSpec * pspec);
43 static void gst_pulsemixer_get_property (GObject * object, guint prop_id,
44 GValue * value, GParamSpec * pspec);
45 static void gst_pulsemixer_finalize (GObject * object);
47 static GstStateChangeReturn gst_pulsemixer_change_state (GstElement * element,
48 GstStateChange transition);
50 static void gst_pulsemixer_init_interfaces (GType type);
52 GST_IMPLEMENT_PULSEMIXER_CTRL_METHODS (GstPulseMixer, gst_pulsemixer);
53 GST_IMPLEMENT_PULSEPROBE_METHODS (GstPulseMixer, gst_pulsemixer);
54 GST_BOILERPLATE_FULL (GstPulseMixer, gst_pulsemixer, GstElement,
55 GST_TYPE_ELEMENT, gst_pulsemixer_init_interfaces);
58 gst_pulsemixer_interface_supported (GstImplementsInterface
59 * iface, GType interface_type)
61 GstPulseMixer *this = GST_PULSEMIXER (iface);
63 if (interface_type == GST_TYPE_MIXER && this->mixer)
66 if (interface_type == GST_TYPE_PROPERTY_PROBE && this->probe)
73 gst_pulsemixer_implements_interface_init (GstImplementsInterfaceClass * klass)
75 klass->supported = gst_pulsemixer_interface_supported;
79 gst_pulsemixer_init_interfaces (GType type)
81 static const GInterfaceInfo implements_iface_info = {
82 (GInterfaceInitFunc) gst_pulsemixer_implements_interface_init,
86 static const GInterfaceInfo mixer_iface_info = {
87 (GInterfaceInitFunc) gst_pulsemixer_mixer_interface_init,
91 static const GInterfaceInfo probe_iface_info = {
92 (GInterfaceInitFunc) gst_pulsemixer_property_probe_interface_init,
97 g_type_add_interface_static (type, GST_TYPE_IMPLEMENTS_INTERFACE,
98 &implements_iface_info);
99 g_type_add_interface_static (type, GST_TYPE_MIXER, &mixer_iface_info);
100 g_type_add_interface_static (type, GST_TYPE_PROPERTY_PROBE,
105 gst_pulsemixer_base_init (gpointer g_class)
108 static const GstElementDetails details =
109 GST_ELEMENT_DETAILS ("PulseAudio Mixer",
111 "Control sound input and output levels for PulseAudio",
112 "Lennart Poettering");
114 gst_element_class_set_details (GST_ELEMENT_CLASS (g_class), &details);
118 gst_pulsemixer_class_init (GstPulseMixerClass * g_class)
120 GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
122 GObjectClass *gobject_class = G_OBJECT_CLASS (g_class);
124 gstelement_class->change_state =
125 GST_DEBUG_FUNCPTR (gst_pulsemixer_change_state);
127 gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_pulsemixer_finalize);
128 gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_pulsemixer_get_property);
129 gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_pulsemixer_set_property);
131 g_object_class_install_property (gobject_class,
133 g_param_spec_string ("server", "Server",
134 "The PulseAudio server to connect to", NULL, G_PARAM_READWRITE));
136 g_object_class_install_property (gobject_class,
138 g_param_spec_string ("device", "Sink/Source",
139 "The PulseAudio sink or source to control", NULL, G_PARAM_READWRITE));
141 g_object_class_install_property (gobject_class,
143 g_param_spec_string ("device-name", "Device name",
144 "Human-readable name of the sound device", NULL, G_PARAM_READABLE));
148 gst_pulsemixer_init (GstPulseMixer * this, GstPulseMixerClass * g_class)
155 gst_pulseprobe_new (G_OBJECT_GET_CLASS (this), PROP_DEVICE, this->device,
160 gst_pulsemixer_finalize (GObject * object)
162 GstPulseMixer *this = GST_PULSEMIXER (object);
164 g_free (this->server);
165 g_free (this->device);
168 gst_pulsemixer_ctrl_free (this->mixer);
173 gst_pulseprobe_free (this->probe);
177 G_OBJECT_CLASS (parent_class)->finalize (object);
181 gst_pulsemixer_set_property (GObject * object,
182 guint prop_id, const GValue * value, GParamSpec * pspec)
185 GstPulseMixer *this = GST_PULSEMIXER (object);
189 g_free (this->server);
190 this->server = g_value_dup_string (value);
194 g_free (this->device);
195 this->device = g_value_dup_string (value);
198 gst_pulseprobe_set_server (this->probe, this->device);
203 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
209 gst_pulsemixer_get_property (GObject * object,
210 guint prop_id, GValue * value, GParamSpec * pspec)
213 GstPulseMixer *this = GST_PULSEMIXER (object);
218 g_value_set_string (value, this->server);
222 g_value_set_string (value, this->device);
225 case PROP_DEVICE_NAME:
228 char *t = g_strdup_printf ("%s: %s",
229 this->mixer->type == GST_PULSEMIXER_SINK ? "Playback" : "Capture",
230 this->mixer->description);
232 g_value_set_string (value, t);
235 g_value_set_string (value, NULL);
240 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
245 static GstStateChangeReturn
246 gst_pulsemixer_change_state (GstElement * element, GstStateChange transition)
248 GstPulseMixer *this = GST_PULSEMIXER (element);
250 switch (transition) {
251 case GST_STATE_CHANGE_NULL_TO_READY:
255 gst_pulsemixer_ctrl_new (this->server, this->device,
256 GST_PULSEMIXER_UNKNOWN);
260 case GST_STATE_CHANGE_READY_TO_NULL:
263 gst_pulsemixer_ctrl_free (this->mixer);
273 if (GST_ELEMENT_CLASS (parent_class)->change_state)
274 return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
276 return GST_STATE_CHANGE_SUCCESS;