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