4 This file is part of gst-pulse.
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"
37 GST_DEBUG_CATEGORY_EXTERN(pulse_debug
);
38 #define GST_CAT_DEFAULT pulse_debug
40 static void gst_pulsemixer_set_property(GObject
*object
, guint prop_id
, const GValue
*value
, GParamSpec
*pspec
);
41 static void gst_pulsemixer_get_property(GObject
*object
, guint prop_id
, GValue
*value
, GParamSpec
*pspec
);
42 static void gst_pulsemixer_finalize(GObject
*object
);
43 static GstStateChangeReturn
gst_pulsemixer_change_state(GstElement
*element
, GstStateChange transition
);
45 static void gst_pulsemixer_init_interfaces(GType type
);
47 GST_IMPLEMENT_PULSEMIXER_CTRL_METHODS(GstPulseMixer
, gst_pulsemixer
)
48 GST_IMPLEMENT_PULSEPROBE_METHODS(GstPulseMixer
, gst_pulsemixer
)
49 GST_BOILERPLATE_FULL(GstPulseMixer
, gst_pulsemixer
, GstElement
, GST_TYPE_ELEMENT
, gst_pulsemixer_init_interfaces
)
51 static gboolean
gst_pulsemixer_interface_supported(GstImplementsInterface
* iface
, GType interface_type
) {
52 GstPulseMixer
*this = GST_PULSEMIXER(iface
);
54 if (interface_type
== GST_TYPE_MIXER
&& this->mixer
)
57 if (interface_type
== GST_TYPE_PROPERTY_PROBE
&& this->probe
)
63 static void gst_pulsemixer_implements_interface_init(GstImplementsInterfaceClass
* klass
) {
64 klass
->supported
= gst_pulsemixer_interface_supported
;
67 static void gst_pulsemixer_init_interfaces(GType type
) {
68 static const GInterfaceInfo implements_iface_info
= {
69 (GInterfaceInitFunc
) gst_pulsemixer_implements_interface_init
,
73 static const GInterfaceInfo mixer_iface_info
= {
74 (GInterfaceInitFunc
) gst_pulsemixer_mixer_interface_init
,
78 static const GInterfaceInfo probe_iface_info
= {
79 (GInterfaceInitFunc
) gst_pulsemixer_property_probe_interface_init
,
84 g_type_add_interface_static(type
, GST_TYPE_IMPLEMENTS_INTERFACE
, &implements_iface_info
);
85 g_type_add_interface_static(type
, GST_TYPE_MIXER
, &mixer_iface_info
);
86 g_type_add_interface_static(type
, GST_TYPE_PROPERTY_PROBE
, &probe_iface_info
);
89 static void gst_pulsemixer_base_init(gpointer g_class
) {
91 static const GstElementDetails details
=
95 "Control sound input and output levels for PulseAudio",
96 "Lennart Poettering");
98 gst_element_class_set_details(GST_ELEMENT_CLASS(g_class
), &details
);
101 static void gst_pulsemixer_class_init(GstPulseMixerClass
*g_class
) {
102 GstElementClass
*gstelement_class
= GST_ELEMENT_CLASS(g_class
);
103 GObjectClass
*gobject_class
= G_OBJECT_CLASS(g_class
);
105 gstelement_class
->change_state
= GST_DEBUG_FUNCPTR(gst_pulsemixer_change_state
);
107 gobject_class
->finalize
= GST_DEBUG_FUNCPTR(gst_pulsemixer_finalize
);
108 gobject_class
->get_property
= GST_DEBUG_FUNCPTR(gst_pulsemixer_get_property
);
109 gobject_class
->set_property
= GST_DEBUG_FUNCPTR(gst_pulsemixer_set_property
);
111 g_object_class_install_property(
114 g_param_spec_string("server", "Server", "The PulseAudio server to connect to", NULL
, G_PARAM_READWRITE
));
116 g_object_class_install_property(
119 g_param_spec_string("device", "Sink/Source", "The PulseAudio sink or source to control", NULL
, G_PARAM_READWRITE
));
121 g_object_class_install_property(
124 g_param_spec_string("device-name", "Device name", "Human-readable name of the sound device", NULL
, G_PARAM_READABLE
));
127 static void gst_pulsemixer_init(GstPulseMixer
*this, GstPulseMixerClass
*g_class
) {
132 this->probe
= gst_pulseprobe_new(G_OBJECT_GET_CLASS(this), PROP_DEVICE
, this->device
, TRUE
, TRUE
);
135 static void gst_pulsemixer_finalize(GObject
*object
) {
136 GstPulseMixer
*this = GST_PULSEMIXER(object
);
138 g_free(this->server
);
139 g_free(this->device
);
142 gst_pulsemixer_ctrl_free(this->mixer
);
147 gst_pulseprobe_free(this->probe
);
151 G_OBJECT_CLASS(parent_class
)->finalize(object
);
154 static void gst_pulsemixer_set_property(
157 const GValue
* value
,
158 GParamSpec
* pspec
) {
160 GstPulseMixer
*this = GST_PULSEMIXER(object
);
164 g_free(this->server
);
165 this->server
= g_value_dup_string(value
);
169 g_free(this->device
);
170 this->device
= g_value_dup_string(value
);
173 gst_pulseprobe_set_server(this->probe
, this->device
);
178 G_OBJECT_WARN_INVALID_PROPERTY_ID(object
, prop_id
, pspec
);
183 static void gst_pulsemixer_get_property(
187 GParamSpec
* pspec
) {
189 GstPulseMixer
*this = GST_PULSEMIXER(object
);
194 g_value_set_string(value
, this->server
);
198 g_value_set_string(value
, this->device
);
201 case PROP_DEVICE_NAME
:
204 char *t
= g_strdup_printf("%s: %s", this->mixer
->type
== GST_PULSEMIXER_SINK
? "Playback" : "Capture", this->mixer
->description
);
205 g_value_set_string(value
, t
);
208 g_value_set_string(value
, NULL
);
213 G_OBJECT_WARN_INVALID_PROPERTY_ID(object
, prop_id
, pspec
);
218 static GstStateChangeReturn
gst_pulsemixer_change_state(GstElement
*element
, GstStateChange transition
) {
219 GstPulseMixer
*this = GST_PULSEMIXER(element
);
221 switch (transition
) {
222 case GST_STATE_CHANGE_NULL_TO_READY
:
225 this->mixer
= gst_pulsemixer_ctrl_new(this->server
, this->device
, GST_PULSEMIXER_UNKNOWN
);
229 case GST_STATE_CHANGE_READY_TO_NULL
:
232 gst_pulsemixer_ctrl_free(this->mixer
);
242 if (GST_ELEMENT_CLASS(parent_class
)->change_state
)
243 return GST_ELEMENT_CLASS(parent_class
)->change_state(element
, transition
);
245 return GST_STATE_CHANGE_SUCCESS
;