fix tabs
[gst-pulse.git] / src / pulsemixer.c
blob3352c1d0f871c76874af1a6cf1bbf388810858f1
1 /* $Id$ */
3 /***
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
19 USA.
20 ***/
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
26 #include <string.h>
27 #include <stdio.h>
29 #include "pulsemixer.h"
31 enum {
32 PROP_SERVER = 1,
33 PROP_DEVICE,
34 PROP_DEVICE_NAME
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)
55 return TRUE;
57 if (interface_type == GST_TYPE_PROPERTY_PROBE && this->probe)
58 return TRUE;
60 return FALSE;
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,
70 NULL,
71 NULL,
73 static const GInterfaceInfo mixer_iface_info = {
74 (GInterfaceInitFunc) gst_pulsemixer_mixer_interface_init,
75 NULL,
76 NULL,
78 static const GInterfaceInfo probe_iface_info = {
79 (GInterfaceInitFunc) gst_pulsemixer_property_probe_interface_init,
80 NULL,
81 NULL,
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 =
92 GST_ELEMENT_DETAILS(
93 "PulseAudio Mixer",
94 "Generic/Audio",
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(
112 gobject_class,
113 PROP_SERVER,
114 g_param_spec_string("server", "Server", "The PulseAudio server to connect to", NULL, G_PARAM_READWRITE));
116 g_object_class_install_property(
117 gobject_class,
118 PROP_DEVICE,
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(
122 gobject_class,
123 PROP_DEVICE_NAME,
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) {
128 this->mixer = NULL;
129 this->server = NULL;
130 this->device = NULL;
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);
141 if (this->mixer) {
142 gst_pulsemixer_ctrl_free(this->mixer);
143 this->mixer = NULL;
146 if (this->probe) {
147 gst_pulseprobe_free(this->probe);
148 this->probe = NULL;
151 G_OBJECT_CLASS(parent_class)->finalize(object);
154 static void gst_pulsemixer_set_property(
155 GObject * object,
156 guint prop_id,
157 const GValue * value,
158 GParamSpec * pspec) {
160 GstPulseMixer *this = GST_PULSEMIXER(object);
162 switch (prop_id) {
163 case PROP_SERVER:
164 g_free(this->server);
165 this->server = g_value_dup_string(value);
166 break;
168 case PROP_DEVICE:
169 g_free(this->device);
170 this->device = g_value_dup_string(value);
172 if (this->probe)
173 gst_pulseprobe_set_server(this->probe, this->device);
175 break;
177 default:
178 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
179 break;
183 static void gst_pulsemixer_get_property(
184 GObject * object,
185 guint prop_id,
186 GValue * value,
187 GParamSpec * pspec) {
189 GstPulseMixer *this = GST_PULSEMIXER(object);
191 switch(prop_id) {
193 case PROP_SERVER:
194 g_value_set_string(value, this->server);
195 break;
197 case PROP_DEVICE:
198 g_value_set_string(value, this->device);
199 break;
201 case PROP_DEVICE_NAME:
203 if (this->mixer) {
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);
206 g_free(t);
207 } else
208 g_value_set_string(value, NULL);
210 break;
212 default:
213 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
214 break;
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:
224 if (!this->mixer)
225 this->mixer = gst_pulsemixer_ctrl_new(this->server, this->device, GST_PULSEMIXER_UNKNOWN);
227 break;
229 case GST_STATE_CHANGE_READY_TO_NULL:
231 if (this->mixer) {
232 gst_pulsemixer_ctrl_free(this->mixer);
233 this->mixer = NULL;
236 break;
238 default:
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;