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