started tests for alsa. Doesn't work yet due to scheduler bugs, but I commit it anywa...
authorBenjamin Otte <otte@gnome.org>
Mon, 3 Mar 2003 23:15:21 +0000 (23:15 +0000)
committerBenjamin Otte <otte@gnome.org>
Mon, 3 Mar 2003 23:15:21 +0000 (23:15 +0000)
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 ;)

tests/old/Makefile.am
tests/old/testsuite/alsa/Makefile.am [new file with mode: 0644]
tests/old/testsuite/alsa/formats.c [new file with mode: 0644]
tests/old/testsuite/alsa/sinesrc.c [new file with mode: 0644]
tests/old/testsuite/alsa/sinesrc.h [new file with mode: 0644]
testsuite/Makefile.am
testsuite/alsa/Makefile.am [new file with mode: 0644]
testsuite/alsa/formats.c [new file with mode: 0644]
testsuite/alsa/sinesrc.c [new file with mode: 0644]
testsuite/alsa/sinesrc.h [new file with mode: 0644]

index 31fd806..c2b9b21 100644 (file)
@@ -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 (file)
index 0000000..e00f26b
--- /dev/null
@@ -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 (file)
index 0000000..24d5965
--- /dev/null
@@ -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 (file)
index 0000000..4ee01f3
--- /dev/null
@@ -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 (file)
index 0000000..ab35237
--- /dev/null
@@ -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__ */
index 31fd806..c2b9b21 100644 (file)
@@ -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 (file)
index 0000000..e00f26b
--- /dev/null
@@ -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 (file)
index 0000000..24d5965
--- /dev/null
@@ -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 (file)
index 0000000..4ee01f3
--- /dev/null
@@ -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 (file)
index 0000000..ab35237
--- /dev/null
@@ -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__ */