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