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 GST_ELEMENT_REGISTER_DEFINE (audioparse, "audioparse", GST_RANK_NONE,
126 gst_audio_parse_get_type ());
127
128 static void
gst_audio_parse_class_init(GstAudioParseClass * klass)129 gst_audio_parse_class_init (GstAudioParseClass * klass)
130 {
131 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
132 GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
133
134 gobject_class->set_property = gst_audio_parse_set_property;
135 gobject_class->get_property = gst_audio_parse_get_property;
136
137 g_object_class_install_property (gobject_class, PROP_FORMAT,
138 g_param_spec_enum ("format", "Format",
139 "Format of audio samples in raw stream", GST_AUDIO_PARSE_FORMAT,
140 GST_AUDIO_PARSE_FORMAT_RAW,
141 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
142
143 g_object_class_install_property (gobject_class, PROP_RAW_FORMAT,
144 g_param_spec_enum ("raw-format", "Raw Format",
145 "Format of audio samples in raw stream", GST_TYPE_AUDIO_FORMAT,
146 GST_AUDIO_FORMAT_S16, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
147
148 g_object_class_install_property (gobject_class, PROP_RATE,
149 g_param_spec_int ("rate", "Rate", "Rate of audio samples in raw stream",
150 1, INT_MAX, 44100, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
151
152 g_object_class_install_property (gobject_class, PROP_CHANNELS,
153 g_param_spec_int ("channels", "Channels",
154 "Number of channels in raw stream", 1, 64, 2,
155 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
156
157 g_object_class_install_property (gobject_class, PROP_INTERLEAVED,
158 g_param_spec_boolean ("interleaved", "Interleaved Layout",
159 "True if audio has interleaved layout", TRUE,
160 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
161
162 g_object_class_install_property (gobject_class, PROP_CHANNEL_POSITIONS,
163 g_param_spec_value_array ("channel-positions", "Channel positions",
164 "Channel positions used on the output",
165 g_param_spec_enum ("channel-position", "Channel position",
166 "Channel position of the n-th input",
167 GST_TYPE_AUDIO_CHANNEL_POSITION,
168 GST_AUDIO_CHANNEL_POSITION_NONE,
169 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS),
170 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
171
172 g_object_class_install_property (gobject_class, PROP_USE_SINK_CAPS,
173 g_param_spec_boolean ("use-sink-caps", "Use sink caps",
174 "Use the sink caps for the format, only performing timestamping",
175 FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
176
177 gst_element_class_set_static_metadata (gstelement_class, "Audio Parse",
178 "Filter/Audio",
179 "Converts stream into audio frames (deprecated: use rawaudioparse instead)",
180 "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
181
182 gst_element_class_add_pad_template (gstelement_class,
183 gst_static_pad_template_get (&static_sink_template));
184 gst_element_class_add_pad_template (gstelement_class,
185 gst_static_pad_template_get (&static_src_template));
186
187 GST_DEBUG_CATEGORY_INIT (gst_audio_parse_debug, "audioparse", 0,
188 "audioparse element");
189
190 gst_type_mark_as_plugin_api (GST_AUDIO_PARSE_FORMAT, 0);
191 }
192
193 static void
gst_audio_parse_init(GstAudioParse * ap)194 gst_audio_parse_init (GstAudioParse * ap)
195 {
196 GstPad *inner_pad;
197 GstPad *ghostpad;
198
199 ap->rawaudioparse =
200 gst_element_factory_make ("rawaudioparse", "inner_rawaudioparse");
201 g_assert (ap->rawaudioparse != NULL);
202
203 gst_bin_add (GST_BIN (ap), ap->rawaudioparse);
204
205 inner_pad = gst_element_get_static_pad (ap->rawaudioparse, "sink");
206 ghostpad =
207 gst_ghost_pad_new_from_template ("sink", inner_pad,
208 gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (ap), "sink"));
209 gst_element_add_pad (GST_ELEMENT (ap), ghostpad);
210 gst_object_unref (GST_OBJECT (inner_pad));
211
212 inner_pad = gst_element_get_static_pad (ap->rawaudioparse, "src");
213 ghostpad =
214 gst_ghost_pad_new_from_template ("src", inner_pad,
215 gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (ap), "src"));
216 gst_element_add_pad (GST_ELEMENT (ap), ghostpad);
217 gst_object_unref (GST_OBJECT (inner_pad));
218 }
219
220 static void
gst_audio_parse_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)221 gst_audio_parse_set_property (GObject * object, guint prop_id,
222 const GValue * value, GParamSpec * pspec)
223 {
224 GstAudioParse *ap = GST_AUDIO_PARSE (object);
225
226 switch (prop_id) {
227 case PROP_FORMAT:{
228 GstRawAudioParseFormat raw_parse_format;
229
230 switch (g_value_get_enum (value)) {
231 case GST_AUDIO_PARSE_FORMAT_RAW:
232 raw_parse_format = GST_RAW_AUDIO_PARSE_FORMAT_PCM;
233 break;
234
235 case GST_AUDIO_PARSE_FORMAT_MULAW:
236 raw_parse_format = GST_RAW_AUDIO_PARSE_FORMAT_MULAW;
237 break;
238
239 case GST_AUDIO_PARSE_FORMAT_ALAW:
240 raw_parse_format = GST_RAW_AUDIO_PARSE_FORMAT_ALAW;
241 break;
242
243 default:
244 g_assert_not_reached ();
245 break;
246 }
247
248 g_object_set (G_OBJECT (ap->rawaudioparse), "format", raw_parse_format,
249 NULL);
250
251 break;
252 }
253
254 case PROP_RAW_FORMAT:
255 g_object_set (G_OBJECT (ap->rawaudioparse), "pcm-format",
256 g_value_get_enum (value), NULL);
257 break;
258
259 case PROP_RATE:
260 g_object_set (G_OBJECT (ap->rawaudioparse), "sample-rate",
261 g_value_get_int (value), NULL);
262 break;
263
264 case PROP_CHANNELS:
265 g_object_set (G_OBJECT (ap->rawaudioparse), "num-channels",
266 g_value_get_int (value), NULL);
267 break;
268
269 case PROP_INTERLEAVED:
270 g_object_set (G_OBJECT (ap->rawaudioparse), "interleaved",
271 g_value_get_boolean (value), NULL);
272 break;
273
274 case PROP_CHANNEL_POSITIONS:
275 g_object_set (G_OBJECT (ap->rawaudioparse), "channel-positions",
276 g_value_get_boxed (value), NULL);
277 break;
278
279 case PROP_USE_SINK_CAPS:
280 g_object_set (G_OBJECT (ap->rawaudioparse), "use-sink-caps",
281 g_value_get_boolean (value), NULL);
282 break;
283
284 default:
285 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
286 break;
287 }
288 }
289
290 static void
gst_audio_parse_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)291 gst_audio_parse_get_property (GObject * object, guint prop_id, GValue * value,
292 GParamSpec * pspec)
293 {
294 GstAudioParse *ap = GST_AUDIO_PARSE (object);
295
296 switch (prop_id) {
297 case PROP_FORMAT:{
298 GstRawAudioParseFormat raw_parse_format;
299 GstAudioParseFormat format;
300
301 g_object_get (G_OBJECT (ap->rawaudioparse), "format", &raw_parse_format,
302 NULL);
303
304 switch (raw_parse_format) {
305 case GST_RAW_AUDIO_PARSE_FORMAT_PCM:
306 format = GST_AUDIO_PARSE_FORMAT_RAW;
307 break;
308
309 case GST_RAW_AUDIO_PARSE_FORMAT_MULAW:
310 format = GST_AUDIO_PARSE_FORMAT_MULAW;
311 break;
312
313 case GST_RAW_AUDIO_PARSE_FORMAT_ALAW:
314 format = GST_AUDIO_PARSE_FORMAT_ALAW;
315 break;
316
317 default:
318 g_assert_not_reached ();
319 break;
320 }
321
322 g_value_set_enum (value, format);
323
324 break;
325 }
326
327 case PROP_RAW_FORMAT:{
328 GstAudioFormat format;
329 g_object_get (G_OBJECT (ap->rawaudioparse), "pcm-format", &format, NULL);
330 g_value_set_enum (value, format);
331 break;
332 }
333
334 case PROP_RATE:{
335 gint sample_rate;
336 g_object_get (G_OBJECT (ap->rawaudioparse), "sample-rate", &sample_rate,
337 NULL);
338 g_value_set_int (value, sample_rate);
339 break;
340 }
341
342 case PROP_CHANNELS:{
343 gint num_channels;
344 g_object_get (G_OBJECT (ap->rawaudioparse), "num-channels", &num_channels,
345 NULL);
346 g_value_set_int (value, num_channels);
347 break;
348 }
349
350 case PROP_INTERLEAVED:{
351 gboolean interleaved;
352 g_object_get (G_OBJECT (ap->rawaudioparse), "interleaved", &interleaved,
353 NULL);
354 g_value_set_boolean (value, interleaved);
355 break;
356 }
357
358 case PROP_CHANNEL_POSITIONS:{
359 gpointer channel_positions;
360 g_object_get (G_OBJECT (ap->rawaudioparse), "channel-positions",
361 &channel_positions, NULL);
362 g_value_set_boxed (value, channel_positions);
363 break;
364 }
365
366 case PROP_USE_SINK_CAPS:{
367 gboolean use_sink_caps;
368 g_object_get (G_OBJECT (ap->rawaudioparse), "use-sink-caps",
369 &use_sink_caps, NULL);
370 g_value_set_boolean (value, use_sink_caps);
371 break;
372 }
373
374 default:
375 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
376 break;
377 }
378 }
379