1 /* GStreamer
2 * Copyright (C) 2007 Sebastian Dröge <slomo@circular-chaos.org>
3 *
4 * gstaudioparse.c:
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 */
21 /**
22 * SECTION:element-audioparse
23 * @title: audioparse
24 *
25 * Converts a byte stream into audio frames.
26 *
27 * This element is deprecated. Use #GstRawAudioParse instead.
28 */
29
30 #ifdef HAVE_CONFIG_H
31 # include "config.h"
32 #endif
33
34 /* FIXME 0.11: suppress warnings for deprecated API such as g_value_array stuff
35 * for now with newer GLib versions (>= 2.31.0) */
36 #define GLIB_DISABLE_DEPRECATION_WARNINGS
37
38 #include <gst/gst.h>
39 #include <gst/audio/audio.h>
40 #include "gstaudioparse.h"
41
42 #include <string.h>
43
44 typedef enum _GstRawAudioParseFormat GstRawAudioParseFormat;
45 enum _GstRawAudioParseFormat
46 {
47 GST_RAW_AUDIO_PARSE_FORMAT_PCM,
48 GST_RAW_AUDIO_PARSE_FORMAT_MULAW,
49 GST_RAW_AUDIO_PARSE_FORMAT_ALAW
50 };
51
52 static GstStaticPadTemplate static_sink_template =
53 GST_STATIC_PAD_TEMPLATE ("sink",
54 GST_PAD_SINK,
55 GST_PAD_ALWAYS,
56 GST_STATIC_CAPS_ANY);
57
58 #define GST_UNALIGNED_RAW_AUDIO_CAPS \
59 "audio/x-unaligned-raw" \
60 ", format = (string) " GST_AUDIO_FORMATS_ALL \
61 ", rate = (int) [ 1, MAX ]" \
62 ", channels = (int) [ 1, MAX ]" \
63 ", layout = (string) { interleaved, non-interleaved }"
64
65 static GstStaticPadTemplate static_src_template =
66 GST_STATIC_PAD_TEMPLATE ("src",
67 GST_PAD_SRC,
68 GST_PAD_ALWAYS,
69 GST_STATIC_CAPS (GST_AUDIO_CAPS_MAKE (GST_AUDIO_FORMATS_ALL)
70 ", layout = (string) { interleaved, non-interleaved }; "
71 GST_UNALIGNED_RAW_AUDIO_CAPS "; "
72 "audio/x-alaw, rate=(int)[1,MAX], channels=(int)[1,MAX]; "
73 "audio/x-mulaw, rate=(int)[1,MAX], channels=(int)[1,MAX]")
74 );
75
76 typedef enum
77 {
78 GST_AUDIO_PARSE_FORMAT_RAW,
79 GST_AUDIO_PARSE_FORMAT_MULAW,
80 GST_AUDIO_PARSE_FORMAT_ALAW
81 } GstAudioParseFormat;
82
83 static void gst_audio_parse_set_property (GObject * object, guint prop_id,
84 const GValue * value, GParamSpec * pspec);
85 static void gst_audio_parse_get_property (GObject * object, guint prop_id,
86 GValue * value, GParamSpec * pspec);
87
88 GST_DEBUG_CATEGORY_STATIC (gst_audio_parse_debug);
89 #define GST_CAT_DEFAULT gst_audio_parse_debug
90
91 enum
92 {
93 PROP_0,
94 PROP_FORMAT,
95 PROP_RAW_FORMAT,
96 PROP_RATE,
97 PROP_CHANNELS,
98 PROP_INTERLEAVED,
99 PROP_CHANNEL_POSITIONS,
100 PROP_USE_SINK_CAPS
101 };
102
103 #define GST_AUDIO_PARSE_FORMAT (gst_audio_parse_format_get_type ())
104 static GType
gst_audio_parse_format_get_type(void)105 gst_audio_parse_format_get_type (void)
106 {
107 static GType audio_parse_format_type = 0;
108 static const GEnumValue format_types[] = {
109 {GST_AUDIO_PARSE_FORMAT_RAW, "Raw", "raw"},
110 {GST_AUDIO_PARSE_FORMAT_ALAW, "A-Law", "alaw"},
111 {GST_AUDIO_PARSE_FORMAT_MULAW, "\302\265-Law", "mulaw"},
112 {0, NULL, NULL}
113 };
114
115 if (!audio_parse_format_type) {
116 audio_parse_format_type =
117 g_enum_register_static ("GstAudioParseFormat", format_types);
118 }
119
120 return audio_parse_format_type;
121 }
122
123 #define gst_audio_parse_parent_class parent_class
124 G_DEFINE_TYPE (GstAudioParse, gst_audio_parse, GST_TYPE_BIN);
125
126 static void
gst_audio_parse_class_init(GstAudioParseClass * klass)127 gst_audio_parse_class_init (GstAudioParseClass * klass)
128 {
129 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
130 GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
131
132 gobject_class->set_property = gst_audio_parse_set_property;
133 gobject_class->get_property = gst_audio_parse_get_property;
134
135 g_object_class_install_property (gobject_class, PROP_FORMAT,
136 g_param_spec_enum ("format", "Format",
137 "Format of audio samples in raw stream", GST_AUDIO_PARSE_FORMAT,
138 GST_AUDIO_PARSE_FORMAT_RAW,
139 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
140
141 g_object_class_install_property (gobject_class, PROP_RAW_FORMAT,
142 g_param_spec_enum ("raw-format", "Raw Format",
143 "Format of audio samples in raw stream", GST_TYPE_AUDIO_FORMAT,
144 GST_AUDIO_FORMAT_S16, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
145
146 g_object_class_install_property (gobject_class, PROP_RATE,
147 g_param_spec_int ("rate", "Rate", "Rate of audio samples in raw stream",
148 1, INT_MAX, 44100, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
149
150 g_object_class_install_property (gobject_class, PROP_CHANNELS,
151 g_param_spec_int ("channels", "Channels",
152 "Number of channels in raw stream", 1, 64, 2,
153 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
154
155 g_object_class_install_property (gobject_class, PROP_INTERLEAVED,
156 g_param_spec_boolean ("interleaved", "Interleaved Layout",
157 "True if audio has interleaved layout", TRUE,
158 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
159
160 g_object_class_install_property (gobject_class, PROP_CHANNEL_POSITIONS,
161 g_param_spec_value_array ("channel-positions", "Channel positions",
162 "Channel positions used on the output",
163 g_param_spec_enum ("channel-position", "Channel position",
164 "Channel position of the n-th input",
165 GST_TYPE_AUDIO_CHANNEL_POSITION,
166 GST_AUDIO_CHANNEL_POSITION_NONE,
167 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS),
168 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
169
170 g_object_class_install_property (gobject_class, PROP_USE_SINK_CAPS,
171 g_param_spec_boolean ("use-sink-caps", "Use sink caps",
172 "Use the sink caps for the format, only performing timestamping",
173 FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
174
175 gst_element_class_set_static_metadata (gstelement_class, "Audio Parse",
176 "Filter/Audio",
177 "Converts stream into audio frames (deprecated: use rawaudioparse instead)",
178 "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
179
180 gst_element_class_add_pad_template (gstelement_class,
181 gst_static_pad_template_get (&static_sink_template));
182 gst_element_class_add_pad_template (gstelement_class,
183 gst_static_pad_template_get (&static_src_template));
184
185 GST_DEBUG_CATEGORY_INIT (gst_audio_parse_debug, "audioparse", 0,
186 "audioparse element");
187 }
188
189 static void
gst_audio_parse_init(GstAudioParse * ap)190 gst_audio_parse_init (GstAudioParse * ap)
191 {
192 GstPad *inner_pad;
193 GstPad *ghostpad;
194
195 ap->rawaudioparse =
196 gst_element_factory_make ("rawaudioparse", "inner_rawaudioparse");
197 g_assert (ap->rawaudioparse != NULL);
198
199 gst_bin_add (GST_BIN (ap), ap->rawaudioparse);
200
201 inner_pad = gst_element_get_static_pad (ap->rawaudioparse, "sink");
202 ghostpad =
203 gst_ghost_pad_new_from_template ("sink", inner_pad,
204 gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (ap), "sink"));
205 gst_element_add_pad (GST_ELEMENT (ap), ghostpad);
206 gst_object_unref (GST_OBJECT (inner_pad));
207
208 inner_pad = gst_element_get_static_pad (ap->rawaudioparse, "src");
209 ghostpad =
210 gst_ghost_pad_new_from_template ("src", inner_pad,
211 gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (ap), "src"));
212 gst_element_add_pad (GST_ELEMENT (ap), ghostpad);
213 gst_object_unref (GST_OBJECT (inner_pad));
214 }
215
216 static void
gst_audio_parse_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)217 gst_audio_parse_set_property (GObject * object, guint prop_id,
218 const GValue * value, GParamSpec * pspec)
219 {
220 GstAudioParse *ap = GST_AUDIO_PARSE (object);
221
222 switch (prop_id) {
223 case PROP_FORMAT:{
224 GstRawAudioParseFormat raw_parse_format;
225
226 switch (g_value_get_enum (value)) {
227 case GST_AUDIO_PARSE_FORMAT_RAW:
228 raw_parse_format = GST_RAW_AUDIO_PARSE_FORMAT_PCM;
229 break;
230
231 case GST_AUDIO_PARSE_FORMAT_MULAW:
232 raw_parse_format = GST_RAW_AUDIO_PARSE_FORMAT_MULAW;
233 break;
234
235 case GST_AUDIO_PARSE_FORMAT_ALAW:
236 raw_parse_format = GST_RAW_AUDIO_PARSE_FORMAT_ALAW;
237 break;
238
239 default:
240 g_assert_not_reached ();
241 break;
242 }
243
244 g_object_set (G_OBJECT (ap->rawaudioparse), "format", raw_parse_format,
245 NULL);
246
247 break;
248 }
249
250 case PROP_RAW_FORMAT:
251 g_object_set (G_OBJECT (ap->rawaudioparse), "pcm-format",
252 g_value_get_enum (value), NULL);
253 break;
254
255 case PROP_RATE:
256 g_object_set (G_OBJECT (ap->rawaudioparse), "sample-rate",
257 g_value_get_int (value), NULL);
258 break;
259
260 case PROP_CHANNELS:
261 g_object_set (G_OBJECT (ap->rawaudioparse), "num-channels",
262 g_value_get_int (value), NULL);
263 break;
264
265 case PROP_INTERLEAVED:
266 g_object_set (G_OBJECT (ap->rawaudioparse), "interleaved",
267 g_value_get_boolean (value), NULL);
268 break;
269
270 case PROP_CHANNEL_POSITIONS:
271 g_object_set (G_OBJECT (ap->rawaudioparse), "channel-positions",
272 g_value_get_boxed (value), NULL);
273 break;
274
275 case PROP_USE_SINK_CAPS:
276 g_object_set (G_OBJECT (ap->rawaudioparse), "use-sink-caps",
277 g_value_get_boolean (value), NULL);
278 break;
279
280 default:
281 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
282 break;
283 }
284 }
285
286 static void
gst_audio_parse_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)287 gst_audio_parse_get_property (GObject * object, guint prop_id, GValue * value,
288 GParamSpec * pspec)
289 {
290 GstAudioParse *ap = GST_AUDIO_PARSE (object);
291
292 switch (prop_id) {
293 case PROP_FORMAT:{
294 GstRawAudioParseFormat raw_parse_format;
295 GstAudioParseFormat format;
296
297 g_object_get (G_OBJECT (ap->rawaudioparse), "format", &raw_parse_format,
298 NULL);
299
300 switch (raw_parse_format) {
301 case GST_RAW_AUDIO_PARSE_FORMAT_PCM:
302 format = GST_AUDIO_PARSE_FORMAT_RAW;
303 break;
304
305 case GST_RAW_AUDIO_PARSE_FORMAT_MULAW:
306 format = GST_AUDIO_PARSE_FORMAT_MULAW;
307 break;
308
309 case GST_RAW_AUDIO_PARSE_FORMAT_ALAW:
310 format = GST_AUDIO_PARSE_FORMAT_ALAW;
311 break;
312
313 default:
314 g_assert_not_reached ();
315 break;
316 }
317
318 g_value_set_enum (value, format);
319
320 break;
321 }
322
323 case PROP_RAW_FORMAT:{
324 GstAudioFormat format;
325 g_object_get (G_OBJECT (ap->rawaudioparse), "pcm-format", &format, NULL);
326 g_value_set_enum (value, format);
327 break;
328 }
329
330 case PROP_RATE:{
331 gint sample_rate;
332 g_object_get (G_OBJECT (ap->rawaudioparse), "sample-rate", &sample_rate,
333 NULL);
334 g_value_set_int (value, sample_rate);
335 break;
336 }
337
338 case PROP_CHANNELS:{
339 gint num_channels;
340 g_object_get (G_OBJECT (ap->rawaudioparse), "num-channels", &num_channels,
341 NULL);
342 g_value_set_int (value, num_channels);
343 break;
344 }
345
346 case PROP_INTERLEAVED:{
347 gboolean interleaved;
348 g_object_get (G_OBJECT (ap->rawaudioparse), "interleaved", &interleaved,
349 NULL);
350 g_value_set_boolean (value, interleaved);
351 break;
352 }
353
354 case PROP_CHANNEL_POSITIONS:{
355 gpointer channel_positions;
356 g_object_get (G_OBJECT (ap->rawaudioparse), "channel-positions",
357 &channel_positions, NULL);
358 g_value_set_boxed (value, channel_positions);
359 break;
360 }
361
362 case PROP_USE_SINK_CAPS:{
363 gboolean use_sink_caps;
364 g_object_get (G_OBJECT (ap->rawaudioparse), "use-sink-caps",
365 &use_sink_caps, NULL);
366 g_value_set_boolean (value, use_sink_caps);
367 break;
368 }
369
370 default:
371 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
372 break;
373 }
374 }
375