Update and add documentation for platform specific plugins (sys).
[platform/upstream/gst-plugins-good.git] / sys / oss / gstossmixerelement.c
1 /* OSS mixer interface element.
2  * Copyright (C) 2005 Andrew Vander Wingo <wingo@pobox.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /**
21  * SECTION:element-ossmixer
22  *
23  * This element lets you adjust sound input and output levels with the
24  * Open Sound System (OSS). It supports the #GstMixer interface, which can be
25  * used to obtain a list of available mixer tracks. Set the mixer element to
26  * READY state before using the #GstMixer interface on it.
27  *
28  * <refsect2>
29  * <title>Example pipelines</title>
30  * <para>
31  * ossmixer can't be used in a sensible way in gst-launch.
32  * </para>
33  * </refsect2>
34  */
35
36 #ifdef HAVE_CONFIG_H
37 #include "config.h"
38 #endif
39
40 #include "gstossmixerelement.h"
41
42 GST_DEBUG_CATEGORY_EXTERN (oss_debug);
43 #define GST_CAT_DEFAULT oss_debug
44
45 #define DEFAULT_DEVICE       "/dev/mixer"
46 #define DEFAULT_DEVICE_NAME  NULL
47
48 enum
49 {
50   PROP_0,
51   PROP_DEVICE,
52   PROP_DEVICE_NAME
53 };
54
55
56 static const GstElementDetails gst_oss_mixer_element_details =
57 GST_ELEMENT_DETAILS ("OSS Mixer",
58     "Generic/Audio",
59     "Control sound input and output levels with OSS",
60     "Andrew Vander Wingo <wingo@pobox.com>");
61
62
63 GST_BOILERPLATE_WITH_INTERFACE (GstOssMixerElement, gst_oss_mixer_element,
64     GstElement, GST_TYPE_ELEMENT, GstMixer, GST_TYPE_MIXER,
65     gst_oss_mixer_element);
66
67 GST_IMPLEMENT_OSS_MIXER_METHODS (GstOssMixerElement, gst_oss_mixer_element);
68
69 static GstStateChangeReturn gst_oss_mixer_element_change_state (GstElement *
70     element, GstStateChange transition);
71
72 static void gst_oss_mixer_element_set_property (GObject * object,
73     guint prop_id, const GValue * value, GParamSpec * pspec);
74 static void gst_oss_mixer_element_get_property (GObject * object,
75     guint prop_id, GValue * value, GParamSpec * pspec);
76 static void gst_oss_mixer_element_finalize (GObject * object);
77
78 static void
79 gst_oss_mixer_element_base_init (gpointer klass)
80 {
81   gst_element_class_set_details (GST_ELEMENT_CLASS (klass),
82       &gst_oss_mixer_element_details);
83 }
84
85 static void
86 gst_oss_mixer_element_class_init (GstOssMixerElementClass * klass)
87 {
88   GstElementClass *element_class;
89   GObjectClass *gobject_class;
90
91   element_class = (GstElementClass *) klass;
92   gobject_class = (GObjectClass *) klass;
93
94   gobject_class->finalize = gst_oss_mixer_element_finalize;
95   gobject_class->set_property = gst_oss_mixer_element_set_property;
96   gobject_class->get_property = gst_oss_mixer_element_get_property;
97
98   /**
99    * GstOssMixerElement:device
100    *
101    * OSS mixer device (usually /dev/mixer)
102    *
103    * Since: 0.10.5
104    **/
105   g_object_class_install_property (gobject_class, PROP_DEVICE,
106       g_param_spec_string ("device", "Device",
107           "OSS mixer device (usually /dev/mixer)", DEFAULT_DEVICE,
108           G_PARAM_READWRITE));
109
110   g_object_class_install_property (gobject_class, PROP_DEVICE_NAME,
111       g_param_spec_string ("device-name", "Device name",
112           "Human-readable name of the sound device", DEFAULT_DEVICE_NAME,
113           G_PARAM_READABLE));
114
115   element_class->change_state =
116       GST_DEBUG_FUNCPTR (gst_oss_mixer_element_change_state);
117 }
118
119 static void
120 gst_oss_mixer_element_finalize (GObject * obj)
121 {
122   GstOssMixerElement *this = GST_OSS_MIXER_ELEMENT (obj);
123
124   g_free (this->device);
125
126   G_OBJECT_CLASS (parent_class)->finalize (obj);
127 }
128
129 static void
130 gst_oss_mixer_element_init (GstOssMixerElement * this,
131     GstOssMixerElementClass * g_class)
132 {
133   this->mixer = NULL;
134   this->device = g_strdup (DEFAULT_DEVICE);
135 }
136
137 static void
138 gst_oss_mixer_element_set_property (GObject * object, guint prop_id,
139     const GValue * value, GParamSpec * pspec)
140 {
141   GstOssMixerElement *this = GST_OSS_MIXER_ELEMENT (object);
142
143   switch (prop_id) {
144     case PROP_DEVICE:
145       g_free (this->device);
146       this->device = g_value_dup_string (value);
147       /* make sure we never set NULL */
148       if (this->device == NULL) {
149         this->device = g_strdup (DEFAULT_DEVICE);
150       }
151       break;
152     default:
153       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
154       break;
155   }
156 }
157
158 static void
159 gst_oss_mixer_element_get_property (GObject * object, guint prop_id,
160     GValue * value, GParamSpec * pspec)
161 {
162   GstOssMixerElement *this = GST_OSS_MIXER_ELEMENT (object);
163
164   switch (prop_id) {
165     case PROP_DEVICE:
166       g_value_set_string (value, this->device);
167       break;
168     case PROP_DEVICE_NAME:
169       if (this->mixer) {
170         g_value_set_string (value, this->mixer->cardname);
171       } else {
172         g_value_set_string (value, NULL);
173       }
174       break;
175     default:
176       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
177       break;
178   }
179 }
180
181 static GstStateChangeReturn
182 gst_oss_mixer_element_change_state (GstElement * element,
183     GstStateChange transition)
184 {
185   GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
186   GstOssMixerElement *this = GST_OSS_MIXER_ELEMENT (element);
187
188   switch (transition) {
189     case GST_STATE_CHANGE_NULL_TO_READY:
190       if (!this->mixer) {
191         this->mixer = gst_ossmixer_new (this->device, GST_OSS_MIXER_ALL);
192         if (!this->mixer)
193           goto open_failed;
194       }
195       break;
196       break;
197     default:
198       break;
199   }
200
201   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
202   if (ret == GST_STATE_CHANGE_FAILURE)
203     return ret;
204
205   switch (transition) {
206     case GST_STATE_CHANGE_READY_TO_NULL:
207       if (this->mixer) {
208         gst_ossmixer_free (this->mixer);
209         this->mixer = NULL;
210       }
211       break;
212     default:
213       break;
214   }
215   return ret;
216
217   /* ERRORS */
218 open_failed:
219   {
220     GST_ELEMENT_ERROR (element, RESOURCE, OPEN_READ_WRITE, (NULL),
221         ("Failed to open oss mixer device '%s'", this->device));
222     return GST_STATE_CHANGE_FAILURE;
223   }
224 }