1 /* GStreamer
2  *
3  * Copyright (C) 2007 Sebastian Dröge <slomo@circular-chaos.org>
4  *
5  * audiowsinclimit.c: Unit test for the audiowsinclimit element
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * as published by the Free Software Foundation; either version 2.1 of
10  * the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20  * 02110-1301 USA
21  */
22 
23 #include <gst/gst.h>
24 #include <gst/audio/audio.h>
25 #include <gst/base/gstbasetransform.h>
26 #include <gst/check/gstcheck.h>
27 
28 #include <math.h>
29 
30 /* For ease of programming we use globals to keep refs for our floating
31  * src and sink pads we create; otherwise we always have to do get_pad,
32  * get_peer, and then remove references in every test function */
33 GstPad *mysrcpad, *mysinkpad;
34 
35 #define AUDIO_WSINC_LIMIT_CAPS_STRING_32           \
36     "audio/x-raw, "                                \
37     "format = (string) " GST_AUDIO_NE (F32) ", "   \
38     "layout = (string) interleaved, "              \
39     "channels = (int) 1, "                         \
40     "rate = (int) 44100"
41 
42 #define AUDIO_WSINC_LIMIT_CAPS_STRING_64           \
43     "audio/x-raw, "                                \
44     "format = (string) " GST_AUDIO_NE (F64) ", "   \
45     "layout = (string) interleaved, "              \
46     "channels = (int) 1, "                         \
47     "rate = (int) 44100"
48 
49 #define FORMATS "{ "GST_AUDIO_NE (F32)","GST_AUDIO_NE (F64)" }"
50 
51 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
52     GST_PAD_SINK,
53     GST_PAD_ALWAYS,
54     GST_STATIC_CAPS ("audio/x-raw, "
55         "format = (string) " FORMATS ", "
56         "layout = (string) interleaved, "
57         "channels = (int) 1, " "rate = (int) 44100")
58     );
59 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
60     GST_PAD_SRC,
61     GST_PAD_ALWAYS,
62     GST_STATIC_CAPS ("audio/x-raw, "
63         "format = (string) " FORMATS ", "
64         "layout = (string) interleaved, "
65         "channels = (int) 1, " "rate = (int) 44100")
66     );
67 
68 static GstElement *
setup_audiowsinclimit(void)69 setup_audiowsinclimit (void)
70 {
71   GstElement *audiowsinclimit;
72 
73   GST_DEBUG ("setup_audiowsinclimit");
74   audiowsinclimit = gst_check_setup_element ("audiowsinclimit");
75   mysrcpad = gst_check_setup_src_pad (audiowsinclimit, &srctemplate);
76   mysinkpad = gst_check_setup_sink_pad (audiowsinclimit, &sinktemplate);
77   gst_pad_set_active (mysrcpad, TRUE);
78   gst_pad_set_active (mysinkpad, TRUE);
79 
80   return audiowsinclimit;
81 }
82 
83 static void
cleanup_audiowsinclimit(GstElement * audiowsinclimit)84 cleanup_audiowsinclimit (GstElement * audiowsinclimit)
85 {
86   GST_DEBUG ("cleanup_audiowsinclimit");
87 
88   g_list_foreach (buffers, (GFunc) gst_mini_object_unref, NULL);
89   g_list_free (buffers);
90   buffers = NULL;
91 
92   gst_pad_set_active (mysrcpad, FALSE);
93   gst_pad_set_active (mysinkpad, FALSE);
94   gst_check_teardown_src_pad (audiowsinclimit);
95   gst_check_teardown_sink_pad (audiowsinclimit);
96   gst_check_teardown_element (audiowsinclimit);
97 }
98 
99 /* Test if data containing only one frequency component
100  * at 0 is preserved with lowpass mode and a cutoff
101  * at rate/4 */
GST_START_TEST(test_32_lp_0hz)102 GST_START_TEST (test_32_lp_0hz)
103 {
104   GstElement *audiowsinclimit;
105   GstBuffer *inbuffer, *outbuffer;
106   GstCaps *caps;
107   gfloat *in, *res, rms;
108   gint i;
109   GstMapInfo map;
110   GList *node;
111   GstSegment segment;
112 
113   audiowsinclimit = setup_audiowsinclimit ();
114   /* Set to lowpass */
115   g_object_set (G_OBJECT (audiowsinclimit), "mode", 0, NULL);
116   g_object_set (G_OBJECT (audiowsinclimit), "length", 21, NULL);
117 
118   fail_unless (gst_element_set_state (audiowsinclimit,
119           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
120       "could not set to playing");
121 
122   /* cutoff = sampling rate / 4, data = 0 */
123   g_object_set (G_OBJECT (audiowsinclimit), "cutoff", 44100 / 4.0, NULL);
124   inbuffer = gst_buffer_new_and_alloc (128 * sizeof (gfloat));
125   GST_BUFFER_TIMESTAMP (inbuffer) = 0;
126   gst_buffer_map (inbuffer, &map, GST_MAP_WRITE);
127   in = (gfloat *) map.data;
128   for (i = 0; i < 128; i++)
129     in[i] = 1.0;
130   gst_buffer_unmap (inbuffer, &map);
131 
132   caps = gst_caps_from_string (AUDIO_WSINC_LIMIT_CAPS_STRING_32);
133   gst_check_setup_events (mysrcpad, audiowsinclimit, caps, GST_FORMAT_TIME);
134   gst_caps_unref (caps);
135   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
136 
137   /* ensure segment (format) properly setup */
138   gst_segment_init (&segment, GST_FORMAT_TIME);
139   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
140 
141   /* pushing gives away my reference ... */
142   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
143   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()));
144   /* ... and puts a new buffer on the global list */
145   fail_unless (g_list_length (buffers) >= 1);
146 
147   for (node = buffers; node; node = node->next) {
148     gint buffer_length;
149 
150     fail_if ((outbuffer = (GstBuffer *) node->data) == NULL);
151 
152     gst_buffer_map (outbuffer, &map, GST_MAP_READ);
153     res = (gfloat *) map.data;
154     buffer_length = map.size / sizeof (gfloat);
155     rms = 0.0;
156     for (i = 0; i < buffer_length; i++)
157       rms += res[i] * res[i];
158     rms = sqrt (rms / buffer_length);
159     gst_buffer_unmap (outbuffer, &map);
160     fail_unless (rms >= 0.9);
161   }
162 
163   /* cleanup */
164   cleanup_audiowsinclimit (audiowsinclimit);
165 }
166 
167 GST_END_TEST;
168 
169 /* Test if data containing only one frequency component
170  * at rate/2 is erased with lowpass mode and a cutoff
171  * at rate/4 */
GST_START_TEST(test_32_lp_22050hz)172 GST_START_TEST (test_32_lp_22050hz)
173 {
174   GstElement *audiowsinclimit;
175   GstBuffer *inbuffer, *outbuffer;
176   GstCaps *caps;
177   gfloat *in, *res, rms;
178   gint i;
179   GstMapInfo map;
180   GList *node;
181   GstSegment segment;
182 
183   audiowsinclimit = setup_audiowsinclimit ();
184   /* Set to lowpass */
185   g_object_set (G_OBJECT (audiowsinclimit), "mode", 0, NULL);
186   g_object_set (G_OBJECT (audiowsinclimit), "length", 21, NULL);
187 
188   fail_unless (gst_element_set_state (audiowsinclimit,
189           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
190       "could not set to playing");
191 
192   g_object_set (G_OBJECT (audiowsinclimit), "cutoff", 44100 / 4.0, NULL);
193   inbuffer = gst_buffer_new_and_alloc (128 * sizeof (gfloat));
194   GST_BUFFER_TIMESTAMP (inbuffer) = 0;
195   gst_buffer_map (inbuffer, &map, GST_MAP_WRITE);
196   in = (gfloat *) map.data;
197   for (i = 0; i < 128; i += 2) {
198     in[i] = 1.0;
199     in[i + 1] = -1.0;
200   }
201   gst_buffer_unmap (inbuffer, &map);
202 
203   caps = gst_caps_from_string (AUDIO_WSINC_LIMIT_CAPS_STRING_32);
204   gst_check_setup_events (mysrcpad, audiowsinclimit, caps, GST_FORMAT_TIME);
205   gst_caps_unref (caps);
206   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
207 
208   /* ensure segment (format) properly setup */
209   gst_segment_init (&segment, GST_FORMAT_TIME);
210   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
211 
212   /* pushing gives away my reference ... */
213   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
214   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()));
215   /* ... and puts a new buffer on the global list */
216   fail_unless (g_list_length (buffers) >= 1);
217 
218   for (node = buffers; node; node = node->next) {
219     gint buffer_length;
220 
221     fail_if ((outbuffer = (GstBuffer *) node->data) == NULL);
222 
223     gst_buffer_map (outbuffer, &map, GST_MAP_READ);
224     res = (gfloat *) map.data;
225     buffer_length = map.size / sizeof (gfloat);
226     rms = 0.0;
227     for (i = 0; i < buffer_length; i++)
228       rms += res[i] * res[i];
229     rms = sqrt (rms / buffer_length);
230     gst_buffer_unmap (outbuffer, &map);
231     fail_unless (rms <= 0.1);
232   }
233 
234   /* cleanup */
235   cleanup_audiowsinclimit (audiowsinclimit);
236 }
237 
238 GST_END_TEST;
239 
240 /* Test if data containing only one frequency component
241  * at 0 is erased with highpass mode and a cutoff
242  * at rate/4 */
GST_START_TEST(test_32_hp_0hz)243 GST_START_TEST (test_32_hp_0hz)
244 {
245   GstElement *audiowsinclimit;
246   GstBuffer *inbuffer, *outbuffer;
247   GstCaps *caps;
248   gfloat *in, *res, rms;
249   gint i;
250   GstMapInfo map;
251   GList *node;
252   GstSegment segment;
253 
254   audiowsinclimit = setup_audiowsinclimit ();
255   /* Set to highpass */
256   g_object_set (G_OBJECT (audiowsinclimit), "mode", 1, NULL);
257   g_object_set (G_OBJECT (audiowsinclimit), "length", 21, NULL);
258 
259   fail_unless (gst_element_set_state (audiowsinclimit,
260           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
261       "could not set to playing");
262 
263   g_object_set (G_OBJECT (audiowsinclimit), "cutoff", 44100 / 4.0, NULL);
264   inbuffer = gst_buffer_new_and_alloc (128 * sizeof (gfloat));
265   GST_BUFFER_TIMESTAMP (inbuffer) = 0;
266   gst_buffer_map (inbuffer, &map, GST_MAP_WRITE);
267   in = (gfloat *) map.data;
268   for (i = 0; i < 128; i++)
269     in[i] = 1.0;
270   gst_buffer_unmap (inbuffer, &map);
271 
272   caps = gst_caps_from_string (AUDIO_WSINC_LIMIT_CAPS_STRING_32);
273   gst_check_setup_events (mysrcpad, audiowsinclimit, caps, GST_FORMAT_TIME);
274   gst_caps_unref (caps);
275   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
276 
277   /* ensure segment (format) properly setup */
278   gst_segment_init (&segment, GST_FORMAT_TIME);
279   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
280 
281   /* pushing gives away my reference ... */
282   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
283   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()));
284   /* ... and puts a new buffer on the global list */
285   fail_unless (g_list_length (buffers) >= 1);
286 
287   for (node = buffers; node; node = node->next) {
288     gint buffer_length;
289 
290     fail_if ((outbuffer = (GstBuffer *) node->data) == NULL);
291 
292     gst_buffer_map (outbuffer, &map, GST_MAP_READ);
293     res = (gfloat *) map.data;
294     buffer_length = map.size / sizeof (gfloat);
295     rms = 0.0;
296     for (i = 0; i < buffer_length; i++)
297       rms += res[i] * res[i];
298     rms = sqrt (rms / buffer_length);
299     gst_buffer_unmap (outbuffer, &map);
300     fail_unless (rms <= 0.1);
301   }
302 
303   /* cleanup */
304   cleanup_audiowsinclimit (audiowsinclimit);
305 }
306 
307 GST_END_TEST;
308 
309 /* Test if data containing only one frequency component
310  * at rate/2 is preserved with highpass mode and a cutoff
311  * at rate/4 */
GST_START_TEST(test_32_hp_22050hz)312 GST_START_TEST (test_32_hp_22050hz)
313 {
314   GstElement *audiowsinclimit;
315   GstBuffer *inbuffer, *outbuffer;
316   GstCaps *caps;
317   gfloat *in, *res, rms;
318   gint i;
319   GstMapInfo map;
320   GList *node;
321   GstSegment segment;
322 
323   audiowsinclimit = setup_audiowsinclimit ();
324   /* Set to highpass */
325   g_object_set (G_OBJECT (audiowsinclimit), "mode", 1, NULL);
326   g_object_set (G_OBJECT (audiowsinclimit), "length", 21, NULL);
327 
328   fail_unless (gst_element_set_state (audiowsinclimit,
329           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
330       "could not set to playing");
331 
332   g_object_set (G_OBJECT (audiowsinclimit), "cutoff", 44100 / 4.0, NULL);
333   inbuffer = gst_buffer_new_and_alloc (128 * sizeof (gfloat));
334   GST_BUFFER_TIMESTAMP (inbuffer) = 0;
335   gst_buffer_map (inbuffer, &map, GST_MAP_WRITE);
336   in = (gfloat *) map.data;
337   for (i = 0; i < 128; i += 2) {
338     in[i] = 1.0;
339     in[i + 1] = -1.0;
340   }
341   gst_buffer_unmap (inbuffer, &map);
342 
343   caps = gst_caps_from_string (AUDIO_WSINC_LIMIT_CAPS_STRING_32);
344   gst_check_setup_events (mysrcpad, audiowsinclimit, caps, GST_FORMAT_TIME);
345   gst_caps_unref (caps);
346   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
347 
348   /* ensure segment (format) properly setup */
349   gst_segment_init (&segment, GST_FORMAT_TIME);
350   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
351 
352   /* pushing gives away my reference ... */
353   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
354   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()));
355   /* ... and puts a new buffer on the global list */
356   fail_unless (g_list_length (buffers) >= 1);
357   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
358 
359   for (node = buffers; node; node = node->next) {
360     gint buffer_length;
361 
362     fail_if ((outbuffer = (GstBuffer *) node->data) == NULL);
363 
364     gst_buffer_map (outbuffer, &map, GST_MAP_READ);
365     res = (gfloat *) map.data;
366     buffer_length = map.size / sizeof (gfloat);
367     rms = 0.0;
368     for (i = 0; i < buffer_length; i++)
369       rms += res[i] * res[i];
370     rms = sqrt (rms / buffer_length);
371     gst_buffer_unmap (outbuffer, &map);
372     fail_unless (rms >= 0.9);
373   }
374 
375   /* cleanup */
376   cleanup_audiowsinclimit (audiowsinclimit);
377 }
378 
379 GST_END_TEST;
380 
381 /* Test if buffers smaller than the kernel size are handled
382  * correctly without accessing wrong memory areas */
GST_START_TEST(test_32_small_buffer)383 GST_START_TEST (test_32_small_buffer)
384 {
385   GstElement *audiowsinclimit;
386   GstBuffer *inbuffer, *outbuffer;
387   GstCaps *caps;
388   gfloat *in;
389   gint i;
390   GstMapInfo map;
391   GstSegment segment;
392 
393   audiowsinclimit = setup_audiowsinclimit ();
394   /* Set to lowpass */
395   g_object_set (G_OBJECT (audiowsinclimit), "mode", 0, NULL);
396   g_object_set (G_OBJECT (audiowsinclimit), "length", 101, NULL);
397 
398   fail_unless (gst_element_set_state (audiowsinclimit,
399           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
400       "could not set to playing");
401 
402   g_object_set (G_OBJECT (audiowsinclimit), "cutoff", 44100 / 4.0, NULL);
403   inbuffer = gst_buffer_new_and_alloc (20 * sizeof (gfloat));
404   GST_BUFFER_TIMESTAMP (inbuffer) = 0;
405   gst_buffer_map (inbuffer, &map, GST_MAP_WRITE);
406   in = (gfloat *) map.data;
407   for (i = 0; i < 20; i++)
408     in[i] = 1.0;
409   gst_buffer_unmap (inbuffer, &map);
410 
411   caps = gst_caps_from_string (AUDIO_WSINC_LIMIT_CAPS_STRING_32);
412   gst_check_setup_events (mysrcpad, audiowsinclimit, caps, GST_FORMAT_TIME);
413   gst_caps_unref (caps);
414   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
415 
416   /* ensure segment (format) properly setup */
417   gst_segment_init (&segment, GST_FORMAT_TIME);
418   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
419 
420   /* pushing gives away my reference ... */
421   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
422   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()));
423   /* ... and puts a new buffer on the global list */
424   fail_unless (g_list_length (buffers) >= 1);
425   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
426 
427   /* cleanup */
428   cleanup_audiowsinclimit (audiowsinclimit);
429 }
430 
431 GST_END_TEST;
432 
433 /* Test if data containing only one frequency component
434  * at 0 is preserved with lowpass mode and a cutoff
435  * at rate/4 */
GST_START_TEST(test_64_lp_0hz)436 GST_START_TEST (test_64_lp_0hz)
437 {
438   GstElement *audiowsinclimit;
439   GstBuffer *inbuffer, *outbuffer;
440   GstCaps *caps;
441   gdouble *in, *res, rms;
442   gint i;
443   GstMapInfo map;
444   GList *node;
445   GstSegment segment;
446 
447   audiowsinclimit = setup_audiowsinclimit ();
448   /* Set to lowpass */
449   g_object_set (G_OBJECT (audiowsinclimit), "mode", 0, NULL);
450   g_object_set (G_OBJECT (audiowsinclimit), "length", 21, NULL);
451 
452   fail_unless (gst_element_set_state (audiowsinclimit,
453           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
454       "could not set to playing");
455 
456   /* cutoff = sampling rate / 4, data = 0 */
457   g_object_set (G_OBJECT (audiowsinclimit), "cutoff", 44100 / 4.0, NULL);
458   inbuffer = gst_buffer_new_and_alloc (128 * sizeof (gdouble));
459   GST_BUFFER_TIMESTAMP (inbuffer) = 0;
460   gst_buffer_map (inbuffer, &map, GST_MAP_WRITE);
461   in = (gdouble *) map.data;
462   for (i = 0; i < 128; i++)
463     in[i] = 1.0;
464   gst_buffer_unmap (inbuffer, &map);
465 
466   caps = gst_caps_from_string (AUDIO_WSINC_LIMIT_CAPS_STRING_64);
467   gst_check_setup_events (mysrcpad, audiowsinclimit, caps, GST_FORMAT_TIME);
468   gst_caps_unref (caps);
469   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
470 
471   /* ensure segment (format) properly setup */
472   gst_segment_init (&segment, GST_FORMAT_TIME);
473   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
474 
475   /* pushing gives away my reference ... */
476   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
477   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()));
478   /* ... and puts a new buffer on the global list */
479   fail_unless (g_list_length (buffers) >= 1);
480 
481   for (node = buffers; node; node = node->next) {
482     gint buffer_length;
483 
484     fail_if ((outbuffer = (GstBuffer *) node->data) == NULL);
485 
486     gst_buffer_map (outbuffer, &map, GST_MAP_READ);
487     res = (gdouble *) map.data;
488     buffer_length = map.size / sizeof (gdouble);
489     rms = 0.0;
490     for (i = 0; i < buffer_length; i++)
491       rms += res[i] * res[i];
492     rms = sqrt (rms / buffer_length);
493     gst_buffer_unmap (outbuffer, &map);
494     fail_unless (rms >= 0.9);
495   }
496 
497   /* cleanup */
498   cleanup_audiowsinclimit (audiowsinclimit);
499 }
500 
501 GST_END_TEST;
502 
503 /* Test if data containing only one frequency component
504  * at rate/2 is erased with lowpass mode and a cutoff
505  * at rate/4 */
GST_START_TEST(test_64_lp_22050hz)506 GST_START_TEST (test_64_lp_22050hz)
507 {
508   GstElement *audiowsinclimit;
509   GstBuffer *inbuffer, *outbuffer;
510   GstCaps *caps;
511   gdouble *in, *res, rms;
512   gint i;
513   GstMapInfo map;
514   GList *node;
515   GstSegment segment;
516 
517   audiowsinclimit = setup_audiowsinclimit ();
518   /* Set to lowpass */
519   g_object_set (G_OBJECT (audiowsinclimit), "mode", 0, NULL);
520   g_object_set (G_OBJECT (audiowsinclimit), "length", 21, NULL);
521 
522   fail_unless (gst_element_set_state (audiowsinclimit,
523           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
524       "could not set to playing");
525 
526   g_object_set (G_OBJECT (audiowsinclimit), "cutoff", 44100 / 4.0, NULL);
527   inbuffer = gst_buffer_new_and_alloc (128 * sizeof (gdouble));
528   GST_BUFFER_TIMESTAMP (inbuffer) = 0;
529   gst_buffer_map (inbuffer, &map, GST_MAP_WRITE);
530   in = (gdouble *) map.data;
531   for (i = 0; i < 128; i += 2) {
532     in[i] = 1.0;
533     in[i + 1] = -1.0;
534   }
535   gst_buffer_unmap (inbuffer, &map);
536 
537   caps = gst_caps_from_string (AUDIO_WSINC_LIMIT_CAPS_STRING_64);
538   gst_check_setup_events (mysrcpad, audiowsinclimit, caps, GST_FORMAT_TIME);
539   gst_caps_unref (caps);
540   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
541 
542   /* ensure segment (format) properly setup */
543   gst_segment_init (&segment, GST_FORMAT_TIME);
544   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
545 
546   /* pushing gives away my reference ... */
547   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
548   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()));
549   /* ... and puts a new buffer on the global list */
550   fail_unless (g_list_length (buffers) >= 1);
551 
552   for (node = buffers; node; node = node->next) {
553     gint buffer_length;
554 
555     fail_if ((outbuffer = (GstBuffer *) node->data) == NULL);
556 
557     gst_buffer_map (outbuffer, &map, GST_MAP_READ);
558     res = (gdouble *) map.data;
559     buffer_length = map.size / sizeof (gdouble);
560     rms = 0.0;
561     for (i = 0; i < buffer_length; i++)
562       rms += res[i] * res[i];
563     rms = sqrt (rms / buffer_length);
564     gst_buffer_unmap (outbuffer, &map);
565     fail_unless (rms <= 0.1);
566   }
567 
568   /* cleanup */
569   cleanup_audiowsinclimit (audiowsinclimit);
570 }
571 
572 GST_END_TEST;
573 
574 /* Test if data containing only one frequency component
575  * at 0 is erased with highpass mode and a cutoff
576  * at rate/4 */
GST_START_TEST(test_64_hp_0hz)577 GST_START_TEST (test_64_hp_0hz)
578 {
579   GstElement *audiowsinclimit;
580   GstBuffer *inbuffer, *outbuffer;
581   GstCaps *caps;
582   gdouble *in, *res, rms;
583   gint i;
584   GstMapInfo map;
585   GList *node;
586   GstSegment segment;
587 
588   audiowsinclimit = setup_audiowsinclimit ();
589   /* Set to highpass */
590   g_object_set (G_OBJECT (audiowsinclimit), "mode", 1, NULL);
591   g_object_set (G_OBJECT (audiowsinclimit), "length", 21, NULL);
592 
593   fail_unless (gst_element_set_state (audiowsinclimit,
594           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
595       "could not set to playing");
596 
597   g_object_set (G_OBJECT (audiowsinclimit), "cutoff", 44100 / 4.0, NULL);
598   inbuffer = gst_buffer_new_and_alloc (128 * sizeof (gdouble));
599   GST_BUFFER_TIMESTAMP (inbuffer) = 0;
600   gst_buffer_map (inbuffer, &map, GST_MAP_WRITE);
601   in = (gdouble *) map.data;
602   for (i = 0; i < 128; i++)
603     in[i] = 1.0;
604   gst_buffer_unmap (inbuffer, &map);
605 
606   caps = gst_caps_from_string (AUDIO_WSINC_LIMIT_CAPS_STRING_64);
607   gst_check_setup_events (mysrcpad, audiowsinclimit, caps, GST_FORMAT_TIME);
608   gst_caps_unref (caps);
609   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
610 
611   /* ensure segment (format) properly setup */
612   gst_segment_init (&segment, GST_FORMAT_TIME);
613   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
614 
615   /* pushing gives away my reference ... */
616   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
617   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()));
618   /* ... and puts a new buffer on the global list */
619   fail_unless (g_list_length (buffers) >= 1);
620 
621   for (node = buffers; node; node = node->next) {
622     gint buffer_length;
623 
624     fail_if ((outbuffer = (GstBuffer *) node->data) == NULL);
625 
626     gst_buffer_map (outbuffer, &map, GST_MAP_READ);
627     res = (gdouble *) map.data;
628     buffer_length = map.size / sizeof (gdouble);
629     rms = 0.0;
630     for (i = 0; i < buffer_length; i++)
631       rms += res[i] * res[i];
632     rms = sqrt (rms / buffer_length);
633     gst_buffer_unmap (outbuffer, &map);
634     fail_unless (rms <= 0.1);
635   }
636 
637   /* cleanup */
638   cleanup_audiowsinclimit (audiowsinclimit);
639 }
640 
641 GST_END_TEST;
642 
643 /* Test if data containing only one frequency component
644  * at rate/2 is preserved with highpass mode and a cutoff
645  * at rate/4 */
GST_START_TEST(test_64_hp_22050hz)646 GST_START_TEST (test_64_hp_22050hz)
647 {
648   GstElement *audiowsinclimit;
649   GstBuffer *inbuffer, *outbuffer;
650   GstCaps *caps;
651   gdouble *in, *res, rms;
652   gint i;
653   GstMapInfo map;
654   GList *node;
655   GstSegment segment;
656 
657   audiowsinclimit = setup_audiowsinclimit ();
658   /* Set to highpass */
659   g_object_set (G_OBJECT (audiowsinclimit), "mode", 1, NULL);
660   g_object_set (G_OBJECT (audiowsinclimit), "length", 21, NULL);
661 
662   fail_unless (gst_element_set_state (audiowsinclimit,
663           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
664       "could not set to playing");
665 
666   g_object_set (G_OBJECT (audiowsinclimit), "cutoff", 44100 / 4.0, NULL);
667   inbuffer = gst_buffer_new_and_alloc (128 * sizeof (gdouble));
668   GST_BUFFER_TIMESTAMP (inbuffer) = 0;
669   gst_buffer_map (inbuffer, &map, GST_MAP_WRITE);
670   in = (gdouble *) map.data;
671   for (i = 0; i < 128; i += 2) {
672     in[i] = 1.0;
673     in[i + 1] = -1.0;
674   }
675   gst_buffer_unmap (inbuffer, &map);
676 
677   caps = gst_caps_from_string (AUDIO_WSINC_LIMIT_CAPS_STRING_64);
678   gst_check_setup_events (mysrcpad, audiowsinclimit, caps, GST_FORMAT_TIME);
679   gst_caps_unref (caps);
680   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
681 
682   /* ensure segment (format) properly setup */
683   gst_segment_init (&segment, GST_FORMAT_TIME);
684   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
685 
686   /* pushing gives away my reference ... */
687   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
688   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()));
689   /* ... and puts a new buffer on the global list */
690   fail_unless (g_list_length (buffers) >= 1);
691   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
692 
693   for (node = buffers; node; node = node->next) {
694     gint buffer_length;
695 
696     fail_if ((outbuffer = (GstBuffer *) node->data) == NULL);
697 
698     gst_buffer_map (outbuffer, &map, GST_MAP_READ);
699     res = (gdouble *) map.data;
700     buffer_length = map.size / sizeof (gdouble);
701     rms = 0.0;
702     for (i = 0; i < buffer_length; i++)
703       rms += res[i] * res[i];
704     rms = sqrt (rms / buffer_length);
705     gst_buffer_unmap (outbuffer, &map);
706     fail_unless (rms >= 0.9);
707   }
708 
709   /* cleanup */
710   cleanup_audiowsinclimit (audiowsinclimit);
711 }
712 
713 GST_END_TEST;
714 
715 /* Test if buffers smaller than the kernel size are handled
716  * correctly without accessing wrong memory areas */
GST_START_TEST(test_64_small_buffer)717 GST_START_TEST (test_64_small_buffer)
718 {
719   GstElement *audiowsinclimit;
720   GstBuffer *inbuffer, *outbuffer;
721   GstCaps *caps;
722   gdouble *in;
723   gint i;
724   GstMapInfo map;
725   GstSegment segment;
726 
727   audiowsinclimit = setup_audiowsinclimit ();
728   /* Set to lowpass */
729   g_object_set (G_OBJECT (audiowsinclimit), "mode", 0, NULL);
730   g_object_set (G_OBJECT (audiowsinclimit), "length", 101, NULL);
731 
732   fail_unless (gst_element_set_state (audiowsinclimit,
733           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
734       "could not set to playing");
735 
736   g_object_set (G_OBJECT (audiowsinclimit), "cutoff", 44100 / 4.0, NULL);
737   inbuffer = gst_buffer_new_and_alloc (20 * sizeof (gdouble));
738   GST_BUFFER_TIMESTAMP (inbuffer) = 0;
739   gst_buffer_map (inbuffer, &map, GST_MAP_WRITE);
740   in = (gdouble *) map.data;
741   for (i = 0; i < 20; i++)
742     in[i] = 1.0;
743   gst_buffer_unmap (inbuffer, &map);
744 
745   caps = gst_caps_from_string (AUDIO_WSINC_LIMIT_CAPS_STRING_64);
746   gst_check_setup_events (mysrcpad, audiowsinclimit, caps, GST_FORMAT_TIME);
747   gst_caps_unref (caps);
748   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
749 
750   /* ensure segment (format) properly setup */
751   gst_segment_init (&segment, GST_FORMAT_TIME);
752   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
753 
754   /* pushing gives away my reference ... */
755   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
756   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()));
757   /* ... and puts a new buffer on the global list */
758   fail_unless (g_list_length (buffers) >= 1);
759   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
760 
761   /* cleanup */
762   cleanup_audiowsinclimit (audiowsinclimit);
763 }
764 
765 GST_END_TEST;
766 
767 static Suite *
audiowsinclimit_suite(void)768 audiowsinclimit_suite (void)
769 {
770   Suite *s = suite_create ("audiowsinclimit");
771   TCase *tc_chain = tcase_create ("general");
772 
773   suite_add_tcase (s, tc_chain);
774   tcase_add_test (tc_chain, test_32_lp_0hz);
775   tcase_add_test (tc_chain, test_32_lp_22050hz);
776   tcase_add_test (tc_chain, test_32_hp_0hz);
777   tcase_add_test (tc_chain, test_32_hp_22050hz);
778   tcase_add_test (tc_chain, test_32_small_buffer);
779   tcase_add_test (tc_chain, test_64_lp_0hz);
780   tcase_add_test (tc_chain, test_64_lp_22050hz);
781   tcase_add_test (tc_chain, test_64_hp_0hz);
782   tcase_add_test (tc_chain, test_64_hp_22050hz);
783   tcase_add_test (tc_chain, test_64_small_buffer);
784 
785   return s;
786 }
787 
788 GST_CHECK_MAIN (audiowsinclimit);
789