-SUBDIRS=autoplug spider #seeking
-DIST_SUBDIRS=autoplug spider
+if USE_ALSA
+ALSA_DIR=alsa
+else
+ALSA_DIR=
+endif
+
+SUBDIRS=autoplug spider $(ALSA_DIR) #seeking
+DIST_SUBDIRS=autoplug spider alsa
GST_PLUGIN_PATH=$(shell cd $(top_builddir) && pwd)
--- /dev/null
+testprogs = formats
+
+TESTS = $(testprogs)
+
+check_PROGRAMS = $(testprogs)
+
+formats_SOURCES = formats.c sinesrc.c sinesrc.h
+
+# we have nothing but apps here, we can do this safely
+LIBS = $(GST_LIBS)
+AM_CFLAGS = $(GST_CFLAGS)
--- /dev/null
+/*
+ * Copyright (C) 2003 Benjamin Otte <in7y118@public.uni-hamburg.de>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "sinesrc.h"
+
+GstElement *pipeline;
+gint channels = 1;
+gboolean sign = FALSE;
+gint endianness = G_LITTLE_ENDIAN;
+gint depth = 8;
+gint width = 8;
+
+#define NUMBER_OF_INT_TESTS 16
+#define NUMBER_OF_FLOAT_TESTS 2
+#define NUMBER_OF_LAW_TESTS 2
+
+gint last = 0;
+gint counter = 0;
+
+static void create_pipeline (void);
+
+
+static void
+pre_get_func (SineSrc *src)
+{
+ counter ++;
+};
+static void
+create_pipeline (void)
+{
+ GstElement *src;
+ SineSrc *sinesrc;
+ GstElement *alsasink;
+
+ pipeline = gst_pipeline_new ("pipeline");
+ src = sinesrc_new ();
+ alsasink = gst_element_factory_make ("alsasink", "alsasink");
+
+ gst_bin_add_many (GST_BIN (pipeline), src, alsasink, NULL);
+ gst_element_link (src, alsasink);
+
+ /* prepare our sinesrc */
+ sinesrc = (SineSrc *) src;
+ sinesrc->pre_get_func = pre_get_func;
+ sinesrc->newcaps = TRUE;
+ /* int tests */
+ if (last < NUMBER_OF_INT_TESTS) {
+ sinesrc->type = SINE_SRC_INT;
+ sinesrc->sign = ((last % 2) == 0) ? TRUE : FALSE;
+ sinesrc->endianness = ((last / 2) % 2 == 0) ? G_LITTLE_ENDIAN : G_BIG_ENDIAN;
+ switch ((last / 4) % 8) {
+ case 0:
+ sinesrc->depth = 8;
+ sinesrc->width = 8;
+ break;
+ case 1:
+ sinesrc->depth = 16;
+ sinesrc->width = 16;
+ break;
+ case 2:
+ sinesrc->depth = 24;
+ sinesrc->width = 32;
+ break;
+ case 3:
+ sinesrc->depth = 32;
+ sinesrc->width = 32;
+ break;
+ /* nomore tests below until i know what 24bit width means to alsa wrt endianness */
+ case 4:
+ sinesrc->depth = 24;
+ sinesrc->width = 24;
+ break;
+ case 5:
+ sinesrc->depth = 20;
+ sinesrc->width = 24;
+ break;
+ case 6:
+ sinesrc->depth = 18;
+ sinesrc->width = 24;
+ break;
+ case 7:
+ /* not used yet */
+ sinesrc->depth = 8;
+ sinesrc->width = 8;
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ g_print ("Setting format to: format: \"int\"\n"
+ " sign: %s\n"
+ " endianness: %d\n"
+ " width: %d\n"
+ " depth: %d\n",
+ sinesrc->sign ? "TRUE" : "FALSE", sinesrc->endianness,
+ sinesrc->width, sinesrc->depth);
+ } else if (last < NUMBER_OF_INT_TESTS + NUMBER_OF_FLOAT_TESTS) {
+ gint temp = last - NUMBER_OF_INT_TESTS;
+ sinesrc->type = SINE_SRC_FLOAT;
+ switch (temp) {
+ case 0:
+ sinesrc->width = 32;
+ break;
+ case 1:
+ sinesrc->width = 64;
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+ g_print ("Setting format to: format: \"float\"\n"
+ " layout: \"%s\"\n"
+ " intercept: 0\n"
+ " slope: 1\n",
+ sinesrc->width == 32 ? "gfloat" : "gdouble");
+ } else if (last < NUMBER_OF_INT_TESTS + NUMBER_OF_FLOAT_TESTS + NUMBER_OF_LAW_TESTS) {
+ gint temp = last - NUMBER_OF_INT_TESTS - NUMBER_OF_FLOAT_TESTS;
+ GstElement *law;
+
+ sinesrc->type = SINE_SRC_INT;
+ sinesrc->sign = TRUE;
+ sinesrc->endianness = G_BYTE_ORDER;
+ sinesrc->depth = 16;
+ sinesrc->width = 16;
+
+ if (temp == 0) {
+ g_assert ((law = gst_element_factory_make ("mulawenc", "mulaw")));
+ } else {
+ g_assert ((law = gst_element_factory_make ("alawenc", "alaw")));
+ }
+ gst_element_unlink (src, alsasink);
+ gst_bin_add (GST_BIN (pipeline), law);
+ gst_element_link_many (src, law, alsasink, NULL);
+ if (temp == 0) {
+ g_print ("Setting format to: format: \"MU law\"\n");
+ } else {
+ g_print ("Setting format to: format: \"A law\"\n");
+ }
+ } else {
+ g_print ("All formats work like a charm.\n");
+ exit (0);
+ }
+ gst_element_set_state (pipeline, GST_STATE_PLAYING);
+}
+gint
+main (gint argc, gchar *argv[])
+{
+ gst_init (&argc, &argv);
+
+ g_print ("\n"
+ "This test will test the various formats ALSA and GStreamer support.\n"
+ "You will hear a short sine tone on your default ALSA soundcard for every\n"
+ "format tested. They should all sound the same.\n"
+ "\n");
+ create_pipeline ();
+
+ while (pipeline) {
+ gst_bin_iterate (GST_BIN (pipeline));
+ if ((counter / 400) > last) {
+ last = counter / 400;
+ gst_object_unref (GST_OBJECT (pipeline));
+ create_pipeline ();
+ }
+ }
+
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (C) 2003 Benjamin Otte <in7y118@public.uni-hamburg.de>
+ *
+ * sinesrc.c: An elemnt emitting a sine src in lots of different formats
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <math.h>
+#include "sinesrc.h"
+
+#define SAMPLES_PER_WAVE 200
+
+GST_PAD_TEMPLATE_FACTORY (sinesrc_src_factory,
+ "src",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ GST_CAPS_NEW (
+ "sinesrc_int_src",
+ "audio/raw",
+ "format", GST_PROPS_STRING ("int"),
+ "law", GST_PROPS_INT (0),
+ "endianness", GST_PROPS_LIST (GST_PROPS_INT (G_LITTLE_ENDIAN), GST_PROPS_INT (G_BIG_ENDIAN)),
+ "signed", GST_PROPS_LIST (GST_PROPS_BOOLEAN (FALSE), GST_PROPS_BOOLEAN (TRUE)),
+ "width", GST_PROPS_INT_RANGE (8, 32),
+ "depth", GST_PROPS_INT_RANGE (8, 32),
+ "rate", GST_PROPS_INT_RANGE (8000, 192000),
+ "channels", GST_PROPS_INT_RANGE (1, 16)
+ ),
+ GST_CAPS_NEW (
+ "sinesrc_float_src",
+ "audio/raw",
+ "format", GST_PROPS_STRING ("float"),
+ "layout", GST_PROPS_LIST (GST_PROPS_STRING ("gfloat"), GST_PROPS_STRING ("gdouble")),
+ "intercept", GST_PROPS_FLOAT (0),
+ "slope", GST_PROPS_FLOAT (1),
+ "channels", GST_PROPS_INT_RANGE (1, 16)
+ )
+);
+
+static GstElementClass *parent_class = NULL;
+
+static void sinesrc_init (SineSrc *src);
+static void sinesrc_class_init (SineSrcClass *klass);
+
+static GstBuffer * sinesrc_get (GstPad *pad);
+
+
+GType
+sinesrc_get_type (void)
+{
+ static GType sinesrc_type = 0;
+
+ if (!sinesrc_type) {
+ static const GTypeInfo sinesrc_info = {
+ sizeof (SineSrcClass), NULL, NULL,
+ (GClassInitFunc) sinesrc_class_init, NULL, NULL,
+ sizeof (SineSrc), 0,
+ (GInstanceInitFunc) sinesrc_init,
+ };
+ sinesrc_type = g_type_register_static (GST_TYPE_ELEMENT, "SineSrc",
+ &sinesrc_info, 0);
+ }
+ return sinesrc_type;
+}
+static void
+sinesrc_class_init (SineSrcClass *klass)
+{
+ parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
+}
+
+static void
+sinesrc_init (SineSrc *src)
+{
+ src->src = gst_pad_new_from_template (
+ GST_PAD_TEMPLATE_GET (sinesrc_src_factory), "src");
+ gst_element_add_pad (GST_ELEMENT(src), src->src);
+ gst_pad_set_get_function (src->src, sinesrc_get);
+
+ src->width = 16;
+ src->depth = 16;
+ src->sign = TRUE;
+ src->endianness = G_BYTE_ORDER;
+ src->rate = 44100;
+ src->channels = 1;
+ src->type = SINE_SRC_INT;
+ src->newcaps = TRUE;
+
+ src->pre_get_func = NULL;
+
+ GST_OBJECT (src)->name = "sinesrc";
+}
+
+static void
+sinesrc_force_caps (SineSrc *src) {
+ GstCaps *caps;
+
+ if (!src->newcaps)
+ return;
+
+ src->newcaps = FALSE;
+
+ switch (src->type) {
+ case SINE_SRC_INT:
+ caps = GST_CAPS_NEW (
+ "sinesrc_src_caps",
+ "audio/raw",
+ "format", GST_PROPS_STRING ("int"),
+ "law", GST_PROPS_INT (0),
+ "signed", GST_PROPS_BOOLEAN (src->sign),
+ "width", GST_PROPS_INT (src->width),
+ "depth", GST_PROPS_INT (src->depth)
+ );
+ if (src->width > 8)
+ gst_props_add_entry (gst_caps_get_props (caps),
+ gst_props_entry_new ("endianness",
+ GST_PROPS_INT (src->endianness)));
+ break;
+ case SINE_SRC_FLOAT:
+ g_assert (src->width == 32 || src->width == 64);
+ caps = GST_CAPS_NEW (
+ "sinesrc_src_caps",
+ "audio/raw",
+ "format", GST_PROPS_STRING ("float"),
+ "intercept", GST_PROPS_FLOAT (0),
+ "slope", GST_PROPS_FLOAT (1)
+ );
+ if (src->width == 32) {
+ gst_props_add_entry (gst_caps_get_props (caps),
+ gst_props_entry_new ("layout",
+ GST_PROPS_STRING ("gfloat")));
+ } else if (src->width == 64) {
+ gst_props_add_entry (gst_caps_get_props (caps),
+ gst_props_entry_new ("layout",
+ GST_PROPS_STRING ("gdouble")));
+ } else {
+ g_assert_not_reached ();
+ }
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ gst_props_add_entry (gst_caps_get_props (caps),
+ gst_props_entry_new ("rate", GST_PROPS_INT (src->rate)));
+ gst_props_add_entry (gst_caps_get_props (caps),
+ gst_props_entry_new ("channels", GST_PROPS_INT (src->channels)));
+
+ g_assert (gst_pad_try_set_caps (src->src, caps) == GST_PAD_LINK_OK);
+}
+/* always return 1 wave
+ * there are 200 waves in 1 second, so the frequency is samplerate/200
+ */
+static guint8 UIDENTITY(guint8 x) { return x; };
+static gint8 IDENTITY(gint8 x) { return x; };
+#define POPULATE(format, be_func, le_func) {\
+ format val = (format) int_value;\
+ switch (src->endianness) {\
+ case G_LITTLE_ENDIAN:\
+ val = le_func (val);\
+ break;\
+ case G_BIG_ENDIAN:\
+ val = be_func (val);\
+ break;\
+ default: \
+ g_assert_not_reached ();\
+ };\
+ format* p = data;\
+ for (j = 0; j < src->channels; j++) {\
+ *p = val;\
+ p ++;\
+ }\
+ data = p;\
+}
+static GstBuffer *
+sinesrc_get (GstPad *pad)
+{
+ GstBuffer *buf;
+ SineSrc *src;
+
+ void *data;
+ gint i, j;
+ gdouble value;
+
+ g_return_val_if_fail (pad != NULL, NULL);
+ src = SINESRC(gst_pad_get_parent (pad));
+
+ if (src->pre_get_func)
+ src->pre_get_func (src);
+
+ g_assert ((buf = gst_buffer_new_and_alloc ((src->width / 8) * src->channels * SAMPLES_PER_WAVE)));
+ g_assert ((data = GST_BUFFER_DATA(buf)));
+
+ for (i = 0; i < SAMPLES_PER_WAVE; i++) {
+ value = sin (i * 2 * M_PI / SAMPLES_PER_WAVE);
+ switch (src->type) {
+ case SINE_SRC_INT: {
+ gint64 int_value = (value + (src->sign ? 0 : 1)) * (((guint64) 1) << (src->depth - 1));
+ if (int_value == (1 + (src->sign ? 0 : 1)) * (((guint64) 1) << (src->depth - 1))) int_value--;
+ switch (src->width) {
+ case 8:
+ if (src->sign)
+ POPULATE (gint8, IDENTITY, IDENTITY)
+ else
+ POPULATE (guint8, UIDENTITY, UIDENTITY)
+ break;
+ case 16:
+ if (src->sign)
+ POPULATE (gint16, GINT16_TO_BE, GINT16_TO_LE)
+ else
+ POPULATE (guint16, GUINT16_TO_BE, GUINT16_TO_LE)
+ break;
+ case 24:
+ /* mom, can I have gint24 plz? */
+ g_assert_not_reached ();
+ break;
+ case 32:
+ if (src->sign)
+ POPULATE (gint32, GINT32_TO_BE, GINT32_TO_LE)
+ else
+ POPULATE (guint32, GUINT32_TO_BE, GUINT32_TO_LE)
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+ break;
+ }
+ case SINE_SRC_FLOAT:
+ if (src->width == 32) {
+ gfloat *p = (gfloat *) data;
+ gfloat fval = (gfloat) value;
+ for (j = 0; j < src->channels; j++) {
+ *p = fval;
+ p++;
+ }
+ data = p;
+ break;
+ }
+ if (src->width == 64) {
+ gdouble *p = (gdouble *) data;
+ for (j = 0; j < src->channels; j++) {
+ *p = value;
+ p++;
+ }
+ data = p;
+ break;
+ }
+ g_assert_not_reached ();
+ default:
+ g_assert_not_reached ();
+ }
+ }
+
+ if (src->newcaps) {
+ sinesrc_force_caps(src);
+ }
+ return buf;
+}
+
+GstElement *
+sinesrc_new (void)
+{
+ return GST_ELEMENT (g_object_new (TYPE_SINESRC, NULL));
+}
+void
+sinesrc_set_pre_get_func (SineSrc *src, PreGetFunc func)
+{
+ src->pre_get_func = func;
+}
--- /dev/null
+/*
+ * Copyright (C) 2003 Benjamin Otte <in7y118@public.uni-hamburg.de>
+ *
+ * sinesrc.h: Header file for sinesrc.c
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __SINESRC_H__
+#define __SINESRC_H__
+
+
+#include <config.h>
+#include <gst/gst.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define TYPE_SINESRC \
+ (sinesrc_get_type())
+#define SINESRC(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj),TYPE_SINESRC,SineSrc))
+#define SINESRC_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass),TYPE_SINESRC,SineSrcClass))
+#define IS_SINESRC(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),TYPE_SINESRC))
+#define IS_SINESRC_CLASS(obj) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass),TYPE_SINESRC))
+
+typedef struct _SineSrc SineSrc;
+typedef struct _SineSrcClass SineSrcClass;
+
+typedef void (*PreGetFunc) (SineSrc *src);
+
+typedef enum {
+ SINE_SRC_INT,
+ SINE_SRC_FLOAT
+} SineSrcAudio;
+
+struct _SineSrc {
+ GstElement element;
+
+ /* pads */
+ GstPad *src;
+
+ /* audio parameters */
+ SineSrcAudio type;
+ gint width; /* int + float */
+ gint depth; /* int */
+ gboolean sign; /* int */
+ gint endianness; /* int */
+
+ gint rate;
+ gint channels; /* interleaved */
+
+ gboolean newcaps;
+
+ /* freaky stuff for testing */
+ PreGetFunc pre_get_func;
+};
+
+struct _SineSrcClass {
+ GstElementClass parent_class;
+};
+
+GType sinesrc_get_type (void);
+GstElement * sinesrc_new (void);
+
+void sinesrc_set_pre_get_func (SineSrc *src, PreGetFunc func);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GST_SINESRC_H__ */
-SUBDIRS=autoplug spider #seeking
-DIST_SUBDIRS=autoplug spider
+if USE_ALSA
+ALSA_DIR=alsa
+else
+ALSA_DIR=
+endif
+
+SUBDIRS=autoplug spider $(ALSA_DIR) #seeking
+DIST_SUBDIRS=autoplug spider alsa
GST_PLUGIN_PATH=$(shell cd $(top_builddir) && pwd)
--- /dev/null
+testprogs = formats
+
+TESTS = $(testprogs)
+
+check_PROGRAMS = $(testprogs)
+
+formats_SOURCES = formats.c sinesrc.c sinesrc.h
+
+# we have nothing but apps here, we can do this safely
+LIBS = $(GST_LIBS)
+AM_CFLAGS = $(GST_CFLAGS)
--- /dev/null
+/*
+ * Copyright (C) 2003 Benjamin Otte <in7y118@public.uni-hamburg.de>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "sinesrc.h"
+
+GstElement *pipeline;
+gint channels = 1;
+gboolean sign = FALSE;
+gint endianness = G_LITTLE_ENDIAN;
+gint depth = 8;
+gint width = 8;
+
+#define NUMBER_OF_INT_TESTS 16
+#define NUMBER_OF_FLOAT_TESTS 2
+#define NUMBER_OF_LAW_TESTS 2
+
+gint last = 0;
+gint counter = 0;
+
+static void create_pipeline (void);
+
+
+static void
+pre_get_func (SineSrc *src)
+{
+ counter ++;
+};
+static void
+create_pipeline (void)
+{
+ GstElement *src;
+ SineSrc *sinesrc;
+ GstElement *alsasink;
+
+ pipeline = gst_pipeline_new ("pipeline");
+ src = sinesrc_new ();
+ alsasink = gst_element_factory_make ("alsasink", "alsasink");
+
+ gst_bin_add_many (GST_BIN (pipeline), src, alsasink, NULL);
+ gst_element_link (src, alsasink);
+
+ /* prepare our sinesrc */
+ sinesrc = (SineSrc *) src;
+ sinesrc->pre_get_func = pre_get_func;
+ sinesrc->newcaps = TRUE;
+ /* int tests */
+ if (last < NUMBER_OF_INT_TESTS) {
+ sinesrc->type = SINE_SRC_INT;
+ sinesrc->sign = ((last % 2) == 0) ? TRUE : FALSE;
+ sinesrc->endianness = ((last / 2) % 2 == 0) ? G_LITTLE_ENDIAN : G_BIG_ENDIAN;
+ switch ((last / 4) % 8) {
+ case 0:
+ sinesrc->depth = 8;
+ sinesrc->width = 8;
+ break;
+ case 1:
+ sinesrc->depth = 16;
+ sinesrc->width = 16;
+ break;
+ case 2:
+ sinesrc->depth = 24;
+ sinesrc->width = 32;
+ break;
+ case 3:
+ sinesrc->depth = 32;
+ sinesrc->width = 32;
+ break;
+ /* nomore tests below until i know what 24bit width means to alsa wrt endianness */
+ case 4:
+ sinesrc->depth = 24;
+ sinesrc->width = 24;
+ break;
+ case 5:
+ sinesrc->depth = 20;
+ sinesrc->width = 24;
+ break;
+ case 6:
+ sinesrc->depth = 18;
+ sinesrc->width = 24;
+ break;
+ case 7:
+ /* not used yet */
+ sinesrc->depth = 8;
+ sinesrc->width = 8;
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ g_print ("Setting format to: format: \"int\"\n"
+ " sign: %s\n"
+ " endianness: %d\n"
+ " width: %d\n"
+ " depth: %d\n",
+ sinesrc->sign ? "TRUE" : "FALSE", sinesrc->endianness,
+ sinesrc->width, sinesrc->depth);
+ } else if (last < NUMBER_OF_INT_TESTS + NUMBER_OF_FLOAT_TESTS) {
+ gint temp = last - NUMBER_OF_INT_TESTS;
+ sinesrc->type = SINE_SRC_FLOAT;
+ switch (temp) {
+ case 0:
+ sinesrc->width = 32;
+ break;
+ case 1:
+ sinesrc->width = 64;
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+ g_print ("Setting format to: format: \"float\"\n"
+ " layout: \"%s\"\n"
+ " intercept: 0\n"
+ " slope: 1\n",
+ sinesrc->width == 32 ? "gfloat" : "gdouble");
+ } else if (last < NUMBER_OF_INT_TESTS + NUMBER_OF_FLOAT_TESTS + NUMBER_OF_LAW_TESTS) {
+ gint temp = last - NUMBER_OF_INT_TESTS - NUMBER_OF_FLOAT_TESTS;
+ GstElement *law;
+
+ sinesrc->type = SINE_SRC_INT;
+ sinesrc->sign = TRUE;
+ sinesrc->endianness = G_BYTE_ORDER;
+ sinesrc->depth = 16;
+ sinesrc->width = 16;
+
+ if (temp == 0) {
+ g_assert ((law = gst_element_factory_make ("mulawenc", "mulaw")));
+ } else {
+ g_assert ((law = gst_element_factory_make ("alawenc", "alaw")));
+ }
+ gst_element_unlink (src, alsasink);
+ gst_bin_add (GST_BIN (pipeline), law);
+ gst_element_link_many (src, law, alsasink, NULL);
+ if (temp == 0) {
+ g_print ("Setting format to: format: \"MU law\"\n");
+ } else {
+ g_print ("Setting format to: format: \"A law\"\n");
+ }
+ } else {
+ g_print ("All formats work like a charm.\n");
+ exit (0);
+ }
+ gst_element_set_state (pipeline, GST_STATE_PLAYING);
+}
+gint
+main (gint argc, gchar *argv[])
+{
+ gst_init (&argc, &argv);
+
+ g_print ("\n"
+ "This test will test the various formats ALSA and GStreamer support.\n"
+ "You will hear a short sine tone on your default ALSA soundcard for every\n"
+ "format tested. They should all sound the same.\n"
+ "\n");
+ create_pipeline ();
+
+ while (pipeline) {
+ gst_bin_iterate (GST_BIN (pipeline));
+ if ((counter / 400) > last) {
+ last = counter / 400;
+ gst_object_unref (GST_OBJECT (pipeline));
+ create_pipeline ();
+ }
+ }
+
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (C) 2003 Benjamin Otte <in7y118@public.uni-hamburg.de>
+ *
+ * sinesrc.c: An elemnt emitting a sine src in lots of different formats
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <math.h>
+#include "sinesrc.h"
+
+#define SAMPLES_PER_WAVE 200
+
+GST_PAD_TEMPLATE_FACTORY (sinesrc_src_factory,
+ "src",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ GST_CAPS_NEW (
+ "sinesrc_int_src",
+ "audio/raw",
+ "format", GST_PROPS_STRING ("int"),
+ "law", GST_PROPS_INT (0),
+ "endianness", GST_PROPS_LIST (GST_PROPS_INT (G_LITTLE_ENDIAN), GST_PROPS_INT (G_BIG_ENDIAN)),
+ "signed", GST_PROPS_LIST (GST_PROPS_BOOLEAN (FALSE), GST_PROPS_BOOLEAN (TRUE)),
+ "width", GST_PROPS_INT_RANGE (8, 32),
+ "depth", GST_PROPS_INT_RANGE (8, 32),
+ "rate", GST_PROPS_INT_RANGE (8000, 192000),
+ "channels", GST_PROPS_INT_RANGE (1, 16)
+ ),
+ GST_CAPS_NEW (
+ "sinesrc_float_src",
+ "audio/raw",
+ "format", GST_PROPS_STRING ("float"),
+ "layout", GST_PROPS_LIST (GST_PROPS_STRING ("gfloat"), GST_PROPS_STRING ("gdouble")),
+ "intercept", GST_PROPS_FLOAT (0),
+ "slope", GST_PROPS_FLOAT (1),
+ "channels", GST_PROPS_INT_RANGE (1, 16)
+ )
+);
+
+static GstElementClass *parent_class = NULL;
+
+static void sinesrc_init (SineSrc *src);
+static void sinesrc_class_init (SineSrcClass *klass);
+
+static GstBuffer * sinesrc_get (GstPad *pad);
+
+
+GType
+sinesrc_get_type (void)
+{
+ static GType sinesrc_type = 0;
+
+ if (!sinesrc_type) {
+ static const GTypeInfo sinesrc_info = {
+ sizeof (SineSrcClass), NULL, NULL,
+ (GClassInitFunc) sinesrc_class_init, NULL, NULL,
+ sizeof (SineSrc), 0,
+ (GInstanceInitFunc) sinesrc_init,
+ };
+ sinesrc_type = g_type_register_static (GST_TYPE_ELEMENT, "SineSrc",
+ &sinesrc_info, 0);
+ }
+ return sinesrc_type;
+}
+static void
+sinesrc_class_init (SineSrcClass *klass)
+{
+ parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
+}
+
+static void
+sinesrc_init (SineSrc *src)
+{
+ src->src = gst_pad_new_from_template (
+ GST_PAD_TEMPLATE_GET (sinesrc_src_factory), "src");
+ gst_element_add_pad (GST_ELEMENT(src), src->src);
+ gst_pad_set_get_function (src->src, sinesrc_get);
+
+ src->width = 16;
+ src->depth = 16;
+ src->sign = TRUE;
+ src->endianness = G_BYTE_ORDER;
+ src->rate = 44100;
+ src->channels = 1;
+ src->type = SINE_SRC_INT;
+ src->newcaps = TRUE;
+
+ src->pre_get_func = NULL;
+
+ GST_OBJECT (src)->name = "sinesrc";
+}
+
+static void
+sinesrc_force_caps (SineSrc *src) {
+ GstCaps *caps;
+
+ if (!src->newcaps)
+ return;
+
+ src->newcaps = FALSE;
+
+ switch (src->type) {
+ case SINE_SRC_INT:
+ caps = GST_CAPS_NEW (
+ "sinesrc_src_caps",
+ "audio/raw",
+ "format", GST_PROPS_STRING ("int"),
+ "law", GST_PROPS_INT (0),
+ "signed", GST_PROPS_BOOLEAN (src->sign),
+ "width", GST_PROPS_INT (src->width),
+ "depth", GST_PROPS_INT (src->depth)
+ );
+ if (src->width > 8)
+ gst_props_add_entry (gst_caps_get_props (caps),
+ gst_props_entry_new ("endianness",
+ GST_PROPS_INT (src->endianness)));
+ break;
+ case SINE_SRC_FLOAT:
+ g_assert (src->width == 32 || src->width == 64);
+ caps = GST_CAPS_NEW (
+ "sinesrc_src_caps",
+ "audio/raw",
+ "format", GST_PROPS_STRING ("float"),
+ "intercept", GST_PROPS_FLOAT (0),
+ "slope", GST_PROPS_FLOAT (1)
+ );
+ if (src->width == 32) {
+ gst_props_add_entry (gst_caps_get_props (caps),
+ gst_props_entry_new ("layout",
+ GST_PROPS_STRING ("gfloat")));
+ } else if (src->width == 64) {
+ gst_props_add_entry (gst_caps_get_props (caps),
+ gst_props_entry_new ("layout",
+ GST_PROPS_STRING ("gdouble")));
+ } else {
+ g_assert_not_reached ();
+ }
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ gst_props_add_entry (gst_caps_get_props (caps),
+ gst_props_entry_new ("rate", GST_PROPS_INT (src->rate)));
+ gst_props_add_entry (gst_caps_get_props (caps),
+ gst_props_entry_new ("channels", GST_PROPS_INT (src->channels)));
+
+ g_assert (gst_pad_try_set_caps (src->src, caps) == GST_PAD_LINK_OK);
+}
+/* always return 1 wave
+ * there are 200 waves in 1 second, so the frequency is samplerate/200
+ */
+static guint8 UIDENTITY(guint8 x) { return x; };
+static gint8 IDENTITY(gint8 x) { return x; };
+#define POPULATE(format, be_func, le_func) {\
+ format val = (format) int_value;\
+ switch (src->endianness) {\
+ case G_LITTLE_ENDIAN:\
+ val = le_func (val);\
+ break;\
+ case G_BIG_ENDIAN:\
+ val = be_func (val);\
+ break;\
+ default: \
+ g_assert_not_reached ();\
+ };\
+ format* p = data;\
+ for (j = 0; j < src->channels; j++) {\
+ *p = val;\
+ p ++;\
+ }\
+ data = p;\
+}
+static GstBuffer *
+sinesrc_get (GstPad *pad)
+{
+ GstBuffer *buf;
+ SineSrc *src;
+
+ void *data;
+ gint i, j;
+ gdouble value;
+
+ g_return_val_if_fail (pad != NULL, NULL);
+ src = SINESRC(gst_pad_get_parent (pad));
+
+ if (src->pre_get_func)
+ src->pre_get_func (src);
+
+ g_assert ((buf = gst_buffer_new_and_alloc ((src->width / 8) * src->channels * SAMPLES_PER_WAVE)));
+ g_assert ((data = GST_BUFFER_DATA(buf)));
+
+ for (i = 0; i < SAMPLES_PER_WAVE; i++) {
+ value = sin (i * 2 * M_PI / SAMPLES_PER_WAVE);
+ switch (src->type) {
+ case SINE_SRC_INT: {
+ gint64 int_value = (value + (src->sign ? 0 : 1)) * (((guint64) 1) << (src->depth - 1));
+ if (int_value == (1 + (src->sign ? 0 : 1)) * (((guint64) 1) << (src->depth - 1))) int_value--;
+ switch (src->width) {
+ case 8:
+ if (src->sign)
+ POPULATE (gint8, IDENTITY, IDENTITY)
+ else
+ POPULATE (guint8, UIDENTITY, UIDENTITY)
+ break;
+ case 16:
+ if (src->sign)
+ POPULATE (gint16, GINT16_TO_BE, GINT16_TO_LE)
+ else
+ POPULATE (guint16, GUINT16_TO_BE, GUINT16_TO_LE)
+ break;
+ case 24:
+ /* mom, can I have gint24 plz? */
+ g_assert_not_reached ();
+ break;
+ case 32:
+ if (src->sign)
+ POPULATE (gint32, GINT32_TO_BE, GINT32_TO_LE)
+ else
+ POPULATE (guint32, GUINT32_TO_BE, GUINT32_TO_LE)
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+ break;
+ }
+ case SINE_SRC_FLOAT:
+ if (src->width == 32) {
+ gfloat *p = (gfloat *) data;
+ gfloat fval = (gfloat) value;
+ for (j = 0; j < src->channels; j++) {
+ *p = fval;
+ p++;
+ }
+ data = p;
+ break;
+ }
+ if (src->width == 64) {
+ gdouble *p = (gdouble *) data;
+ for (j = 0; j < src->channels; j++) {
+ *p = value;
+ p++;
+ }
+ data = p;
+ break;
+ }
+ g_assert_not_reached ();
+ default:
+ g_assert_not_reached ();
+ }
+ }
+
+ if (src->newcaps) {
+ sinesrc_force_caps(src);
+ }
+ return buf;
+}
+
+GstElement *
+sinesrc_new (void)
+{
+ return GST_ELEMENT (g_object_new (TYPE_SINESRC, NULL));
+}
+void
+sinesrc_set_pre_get_func (SineSrc *src, PreGetFunc func)
+{
+ src->pre_get_func = func;
+}
--- /dev/null
+/*
+ * Copyright (C) 2003 Benjamin Otte <in7y118@public.uni-hamburg.de>
+ *
+ * sinesrc.h: Header file for sinesrc.c
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __SINESRC_H__
+#define __SINESRC_H__
+
+
+#include <config.h>
+#include <gst/gst.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define TYPE_SINESRC \
+ (sinesrc_get_type())
+#define SINESRC(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj),TYPE_SINESRC,SineSrc))
+#define SINESRC_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass),TYPE_SINESRC,SineSrcClass))
+#define IS_SINESRC(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),TYPE_SINESRC))
+#define IS_SINESRC_CLASS(obj) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass),TYPE_SINESRC))
+
+typedef struct _SineSrc SineSrc;
+typedef struct _SineSrcClass SineSrcClass;
+
+typedef void (*PreGetFunc) (SineSrc *src);
+
+typedef enum {
+ SINE_SRC_INT,
+ SINE_SRC_FLOAT
+} SineSrcAudio;
+
+struct _SineSrc {
+ GstElement element;
+
+ /* pads */
+ GstPad *src;
+
+ /* audio parameters */
+ SineSrcAudio type;
+ gint width; /* int + float */
+ gint depth; /* int */
+ gboolean sign; /* int */
+ gint endianness; /* int */
+
+ gint rate;
+ gint channels; /* interleaved */
+
+ gboolean newcaps;
+
+ /* freaky stuff for testing */
+ PreGetFunc pre_get_func;
+};
+
+struct _SineSrcClass {
+ GstElementClass parent_class;
+};
+
+GType sinesrc_get_type (void);
+GstElement * sinesrc_new (void);
+
+void sinesrc_set_pre_get_func (SineSrc *src, PreGetFunc func);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GST_SINESRC_H__ */