Merge branch 'master' into 0.11
[platform/upstream/gstreamer.git] / tests / check / elements / volume.c
1 /* GStreamer
2  *
3  * unit test for volume
4  *
5  * Copyright (C) <2005> Thomas Vander Stichele <thomas at apestaart dot 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., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 #include <unistd.h>
24
25 #include <gst/base/gstbasetransform.h>
26 #include <gst/check/gstcheck.h>
27 #include <gst/controller/gstcontroller.h>
28 #include <gst/interfaces/streamvolume.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 static GstPad *mysrcpad, *mysinkpad;
34
35
36 #define VOLUME_CAPS_TEMPLATE_STRING     \
37     "audio/x-raw-int, "                 \
38     "channels = (int) [ 1, MAX ], "     \
39     "rate = (int) [ 1,  MAX ], "        \
40     "endianness = (int) BYTE_ORDER, "   \
41     "width = (int) { 8, 16, 24, 32 }, " \
42     "depth = (int) { 8, 16, 24, 32 }, " \
43     "signed = (bool) TRUE; "            \
44     "audio/x-raw-float, "               \
45     "channels = (int) [ 1, MAX ], "     \
46     "rate = (int) [ 1,  MAX ], "        \
47     "endianness = (int) BYTE_ORDER, "   \
48     "width = (int) { 32, 64 }"          \
49
50 #define VOLUME_CAPS_STRING_S8           \
51     "audio/x-raw-int, "                 \
52     "channels = (int) 1, "              \
53     "rate = (int) 44100, "              \
54     "endianness = (int) BYTE_ORDER, "   \
55     "width = (int) 8, "                 \
56     "depth = (int) 8, "                 \
57     "signed = (bool) TRUE"
58
59 #define VOLUME_CAPS_STRING_S16          \
60     "audio/x-raw-int, "                 \
61     "channels = (int) 1, "              \
62     "rate = (int) 44100, "              \
63     "endianness = (int) BYTE_ORDER, "   \
64     "width = (int) 16, "                \
65     "depth = (int) 16, "                \
66     "signed = (bool) TRUE"
67
68 #define VOLUME_CAPS_STRING_S24          \
69     "audio/x-raw-int, "                 \
70     "channels = (int) 1, "              \
71     "rate = (int) 44100, "              \
72     "endianness = (int) BYTE_ORDER, "   \
73     "width = (int) 24, "                \
74     "depth = (int) 24, "                \
75     "signed = (bool) TRUE"
76
77 #define VOLUME_CAPS_STRING_S32          \
78     "audio/x-raw-int, "                 \
79     "channels = (int) 1, "              \
80     "rate = (int) 44100, "              \
81     "endianness = (int) BYTE_ORDER, "   \
82     "width = (int) 32, "                \
83     "depth = (int) 32, "                \
84     "signed = (bool) TRUE"
85
86 #define VOLUME_CAPS_STRING_F32          \
87     "audio/x-raw-float, "               \
88     "channels = (int) 1, "              \
89     "rate = (int) 44100, "              \
90     "endianness = (int) BYTE_ORDER, "   \
91     "width = (int) 32"
92
93 #define VOLUME_CAPS_STRING_F64          \
94     "audio/x-raw-float, "               \
95     "channels = (int) 1, "              \
96     "rate = (int) 44100, "              \
97     "endianness = (int) BYTE_ORDER, "   \
98     "width = (int) 64"
99
100 #define VOLUME_WRONG_CAPS_STRING        \
101     "audio/x-raw-int, "                 \
102     "channels = (int) 1, "              \
103     "rate = (int) 44100, "              \
104     "endianness = (int) BYTE_ORDER, "   \
105     "width = (int) 16, "                \
106     "depth = (int) 16, "                \
107     "signed = (bool) FALSE"
108
109
110 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
111     GST_PAD_SINK,
112     GST_PAD_ALWAYS,
113     GST_STATIC_CAPS (VOLUME_CAPS_TEMPLATE_STRING)
114     );
115 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
116     GST_PAD_SRC,
117     GST_PAD_ALWAYS,
118     GST_STATIC_CAPS (VOLUME_CAPS_TEMPLATE_STRING)
119     );
120
121 static GstElement *
122 setup_volume (void)
123 {
124   GstElement *volume;
125
126   GST_DEBUG ("setup_volume");
127   volume = gst_check_setup_element ("volume");
128   mysrcpad = gst_check_setup_src_pad (volume, &srctemplate, NULL);
129   mysinkpad = gst_check_setup_sink_pad (volume, &sinktemplate, NULL);
130   gst_pad_set_active (mysrcpad, TRUE);
131   gst_pad_set_active (mysinkpad, TRUE);
132
133   return volume;
134 }
135
136 static void
137 cleanup_volume (GstElement * volume)
138 {
139   GST_DEBUG ("cleanup_volume");
140
141   g_list_foreach (buffers, (GFunc) gst_mini_object_unref, NULL);
142   g_list_free (buffers);
143   buffers = NULL;
144
145   gst_pad_set_active (mysrcpad, FALSE);
146   gst_pad_set_active (mysinkpad, FALSE);
147   gst_check_teardown_src_pad (volume);
148   gst_check_teardown_sink_pad (volume);
149   gst_check_teardown_element (volume);
150 }
151
152 GST_START_TEST (test_get_set)
153 {
154   GstElement *volume = gst_element_factory_make ("volume", NULL);
155   gdouble val;
156
157   fail_unless (volume != NULL);
158   g_object_get (G_OBJECT (volume), "volume", &val, NULL);
159   fail_unless (val == 1.0);
160   fail_unless (val == gst_stream_volume_get_volume (GST_STREAM_VOLUME (volume),
161           GST_STREAM_VOLUME_FORMAT_LINEAR));
162
163   g_object_set (G_OBJECT (volume), "volume", 0.5, NULL);
164   g_object_get (G_OBJECT (volume), "volume", &val, NULL);
165   fail_unless (val == 0.5);
166   fail_unless (val == gst_stream_volume_get_volume (GST_STREAM_VOLUME (volume),
167           GST_STREAM_VOLUME_FORMAT_LINEAR));
168
169   gst_stream_volume_set_volume (GST_STREAM_VOLUME (volume),
170       GST_STREAM_VOLUME_FORMAT_LINEAR, 1.0);
171   g_object_get (G_OBJECT (volume), "volume", &val, NULL);
172   fail_unless (val == 1.0);
173   fail_unless (val == gst_stream_volume_get_volume (GST_STREAM_VOLUME (volume),
174           GST_STREAM_VOLUME_FORMAT_LINEAR));
175
176   gst_object_unref (volume);
177 }
178
179 GST_END_TEST;
180
181 GST_START_TEST (test_unity_s8)
182 {
183   GstElement *volume;
184   GstBuffer *inbuffer, *outbuffer;
185   GstCaps *caps;
186   gint8 in[2] = { 64, -16 };
187   gint8 *res;
188   gsize size;
189
190   volume = setup_volume ();
191   fail_unless (gst_element_set_state (volume,
192           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
193       "could not set to playing");
194
195   inbuffer = gst_buffer_new_and_alloc (2);
196   gst_buffer_fill (inbuffer, 0, in, 2);
197   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S8);
198   gst_buffer_set_caps (inbuffer, caps);
199   gst_caps_unref (caps);
200   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
201
202   /* pushing gives away my reference ... */
203   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
204   /* ... but it ends up being collected on the global buffer list */
205   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
206   fail_unless_equals_int (g_list_length (buffers), 1);
207   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
208   fail_unless (inbuffer == outbuffer);
209   res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
210   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", in[0], in[1], res[0], res[1]);
211   fail_unless (memcmp (res, in, 2) == 0);
212   gst_buffer_unmap (outbuffer, res, size);
213
214   /* cleanup */
215   cleanup_volume (volume);
216 }
217
218 GST_END_TEST;
219
220 GST_START_TEST (test_half_s8)
221 {
222   GstElement *volume;
223   GstBuffer *inbuffer;
224   GstBuffer *outbuffer;
225   GstCaps *caps;
226   gint8 in[2] = { 64, -16 };
227   gint8 out[2] = { 32, -8 };
228   gint8 *res;
229   gsize size;
230
231   volume = setup_volume ();
232   g_object_set (G_OBJECT (volume), "volume", 0.5, NULL);
233   fail_unless (gst_element_set_state (volume,
234           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
235       "could not set to playing");
236
237   inbuffer = gst_buffer_new_and_alloc (2);
238   gst_buffer_fill (inbuffer, 0, in, 2);
239   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S8);
240   gst_buffer_set_caps (inbuffer, caps);
241   gst_caps_unref (caps);
242   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
243   /* FIXME: reffing the inbuffer should make the transformation not be
244    * inplace
245    gst_buffer_ref (inbuffer);
246    */
247
248   /* pushing gives away my reference ... */
249   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
250   /* ... but it ends up being modified inplace and
251    * collected on the global buffer list */
252   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
253   fail_unless_equals_int (g_list_length (buffers), 1);
254   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
255   fail_unless (inbuffer == outbuffer);
256   res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
257   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", out[0], out[1], res[0],
258       res[1]);
259   fail_unless (memcmp (res, out, 2) == 0);
260   gst_buffer_unmap (outbuffer, res, size);
261
262   /* cleanup */
263   cleanup_volume (volume);
264 }
265
266 GST_END_TEST;
267
268 GST_START_TEST (test_double_s8)
269 {
270   GstElement *volume;
271   GstBuffer *inbuffer;
272   GstBuffer *outbuffer;
273   GstCaps *caps;
274   gint8 in[2] = { 64, -16 };
275   gint8 out[2] = { 127, -32 };  /* notice the clamped sample */
276   gint8 *res;
277   gsize size;
278
279   volume = setup_volume ();
280   g_object_set (G_OBJECT (volume), "volume", 2.0, NULL);
281   fail_unless (gst_element_set_state (volume,
282           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
283       "could not set to playing");
284
285   inbuffer = gst_buffer_new_and_alloc (2);
286   gst_buffer_fill (inbuffer, 0, in, 2);
287   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S8);
288   gst_buffer_set_caps (inbuffer, caps);
289   gst_caps_unref (caps);
290   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
291   /* FIXME: reffing the inbuffer should make the transformation not be
292    * inplace
293    gst_buffer_ref (inbuffer);
294    */
295
296   /* pushing gives away my reference ... */
297   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
298   /* ... but it ends up being modified inplace and
299    * collected on the global buffer list */
300   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
301   fail_unless_equals_int (g_list_length (buffers), 1);
302   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
303   fail_unless (inbuffer == outbuffer);
304   res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
305   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", out[0], out[1], res[0],
306       res[1]);
307   fail_unless (memcmp (res, out, 2) == 0);
308   gst_buffer_unmap (outbuffer, res, size);
309
310   /* cleanup */
311   cleanup_volume (volume);
312 }
313
314 GST_END_TEST;
315
316 GST_START_TEST (test_ten_s8)
317 {
318   GstElement *volume;
319   GstBuffer *inbuffer;
320   GstBuffer *outbuffer;
321   GstCaps *caps;
322   gint8 in[2] = { 64, -10 };
323   gint8 out[2] = { 127, -100 }; /* notice the clamped sample */
324   gint8 *res;
325
326   volume = setup_volume ();
327   g_object_set (G_OBJECT (volume), "volume", 10.0, NULL);
328   fail_unless (gst_element_set_state (volume,
329           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
330       "could not set to playing");
331
332   inbuffer = gst_buffer_new_and_alloc (2);
333   memcpy (GST_BUFFER_DATA (inbuffer), in, 2);
334   fail_unless (memcmp (GST_BUFFER_DATA (inbuffer), in, 2) == 0);
335   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S8);
336   gst_buffer_set_caps (inbuffer, caps);
337   gst_caps_unref (caps);
338   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
339   /* FIXME: reffing the inbuffer should make the transformation not be
340    * inplace
341    gst_buffer_ref (inbuffer);
342    */
343
344   /* pushing gives away my reference ... */
345   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
346   /* ... but it ends up being modified inplace and
347    * collected on the global buffer list */
348   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
349   fail_unless_equals_int (g_list_length (buffers), 1);
350   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
351   fail_unless (inbuffer == outbuffer);
352   res = (gint8 *) GST_BUFFER_DATA (outbuffer);
353   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", out[0], out[1], res[0],
354       res[1]);
355   fail_unless (memcmp (GST_BUFFER_DATA (outbuffer), out, 2) == 0);
356
357   /* cleanup */
358   cleanup_volume (volume);
359 }
360
361 GST_END_TEST;
362
363 GST_START_TEST (test_mute_s8)
364 {
365   GstElement *volume;
366   GstBuffer *inbuffer;
367   GstBuffer *outbuffer;
368   GstCaps *caps;
369   gint8 in[2] = { 64, -16 };
370   gint8 out[2] = { 0, 0 };
371   gint8 *res;
372   gsize size;
373
374   volume = setup_volume ();
375   g_object_set (G_OBJECT (volume), "mute", TRUE, NULL);
376   fail_unless (gst_element_set_state (volume,
377           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
378       "could not set to playing");
379
380   inbuffer = gst_buffer_new_and_alloc (2);
381   gst_buffer_fill (inbuffer, 0, in, 2);
382   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S8);
383   gst_buffer_set_caps (inbuffer, caps);
384   gst_caps_unref (caps);
385   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
386   /* FIXME: reffing the inbuffer should make the transformation not be
387    * inplace
388    gst_buffer_ref (inbuffer);
389    */
390
391   /* pushing gives away my reference ... */
392   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
393   /* ... but it ends up being modified inplace and
394    * collected on the global buffer list */
395   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
396   fail_unless_equals_int (g_list_length (buffers), 1);
397   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
398   fail_unless (inbuffer == outbuffer);
399   res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
400   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", out[0], out[1], res[0],
401       res[1]);
402   fail_unless (memcmp (res, out, 2) == 0);
403   gst_buffer_unmap (outbuffer, res, size);
404
405   /* cleanup */
406   cleanup_volume (volume);
407 }
408
409 GST_END_TEST;
410
411 GST_START_TEST (test_unity_s16)
412 {
413   GstElement *volume;
414   GstBuffer *inbuffer, *outbuffer;
415   GstCaps *caps;
416   gint16 in[2] = { 16384, -256 };
417   gint16 *res;
418   gsize size;
419
420   volume = setup_volume ();
421   fail_unless (gst_element_set_state (volume,
422           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
423       "could not set to playing");
424
425   inbuffer = gst_buffer_new_and_alloc (4);
426   gst_buffer_fill (inbuffer, 0, in, 4);
427   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S16);
428   gst_buffer_set_caps (inbuffer, caps);
429   gst_caps_unref (caps);
430   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
431
432   /* pushing gives away my reference ... */
433   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
434   /* ... but it ends up being collected on the global buffer list */
435   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
436   fail_unless_equals_int (g_list_length (buffers), 1);
437   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
438   fail_unless (inbuffer == outbuffer);
439   res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
440   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", in[0], in[1], res[0], res[1]);
441   fail_unless (memcmp (res, in, 4) == 0);
442   gst_buffer_unmap (outbuffer, res, size);
443
444   /* cleanup */
445   cleanup_volume (volume);
446 }
447
448 GST_END_TEST;
449
450 GST_START_TEST (test_half_s16)
451 {
452   GstElement *volume;
453   GstBuffer *inbuffer;
454   GstBuffer *outbuffer;
455   GstCaps *caps;
456   gint16 in[2] = { 16384, -256 };
457   gint16 out[2] = { 8192, -128 };
458   gint16 *res;
459   gsize size;
460
461   volume = setup_volume ();
462   g_object_set (G_OBJECT (volume), "volume", 0.5, NULL);
463   fail_unless (gst_element_set_state (volume,
464           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
465       "could not set to playing");
466
467   inbuffer = gst_buffer_new_and_alloc (4);
468   gst_buffer_fill (inbuffer, 0, in, 4);
469   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S16);
470   gst_buffer_set_caps (inbuffer, caps);
471   gst_caps_unref (caps);
472   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
473   /* FIXME: reffing the inbuffer should make the transformation not be
474    * inplace
475    gst_buffer_ref (inbuffer);
476    */
477
478   /* pushing gives away my reference ... */
479   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
480   /* ... but it ends up being modified inplace and
481    * collected on the global buffer list */
482   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
483   fail_unless_equals_int (g_list_length (buffers), 1);
484   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
485   fail_unless (inbuffer == outbuffer);
486   res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
487   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", out[0], out[1], res[0],
488       res[1]);
489   fail_unless (memcmp (res, out, 4) == 0);
490   gst_buffer_unmap (outbuffer, res, size);
491
492   /* cleanup */
493   cleanup_volume (volume);
494 }
495
496 GST_END_TEST;
497
498 GST_START_TEST (test_double_s16)
499 {
500   GstElement *volume;
501   GstBuffer *inbuffer;
502   GstBuffer *outbuffer;
503   GstCaps *caps;
504   gint16 in[2] = { 16384, -256 };
505   gint16 out[2] = { 32767, -512 };      /* notice the clamped sample */
506   gint16 *res;
507   gsize size;
508
509   volume = setup_volume ();
510   g_object_set (G_OBJECT (volume), "volume", 2.0, NULL);
511   fail_unless (gst_element_set_state (volume,
512           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
513       "could not set to playing");
514
515   inbuffer = gst_buffer_new_and_alloc (4);
516   gst_buffer_fill (inbuffer, 0, in, 4);
517   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S16);
518   gst_buffer_set_caps (inbuffer, caps);
519   gst_caps_unref (caps);
520   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
521   /* FIXME: reffing the inbuffer should make the transformation not be
522    * inplace
523    gst_buffer_ref (inbuffer);
524    */
525
526   /* pushing gives away my reference ... */
527   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
528   /* ... but it ends up being modified inplace and
529    * collected on the global buffer list */
530   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
531   fail_unless_equals_int (g_list_length (buffers), 1);
532   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
533   fail_unless (inbuffer == outbuffer);
534   res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
535   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", out[0], out[1], res[0],
536       res[1]);
537   fail_unless (memcmp (res, out, 4) == 0);
538   gst_buffer_unmap (outbuffer, res, size);
539
540   /* cleanup */
541   cleanup_volume (volume);
542 }
543
544 GST_END_TEST;
545
546 GST_START_TEST (test_ten_s16)
547 {
548   GstElement *volume;
549   GstBuffer *inbuffer;
550   GstBuffer *outbuffer;
551   GstCaps *caps;
552   gint16 in[2] = { 16384, -10 };
553   gint16 out[2] = { 32767, -100 };      /* notice the clamped sample */
554   gint16 *res;
555
556   volume = setup_volume ();
557   g_object_set (G_OBJECT (volume), "volume", 10.0, NULL);
558   fail_unless (gst_element_set_state (volume,
559           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
560       "could not set to playing");
561
562   inbuffer = gst_buffer_new_and_alloc (4);
563   memcpy (GST_BUFFER_DATA (inbuffer), in, 4);
564   fail_unless (memcmp (GST_BUFFER_DATA (inbuffer), in, 4) == 0);
565   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S16);
566   gst_buffer_set_caps (inbuffer, caps);
567   gst_caps_unref (caps);
568   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
569   /* FIXME: reffing the inbuffer should make the transformation not be
570    * inplace
571    gst_buffer_ref (inbuffer);
572    */
573
574   /* pushing gives away my reference ... */
575   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
576   /* ... but it ends up being modified inplace and
577    * collected on the global buffer list */
578   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
579   fail_unless_equals_int (g_list_length (buffers), 1);
580   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
581   fail_unless (inbuffer == outbuffer);
582   res = (gint16 *) GST_BUFFER_DATA (outbuffer);
583   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", out[0], out[1], res[0],
584       res[1]);
585   fail_unless (memcmp (GST_BUFFER_DATA (outbuffer), out, 4) == 0);
586
587   /* cleanup */
588   cleanup_volume (volume);
589 }
590
591 GST_END_TEST;
592
593
594 GST_START_TEST (test_mute_s16)
595 {
596   GstElement *volume;
597   GstBuffer *inbuffer;
598   GstBuffer *outbuffer;
599   GstCaps *caps;
600   gint16 in[2] = { 16384, -256 };
601   gint16 out[2] = { 0, 0 };
602   gint16 *res;
603   gsize size;
604
605   volume = setup_volume ();
606   g_object_set (G_OBJECT (volume), "mute", TRUE, NULL);
607   fail_unless (gst_element_set_state (volume,
608           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
609       "could not set to playing");
610
611   inbuffer = gst_buffer_new_and_alloc (4);
612   gst_buffer_fill (inbuffer, 0, in, 4);
613   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S16);
614   gst_buffer_set_caps (inbuffer, caps);
615   gst_caps_unref (caps);
616   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
617   /* FIXME: reffing the inbuffer should make the transformation not be
618    * inplace
619    gst_buffer_ref (inbuffer);
620    */
621
622   /* pushing gives away my reference ... */
623   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
624   /* ... but it ends up being modified inplace and
625    * collected on the global buffer list */
626   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
627   fail_unless_equals_int (g_list_length (buffers), 1);
628   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
629   fail_unless (inbuffer == outbuffer);
630   res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
631   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", out[0], out[1], res[0],
632       res[1]);
633   fail_unless (memcmp (res, out, 4) == 0);
634   gst_buffer_unmap (outbuffer, res, size);
635
636   /* cleanup */
637   cleanup_volume (volume);
638 }
639
640 GST_END_TEST;
641
642 #if (G_BYTE_ORDER == G_LITTLE_ENDIAN)
643 #define get_unaligned_i24(_x) ( (((guint8*)_x)[0]) | ((((guint8*)_x)[1]) << 8) | ((((gint8*)_x)[2]) << 16) )
644 #define write_unaligned_u24(_x,samp) do { (((guint8*)_x)[0]) = samp & 0xFF; (((guint8*)_x)[1]) = (samp >> 8) & 0xFF; (((guint8*)_x)[2]) = (samp >> 16) & 0xFF; } while (0)
645 #else /* BIG ENDIAN */
646 #define get_unaligned_i24(_x) ( (((guint8*)_x)[2]) | ((((guint8*)_x)[1]) << 8) | ((((gint8*)_x)[0]) << 16) )
647 #define write_unaligned_u24(_x,samp) do { (((guint8*)_x)[0]) = (samp >> 16) & 0xFF; (((guint8*)_x)[1]) = (samp >> 8) & 0xFF; (((guint8*)_x)[2]) = samp & 0xFF; } while (0)
648 #endif
649
650 GST_START_TEST (test_unity_s24)
651 {
652   GstElement *volume;
653   GstBuffer *inbuffer, *outbuffer;
654   GstCaps *caps;
655   gint32 in_32[2] = { 4194304, -4096 };
656   guint8 in[6];
657   guint8 *res;
658   gint32 res_32[2];
659   gsize size;
660
661   write_unaligned_u24 (in, in_32[0]);
662   write_unaligned_u24 (in + 3, in_32[1]);
663
664   volume = setup_volume ();
665   fail_unless (gst_element_set_state (volume,
666           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
667       "could not set to playing");
668
669   inbuffer = gst_buffer_new_and_alloc (6);
670   gst_buffer_fill (inbuffer, 0, in, 6);
671   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S24);
672   gst_buffer_set_caps (inbuffer, caps);
673   gst_caps_unref (caps);
674   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
675
676   /* pushing gives away my reference ... */
677   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
678   /* ... but it ends up being collected on the global buffer list */
679   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
680   fail_unless_equals_int (g_list_length (buffers), 1);
681   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
682   fail_unless (inbuffer == outbuffer);
683   res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
684
685   res_32[0] = get_unaligned_i24 (res);
686   res_32[1] = get_unaligned_i24 ((res + 3));
687
688   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", in_32[0], in_32[1], res_32[0],
689       res_32[1]);
690   fail_unless (memcmp (res, in, 6) == 0);
691   gst_buffer_unmap (outbuffer, res, size);
692
693   /* cleanup */
694   cleanup_volume (volume);
695 }
696
697 GST_END_TEST;
698
699 GST_START_TEST (test_half_s24)
700 {
701   GstElement *volume;
702   GstBuffer *inbuffer;
703   GstBuffer *outbuffer;
704   GstCaps *caps;
705   gint32 in_32[2] = { 4194304, -4096 };
706   guint8 in[6];
707   guint8 *res;
708   gint32 res_32[2];
709   gint32 out_32[2] = { 2097152, -2048 };
710   gsize size;
711
712   write_unaligned_u24 (in, in_32[0]);
713   write_unaligned_u24 (in + 3, in_32[1]);
714
715   volume = setup_volume ();
716   g_object_set (G_OBJECT (volume), "volume", 0.5, NULL);
717   fail_unless (gst_element_set_state (volume,
718           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
719       "could not set to playing");
720
721   inbuffer = gst_buffer_new_and_alloc (6);
722   gst_buffer_fill (inbuffer, 0, in, 6);
723   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S24);
724   gst_buffer_set_caps (inbuffer, caps);
725   gst_caps_unref (caps);
726   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
727   /* FIXME: reffing the inbuffer should make the transformation not be
728    * inplace
729    gst_buffer_ref (inbuffer);
730    */
731
732   /* pushing gives away my reference ... */
733   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
734   /* ... but it ends up being modified inplace and
735    * collected on the global buffer list */
736   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
737   fail_unless_equals_int (g_list_length (buffers), 1);
738   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
739   fail_unless (inbuffer == outbuffer);
740   res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
741
742   res_32[0] = get_unaligned_i24 (res);
743   res_32[1] = get_unaligned_i24 ((res + 3));
744
745   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", out_32[0], out_32[1],
746       res_32[0], res_32[1]);
747   fail_unless (memcmp (res_32, out_32, 8) == 0);
748   gst_buffer_unmap (outbuffer, res, size);
749
750   /* cleanup */
751   cleanup_volume (volume);
752 }
753
754 GST_END_TEST;
755
756 GST_START_TEST (test_double_s24)
757 {
758   GstElement *volume;
759   GstBuffer *inbuffer;
760   GstBuffer *outbuffer;
761   GstCaps *caps;
762   gint32 in_32[2] = { 4194304, -4096 };
763   guint8 in[6];
764   guint8 *res;
765   gint32 res_32[2];
766   gint32 out_32[2] = { 8388607, -8192 };        /* notice the clamped sample */
767   gsize size;
768
769   write_unaligned_u24 (in, in_32[0]);
770   write_unaligned_u24 (in + 3, in_32[1]);
771
772   volume = setup_volume ();
773   g_object_set (G_OBJECT (volume), "volume", 2.0, NULL);
774   fail_unless (gst_element_set_state (volume,
775           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
776       "could not set to playing");
777
778   inbuffer = gst_buffer_new_and_alloc (6);
779   gst_buffer_fill (inbuffer, 0, in, 6);
780   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S24);
781   gst_buffer_set_caps (inbuffer, caps);
782   gst_caps_unref (caps);
783   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
784   /* FIXME: reffing the inbuffer should make the transformation not be
785    * inplace
786    gst_buffer_ref (inbuffer);
787    */
788
789   /* pushing gives away my reference ... */
790   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
791   /* ... but it ends up being modified inplace and
792    * collected on the global buffer list */
793   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
794   fail_unless_equals_int (g_list_length (buffers), 1);
795   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
796   fail_unless (inbuffer == outbuffer);
797   res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
798
799   res_32[0] = get_unaligned_i24 (res);
800   res_32[1] = get_unaligned_i24 ((res + 3));
801
802   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", out_32[0], out_32[1],
803       res_32[0], res_32[1]);
804   fail_unless (memcmp (res_32, out_32, 8) == 0);
805   gst_buffer_unmap (outbuffer, res, size);
806
807   /* cleanup */
808   cleanup_volume (volume);
809 }
810
811 GST_END_TEST;
812
813 GST_START_TEST (test_ten_s24)
814 {
815   GstElement *volume;
816   GstBuffer *inbuffer;
817   GstBuffer *outbuffer;
818   GstCaps *caps;
819   gint32 in_32[2] = { 4194304, -10 };
820   guint8 in[6];
821   guint8 *res;
822   gint32 res_32[2];
823   gint32 out_32[2] = { 8388607, -100 }; /* notice the clamped sample */
824
825   write_unaligned_u24 (in, in_32[0]);
826   write_unaligned_u24 (in + 3, in_32[1]);
827
828   volume = setup_volume ();
829   g_object_set (G_OBJECT (volume), "volume", 10.0, NULL);
830   fail_unless (gst_element_set_state (volume,
831           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
832       "could not set to playing");
833
834   inbuffer = gst_buffer_new_and_alloc (6);
835   memcpy (GST_BUFFER_DATA (inbuffer), in, 6);
836   fail_unless (memcmp (GST_BUFFER_DATA (inbuffer), in, 6) == 0);
837   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S24);
838   gst_buffer_set_caps (inbuffer, caps);
839   gst_caps_unref (caps);
840   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
841   /* FIXME: reffing the inbuffer should make the transformation not be
842    * inplace
843    gst_buffer_ref (inbuffer);
844    */
845
846   /* pushing gives away my reference ... */
847   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
848   /* ... but it ends up being modified inplace and
849    * collected on the global buffer list */
850   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
851   fail_unless_equals_int (g_list_length (buffers), 1);
852   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
853   fail_unless (inbuffer == outbuffer);
854   res = GST_BUFFER_DATA (outbuffer);
855
856   res_32[0] = get_unaligned_i24 (res);
857   res_32[1] = get_unaligned_i24 ((res + 3));
858
859   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", out_32[0], out_32[1],
860       res_32[0], res_32[1]);
861   fail_unless (memcmp (res_32, out_32, 8) == 0);
862
863   /* cleanup */
864   cleanup_volume (volume);
865 }
866
867 GST_END_TEST;
868
869 GST_START_TEST (test_mute_s24)
870 {
871   GstElement *volume;
872   GstBuffer *inbuffer;
873   GstBuffer *outbuffer;
874   GstCaps *caps;
875   gint32 in_32[2] = { 4194304, -4096 };
876   guint8 in[6];
877   guint8 *res;
878   gint32 res_32[2];
879   gint32 out_32[2] = { 0, 0 };  /* notice the clamped sample */
880   gsize size;
881
882   write_unaligned_u24 (in, in_32[0]);
883   write_unaligned_u24 (in + 3, in_32[1]);
884
885   volume = setup_volume ();
886   g_object_set (G_OBJECT (volume), "mute", TRUE, NULL);
887   fail_unless (gst_element_set_state (volume,
888           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
889       "could not set to playing");
890
891   inbuffer = gst_buffer_new_and_alloc (6);
892   gst_buffer_fill (inbuffer, 0, in, 6);
893   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S24);
894   gst_buffer_set_caps (inbuffer, caps);
895   gst_caps_unref (caps);
896   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
897   /* FIXME: reffing the inbuffer should make the transformation not be
898    * inplace
899    gst_buffer_ref (inbuffer);
900    */
901
902   /* pushing gives away my reference ... */
903   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
904   /* ... but it ends up being modified inplace and
905    * collected on the global buffer list */
906   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
907   fail_unless_equals_int (g_list_length (buffers), 1);
908   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
909   fail_unless (inbuffer == outbuffer);
910
911   res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
912
913   res_32[0] = get_unaligned_i24 (res);
914   res_32[1] = get_unaligned_i24 ((res + 3));
915
916   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", out_32[0], out_32[1],
917       res_32[0], res_32[1]);
918   fail_unless (memcmp (res_32, out_32, 8) == 0);
919   gst_buffer_unmap (outbuffer, res, size);
920
921   /* cleanup */
922   cleanup_volume (volume);
923 }
924
925 GST_END_TEST;
926
927 GST_START_TEST (test_unity_s32)
928 {
929   GstElement *volume;
930   GstBuffer *inbuffer, *outbuffer;
931   GstCaps *caps;
932   gint32 in[2] = { 1073741824, -65536 };
933   gint32 *res;
934   gsize size;
935
936   volume = setup_volume ();
937   fail_unless (gst_element_set_state (volume,
938           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
939       "could not set to playing");
940
941   inbuffer = gst_buffer_new_and_alloc (8);
942   gst_buffer_fill (inbuffer, 0, in, 8);
943   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S32);
944   gst_buffer_set_caps (inbuffer, caps);
945   gst_caps_unref (caps);
946   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
947
948   /* pushing gives away my reference ... */
949   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
950   /* ... but it ends up being collected on the global buffer list */
951   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
952   fail_unless_equals_int (g_list_length (buffers), 1);
953   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
954   fail_unless (inbuffer == outbuffer);
955   res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
956   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", in[0], in[1], res[0], res[1]);
957   fail_unless (memcmp (res, in, 8) == 0);
958   gst_buffer_unmap (outbuffer, res, size);
959
960   /* cleanup */
961   cleanup_volume (volume);
962 }
963
964 GST_END_TEST;
965
966 GST_START_TEST (test_half_s32)
967 {
968   GstElement *volume;
969   GstBuffer *inbuffer;
970   GstBuffer *outbuffer;
971   GstCaps *caps;
972   gint32 in[2] = { 1073741824, -65536 };
973   gint32 out[2] = { 536870912, -32768 };
974   gint32 *res;
975   gsize size;
976
977   volume = setup_volume ();
978   g_object_set (G_OBJECT (volume), "volume", 0.5, NULL);
979   fail_unless (gst_element_set_state (volume,
980           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
981       "could not set to playing");
982
983   inbuffer = gst_buffer_new_and_alloc (8);
984   gst_buffer_fill (inbuffer, 0, in, 8);
985   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S32);
986   gst_buffer_set_caps (inbuffer, caps);
987   gst_caps_unref (caps);
988   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
989   /* FIXME: reffing the inbuffer should make the transformation not be
990    * inplace
991    gst_buffer_ref (inbuffer);
992    */
993
994   /* pushing gives away my reference ... */
995   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
996   /* ... but it ends up being modified inplace and
997    * collected on the global buffer list */
998   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
999   fail_unless_equals_int (g_list_length (buffers), 1);
1000   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
1001   fail_unless (inbuffer == outbuffer);
1002   res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
1003   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", out[0], out[1], res[0],
1004       res[1]);
1005   fail_unless (memcmp (res, out, 8) == 0);
1006   gst_buffer_unmap (outbuffer, res, size);
1007
1008   /* cleanup */
1009   cleanup_volume (volume);
1010 }
1011
1012 GST_END_TEST;
1013
1014 GST_START_TEST (test_double_s32)
1015 {
1016   GstElement *volume;
1017   GstBuffer *inbuffer;
1018   GstBuffer *outbuffer;
1019   GstCaps *caps;
1020   gint32 in[2] = { 1073741824, -65536 };
1021   gint32 out[2] = { 2147483647, -131072 };      /* notice the clamped sample */
1022   gint32 *res;
1023   gsize size;
1024
1025   volume = setup_volume ();
1026   g_object_set (G_OBJECT (volume), "volume", 2.0, NULL);
1027   fail_unless (gst_element_set_state (volume,
1028           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
1029       "could not set to playing");
1030
1031   inbuffer = gst_buffer_new_and_alloc (8);
1032   gst_buffer_fill (inbuffer, 0, in, 8);
1033   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S32);
1034   gst_buffer_set_caps (inbuffer, caps);
1035   gst_caps_unref (caps);
1036   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1037   /* FIXME: reffing the inbuffer should make the transformation not be
1038    * inplace
1039    gst_buffer_ref (inbuffer);
1040    */
1041
1042   /* pushing gives away my reference ... */
1043   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
1044   /* ... but it ends up being modified inplace and
1045    * collected on the global buffer list */
1046   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1047   fail_unless_equals_int (g_list_length (buffers), 1);
1048   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
1049   fail_unless (inbuffer == outbuffer);
1050   res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
1051   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", out[0], out[1], res[0],
1052       res[1]);
1053   fail_unless (memcmp (res, out, 8) == 0);
1054   gst_buffer_unmap (outbuffer, res, size);
1055
1056   /* cleanup */
1057   cleanup_volume (volume);
1058 }
1059
1060 GST_END_TEST;
1061
1062 GST_START_TEST (test_ten_s32)
1063 {
1064   GstElement *volume;
1065   GstBuffer *inbuffer;
1066   GstBuffer *outbuffer;
1067   GstCaps *caps;
1068   gint32 in[2] = { 1073741824, -10 };
1069   gint32 out[2] = { 2147483647, -100 }; /* notice the clamped sample */
1070   gint32 *res;
1071
1072   volume = setup_volume ();
1073   g_object_set (G_OBJECT (volume), "volume", 10.0, NULL);
1074   fail_unless (gst_element_set_state (volume,
1075           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
1076       "could not set to playing");
1077
1078   inbuffer = gst_buffer_new_and_alloc (8);
1079   memcpy (GST_BUFFER_DATA (inbuffer), in, 8);
1080   fail_unless (memcmp (GST_BUFFER_DATA (inbuffer), in, 8) == 0);
1081   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S32);
1082   gst_buffer_set_caps (inbuffer, caps);
1083   gst_caps_unref (caps);
1084   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1085   /* FIXME: reffing the inbuffer should make the transformation not be
1086    * inplace
1087    gst_buffer_ref (inbuffer);
1088    */
1089
1090   /* pushing gives away my reference ... */
1091   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
1092   /* ... but it ends up being modified inplace and
1093    * collected on the global buffer list */
1094   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1095   fail_unless_equals_int (g_list_length (buffers), 1);
1096   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
1097   fail_unless (inbuffer == outbuffer);
1098   res = (gint32 *) GST_BUFFER_DATA (outbuffer);
1099   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", out[0], out[1], res[0],
1100       res[1]);
1101   fail_unless (memcmp (GST_BUFFER_DATA (outbuffer), out, 8) == 0);
1102
1103   /* cleanup */
1104   cleanup_volume (volume);
1105 }
1106
1107 GST_END_TEST;
1108
1109 GST_START_TEST (test_mute_s32)
1110 {
1111   GstElement *volume;
1112   GstBuffer *inbuffer;
1113   GstBuffer *outbuffer;
1114   GstCaps *caps;
1115   gint32 in[2] = { 1073741824, -65536 };
1116   gint32 out[2] = { 0, 0 };
1117   gint32 *res;
1118   gsize size;
1119
1120   volume = setup_volume ();
1121   g_object_set (G_OBJECT (volume), "mute", TRUE, NULL);
1122   fail_unless (gst_element_set_state (volume,
1123           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
1124       "could not set to playing");
1125
1126   inbuffer = gst_buffer_new_and_alloc (8);
1127   gst_buffer_fill (inbuffer, 0, in, 8);
1128   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S32);
1129   gst_buffer_set_caps (inbuffer, caps);
1130   gst_caps_unref (caps);
1131   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1132   /* FIXME: reffing the inbuffer should make the transformation not be
1133    * inplace
1134    gst_buffer_ref (inbuffer);
1135    */
1136
1137   /* pushing gives away my reference ... */
1138   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
1139   /* ... but it ends up being modified inplace and
1140    * collected on the global buffer list */
1141   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1142   fail_unless_equals_int (g_list_length (buffers), 1);
1143   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
1144   fail_unless (inbuffer == outbuffer);
1145   res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
1146   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", out[0], out[1], res[0],
1147       res[1]);
1148   fail_unless (memcmp (res, out, 8) == 0);
1149   gst_buffer_unmap (outbuffer, res, size);
1150
1151   /* cleanup */
1152   cleanup_volume (volume);
1153 }
1154
1155 GST_END_TEST;
1156
1157 GST_START_TEST (test_unity_f32)
1158 {
1159   GstElement *volume;
1160   GstBuffer *inbuffer, *outbuffer;
1161   GstCaps *caps;
1162   gfloat in[2] = { 0.75, -0.25 };
1163   gfloat *res;
1164   gsize size;
1165
1166   volume = setup_volume ();
1167   fail_unless (gst_element_set_state (volume,
1168           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
1169       "could not set to playing");
1170
1171   inbuffer = gst_buffer_new_and_alloc (8);
1172   gst_buffer_fill (inbuffer, 0, in, 8);
1173   caps = gst_caps_from_string (VOLUME_CAPS_STRING_F32);
1174   gst_buffer_set_caps (inbuffer, caps);
1175   gst_caps_unref (caps);
1176   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1177
1178   /* pushing gives away my reference ... */
1179   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
1180   /* ... but it ends up being collected on the global buffer list */
1181   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1182   fail_unless_equals_int (g_list_length (buffers), 1);
1183   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
1184   fail_unless (inbuffer == outbuffer);
1185   res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
1186   GST_INFO ("expected %+1.4f %+1.4f  real %+1.4f %+1.4f", in[0], in[1], res[0],
1187       res[1]);
1188   fail_unless_equals_float (res[0], in[0]);
1189   fail_unless_equals_float (res[1], in[1]);
1190
1191   /* cleanup */
1192   cleanup_volume (volume);
1193 }
1194
1195 GST_END_TEST;
1196
1197 GST_START_TEST (test_half_f32)
1198 {
1199   GstElement *volume;
1200   GstBuffer *inbuffer;
1201   GstBuffer *outbuffer;
1202   GstCaps *caps;
1203   gfloat in[2] = { 0.75, -0.25 };
1204   gfloat out[2] = { 0.375, -0.125 };
1205   gfloat *res;
1206   gsize size;
1207
1208   volume = setup_volume ();
1209   g_object_set (G_OBJECT (volume), "volume", 0.5, NULL);
1210   fail_unless (gst_element_set_state (volume,
1211           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
1212       "could not set to playing");
1213
1214   inbuffer = gst_buffer_new_and_alloc (8);
1215   gst_buffer_fill (inbuffer, 0, in, 8);
1216   caps = gst_caps_from_string (VOLUME_CAPS_STRING_F32);
1217   gst_buffer_set_caps (inbuffer, caps);
1218   gst_caps_unref (caps);
1219   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1220   /* FIXME: reffing the inbuffer should make the transformation not be
1221    * inplace
1222    gst_buffer_ref (inbuffer);
1223    */
1224
1225   /* pushing gives away my reference ... */
1226   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
1227   /* ... but it ends up being modified inplace and
1228    * collected on the global buffer list */
1229   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1230   fail_unless_equals_int (g_list_length (buffers), 1);
1231   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
1232   fail_unless (inbuffer == outbuffer);
1233   res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
1234   GST_INFO ("expected %+1.4f %+1.4f  real %+1.4f %+1.4f", out[0], out[1],
1235       res[0], res[1]);
1236   fail_unless_equals_float (res[0], out[0]);
1237   fail_unless_equals_float (res[1], out[1]);
1238   gst_buffer_unmap (outbuffer, res, size);
1239
1240   /* cleanup */
1241   cleanup_volume (volume);
1242 }
1243
1244 GST_END_TEST;
1245
1246 GST_START_TEST (test_double_f32)
1247 {
1248   GstElement *volume;
1249   GstBuffer *inbuffer;
1250   GstBuffer *outbuffer;
1251   GstCaps *caps;
1252   gfloat in[2] = { 0.75, -0.25 };
1253   gfloat out[2] = { 1.5, -0.5 };        /* nothing is clamped */
1254   gfloat *res;
1255   gsize size;
1256
1257   volume = setup_volume ();
1258   g_object_set (G_OBJECT (volume), "volume", 2.0, NULL);
1259   fail_unless (gst_element_set_state (volume,
1260           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
1261       "could not set to playing");
1262
1263   inbuffer = gst_buffer_new_and_alloc (8);
1264   gst_buffer_fill (inbuffer, 0, in, 8);
1265   caps = gst_caps_from_string (VOLUME_CAPS_STRING_F32);
1266   gst_buffer_set_caps (inbuffer, caps);
1267   gst_caps_unref (caps);
1268   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1269   /* FIXME: reffing the inbuffer should make the transformation not be
1270    * inplace
1271    gst_buffer_ref (inbuffer);
1272    */
1273
1274   /* pushing gives away my reference ... */
1275   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
1276   /* ... but it ends up being modified inplace and
1277    * collected on the global buffer list */
1278   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1279   fail_unless_equals_int (g_list_length (buffers), 1);
1280   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
1281   fail_unless (inbuffer == outbuffer);
1282   res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
1283   GST_INFO ("expected %+1.4f %+1.4f  real %+1.4f %+1.4f", out[0], out[1],
1284       res[0], res[1]);
1285   fail_unless_equals_float (res[0], out[0]);
1286   fail_unless_equals_float (res[1], out[1]);
1287   gst_buffer_unmap (outbuffer, res, size);
1288
1289   /* cleanup */
1290   cleanup_volume (volume);
1291 }
1292
1293 GST_END_TEST;
1294
1295 GST_START_TEST (test_ten_f32)
1296 {
1297   GstElement *volume;
1298   GstBuffer *inbuffer;
1299   GstBuffer *outbuffer;
1300   GstCaps *caps;
1301   gfloat in[2] = { 0.75, -0.25 };
1302   gfloat out[2] = { 7.5, -2.5 };        /* nothing is clamped */
1303   gfloat *res;
1304
1305   volume = setup_volume ();
1306   g_object_set (G_OBJECT (volume), "volume", 10.0, NULL);
1307   fail_unless (gst_element_set_state (volume,
1308           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
1309       "could not set to playing");
1310
1311   inbuffer = gst_buffer_new_and_alloc (8);
1312   memcpy (GST_BUFFER_DATA (inbuffer), in, 8);
1313   fail_unless (memcmp (GST_BUFFER_DATA (inbuffer), in, 8) == 0);
1314   caps = gst_caps_from_string (VOLUME_CAPS_STRING_F32);
1315   gst_buffer_set_caps (inbuffer, caps);
1316   gst_caps_unref (caps);
1317   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1318   /* FIXME: reffing the inbuffer should make the transformation not be
1319    * inplace
1320    gst_buffer_ref (inbuffer);
1321    */
1322
1323   /* pushing gives away my reference ... */
1324   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
1325   /* ... but it ends up being modified inplace and
1326    * collected on the global buffer list */
1327   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1328   fail_unless_equals_int (g_list_length (buffers), 1);
1329   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
1330   fail_unless (inbuffer == outbuffer);
1331   res = (gfloat *) GST_BUFFER_DATA (outbuffer);
1332   GST_INFO ("expected %+1.4f %+1.4f  real %+1.4f %+1.4f", out[0], out[1],
1333       res[0], res[1]);
1334   fail_unless_equals_float (res[0], out[0]);
1335   fail_unless_equals_float (res[1], out[1]);
1336
1337   /* cleanup */
1338   cleanup_volume (volume);
1339 }
1340
1341 GST_END_TEST;
1342
1343
1344 GST_START_TEST (test_mute_f32)
1345 {
1346   GstElement *volume;
1347   GstBuffer *inbuffer;
1348   GstBuffer *outbuffer;
1349   GstCaps *caps;
1350   gfloat in[2] = { 0.75, -0.25 };
1351   gfloat out[2] = { 0, 0 };
1352   gfloat *res;
1353   gsize size;
1354
1355   volume = setup_volume ();
1356   g_object_set (G_OBJECT (volume), "mute", TRUE, NULL);
1357   fail_unless (gst_element_set_state (volume,
1358           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
1359       "could not set to playing");
1360
1361   inbuffer = gst_buffer_new_and_alloc (8);
1362   gst_buffer_fill (inbuffer, 0, in, 8);
1363   caps = gst_caps_from_string (VOLUME_CAPS_STRING_F32);
1364   gst_buffer_set_caps (inbuffer, caps);
1365   gst_caps_unref (caps);
1366   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1367   /* FIXME: reffing the inbuffer should make the transformation not be
1368    * inplace
1369    gst_buffer_ref (inbuffer);
1370    */
1371
1372   /* pushing gives away my reference ... */
1373   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
1374   /* ... but it ends up being modified inplace and
1375    * collected on the global buffer list */
1376   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1377   fail_unless_equals_int (g_list_length (buffers), 1);
1378   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
1379   fail_unless (inbuffer == outbuffer);
1380   res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
1381   GST_INFO ("expected %+1.4f %+1.4f  real %+1.4f %+1.4f", out[0], out[1],
1382       res[0], res[1]);
1383   fail_unless_equals_float (res[0], out[0]);
1384   fail_unless_equals_float (res[1], out[1]);
1385   gst_buffer_unmap (outbuffer, res, size);
1386
1387   /* cleanup */
1388   cleanup_volume (volume);
1389 }
1390
1391 GST_END_TEST;
1392
1393 GST_START_TEST (test_unity_f64)
1394 {
1395   GstElement *volume;
1396   GstBuffer *inbuffer, *outbuffer;
1397   GstCaps *caps;
1398   gdouble in[2] = { 0.75, -0.25 };
1399   gdouble *res;
1400   gsize size;
1401
1402   volume = setup_volume ();
1403   fail_unless (gst_element_set_state (volume,
1404           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
1405       "could not set to playing");
1406
1407   inbuffer = gst_buffer_new_and_alloc (16);
1408   gst_buffer_fill (inbuffer, 0, in, 16);
1409   caps = gst_caps_from_string (VOLUME_CAPS_STRING_F64);
1410   gst_buffer_set_caps (inbuffer, caps);
1411   gst_caps_unref (caps);
1412   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1413
1414   /* pushing gives away my reference ... */
1415   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
1416   /* ... but it ends up being collected on the global buffer list */
1417   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1418   fail_unless_equals_int (g_list_length (buffers), 1);
1419   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
1420   fail_unless (inbuffer == outbuffer);
1421   res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
1422   GST_INFO ("expected %+1.4f %+1.4f  real %+1.4f %+1.4f", in[0], in[1], res[0],
1423       res[1]);
1424   fail_unless_equals_float (res[0], in[0]);
1425   fail_unless_equals_float (res[1], in[1]);
1426
1427   /* cleanup */
1428   cleanup_volume (volume);
1429 }
1430
1431 GST_END_TEST;
1432
1433 GST_START_TEST (test_half_f64)
1434 {
1435   GstElement *volume;
1436   GstBuffer *inbuffer;
1437   GstBuffer *outbuffer;
1438   GstCaps *caps;
1439   gdouble in[2] = { 0.75, -0.25 };
1440   gdouble out[2] = { 0.375, -0.125 };
1441   gdouble *res;
1442   gsize size;
1443
1444   volume = setup_volume ();
1445   g_object_set (G_OBJECT (volume), "volume", 0.5, NULL);
1446   fail_unless (gst_element_set_state (volume,
1447           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
1448       "could not set to playing");
1449
1450   inbuffer = gst_buffer_new_and_alloc (16);
1451   gst_buffer_fill (inbuffer, 0, in, 16);
1452   caps = gst_caps_from_string (VOLUME_CAPS_STRING_F64);
1453   gst_buffer_set_caps (inbuffer, caps);
1454   gst_caps_unref (caps);
1455   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1456   /* FIXME: reffing the inbuffer should make the transformation not be
1457    * inplace
1458    gst_buffer_ref (inbuffer);
1459    */
1460
1461   /* pushing gives away my reference ... */
1462   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
1463   /* ... but it ends up being modified inplace and
1464    * collected on the global buffer list */
1465   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1466   fail_unless_equals_int (g_list_length (buffers), 1);
1467   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
1468   fail_unless (inbuffer == outbuffer);
1469   res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
1470   GST_INFO ("expected %+1.4f %+1.4f  real %+1.4f %+1.4f", out[0], out[1],
1471       res[0], res[1]);
1472   fail_unless_equals_float (res[0], out[0]);
1473   fail_unless_equals_float (res[1], out[1]);
1474   gst_buffer_unmap (outbuffer, res, size);
1475
1476   /* cleanup */
1477   cleanup_volume (volume);
1478 }
1479
1480 GST_END_TEST;
1481
1482 GST_START_TEST (test_double_f64)
1483 {
1484   GstElement *volume;
1485   GstBuffer *inbuffer;
1486   GstBuffer *outbuffer;
1487   GstCaps *caps;
1488   gdouble in[2] = { 0.75, -0.25 };
1489   gdouble out[2] = { 1.5, -0.5 };       /* nothing is clamped */
1490   gdouble *res;
1491   gsize size;
1492
1493   volume = setup_volume ();
1494   g_object_set (G_OBJECT (volume), "volume", 2.0, NULL);
1495   fail_unless (gst_element_set_state (volume,
1496           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
1497       "could not set to playing");
1498
1499   inbuffer = gst_buffer_new_and_alloc (16);
1500   gst_buffer_fill (inbuffer, 0, in, 16);
1501   caps = gst_caps_from_string (VOLUME_CAPS_STRING_F64);
1502   gst_buffer_set_caps (inbuffer, caps);
1503   gst_caps_unref (caps);
1504   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1505   /* FIXME: reffing the inbuffer should make the transformation not be
1506    * inplace
1507    gst_buffer_ref (inbuffer);
1508    */
1509
1510   /* pushing gives away my reference ... */
1511   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
1512   /* ... but it ends up being modified inplace and
1513    * collected on the global buffer list */
1514   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1515   fail_unless_equals_int (g_list_length (buffers), 1);
1516   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
1517   fail_unless (inbuffer == outbuffer);
1518   res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
1519   GST_INFO ("expected %+1.4f %+1.4f  real %+1.4f %+1.4f", out[0], out[1],
1520       res[0], res[1]);
1521   fail_unless_equals_float (res[0], out[0]);
1522   fail_unless_equals_float (res[1], out[1]);
1523   gst_buffer_unmap (outbuffer, res, size);
1524
1525   /* cleanup */
1526   cleanup_volume (volume);
1527 }
1528
1529 GST_END_TEST;
1530
1531 GST_START_TEST (test_ten_f64)
1532 {
1533   GstElement *volume;
1534   GstBuffer *inbuffer;
1535   GstBuffer *outbuffer;
1536   GstCaps *caps;
1537   gdouble in[2] = { 0.75, -0.25 };
1538   gdouble out[2] = { 7.5, -2.5 };       /* nothing is clamped */
1539   gdouble *res;
1540
1541   volume = setup_volume ();
1542   g_object_set (G_OBJECT (volume), "volume", 10.0, NULL);
1543   fail_unless (gst_element_set_state (volume,
1544           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
1545       "could not set to playing");
1546
1547   inbuffer = gst_buffer_new_and_alloc (16);
1548   memcpy (GST_BUFFER_DATA (inbuffer), in, 16);
1549   fail_unless (memcmp (GST_BUFFER_DATA (inbuffer), in, 16) == 0);
1550   caps = gst_caps_from_string (VOLUME_CAPS_STRING_F64);
1551   gst_buffer_set_caps (inbuffer, caps);
1552   gst_caps_unref (caps);
1553   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1554   /* FIXME: reffing the inbuffer should make the transformation not be
1555    * inplace
1556    gst_buffer_ref (inbuffer);
1557    */
1558
1559   /* pushing gives away my reference ... */
1560   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
1561   /* ... but it ends up being modified inplace and
1562    * collected on the global buffer list */
1563   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1564   fail_unless_equals_int (g_list_length (buffers), 1);
1565   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
1566   fail_unless (inbuffer == outbuffer);
1567   res = (gdouble *) GST_BUFFER_DATA (outbuffer);
1568   GST_INFO ("expected %+1.4f %+1.4f  real %+1.4f %+1.4f", out[0], out[1],
1569       res[0], res[1]);
1570   fail_unless_equals_float (res[0], out[0]);
1571   fail_unless_equals_float (res[1], out[1]);
1572
1573   /* cleanup */
1574   cleanup_volume (volume);
1575 }
1576
1577 GST_END_TEST;
1578
1579
1580 GST_START_TEST (test_mute_f64)
1581 {
1582   GstElement *volume;
1583   GstBuffer *inbuffer;
1584   GstBuffer *outbuffer;
1585   GstCaps *caps;
1586   gdouble in[2] = { 0.75, -0.25 };
1587   gdouble out[2] = { 0, 0 };
1588   gdouble *res;
1589   gsize size;
1590
1591   volume = setup_volume ();
1592   g_object_set (G_OBJECT (volume), "mute", TRUE, NULL);
1593   fail_unless (gst_element_set_state (volume,
1594           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
1595       "could not set to playing");
1596
1597   inbuffer = gst_buffer_new_and_alloc (16);
1598   gst_buffer_fill (inbuffer, 0, in, 16);
1599   caps = gst_caps_from_string (VOLUME_CAPS_STRING_F64);
1600   gst_buffer_set_caps (inbuffer, caps);
1601   gst_caps_unref (caps);
1602   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1603   /* FIXME: reffing the inbuffer should make the transformation not be
1604    * inplace
1605    gst_buffer_ref (inbuffer);
1606    */
1607
1608   /* pushing gives away my reference ... */
1609   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
1610   /* ... but it ends up being modified inplace and
1611    * collected on the global buffer list */
1612   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1613   fail_unless_equals_int (g_list_length (buffers), 1);
1614   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
1615   fail_unless (inbuffer == outbuffer);
1616   res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
1617   GST_INFO ("expected %+1.4f %+1.4f  real %+1.4f %+1.4f", out[0], out[1],
1618       res[0], res[1]);
1619   fail_unless_equals_float (res[0], out[0]);
1620   fail_unless_equals_float (res[1], out[1]);
1621   gst_buffer_unmap (outbuffer, res, size);
1622
1623   /* cleanup */
1624   cleanup_volume (volume);
1625 }
1626
1627 GST_END_TEST;
1628
1629 GST_START_TEST (test_wrong_caps)
1630 {
1631   GstElement *volume;
1632   GstBuffer *inbuffer;
1633   gint16 in[2] = { 16384, -256 };
1634   GstBus *bus;
1635   GstMessage *message;
1636   GstCaps *caps;
1637
1638   volume = setup_volume ();
1639   bus = gst_bus_new ();
1640
1641   fail_unless (gst_element_set_state (volume,
1642           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
1643       "could not set to playing");
1644
1645   inbuffer = gst_buffer_new_and_alloc (4);
1646   gst_buffer_fill (inbuffer, 0, in, 4);
1647   caps = gst_caps_from_string (VOLUME_WRONG_CAPS_STRING);
1648   gst_buffer_set_caps (inbuffer, caps);
1649   gst_caps_unref (caps);
1650   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1651   gst_buffer_ref (inbuffer);
1652
1653   /* set a bus here so we avoid getting state change messages */
1654   gst_element_set_bus (volume, bus);
1655
1656   /* pushing gives an error because it can't negotiate with wrong caps */
1657   fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer),
1658       GST_FLOW_NOT_NEGOTIATED);
1659   /* ... and the buffer would have been lost if we didn't ref it ourselves */
1660   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1661   gst_buffer_unref (inbuffer);
1662   fail_unless_equals_int (g_list_length (buffers), 0);
1663
1664   /* volume_set_caps should not have been called since basetransform caught
1665    * the negotiation problem */
1666   fail_if ((message = gst_bus_pop (bus)) != NULL);
1667
1668   /* cleanup */
1669   gst_element_set_bus (volume, NULL);
1670   gst_object_unref (GST_OBJECT (bus));
1671   cleanup_volume (volume);
1672 }
1673
1674 GST_END_TEST;
1675
1676 GST_START_TEST (test_passthrough)
1677 {
1678   GstElement *volume;
1679   GstBuffer *inbuffer, *outbuffer;
1680   GstCaps *caps;
1681   gint16 in[2] = { 16384, -256 };
1682   gint16 *res;
1683   gsize size;
1684
1685   volume = setup_volume ();
1686   g_object_set (G_OBJECT (volume), "volume", 1.0, NULL);
1687   fail_unless (gst_element_set_state (volume,
1688           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
1689       "could not set to playing");
1690
1691   inbuffer = gst_buffer_new_and_alloc (4);
1692   gst_buffer_fill (inbuffer, 0, in, 4);
1693   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S16);
1694   gst_buffer_set_caps (inbuffer, caps);
1695   gst_caps_unref (caps);
1696   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1697
1698   /* pushing gives away my reference ... */
1699   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
1700   /* ... but it ends up being collected on the global buffer list */
1701   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1702   fail_unless_equals_int (g_list_length (buffers), 1);
1703   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
1704   fail_unless (inbuffer == outbuffer);
1705   res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
1706   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", in[0], in[1], res[0], res[1]);
1707   fail_unless (memcmp (res, in, 4) == 0);
1708   gst_buffer_unmap (outbuffer, res, size);
1709
1710   /* cleanup */
1711   cleanup_volume (volume);
1712 }
1713
1714 GST_END_TEST;
1715
1716 GST_START_TEST (test_controller_usability)
1717 {
1718   GstInterpolationControlSource *csource;
1719   GstController *c;
1720   GstElement *volume;
1721   GValue value = { 0, };
1722
1723   /* note: the volume element should init the controller library for us */
1724   volume = setup_volume ();
1725
1726   c = gst_controller_new (G_OBJECT (volume), "volume", NULL);
1727
1728   fail_unless (GST_IS_CONTROLLER (c));
1729
1730   /* this shouldn't crash, whether this mode is implemented or not */
1731   csource = gst_interpolation_control_source_new ();
1732   gst_interpolation_control_source_set_interpolation_mode (csource,
1733       GST_INTERPOLATE_CUBIC);
1734   gst_controller_set_control_source (c, "volume", GST_CONTROL_SOURCE (csource));
1735   g_object_unref (csource);
1736
1737   g_value_init (&value, G_TYPE_DOUBLE);
1738   g_value_set_double (&value, 0.0);
1739   gst_interpolation_control_source_set (csource, 0 * GST_SECOND, &value);
1740   g_value_set_double (&value, 1.0);
1741   gst_interpolation_control_source_set (csource, 5 * GST_SECOND, &value);
1742   g_value_set_double (&value, 0.0);
1743   gst_interpolation_control_source_set (csource, 10 * GST_SECOND, &value);
1744   g_value_unset (&value);
1745
1746   g_object_unref (c);
1747
1748   cleanup_volume (volume);
1749 }
1750
1751 GST_END_TEST;
1752
1753 GST_START_TEST (test_controller_processing)
1754 {
1755   GstInterpolationControlSource *csource;
1756   GstController *c;
1757   GstElement *volume;
1758   GstBuffer *inbuffer, *outbuffer;
1759   GstCaps *caps;
1760   gint16 in[2] = { 16384, -256 };
1761   gint16 *res;
1762   gsize size;
1763
1764   volume = setup_volume ();
1765
1766   c = gst_controller_new (G_OBJECT (volume), "volume", NULL);
1767
1768   fail_unless (GST_IS_CONTROLLER (c));
1769
1770   csource = gst_interpolation_control_source_new ();
1771   gst_interpolation_control_source_set_interpolation_mode (csource,
1772       GST_INTERPOLATE_CUBIC);
1773   gst_controller_set_control_source (c, "volume", GST_CONTROL_SOURCE (csource));
1774   g_object_unref (csource);
1775
1776   fail_unless (gst_element_set_state (volume,
1777           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
1778       "could not set to playing");
1779
1780   inbuffer = gst_buffer_new_and_alloc (4);
1781   gst_buffer_fill (inbuffer, 0, in, 4);
1782   caps = gst_caps_from_string (VOLUME_CAPS_STRING_S16);
1783   gst_buffer_set_caps (inbuffer, caps);
1784   GST_BUFFER_TIMESTAMP (inbuffer) = 0;
1785   gst_caps_unref (caps);
1786   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1787
1788   /* pushing gives away my reference ... */
1789   fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
1790   /* ... but it ends up being collected on the global buffer list */
1791   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
1792   fail_unless_equals_int (g_list_length (buffers), 1);
1793   fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
1794   fail_unless (inbuffer == outbuffer);
1795   res = gst_buffer_map (outbuffer, &size, NULL, GST_MAP_READ);
1796   GST_INFO ("expected %+5d %+5d  real %+5d %+5d", in[0], in[1], res[0], res[1]);
1797   fail_unless (memcmp (res, in, 4) == 0);
1798   gst_buffer_unmap (outbuffer, res, size);
1799
1800   g_object_unref (c);
1801
1802   cleanup_volume (volume);
1803 }
1804
1805 GST_END_TEST;
1806
1807 static Suite *
1808 volume_suite (void)
1809 {
1810   Suite *s = suite_create ("volume");
1811   TCase *tc_chain = tcase_create ("general");
1812
1813   suite_add_tcase (s, tc_chain);
1814   tcase_add_test (tc_chain, test_get_set);
1815   tcase_add_test (tc_chain, test_unity_s8);
1816   tcase_add_test (tc_chain, test_half_s8);
1817   tcase_add_test (tc_chain, test_double_s8);
1818   tcase_add_test (tc_chain, test_ten_s8);
1819   tcase_add_test (tc_chain, test_mute_s8);
1820   tcase_add_test (tc_chain, test_unity_s16);
1821   tcase_add_test (tc_chain, test_half_s16);
1822   tcase_add_test (tc_chain, test_double_s16);
1823   tcase_add_test (tc_chain, test_ten_s16);
1824   tcase_add_test (tc_chain, test_mute_s16);
1825   tcase_add_test (tc_chain, test_unity_s24);
1826   tcase_add_test (tc_chain, test_half_s24);
1827   tcase_add_test (tc_chain, test_double_s24);
1828   tcase_add_test (tc_chain, test_ten_s24);
1829   tcase_add_test (tc_chain, test_mute_s24);
1830   tcase_add_test (tc_chain, test_unity_s32);
1831   tcase_add_test (tc_chain, test_half_s32);
1832   tcase_add_test (tc_chain, test_double_s32);
1833   tcase_add_test (tc_chain, test_ten_s32);
1834   tcase_add_test (tc_chain, test_mute_s32);
1835   tcase_add_test (tc_chain, test_unity_f32);
1836   tcase_add_test (tc_chain, test_half_f32);
1837   tcase_add_test (tc_chain, test_double_f32);
1838   tcase_add_test (tc_chain, test_ten_f32);
1839   tcase_add_test (tc_chain, test_mute_f32);
1840   tcase_add_test (tc_chain, test_unity_f64);
1841   tcase_add_test (tc_chain, test_half_f64);
1842   tcase_add_test (tc_chain, test_double_f64);
1843   tcase_add_test (tc_chain, test_ten_f64);
1844   tcase_add_test (tc_chain, test_mute_f64);
1845   tcase_add_test (tc_chain, test_wrong_caps);
1846   tcase_add_test (tc_chain, test_passthrough);
1847   tcase_add_test (tc_chain, test_controller_usability);
1848   tcase_add_test (tc_chain, test_controller_processing);
1849
1850   return s;
1851 }
1852
1853 GST_CHECK_MAIN (volume)