1 /* GStreamer
2 *
3 * unit test for FFT library
4 *
5 * Copyright (C) 2007 Sebastian Dröge <slomo@circular-chaos.org>
6 *
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.
11 *
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.
16 *
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., 51 Franklin St, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include <gst/check/gstcheck.h>
28
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>
34
GST_START_TEST(test_next_fast_length)35 GST_START_TEST (test_next_fast_length)
36 {
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);
41 }
42
43 GST_END_TEST;
44
GST_START_TEST(test_s16_0hz)45 GST_START_TEST (test_s16_0hz)
46 {
47 gint i;
48 gint16 *in;
49 GstFFTS16Complex *out;
50 GstFFTS16 *ctx;
51
52 in = g_new (gint16, 2048);
53 out = g_new (GstFFTS16Complex, 1025);
54 ctx = gst_fft_s16_new (2048, FALSE);
55
56 for (i = 0; i < 2048; i++)
57 in[i] = G_MAXINT16;
58
59 gst_fft_s16_window (ctx, in, GST_FFT_WINDOW_HAMMING);
60 gst_fft_s16_fft (ctx, in, out);
61
62 for (i = 0; i < 1025; i++) {
63 gdouble mag;
64
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);
69 if (i < 2)
70 fail_unless (mag > -15.0);
71 else
72 fail_unless (mag < -55.0);
73 }
74
75 gst_fft_s16_free (ctx);
76 g_free (in);
77 g_free (out);
78 }
79
80 GST_END_TEST;
81
GST_START_TEST(test_s16_11025hz)82 GST_START_TEST (test_s16_11025hz)
83 {
84 gint i;
85 gint16 *in;
86 GstFFTS16Complex *out;
87 GstFFTS16 *ctx;
88
89 in = g_new (gint16, 2048);
90 out = g_new (GstFFTS16Complex, 1025);
91 ctx = gst_fft_s16_new (2048, FALSE);
92
93 for (i = 0; i < 2048; i += 4) {
94 in[i] = 0;
95 in[i + 1] = G_MAXINT16;
96 in[i + 2] = 0;
97 in[i + 3] = G_MININT16;
98 }
99
100 gst_fft_s16_window (ctx, in, GST_FFT_WINDOW_HAMMING);
101 gst_fft_s16_fft (ctx, in, out);
102
103 for (i = 0; i < 1025; i++) {
104 gdouble mag;
105
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);
110
111 if (abs (512 - i) < 2)
112 fail_unless (mag > -20.0);
113 else
114 fail_unless (mag < -55.0);
115 }
116
117 gst_fft_s16_free (ctx);
118 g_free (in);
119 g_free (out);
120 }
121
122 GST_END_TEST;
123
GST_START_TEST(test_s16_22050hz)124 GST_START_TEST (test_s16_22050hz)
125 {
126 gint i;
127 gint16 *in;
128 GstFFTS16Complex *out;
129 GstFFTS16 *ctx;
130
131 in = g_new (gint16, 2048);
132 out = g_new (GstFFTS16Complex, 1025);
133 ctx = gst_fft_s16_new (2048, FALSE);
134
135 for (i = 0; i < 2048; i += 2) {
136 in[i] = G_MAXINT16;
137 in[i + 1] = G_MININT16;
138 }
139
140 gst_fft_s16_window (ctx, in, GST_FFT_WINDOW_HAMMING);
141 gst_fft_s16_fft (ctx, in, out);
142
143 for (i = 0; i < 1025; i++) {
144 gdouble mag;
145
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);
150
151 if (i > 1022)
152 fail_unless (mag > -15.0);
153 else
154 fail_unless (mag < -55.0);
155 }
156
157 gst_fft_s16_free (ctx);
158 g_free (in);
159 g_free (out);
160 }
161
162 GST_END_TEST;
163
GST_START_TEST(test_s32_0hz)164 GST_START_TEST (test_s32_0hz)
165 {
166 gint i;
167 gint32 *in;
168 GstFFTS32Complex *out;
169 GstFFTS32 *ctx;
170
171 in = g_new (gint32, 2048);
172 out = g_new (GstFFTS32Complex, 1025);
173 ctx = gst_fft_s32_new (2048, FALSE);
174
175 for (i = 0; i < 2048; i++)
176 in[i] = 2147483647;
177
178 gst_fft_s32_window (ctx, in, GST_FFT_WINDOW_HAMMING);
179 gst_fft_s32_fft (ctx, in, out);
180
181 for (i = 0; i < 1025; i++) {
182 gdouble mag;
183
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);
188
189 if (i < 2)
190 fail_unless (mag > -15.0);
191 else
192 fail_unless (mag < -60.0);
193 }
194
195 gst_fft_s32_free (ctx);
196 g_free (in);
197 g_free (out);
198 }
199
200 GST_END_TEST;
201
GST_START_TEST(test_s32_11025hz)202 GST_START_TEST (test_s32_11025hz)
203 {
204 gint i;
205 gint32 *in;
206 GstFFTS32Complex *out;
207 GstFFTS32 *ctx;
208
209 in = g_new (gint32, 2048);
210 out = g_new (GstFFTS32Complex, 1025);
211 ctx = gst_fft_s32_new (2048, FALSE);
212
213 for (i = 0; i < 2048; i += 4) {
214 in[i] = 0;
215 in[i + 1] = G_MAXINT32;
216 in[i + 2] = 0;
217 in[i + 3] = G_MININT32;
218 }
219
220 gst_fft_s32_window (ctx, in, GST_FFT_WINDOW_HAMMING);
221 gst_fft_s32_fft (ctx, in, out);
222
223 for (i = 0; i < 1025; i++) {
224 gdouble mag;
225
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);
230
231 if (abs (512 - i) < 2)
232 fail_unless (mag > -20.0);
233 else
234 fail_unless (mag < -60.0);
235 }
236
237 gst_fft_s32_free (ctx);
238 g_free (in);
239 g_free (out);
240 }
241
242 GST_END_TEST;
243
GST_START_TEST(test_s32_22050hz)244 GST_START_TEST (test_s32_22050hz)
245 {
246 gint i;
247 gint32 *in;
248 GstFFTS32Complex *out;
249 GstFFTS32 *ctx;
250
251 in = g_new (gint32, 2048);
252 out = g_new (GstFFTS32Complex, 1025);
253 ctx = gst_fft_s32_new (2048, FALSE);
254
255 for (i = 0; i < 2048; i += 2) {
256 in[i] = G_MAXINT32;
257 in[i + 1] = G_MININT32;
258 }
259
260 gst_fft_s32_window (ctx, in, GST_FFT_WINDOW_HAMMING);
261 gst_fft_s32_fft (ctx, in, out);
262
263 for (i = 0; i < 1025; i++) {
264 gdouble mag;
265
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);
270
271 if (i > 1022)
272 fail_unless (mag > -15.0);
273 else
274 fail_unless (mag < -60.0);
275 }
276
277 gst_fft_s32_free (ctx);
278 g_free (in);
279 g_free (out);
280 }
281
282 GST_END_TEST;
283
GST_START_TEST(test_f32_0hz)284 GST_START_TEST (test_f32_0hz)
285 {
286 gint i;
287 gfloat *in;
288 GstFFTF32Complex *out;
289 GstFFTF32 *ctx;
290
291 in = g_new (gfloat, 2048);
292 out = g_new (GstFFTF32Complex, 1025);
293 ctx = gst_fft_f32_new (2048, FALSE);
294
295 for (i = 0; i < 2048; i++)
296 in[i] = 1.0;
297
298 gst_fft_f32_window (ctx, in, GST_FFT_WINDOW_HAMMING);
299 gst_fft_f32_fft (ctx, in, out);
300
301 for (i = 0; i < 1025; i++) {
302 gdouble mag;
303
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);
308
309 if (i < 2)
310 fail_unless (mag > -15.0);
311 else
312 fail_unless (mag < -60.0);
313 }
314
315 gst_fft_f32_free (ctx);
316 g_free (in);
317 g_free (out);
318 }
319
320 GST_END_TEST;
321
GST_START_TEST(test_f32_11025hz)322 GST_START_TEST (test_f32_11025hz)
323 {
324 gint i;
325 gfloat *in;
326 GstFFTF32Complex *out;
327 GstFFTF32 *ctx;
328
329 in = g_new (gfloat, 2048);
330 out = g_new (GstFFTF32Complex, 1025);
331 ctx = gst_fft_f32_new (2048, FALSE);
332
333 for (i = 0; i < 2048; i += 4) {
334 in[i] = 0.0;
335 in[i + 1] = 1.0;
336 in[i + 2] = 0.0;
337 in[i + 3] = -1.0;
338 }
339
340 gst_fft_f32_window (ctx, in, GST_FFT_WINDOW_HAMMING);
341 gst_fft_f32_fft (ctx, in, out);
342
343 for (i = 0; i < 1025; i++) {
344 gdouble mag;
345
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);
350
351 if (abs (512 - i) < 2)
352 fail_unless (mag > -20.0);
353 else
354 fail_unless (mag < -60.0);
355 }
356
357 gst_fft_f32_free (ctx);
358 g_free (in);
359 g_free (out);
360 }
361
362 GST_END_TEST;
363
GST_START_TEST(test_f32_22050hz)364 GST_START_TEST (test_f32_22050hz)
365 {
366 gint i;
367 gfloat *in;
368 GstFFTF32Complex *out;
369 GstFFTF32 *ctx;
370
371 in = g_new (gfloat, 2048);
372 out = g_new (GstFFTF32Complex, 1025);
373 ctx = gst_fft_f32_new (2048, FALSE);
374
375 for (i = 0; i < 2048; i += 2) {
376 in[i] = 1.0;
377 in[i + 1] = -1.0;
378 }
379
380 gst_fft_f32_window (ctx, in, GST_FFT_WINDOW_HAMMING);
381 gst_fft_f32_fft (ctx, in, out);
382
383 for (i = 0; i < 1025; i++) {
384 gdouble mag;
385
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);
390
391 if (i > 1022)
392 fail_unless (mag > -15.0);
393 else
394 fail_unless (mag < -60.0);
395 }
396
397 gst_fft_f32_free (ctx);
398 g_free (in);
399 g_free (out);
400 }
401
402 GST_END_TEST;
403
GST_START_TEST(test_f64_0hz)404 GST_START_TEST (test_f64_0hz)
405 {
406 gint i;
407 gdouble *in;
408 GstFFTF64Complex *out;
409 GstFFTF64 *ctx;
410
411 in = g_new (gdouble, 2048);
412 out = g_new (GstFFTF64Complex, 1025);
413 ctx = gst_fft_f64_new (2048, FALSE);
414
415 for (i = 0; i < 2048; i++)
416 in[i] = 1.0;
417
418 gst_fft_f64_window (ctx, in, GST_FFT_WINDOW_HAMMING);
419 gst_fft_f64_fft (ctx, in, out);
420
421 for (i = 0; i < 1025; i++) {
422 gdouble mag;
423
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);
428
429 if (i < 2)
430 fail_unless (mag > -15.0);
431 else
432 fail_unless (mag < -60.0);
433 }
434
435 gst_fft_f64_free (ctx);
436 g_free (in);
437 g_free (out);
438 }
439
440 GST_END_TEST;
441
GST_START_TEST(test_f64_11025hz)442 GST_START_TEST (test_f64_11025hz)
443 {
444 gint i;
445 gdouble *in;
446 GstFFTF64Complex *out;
447 GstFFTF64 *ctx;
448
449 in = g_new (gdouble, 2048);
450 out = g_new (GstFFTF64Complex, 1025);
451 ctx = gst_fft_f64_new (2048, FALSE);
452
453 for (i = 0; i < 2048; i += 4) {
454 in[i] = 0.0;
455 in[i + 1] = 1.0;
456 in[i + 2] = 0.0;
457 in[i + 3] = -1.0;
458 }
459
460 gst_fft_f64_window (ctx, in, GST_FFT_WINDOW_HAMMING);
461 gst_fft_f64_fft (ctx, in, out);
462
463 for (i = 0; i < 1025; i++) {
464 gdouble mag;
465
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);
470
471 if (abs (512 - i) < 2)
472 fail_unless (mag > -20.0);
473 else
474 fail_unless (mag < -60.0);
475 }
476
477 gst_fft_f64_free (ctx);
478 g_free (in);
479 g_free (out);
480 }
481
482 GST_END_TEST;
483
GST_START_TEST(test_f64_22050hz)484 GST_START_TEST (test_f64_22050hz)
485 {
486 gint i;
487 gdouble *in;
488 GstFFTF64Complex *out;
489 GstFFTF64 *ctx;
490
491 in = g_new (gdouble, 2048);
492 out = g_new (GstFFTF64Complex, 1025);
493 ctx = gst_fft_f64_new (2048, FALSE);
494
495 for (i = 0; i < 2048; i += 2) {
496 in[i] = 1.0;
497 in[i + 1] = -1.0;
498 }
499
500 gst_fft_f64_window (ctx, in, GST_FFT_WINDOW_HAMMING);
501 gst_fft_f64_fft (ctx, in, out);
502
503 for (i = 0; i < 1025; i++) {
504 gdouble mag;
505
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);
510
511 if (i > 1022)
512 fail_unless (mag > -15.0);
513 else
514 fail_unless (mag < -60.0);
515 }
516
517 gst_fft_f64_free (ctx);
518 g_free (in);
519 g_free (out);
520 }
521
522 GST_END_TEST;
523
524 static Suite *
fft_suite(void)525 fft_suite (void)
526 {
527 Suite *s = suite_create ("fft library");
528 TCase *tc_chain = tcase_create ("general");
529
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);
544
545 return s;
546 }
547
548 GST_CHECK_MAIN (fft);
549