summaryrefslogtreecommitdiffstats
path: root/gst/rawparse/gstaudioparse.c
diff options
context:
space:
mode:
Diffstat (limited to 'gst/rawparse/gstaudioparse.c')
-rw-r--r--gst/rawparse/gstaudioparse.c319
1 files changed, 319 insertions, 0 deletions
diff --git a/gst/rawparse/gstaudioparse.c b/gst/rawparse/gstaudioparse.c
new file mode 100644
index 00000000..b8fcd82d
--- /dev/null
+++ b/gst/rawparse/gstaudioparse.c
@@ -0,0 +1,319 @@
+/* GStreamer
+ * Copyright (C) 2007 Sebastian Dröge <slomo@circular-chaos.org>
+ *
+ * gstaudioparse.c:
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/**
+ * SECTION:element-audioparse
+ * @short_description: parses a byte stream into audio frames
+ *
+ * Converts a byte stream into audio frames.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "gstaudioparse.h"
+
+typedef enum
+{
+ GST_AUDIO_PARSE_FORMAT_INT,
+ GST_AUDIO_PARSE_FORMAT_FLOAT
+} GstAudioParseFormat;
+
+typedef enum
+{
+ GST_AUDIO_PARSE_ENDIANNESS_LITTLE = 1234,
+ GST_AUDIO_PARSE_ENDIANNESS_BIG = 4321
+} GstAudioParseEndianness;
+
+static void gst_audio_parse_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec);
+static void gst_audio_parse_get_property (GObject * object, guint prop_id,
+ GValue * value, GParamSpec * pspec);
+
+static GstCaps *gst_audio_parse_get_caps (GstRawParse * rp);
+
+static void gst_audio_parse_update_frame_size (GstAudioParse * ap);
+
+GST_DEBUG_CATEGORY_STATIC (gst_audio_parse_debug);
+#define GST_CAT_DEFAULT gst_audio_parse_debug
+
+static const GstElementDetails gst_audio_parse_details =
+GST_ELEMENT_DETAILS ("Audio Parse",
+ "Filter/Audio",
+ "Converts stream into audio frames",
+ "Sebastian Dröge <slomo@circular-chaos.org>");
+
+enum
+{
+ ARG_0,
+ ARG_FORMAT,
+ ARG_RATE,
+ ARG_CHANNELS,
+ ARG_ENDIANNESS,
+ ARG_WIDTH,
+ ARG_DEPTH,
+ ARG_SIGNED,
+};
+
+
+#define GST_AUDIO_PARSE_FORMAT (gst_audio_parse_format_get_type ())
+static GType
+gst_audio_parse_format_get_type (void)
+{
+ static GType audio_parse_format_type = 0;
+ static const GEnumValue format_types[] = {
+ {GST_AUDIO_PARSE_FORMAT_INT, "Integer", "int"},
+ {GST_AUDIO_PARSE_FORMAT_FLOAT, "Floating Point", "float"},
+ {0, NULL, NULL}
+ };
+
+ if (!audio_parse_format_type) {
+ audio_parse_format_type =
+ g_enum_register_static ("GstAudioParseFormat", format_types);
+ }
+
+ return audio_parse_format_type;
+}
+
+#define GST_AUDIO_PARSE_ENDIANNESS (gst_audio_parse_endianness_get_type ())
+static GType
+gst_audio_parse_endianness_get_type (void)
+{
+ static GType audio_parse_endianness_type = 0;
+ static const GEnumValue endian_types[] = {
+ {GST_AUDIO_PARSE_ENDIANNESS_LITTLE, "Little Endian", "little"},
+ {GST_AUDIO_PARSE_ENDIANNESS_BIG, "Big Endian", "big"},
+ {0, NULL, NULL}
+ };
+
+ if (!audio_parse_endianness_type) {
+ audio_parse_endianness_type =
+ g_enum_register_static ("GstAudioParseEndianness", endian_types);
+ }
+
+ return audio_parse_endianness_type;
+}
+
+GST_BOILERPLATE (GstAudioParse, gst_audio_parse, GstRawParse,
+ GST_TYPE_RAW_PARSE);
+
+static void
+gst_audio_parse_base_init (gpointer g_class)
+{
+ GstRawParseClass *rp_class = GST_RAW_PARSE_CLASS (g_class);
+ GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
+ GstCaps *caps;
+
+ GST_DEBUG_CATEGORY_INIT (gst_audio_parse_debug, "audioparse", 0,
+ "audioparse element");
+
+ gst_element_class_set_details (gstelement_class, &gst_audio_parse_details);
+
+ caps =
+ gst_caps_from_string ("audio/x-raw-int,"
+ " depth=(int) [ 1, 32 ],"
+ " width=(int) { 8, 16, 24, 32 },"
+ " endianness=(int) { LITTLE_ENDIAN, BIG_ENDIAN }, "
+ " signed=(bool) { TRUE, FALSE },"
+ " rate=(int) [ 1, MAX ],"
+ " channels=(int) [ 1, MAX ]; "
+ "audio/x-raw-float,"
+ " width=(int) { 32, 64 },"
+ " endianness=(int) { LITTLE_ENDIAN, BIG_ENDIAN }, "
+ " rate=(int)[1,MAX]," " channels=(int)[1,MAX]");
+
+ gst_raw_parse_class_set_src_pad_template (rp_class, caps);
+ gst_raw_parse_class_set_multiple_frames_per_buffer (rp_class, TRUE);
+ gst_caps_unref (caps);
+}
+
+static void
+gst_audio_parse_class_init (GstAudioParseClass * klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GstRawParseClass *rp_class = GST_RAW_PARSE_CLASS (klass);
+
+ gobject_class->set_property = gst_audio_parse_set_property;
+ gobject_class->get_property = gst_audio_parse_get_property;
+
+ rp_class->get_caps = gst_audio_parse_get_caps;
+
+ g_object_class_install_property (gobject_class, ARG_FORMAT,
+ g_param_spec_enum ("format", "Format",
+ "Format of audio samples in raw stream", GST_AUDIO_PARSE_FORMAT,
+ GST_AUDIO_PARSE_FORMAT_INT, G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, ARG_RATE,
+ g_param_spec_int ("rate", "Rate", "Rate of audio samples in raw stream",
+ 1, INT_MAX, 44100, G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, ARG_CHANNELS,
+ g_param_spec_int ("channels", "Channels",
+ "Number of channels in raw stream", 1, INT_MAX, 2,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, ARG_WIDTH,
+ g_param_spec_int ("width", "Width",
+ "Width of audio samples in raw stream", 1, INT_MAX, 16,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, ARG_DEPTH,
+ g_param_spec_int ("depth", "Depth",
+ "Depth of audio samples in raw stream", 1, INT_MAX, 16,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, ARG_SIGNED,
+ g_param_spec_boolean ("signed", "signed",
+ "Sign of audio samples in raw stream", TRUE, G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, ARG_ENDIANNESS,
+ g_param_spec_enum ("endianness", "Endianness",
+ "Endianness of audio samples in raw stream",
+ GST_AUDIO_PARSE_ENDIANNESS, G_BYTE_ORDER, G_PARAM_READWRITE));
+}
+
+static void
+gst_audio_parse_init (GstAudioParse * ap, GstAudioParseClass * g_class)
+{
+ ap->format = GST_AUDIO_PARSE_FORMAT_INT;
+ ap->channels = 2;
+ ap->width = 16;
+ ap->depth = 16;
+ ap->signedness = TRUE;
+ ap->endianness = G_BYTE_ORDER;
+
+ gst_audio_parse_update_frame_size (ap);
+ gst_raw_parse_set_fps (GST_RAW_PARSE (ap), 44100, 1);
+}
+
+static void
+gst_audio_parse_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ GstAudioParse *ap = GST_AUDIO_PARSE (object);
+
+ g_return_if_fail (!gst_raw_parse_is_negotiated (GST_RAW_PARSE (ap)));
+
+ switch (prop_id) {
+ case ARG_FORMAT:
+ ap->format = g_value_get_enum (value);
+ break;
+ case ARG_RATE:
+ gst_raw_parse_set_fps (GST_RAW_PARSE (ap), g_value_get_int (value), 1);
+ break;
+ case ARG_CHANNELS:
+ ap->channels = g_value_get_int (value);
+ break;
+ case ARG_WIDTH:
+ ap->width = g_value_get_int (value);
+ break;
+ case ARG_DEPTH:
+ ap->depth = g_value_get_int (value);
+ break;
+ case ARG_SIGNED:
+ ap->signedness = g_value_get_boolean (value);
+ break;
+ case ARG_ENDIANNESS:
+ ap->endianness = g_value_get_enum (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+
+ gst_audio_parse_update_frame_size (ap);
+}
+
+static void
+gst_audio_parse_get_property (GObject * object, guint prop_id, GValue * value,
+ GParamSpec * pspec)
+{
+ GstAudioParse *ap = GST_AUDIO_PARSE (object);
+
+ switch (prop_id) {
+ case ARG_FORMAT:
+ g_value_set_enum (value, ap->format);
+ break;
+ case ARG_RATE:{
+ gint fps_n, fps_d;
+
+ gst_raw_parse_get_fps (GST_RAW_PARSE (ap), &fps_n, &fps_d);
+ g_value_set_int (value, fps_n);
+ break;
+ }
+ case ARG_CHANNELS:
+ g_value_set_int (value, ap->channels);
+ break;
+ case ARG_WIDTH:
+ g_value_set_int (value, ap->width);
+ break;
+ case ARG_DEPTH:
+ g_value_set_int (value, ap->depth);
+ break;
+ case ARG_SIGNED:
+ g_value_set_boolean (value, ap->signedness);
+ break;
+ case ARG_ENDIANNESS:
+ g_value_set_enum (value, ap->endianness);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+void
+gst_audio_parse_update_frame_size (GstAudioParse * ap)
+{
+ gint framesize;
+
+ framesize = (ap->width / 8) * ap->channels;
+
+ gst_raw_parse_set_framesize (GST_RAW_PARSE (ap), framesize);
+}
+
+static GstCaps *
+gst_audio_parse_get_caps (GstRawParse * rp)
+{
+ GstAudioParse *ap = GST_AUDIO_PARSE (rp);
+ GstCaps *caps;
+
+ gint fps_n, fps_d;
+
+ gst_raw_parse_get_fps (rp, &fps_n, &fps_d);
+
+ if (ap->format == GST_AUDIO_PARSE_FORMAT_INT) {
+ caps = gst_caps_new_simple ("audio/x-raw-int",
+ "rate", G_TYPE_INT, fps_n,
+ "channels", G_TYPE_INT, ap->channels,
+ "width", G_TYPE_INT, ap->width,
+ "depth", G_TYPE_INT, ap->depth,
+ "signed", G_TYPE_BOOLEAN, ap->signedness,
+ "endianness", G_TYPE_INT, ap->endianness, NULL);
+ } else {
+ caps = gst_caps_new_simple ("audio/x-raw-float",
+ "rate", G_TYPE_INT, fps_n,
+ "channels", G_TYPE_INT, ap->channels,
+ "width", G_TYPE_INT, ap->width,
+ "endianness", G_TYPE_INT, ap->endianness, NULL);
+ }
+ return caps;
+}