Tizen 2.0 Release
[framework/multimedia/gst-plugins-good0.10.git] / tests / check / elements / equalizer.c
1 /* GStreamer
2  *
3  * Copyright (C) 2008 Sebastian Dröge <slomo@circular-chaos.org>
4  *
5  * equalizer.c: Unit test for the equalizer 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/base/gstbasetransform.h>
25 #include <gst/check/gstcheck.h>
26
27 #include <math.h>
28
29 /* For ease of programming we use globals to keep refs for our floating
30  * src and sink pads we create; otherwise we always have to do get_pad,
31  * get_peer, and then remove references in every test function */
32 GstPad *mysrcpad, *mysinkpad;
33
34 #define EQUALIZER_CAPS_STRING             \
35     "audio/x-raw-float, "               \
36     "channels = (int) 1, "              \
37     "rate = (int) 48000, "              \
38     "endianness = (int) BYTE_ORDER, "   \
39     "width = (int) 64"                  \
40
41 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
42     GST_PAD_SINK,
43     GST_PAD_ALWAYS,
44     GST_STATIC_CAPS ("audio/x-raw-float, "
45         "channels = (int) 1, "
46         "rate = (int) 48000, "
47         "endianness = (int) BYTE_ORDER, " "width = (int) 64 ")
48     );
49 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
50     GST_PAD_SRC,
51     GST_PAD_ALWAYS,
52     GST_STATIC_CAPS ("audio/x-raw-float, "
53         "channels = (int) 1, "
54         "rate = (int) 48000, "
55         "endianness = (int) BYTE_ORDER, " "width = (int) 64 ")
56     );
57
58 static GstElement *
59 setup_equalizer (void)
60 {
61   GstElement *equalizer;
62
63   GST_DEBUG ("setup_equalizer");
64   equalizer = gst_check_setup_element ("equalizer-nbands");
65   mysrcpad = gst_check_setup_src_pad (equalizer, &srctemplate, NULL);
66   mysinkpad = gst_check_setup_sink_pad (equalizer, &sinktemplate, NULL);
67   gst_pad_set_active (mysrcpad, TRUE);
68   gst_pad_set_active (mysinkpad, TRUE);
69
70   return equalizer;
71 }
72
73 static void
74 cleanup_equalizer (GstElement * equalizer)
75 {
76   GST_DEBUG ("cleanup_equalizer");
77
78   g_list_foreach (buffers, (GFunc) gst_mini_object_unref, NULL);
79   g_list_free (buffers);
80   buffers = NULL;
81
82   gst_pad_set_active (mysrcpad, FALSE);
83   gst_pad_set_active (mysinkpad, FALSE);
84   gst_check_teardown_src_pad (equalizer);
85   gst_check_teardown_sink_pad (equalizer);
86   gst_check_teardown_element (equalizer);
87 }
88
89 GST_START_TEST (test_equalizer_5bands_passthrough)
90 {
91   GstElement *equalizer;
92   GstBuffer *inbuffer;
93   GstCaps *caps;
94   gdouble *in, *res;
95   gint i;
96
97   equalizer = setup_equalizer ();
98   g_object_set (G_OBJECT (equalizer), "num-bands", 5, NULL);
99
100   fail_unless_equals_int (gst_child_proxy_get_children_count (GST_CHILD_PROXY
101           (equalizer)), 5);
102
103   fail_unless (gst_element_set_state (equalizer,
104           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
105       "could not set to playing");
106
107   inbuffer = gst_buffer_new_and_alloc (1024 * sizeof (gdouble));
108   in = (gdouble *) GST_BUFFER_DATA (inbuffer);
109   for (i = 0; i < 1024; i++)
110     in[i] = g_random_double_range (-1.0, 1.0);
111
112   caps = gst_caps_from_string (EQUALIZER_CAPS_STRING);
113   gst_buffer_set_caps (inbuffer, caps);
114   gst_caps_unref (caps);
115   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
116
117   /* pushing gives away my reference ... */
118   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
119   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()));
120   /* ... and puts a new buffer on the global list */
121   fail_unless (g_list_length (buffers) == 1);
122
123   res = (gdouble *) GST_BUFFER_DATA (GST_BUFFER (buffers->data));
124
125   for (i = 0; i < 1024; i++)
126     fail_unless_equals_float (in[i], res[i]);
127
128   /* cleanup */
129   cleanup_equalizer (equalizer);
130 }
131
132 GST_END_TEST;
133
134 GST_START_TEST (test_equalizer_5bands_minus_24)
135 {
136   GstElement *equalizer;
137   GstBuffer *inbuffer;
138   GstCaps *caps;
139   gdouble *in, *res, rms_in, rms_out;
140   gint i;
141
142   equalizer = setup_equalizer ();
143   g_object_set (G_OBJECT (equalizer), "num-bands", 5, NULL);
144
145   fail_unless_equals_int (gst_child_proxy_get_children_count (GST_CHILD_PROXY
146           (equalizer)), 5);
147
148   for (i = 0; i < 5; i++) {
149     GstObject *band =
150         gst_child_proxy_get_child_by_index (GST_CHILD_PROXY (equalizer), i);
151     fail_unless (band != NULL);
152
153     g_object_set (G_OBJECT (band), "gain", -24.0, NULL);
154     g_object_unref (G_OBJECT (band));
155   }
156
157   fail_unless (gst_element_set_state (equalizer,
158           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
159       "could not set to playing");
160
161   inbuffer = gst_buffer_new_and_alloc (1024 * sizeof (gdouble));
162   in = (gdouble *) GST_BUFFER_DATA (inbuffer);
163   for (i = 0; i < 1024; i++)
164     in[i] = g_random_double_range (-1.0, 1.0);
165
166   rms_in = 0.0;
167   for (i = 0; i < 1024; i++)
168     rms_in += in[i] * in[i];
169   rms_in = sqrt (rms_in / 1024);
170
171   caps = gst_caps_from_string (EQUALIZER_CAPS_STRING);
172   gst_buffer_set_caps (inbuffer, caps);
173   gst_caps_unref (caps);
174   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
175
176   /* pushing gives away my reference ... */
177   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
178   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()));
179   /* ... and puts a new buffer on the global list */
180   fail_unless (g_list_length (buffers) == 1);
181
182   res = (gdouble *) GST_BUFFER_DATA (GST_BUFFER (buffers->data));
183
184   rms_out = 0.0;
185   for (i = 0; i < 1024; i++)
186     rms_out += res[i] * res[i];
187   rms_out = sqrt (rms_out / 1024);
188
189   fail_unless (rms_in > rms_out);
190
191   /* cleanup */
192   cleanup_equalizer (equalizer);
193 }
194
195 GST_END_TEST;
196
197 GST_START_TEST (test_equalizer_5bands_plus_12)
198 {
199   GstElement *equalizer;
200   GstBuffer *inbuffer;
201   GstCaps *caps;
202   gdouble *in, *res, rms_in, rms_out;
203   gint i;
204
205   equalizer = setup_equalizer ();
206   g_object_set (G_OBJECT (equalizer), "num-bands", 5, NULL);
207
208   fail_unless_equals_int (gst_child_proxy_get_children_count (GST_CHILD_PROXY
209           (equalizer)), 5);
210
211   for (i = 0; i < 5; i++) {
212     GstObject *band =
213         gst_child_proxy_get_child_by_index (GST_CHILD_PROXY (equalizer), i);
214     fail_unless (band != NULL);
215
216     g_object_set (G_OBJECT (band), "gain", 12.0, NULL);
217     g_object_unref (G_OBJECT (band));
218   }
219
220   fail_unless (gst_element_set_state (equalizer,
221           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
222       "could not set to playing");
223
224   inbuffer = gst_buffer_new_and_alloc (1024 * sizeof (gdouble));
225   in = (gdouble *) GST_BUFFER_DATA (inbuffer);
226   for (i = 0; i < 1024; i++)
227     in[i] = g_random_double_range (-1.0, 1.0);
228
229   rms_in = 0.0;
230   for (i = 0; i < 1024; i++)
231     rms_in += in[i] * in[i];
232   rms_in = sqrt (rms_in / 1024);
233
234   caps = gst_caps_from_string (EQUALIZER_CAPS_STRING);
235   gst_buffer_set_caps (inbuffer, caps);
236   gst_caps_unref (caps);
237   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
238
239   /* pushing gives away my reference ... */
240   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
241   fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_eos ()));
242   /* ... and puts a new buffer on the global list */
243   fail_unless (g_list_length (buffers) == 1);
244
245   res = (gdouble *) GST_BUFFER_DATA (GST_BUFFER (buffers->data));
246
247   rms_out = 0.0;
248   for (i = 0; i < 1024; i++)
249     rms_out += res[i] * res[i];
250   rms_out = sqrt (rms_out / 1024);
251
252   fail_unless (rms_in < rms_out);
253
254   /* cleanup */
255   cleanup_equalizer (equalizer);
256 }
257
258 GST_END_TEST;
259
260 GST_START_TEST (test_equalizer_band_number_changing)
261 {
262   GstElement *equalizer;
263   gint i;
264
265   equalizer = setup_equalizer ();
266
267   g_object_set (G_OBJECT (equalizer), "num-bands", 5, NULL);
268   fail_unless_equals_int (gst_child_proxy_get_children_count (GST_CHILD_PROXY
269           (equalizer)), 5);
270
271   for (i = 0; i < 5; i++) {
272     GstObject *band;
273
274     band = gst_child_proxy_get_child_by_index (GST_CHILD_PROXY (equalizer), i);
275     fail_unless (band != NULL);
276     gst_object_unref (band);
277   }
278
279   g_object_set (G_OBJECT (equalizer), "num-bands", 10, NULL);
280   fail_unless_equals_int (gst_child_proxy_get_children_count (GST_CHILD_PROXY
281           (equalizer)), 10);
282
283   for (i = 0; i < 10; i++) {
284     GstObject *band;
285
286     band = gst_child_proxy_get_child_by_index (GST_CHILD_PROXY (equalizer), i);
287     fail_unless (band != NULL);
288     gst_object_unref (band);
289   }
290
291   /* cleanup */
292   cleanup_equalizer (equalizer);
293 }
294
295 GST_END_TEST;
296
297 static Suite *
298 equalizer_suite (void)
299 {
300   Suite *s = suite_create ("equalizer");
301   TCase *tc_chain = tcase_create ("general");
302
303   suite_add_tcase (s, tc_chain);
304   tcase_add_test (tc_chain, test_equalizer_5bands_passthrough);
305   tcase_add_test (tc_chain, test_equalizer_5bands_minus_24);
306   tcase_add_test (tc_chain, test_equalizer_5bands_plus_12);
307   tcase_add_test (tc_chain, test_equalizer_band_number_changing);
308
309   return s;
310 }
311
312 int
313 main (int argc, char **argv)
314 {
315   int nf;
316
317   Suite *s = equalizer_suite ();
318   SRunner *sr = srunner_create (s);
319
320   gst_check_init (&argc, &argv);
321
322   srunner_run_all (sr, CK_NORMAL);
323   nf = srunner_ntests_failed (sr);
324   srunner_free (sr);
325
326   return nf;
327 }