diff options
author | Benjamin Otte <otte@gnome.org> | 2003-03-03 23:15:21 +0000 |
---|---|---|
committer | Benjamin Otte <otte@gnome.org> | 2003-03-03 23:15:21 +0000 |
commit | 91e18767bc7a9a4c08d5b12e3f984a7ac760b1f6 (patch) | |
tree | 5972fb3812ef8226d0fe0c2569b0483a26e35919 | |
parent | efcf22752452e188ede9244439e0e4cfc49d4b5d (diff) | |
download | gstreamer-plugins-base-91e18767bc7a9a4c08d5b12e3f984a7ac760b1f6.tar.gz |
started tests for alsa. Doesn't work yet due to scheduler bugs, but I commit it anyway so everyone has it in Norway ;)
Original commit message from CVS:
started tests for alsa. Doesn't work yet due to scheduler bugs, but I commit it anyway so everyone has it in Norway ;)
-rw-r--r-- | tests/old/Makefile.am | 10 | ||||
-rw-r--r-- | tests/old/testsuite/alsa/Makefile.am | 11 | ||||
-rw-r--r-- | tests/old/testsuite/alsa/formats.c | 181 | ||||
-rw-r--r-- | tests/old/testsuite/alsa/sinesrc.c | 280 | ||||
-rw-r--r-- | tests/old/testsuite/alsa/sinesrc.h | 90 | ||||
-rw-r--r-- | testsuite/Makefile.am | 10 | ||||
-rw-r--r-- | testsuite/alsa/Makefile.am | 11 | ||||
-rw-r--r-- | testsuite/alsa/formats.c | 181 | ||||
-rw-r--r-- | testsuite/alsa/sinesrc.c | 280 | ||||
-rw-r--r-- | testsuite/alsa/sinesrc.h | 90 |
10 files changed, 1140 insertions, 4 deletions
diff --git a/tests/old/Makefile.am b/tests/old/Makefile.am index 31fd80606..c2b9b2194 100644 --- a/tests/old/Makefile.am +++ b/tests/old/Makefile.am @@ -1,5 +1,11 @@ -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) diff --git a/tests/old/testsuite/alsa/Makefile.am b/tests/old/testsuite/alsa/Makefile.am new file mode 100644 index 000000000..e00f26b00 --- /dev/null +++ b/tests/old/testsuite/alsa/Makefile.am @@ -0,0 +1,11 @@ +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) diff --git a/tests/old/testsuite/alsa/formats.c b/tests/old/testsuite/alsa/formats.c new file mode 100644 index 000000000..24d5965e4 --- /dev/null +++ b/tests/old/testsuite/alsa/formats.c @@ -0,0 +1,181 @@ +/* + * 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; +} diff --git a/tests/old/testsuite/alsa/sinesrc.c b/tests/old/testsuite/alsa/sinesrc.c new file mode 100644 index 000000000..4ee01f341 --- /dev/null +++ b/tests/old/testsuite/alsa/sinesrc.c @@ -0,0 +1,280 @@ +/* + * 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; +} diff --git a/tests/old/testsuite/alsa/sinesrc.h b/tests/old/testsuite/alsa/sinesrc.h new file mode 100644 index 000000000..ab352378f --- /dev/null +++ b/tests/old/testsuite/alsa/sinesrc.h @@ -0,0 +1,90 @@ +/* + * 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__ */ diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am index 31fd80606..c2b9b2194 100644 --- a/testsuite/Makefile.am +++ b/testsuite/Makefile.am @@ -1,5 +1,11 @@ -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) diff --git a/testsuite/alsa/Makefile.am b/testsuite/alsa/Makefile.am new file mode 100644 index 000000000..e00f26b00 --- /dev/null +++ b/testsuite/alsa/Makefile.am @@ -0,0 +1,11 @@ +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) diff --git a/testsuite/alsa/formats.c b/testsuite/alsa/formats.c new file mode 100644 index 000000000..24d5965e4 --- /dev/null +++ b/testsuite/alsa/formats.c @@ -0,0 +1,181 @@ +/* + * 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; +} diff --git a/testsuite/alsa/sinesrc.c b/testsuite/alsa/sinesrc.c new file mode 100644 index 000000000..4ee01f341 --- /dev/null +++ b/testsuite/alsa/sinesrc.c @@ -0,0 +1,280 @@ +/* + * 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; +} diff --git a/testsuite/alsa/sinesrc.h b/testsuite/alsa/sinesrc.h new file mode 100644 index 000000000..ab352378f --- /dev/null +++ b/testsuite/alsa/sinesrc.h @@ -0,0 +1,90 @@ +/* + * 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__ */ |