Index: tests/check/Makefile.am
===================================================================
RCS file: /cvs/gstreamer/gst-plugins-base/tests/check/Makefile.am,v
retrieving revision 1.75
diff -u -p -u -p -r1.75 Makefile.am
--- tests/check/Makefile.am	21 Jul 2007 09:21:12 -0000	1.75
+++ tests/check/Makefile.am	23 Aug 2007 21:31:26 -0000
@@ -89,6 +89,7 @@ check_PROGRAMS = \
 	gst/typefindfunctions \
 	libs/audio \
 	libs/cddabasesrc \
+	libs/fft \
 	libs/mixer \
 	libs/netbuffer \
 	libs/pbutils \
@@ -139,6 +140,16 @@ libs_cddabasesrc_LDADD = \
 	$(GST_BASE_LIBS) \
 	$(LDADD)
 
+libs_fft_CFLAGS = \
+	$(GST_PLUGINS_BASE_CFLAGS) \
+	$(GST_BASE_CFLAGS) \
+	$(AM_CFLAGS)
+
+libs_fft_LDADD = \
+	$(top_builddir)/gst-libs/gst/fft/libgstfft-@GST_MAJORMINOR@.la \
+	$(GST_BASE_LIBS) \
+	$(LDADD)
+
 libs_mixer_CFLAGS = \
 	$(GST_PLUGINS_BASE_CFLAGS) \
         $(GST_BASE_CFLAGS) \
@@ -249,6 +260,10 @@ libs_video_LDADD = \
 	$(GST_BASE_LIBS) \
 	$(LDADD)
 
+pipelines_vorbisenc_CFLAGS = \
+        $(GST_PLUGINS_BASE_CFLAGS) \
+        $(AM_CFLAGS)
+
 # this seemingly useless CFLAGS line is here only to avoid
 # vorbisdec.$(OBJEXT) by triggering creation of pipelines_vorbisdec.$(OBJEXT)
 # instead
Index: tests/check/libs/fft.c
===================================================================
RCS file: tests/check/libs/fft.c
diff -N tests/check/libs/fft.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/check/libs/fft.c	23 Aug 2007 21:31:26 -0000
@@ -0,0 +1,504 @@
+/* GStreamer
+ *
+ * unit test for FFT library
+ *
+ * Copyright (C) 2007 Sebastian Dröge <slomo@circular-chaos.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gst/check/gstcheck.h>
+
+#include <gst/fft/gstfft.h>
+#include <gst/fft/gstffts16.h>
+#include <gst/fft/gstffts32.h>
+#include <gst/fft/gstfftf32.h>
+#include <gst/fft/gstfftf64.h>
+
+GST_START_TEST (test_next_fast_length)
+{
+  fail_unless_equals_int (gst_fft_next_fast_length (13), 16);
+  fail_unless_equals_int (gst_fft_next_fast_length (30), 30);
+  fail_unless_equals_int (gst_fft_next_fast_length (31), 32);
+  fail_unless_equals_int (gst_fft_next_fast_length (1), 2);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_s16_0hz)
+{
+  gint i;
+  gint16 *in;
+  GstFFTS16Complex *out;
+  gdouble *mag;
+  GstFFTS16 *ctx;
+
+  in = g_new (gint16, 2048);
+  out = g_new (GstFFTS16Complex, 1025);
+  mag = g_new (gdouble, 1025);
+  ctx = gst_fft_s16_new (2048, FALSE);
+
+  for (i = 0; i < 2048; i++)
+    in[i] = G_MAXINT16;
+
+  gst_fft_s16_window (ctx, in, GST_FFT_WINDOW_HAMMING);
+  gst_fft_s16_fft (ctx, in, out);
+  gst_fft_s16_magnitude (ctx, out, mag, TRUE);
+
+  for (i = 0; i < 1025; i++) {
+    fail_if (i < 2 && mag[i] < -15.0);
+    fail_if (i >= 2 && mag[i] > -60.0);
+  }
+
+  gst_fft_s16_free (ctx);
+  g_free (in);
+  g_free (out);
+  g_free (mag);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_s16_11025hz)
+{
+  gint i;
+  gint16 *in;
+  GstFFTS16Complex *out;
+  gdouble *mag;
+  GstFFTS16 *ctx;
+
+  in = g_new (gint16, 2048);
+  out = g_new (GstFFTS16Complex, 1025);
+  mag = g_new (gdouble, 1025);
+  ctx = gst_fft_s16_new (2048, FALSE);
+
+  for (i = 0; i < 2048; i += 4) {
+    in[i] = 0;
+    in[i+1] = G_MAXINT16;
+    in[i+2] = 0;
+    in[i+3] = G_MININT16;
+  }
+
+  gst_fft_s16_window (ctx, in, GST_FFT_WINDOW_HAMMING);
+  gst_fft_s16_fft (ctx, in, out);
+  gst_fft_s16_magnitude (ctx, out, mag, TRUE);
+
+  for (i = 0; i < 1025; i++) {
+    fail_if (abs (512 - i) < 2 && mag[i] < -20.0);
+    fail_if (abs (512 - i) >= 2 && mag[i] > -60.0);
+  }
+
+  gst_fft_s16_free (ctx);
+  g_free (in);
+  g_free (out);
+  g_free (mag);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_s16_22050hz)
+{
+  gint i;
+  gint16 *in;
+  GstFFTS16Complex *out;
+  gdouble *mag;
+  GstFFTS16 *ctx;
+
+  in = g_new (gint16, 2048);
+  out = g_new (GstFFTS16Complex, 1025);
+  mag = g_new (gdouble, 1025);
+  ctx = gst_fft_s16_new (2048, FALSE);
+
+  for (i = 0; i < 2048; i += 2) {
+    in[i] = G_MAXINT16;
+    in[i+1] = G_MININT16;
+  }
+
+  gst_fft_s16_window (ctx, in, GST_FFT_WINDOW_HAMMING);
+  gst_fft_s16_fft (ctx, in, out);
+  gst_fft_s16_magnitude (ctx, out, mag, TRUE);
+
+  for (i = 0; i < 1025; i++) {
+    fail_if (i > 1022 && mag[i] < -20.0);
+    fail_if (i <= 1022 && mag[i] > -60.0);
+  }
+
+  gst_fft_s16_free (ctx);
+  g_free (in);
+  g_free (out);
+  g_free (mag);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_s32_0hz)
+{
+  gint i;
+  gint32 *in;
+  GstFFTS32Complex *out;
+  gdouble *mag;
+  GstFFTS32 *ctx;
+
+  in = g_new (gint32, 2048);
+  out = g_new (GstFFTS32Complex, 1025);
+  mag = g_new (gdouble, 1025);
+  ctx = gst_fft_s32_new (2048, FALSE);
+
+  for (i = 0; i < 2048; i++)
+    in[i] = 2147483647;
+
+  gst_fft_s32_window (ctx, in, GST_FFT_WINDOW_HAMMING);
+  gst_fft_s32_fft (ctx, in, out);
+  gst_fft_s32_magnitude (ctx, out, mag, TRUE);
+
+  for (i = 0; i < 1025; i++) {
+    fail_if (i < 2 && mag[i] < -15.0);
+    fail_if (i >= 2 && mag[i] > -60.0);
+  }
+
+  gst_fft_s32_free (ctx);
+  g_free (in);
+  g_free (out);
+  g_free (mag);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_s32_11025hz)
+{
+  gint i;
+  gint32 *in;
+  GstFFTS32Complex *out;
+  gdouble *mag;
+  GstFFTS32 *ctx;
+
+  in = g_new (gint32, 2048);
+  out = g_new (GstFFTS32Complex, 1025);
+  mag = g_new (gdouble, 1025);
+  ctx = gst_fft_s32_new (2048, FALSE);
+
+  for (i = 0; i < 2048; i += 4) {
+    in[i] = 0;
+    in[i+1] = G_MAXINT32;
+    in[i+2] = 0;
+    in[i+3] = G_MININT32;
+  }
+
+  gst_fft_s32_window (ctx, in, GST_FFT_WINDOW_HAMMING);
+  gst_fft_s32_fft (ctx, in, out);
+  gst_fft_s32_magnitude (ctx, out, mag, TRUE);
+
+  for (i = 0; i < 1025; i++) {
+    fail_if (abs (512 - i) < 2 && mag[i] < -20.0);
+    fail_if (abs (512 - i) >= 2 && mag[i] > -60.0);
+  }
+
+  gst_fft_s32_free (ctx);
+  g_free (in);
+  g_free (out);
+  g_free (mag);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_s32_22050hz)
+{
+  gint i;
+  gint32 *in;
+  GstFFTS32Complex *out;
+  gdouble *mag;
+  GstFFTS32 *ctx;
+
+  in = g_new (gint32, 2048);
+  out = g_new (GstFFTS32Complex, 1025);
+  mag = g_new (gdouble, 1025);
+  ctx = gst_fft_s32_new (2048, FALSE);
+
+  for (i = 0; i < 2048; i += 2) {
+    in[i] = G_MAXINT32;
+    in[i+1] = G_MININT32;
+  }
+
+  gst_fft_s32_window (ctx, in, GST_FFT_WINDOW_HAMMING);
+  gst_fft_s32_fft (ctx, in, out);
+  gst_fft_s32_magnitude (ctx, out, mag, TRUE);
+
+  for (i = 0; i < 1025; i++) {
+    fail_if (i > 1022 && mag[i] < -20.0);
+    fail_if (i <= 1022 && mag[i] > -60.0);
+  }
+
+  gst_fft_s32_free (ctx);
+  g_free (in);
+  g_free (out);
+  g_free (mag);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_f32_0hz)
+{
+  gint i;
+  gfloat *in;
+  GstFFTF32Complex *out;
+  gdouble *mag;
+  GstFFTF32 *ctx;
+
+  in = g_new (gfloat, 2048);
+  out = g_new (GstFFTF32Complex, 1025);
+  mag = g_new (gdouble, 1025);
+  ctx = gst_fft_f32_new (2048, FALSE);
+
+  for (i = 0; i < 2048; i++)
+    in[i] = 1.0;
+
+  gst_fft_f32_window (ctx, in, GST_FFT_WINDOW_HAMMING);
+  gst_fft_f32_fft (ctx, in, out);
+  gst_fft_f32_magnitude (ctx, out, mag, TRUE);
+
+  for (i = 0; i < 1025; i++) {
+    fail_if (i < 2 && mag[i] < -15.0);
+    fail_if (i >= 2 && mag[i] > -60.0);
+  }
+
+  gst_fft_f32_free (ctx);
+  g_free (in);
+  g_free (out);
+  g_free (mag);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_f32_11025hz)
+{
+  gint i;
+  gfloat *in;
+  GstFFTF32Complex *out;
+  gdouble *mag;
+  GstFFTF32 *ctx;
+
+  in = g_new (gfloat, 2048);
+  out = g_new (GstFFTF32Complex, 1025);
+  mag = g_new (gdouble, 1025);
+  ctx = gst_fft_f32_new (2048, FALSE);
+
+  for (i = 0; i < 2048; i += 4) {
+    in[i] = 0.0;
+    in[i+1] = 1.0;
+    in[i+2] = 0.0;
+    in[i+3] = -1.0;
+  }
+
+  gst_fft_f32_window (ctx, in, GST_FFT_WINDOW_HAMMING);
+  gst_fft_f32_fft (ctx, in, out);
+  gst_fft_f32_magnitude (ctx, out, mag, TRUE);
+
+  for (i = 0; i < 1025; i++) {
+    fail_if (abs (512 - i) < 2 && mag[i] < -20.0);
+    fail_if (abs (512 - i) >= 2 && mag[i] > -60.0);
+  }
+
+  gst_fft_f32_free (ctx);
+  g_free (in);
+  g_free (out);
+  g_free (mag);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_f32_22050hz)
+{
+  gint i;
+  gfloat *in;
+  GstFFTF32Complex *out;
+  gdouble *mag;
+  GstFFTF32 *ctx;
+
+  in = g_new (gfloat, 2048);
+  out = g_new (GstFFTF32Complex, 1025);
+  mag = g_new (gdouble, 1025);
+  ctx = gst_fft_f32_new (2048, FALSE);
+
+  for (i = 0; i < 2048; i += 2) {
+    in[i] = 1.0;
+    in[i+1] = -1.0;
+  }
+
+  gst_fft_f32_window (ctx, in, GST_FFT_WINDOW_HAMMING);
+  gst_fft_f32_fft (ctx, in, out);
+  gst_fft_f32_magnitude (ctx, out, mag, TRUE);
+
+  for (i = 0; i < 1025; i++) {
+    fail_if (i > 1022 && mag[i] < -20.0);
+    fail_if (i <= 1022 && mag[i] > -60.0);
+  }
+
+  gst_fft_f32_free (ctx);
+  g_free (in);
+  g_free (out);
+  g_free (mag);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_f64_0hz)
+{
+  gint i;
+  gdouble *in;
+  GstFFTF64Complex *out;
+  gdouble *mag;
+  GstFFTF64 *ctx;
+
+  in = g_new (gdouble, 2048);
+  out = g_new (GstFFTF64Complex, 1025);
+  mag = g_new (gdouble, 1025);
+  ctx = gst_fft_f64_new (2048, FALSE);
+
+  for (i = 0; i < 2048; i++)
+    in[i] = 1.0;
+
+  gst_fft_f64_window (ctx, in, GST_FFT_WINDOW_HAMMING);
+  gst_fft_f64_fft (ctx, in, out);
+  gst_fft_f64_magnitude (ctx, out, mag, TRUE);
+
+  for (i = 0; i < 1025; i++) {
+    fail_if (i < 2 && mag[i] < -15.0);
+    fail_if (i >= 2 && mag[i] > -60.0);
+  }
+
+  gst_fft_f64_free (ctx);
+  g_free (in);
+  g_free (out);
+  g_free (mag);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_f64_11025hz)
+{
+  gint i;
+  gdouble *in;
+  GstFFTF64Complex *out;
+  gdouble *mag;
+  GstFFTF64 *ctx;
+
+  in = g_new (gdouble, 2048);
+  out = g_new (GstFFTF64Complex, 1025);
+  mag = g_new (gdouble, 1025);
+  ctx = gst_fft_f64_new (2048, FALSE);
+
+  for (i = 0; i < 2048; i += 4) {
+    in[i] = 0.0;
+    in[i+1] = 1.0;
+    in[i+2] = 0.0;
+    in[i+3] = -1.0;
+  }
+
+  gst_fft_f64_window (ctx, in, GST_FFT_WINDOW_HAMMING);
+  gst_fft_f64_fft (ctx, in, out);
+  gst_fft_f64_magnitude (ctx, out, mag, TRUE);
+
+  for (i = 0; i < 1025; i++) {
+    fail_if (abs (512 - i) < 2 && mag[i] < -20.0);
+    fail_if (abs (512 - i) >= 2 && mag[i] > -60.0);
+  }
+
+  gst_fft_f64_free (ctx);
+  g_free (in);
+  g_free (out);
+  g_free (mag);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_f64_22050hz)
+{
+  gint i;
+  gdouble *in;
+  GstFFTF64Complex *out;
+  gdouble *mag;
+  GstFFTF64 *ctx;
+
+  in = g_new (gdouble, 2048);
+  out = g_new (GstFFTF64Complex, 1025);
+  mag = g_new (gdouble, 1025);
+  ctx = gst_fft_f64_new (2048, FALSE);
+
+  for (i = 0; i < 2048; i += 2) {
+    in[i] = 1.0;
+    in[i+1] = -1.0;
+  }
+
+  gst_fft_f64_window (ctx, in, GST_FFT_WINDOW_HAMMING);
+  gst_fft_f64_fft (ctx, in, out);
+  gst_fft_f64_magnitude (ctx, out, mag, TRUE);
+
+  for (i = 0; i < 1025; i++) {
+    fail_if (i > 1022 && mag[i] < -20.0);
+    fail_if (i <= 1022 && mag[i] > -60.0);
+  }
+
+  gst_fft_f64_free (ctx);
+  g_free (in);
+  g_free (out);
+  g_free (mag);
+}
+
+GST_END_TEST;
+
+static Suite *
+fft_suite (void)
+{
+  Suite *s = suite_create ("fft library");
+  TCase *tc_chain = tcase_create ("general");
+
+  suite_add_tcase (s, tc_chain);
+  tcase_add_test (tc_chain, test_next_fast_length);
+  tcase_add_test (tc_chain, test_s16_0hz);
+  tcase_add_test (tc_chain, test_s16_11025hz);
+  tcase_add_test (tc_chain, test_s16_22050hz);
+  tcase_add_test (tc_chain, test_s32_0hz);
+  tcase_add_test (tc_chain, test_s32_11025hz);
+  tcase_add_test (tc_chain, test_s32_22050hz);
+  tcase_add_test (tc_chain, test_f32_0hz);
+  tcase_add_test (tc_chain, test_f32_11025hz);
+  tcase_add_test (tc_chain, test_f32_22050hz);
+  tcase_add_test (tc_chain, test_f64_0hz);
+  tcase_add_test (tc_chain, test_f64_11025hz);
+  tcase_add_test (tc_chain, test_f64_22050hz);
+
+  return s;
+}
+
+int
+main (int argc, char **argv)
+{
+  int nf;
+
+  Suite *s = fft_suite ();
+  SRunner *sr = srunner_create (s);
+
+  gst_check_init (&argc, &argv);
+
+  srunner_run_all (sr, CK_NORMAL);
+  nf = srunner_ntests_failed (sr);
+  srunner_free (sr);
+
+  return nf;
+}
