3 * unit test for FFT library
5 * Copyright (C) 2007 Sebastian Dröge <slomo@circular-chaos.org>
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
27 #include <gst/check/gstcheck.h>
29 #include <gst/fft/gstfft.h>
30 #include <gst/fft/gstffts16.h>
31 #include <gst/fft/gstffts32.h>
32 #include <gst/fft/gstfftf32.h>
33 #include <gst/fft/gstfftf64.h>
35 GST_START_TEST (test_next_fast_length)
37 fail_unless_equals_int (gst_fft_next_fast_length (13), 16);
38 fail_unless_equals_int (gst_fft_next_fast_length (30), 30);
39 fail_unless_equals_int (gst_fft_next_fast_length (31), 32);
40 fail_unless_equals_int (gst_fft_next_fast_length (1), 2);
45 GST_START_TEST (test_s16_0hz)
49 GstFFTS16Complex *out;
52 in = g_new (gint16, 2048);
53 out = g_new (GstFFTS16Complex, 1025);
54 ctx = gst_fft_s16_new (2048, FALSE);
56 for (i = 0; i < 2048; i++)
59 gst_fft_s16_window (ctx, in, GST_FFT_WINDOW_HAMMING);
60 gst_fft_s16_fft (ctx, in, out);
62 for (i = 0; i < 1025; i++) {
65 mag = (gdouble) out[i].r * (gdouble) out[i].r;
66 mag += (gdouble) out[i].i * (gdouble) out[i].i;
67 mag /= 32767.0 * 32767.0;
68 mag = 10.0 * log10 (mag);
70 fail_unless (mag > -15.0);
72 fail_unless (mag < -55.0);
75 gst_fft_s16_free (ctx);
82 GST_START_TEST (test_s16_11025hz)
86 GstFFTS16Complex *out;
89 in = g_new (gint16, 2048);
90 out = g_new (GstFFTS16Complex, 1025);
91 ctx = gst_fft_s16_new (2048, FALSE);
93 for (i = 0; i < 2048; i += 4) {
95 in[i + 1] = G_MAXINT16;
97 in[i + 3] = G_MININT16;
100 gst_fft_s16_window (ctx, in, GST_FFT_WINDOW_HAMMING);
101 gst_fft_s16_fft (ctx, in, out);
103 for (i = 0; i < 1025; i++) {
106 mag = (gdouble) out[i].r * (gdouble) out[i].r;
107 mag += (gdouble) out[i].i * (gdouble) out[i].i;
108 mag /= 32767.0 * 32767.0;
109 mag = 10.0 * log10 (mag);
111 if (abs (512 - i) < 2)
112 fail_unless (mag > -20.0);
114 fail_unless (mag < -55.0);
117 gst_fft_s16_free (ctx);
124 GST_START_TEST (test_s16_22050hz)
128 GstFFTS16Complex *out;
131 in = g_new (gint16, 2048);
132 out = g_new (GstFFTS16Complex, 1025);
133 ctx = gst_fft_s16_new (2048, FALSE);
135 for (i = 0; i < 2048; i += 2) {
137 in[i + 1] = G_MININT16;
140 gst_fft_s16_window (ctx, in, GST_FFT_WINDOW_HAMMING);
141 gst_fft_s16_fft (ctx, in, out);
143 for (i = 0; i < 1025; i++) {
146 mag = (gdouble) out[i].r * (gdouble) out[i].r;
147 mag += (gdouble) out[i].i * (gdouble) out[i].i;
148 mag /= 32767.0 * 32767.0;
149 mag = 10.0 * log10 (mag);
152 fail_unless (mag > -15.0);
154 fail_unless (mag < -55.0);
157 gst_fft_s16_free (ctx);
164 GST_START_TEST (test_s32_0hz)
168 GstFFTS32Complex *out;
171 in = g_new (gint32, 2048);
172 out = g_new (GstFFTS32Complex, 1025);
173 ctx = gst_fft_s32_new (2048, FALSE);
175 for (i = 0; i < 2048; i++)
178 gst_fft_s32_window (ctx, in, GST_FFT_WINDOW_HAMMING);
179 gst_fft_s32_fft (ctx, in, out);
181 for (i = 0; i < 1025; i++) {
184 mag = (gdouble) out[i].r * (gdouble) out[i].r;
185 mag += (gdouble) out[i].i * (gdouble) out[i].i;
186 mag /= 2147483647.0 * 2147483647.0;
187 mag = 10.0 * log10 (mag);
190 fail_unless (mag > -15.0);
192 fail_unless (mag < -60.0);
195 gst_fft_s32_free (ctx);
202 GST_START_TEST (test_s32_11025hz)
206 GstFFTS32Complex *out;
209 in = g_new (gint32, 2048);
210 out = g_new (GstFFTS32Complex, 1025);
211 ctx = gst_fft_s32_new (2048, FALSE);
213 for (i = 0; i < 2048; i += 4) {
215 in[i + 1] = G_MAXINT32;
217 in[i + 3] = G_MININT32;
220 gst_fft_s32_window (ctx, in, GST_FFT_WINDOW_HAMMING);
221 gst_fft_s32_fft (ctx, in, out);
223 for (i = 0; i < 1025; i++) {
226 mag = (gdouble) out[i].r * (gdouble) out[i].r;
227 mag += (gdouble) out[i].i * (gdouble) out[i].i;
228 mag /= 2147483647.0 * 2147483647.0;
229 mag = 10.0 * log10 (mag);
231 if (abs (512 - i) < 2)
232 fail_unless (mag > -20.0);
234 fail_unless (mag < -60.0);
237 gst_fft_s32_free (ctx);
244 GST_START_TEST (test_s32_22050hz)
248 GstFFTS32Complex *out;
251 in = g_new (gint32, 2048);
252 out = g_new (GstFFTS32Complex, 1025);
253 ctx = gst_fft_s32_new (2048, FALSE);
255 for (i = 0; i < 2048; i += 2) {
257 in[i + 1] = G_MININT32;
260 gst_fft_s32_window (ctx, in, GST_FFT_WINDOW_HAMMING);
261 gst_fft_s32_fft (ctx, in, out);
263 for (i = 0; i < 1025; i++) {
266 mag = (gdouble) out[i].r * (gdouble) out[i].r;
267 mag += (gdouble) out[i].i * (gdouble) out[i].i;
268 mag /= 2147483647.0 * 2147483647.0;
269 mag = 10.0 * log10 (mag);
272 fail_unless (mag > -15.0);
274 fail_unless (mag < -60.0);
277 gst_fft_s32_free (ctx);
284 GST_START_TEST (test_f32_0hz)
288 GstFFTF32Complex *out;
291 in = g_new (gfloat, 2048);
292 out = g_new (GstFFTF32Complex, 1025);
293 ctx = gst_fft_f32_new (2048, FALSE);
295 for (i = 0; i < 2048; i++)
298 gst_fft_f32_window (ctx, in, GST_FFT_WINDOW_HAMMING);
299 gst_fft_f32_fft (ctx, in, out);
301 for (i = 0; i < 1025; i++) {
304 mag = (gdouble) out[i].r * (gdouble) out[i].r;
305 mag += (gdouble) out[i].i * (gdouble) out[i].i;
306 mag /= 2048.0 * 2048.0;
307 mag = 10.0 * log10 (mag);
310 fail_unless (mag > -15.0);
312 fail_unless (mag < -60.0);
315 gst_fft_f32_free (ctx);
322 GST_START_TEST (test_f32_11025hz)
326 GstFFTF32Complex *out;
329 in = g_new (gfloat, 2048);
330 out = g_new (GstFFTF32Complex, 1025);
331 ctx = gst_fft_f32_new (2048, FALSE);
333 for (i = 0; i < 2048; i += 4) {
340 gst_fft_f32_window (ctx, in, GST_FFT_WINDOW_HAMMING);
341 gst_fft_f32_fft (ctx, in, out);
343 for (i = 0; i < 1025; i++) {
346 mag = (gdouble) out[i].r * (gdouble) out[i].r;
347 mag += (gdouble) out[i].i * (gdouble) out[i].i;
348 mag /= 2048.0 * 2048.0;
349 mag = 10.0 * log10 (mag);
351 if (abs (512 - i) < 2)
352 fail_unless (mag > -20.0);
354 fail_unless (mag < -60.0);
357 gst_fft_f32_free (ctx);
364 GST_START_TEST (test_f32_22050hz)
368 GstFFTF32Complex *out;
371 in = g_new (gfloat, 2048);
372 out = g_new (GstFFTF32Complex, 1025);
373 ctx = gst_fft_f32_new (2048, FALSE);
375 for (i = 0; i < 2048; i += 2) {
380 gst_fft_f32_window (ctx, in, GST_FFT_WINDOW_HAMMING);
381 gst_fft_f32_fft (ctx, in, out);
383 for (i = 0; i < 1025; i++) {
386 mag = (gdouble) out[i].r * (gdouble) out[i].r;
387 mag += (gdouble) out[i].i * (gdouble) out[i].i;
388 mag /= 2048.0 * 2048.0;
389 mag = 10.0 * log10 (mag);
392 fail_unless (mag > -15.0);
394 fail_unless (mag < -60.0);
397 gst_fft_f32_free (ctx);
404 GST_START_TEST (test_f64_0hz)
408 GstFFTF64Complex *out;
411 in = g_new (gdouble, 2048);
412 out = g_new (GstFFTF64Complex, 1025);
413 ctx = gst_fft_f64_new (2048, FALSE);
415 for (i = 0; i < 2048; i++)
418 gst_fft_f64_window (ctx, in, GST_FFT_WINDOW_HAMMING);
419 gst_fft_f64_fft (ctx, in, out);
421 for (i = 0; i < 1025; i++) {
424 mag = (gdouble) out[i].r * (gdouble) out[i].r;
425 mag += (gdouble) out[i].i * (gdouble) out[i].i;
426 mag /= 2048.0 * 2048.0;
427 mag = 10.0 * log10 (mag);
430 fail_unless (mag > -15.0);
432 fail_unless (mag < -60.0);
435 gst_fft_f64_free (ctx);
442 GST_START_TEST (test_f64_11025hz)
446 GstFFTF64Complex *out;
449 in = g_new (gdouble, 2048);
450 out = g_new (GstFFTF64Complex, 1025);
451 ctx = gst_fft_f64_new (2048, FALSE);
453 for (i = 0; i < 2048; i += 4) {
460 gst_fft_f64_window (ctx, in, GST_FFT_WINDOW_HAMMING);
461 gst_fft_f64_fft (ctx, in, out);
463 for (i = 0; i < 1025; i++) {
466 mag = (gdouble) out[i].r * (gdouble) out[i].r;
467 mag += (gdouble) out[i].i * (gdouble) out[i].i;
468 mag /= 2048.0 * 2048.0;
469 mag = 10.0 * log10 (mag);
471 if (abs (512 - i) < 2)
472 fail_unless (mag > -20.0);
474 fail_unless (mag < -60.0);
477 gst_fft_f64_free (ctx);
484 GST_START_TEST (test_f64_22050hz)
488 GstFFTF64Complex *out;
491 in = g_new (gdouble, 2048);
492 out = g_new (GstFFTF64Complex, 1025);
493 ctx = gst_fft_f64_new (2048, FALSE);
495 for (i = 0; i < 2048; i += 2) {
500 gst_fft_f64_window (ctx, in, GST_FFT_WINDOW_HAMMING);
501 gst_fft_f64_fft (ctx, in, out);
503 for (i = 0; i < 1025; i++) {
506 mag = (gdouble) out[i].r * (gdouble) out[i].r;
507 mag += (gdouble) out[i].i * (gdouble) out[i].i;
508 mag /= 2048.0 * 2048.0;
509 mag = 10.0 * log10 (mag);
512 fail_unless (mag > -15.0);
514 fail_unless (mag < -60.0);
517 gst_fft_f64_free (ctx);
527 Suite *s = suite_create ("fft library");
528 TCase *tc_chain = tcase_create ("general");
530 suite_add_tcase (s, tc_chain);
531 tcase_add_test (tc_chain, test_next_fast_length);
532 tcase_add_test (tc_chain, test_s16_0hz);
533 tcase_add_test (tc_chain, test_s16_11025hz);
534 tcase_add_test (tc_chain, test_s16_22050hz);
535 tcase_add_test (tc_chain, test_s32_0hz);
536 tcase_add_test (tc_chain, test_s32_11025hz);
537 tcase_add_test (tc_chain, test_s32_22050hz);
538 tcase_add_test (tc_chain, test_f32_0hz);
539 tcase_add_test (tc_chain, test_f32_11025hz);
540 tcase_add_test (tc_chain, test_f32_22050hz);
541 tcase_add_test (tc_chain, test_f64_0hz);
542 tcase_add_test (tc_chain, test_f64_11025hz);
543 tcase_add_test (tc_chain, test_f64_22050hz);
549 main (int argc, char **argv)
553 Suite *s = fft_suite ();
554 SRunner *sr = srunner_create (s);
556 gst_check_init (&argc, &argv);
558 srunner_run_all (sr, CK_NORMAL);
559 nf = srunner_ntests_failed (sr);