controller: expand the api to offer functions for plain and GValue arrays
[platform/upstream/gstreamer.git] / tests / check / libs / controller.c
1 /* GStreamer
2  *
3  * unit test for the controller library
4  *
5  * Copyright (C) <2005> Stefan Kost <ensonic at users dot sf dot net>
6  * Copyright (C) <2006-2007> Sebastian Dröge <slomo@circular-chaos.org>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27 #include <gst/gst.h>
28 #include <gst/check/gstcheck.h>
29 #include <gst/controller/gstinterpolationcontrolsource.h>
30 #include <gst/controller/gstlfocontrolsource.h>
31 #include <gst/controller/gsttriggercontrolsource.h>
32 #include <gst/controller/gstdirectcontrolbinding.h>
33
34 /* enum for text element */
35
36 #define GST_TYPE_TEST_ENUM (gst_test_enum_get_type ())
37
38 typedef enum
39 {
40   ENUM_V0 = 0,
41   ENUM_V10 = 10,
42   ENUM_V11,
43   ENUM_V12,
44   ENUM_V255 = 255
45 } GstTestEnum;
46
47 static GType
48 gst_test_enum_get_type (void)
49 {
50   static gsize gtype = 0;
51   static const GEnumValue values[] = {
52     {ENUM_V0, "ENUM_V0", "0"},
53     {ENUM_V10, "ENUM_V10", "10"},
54     {ENUM_V11, "ENUM_V11", "11"},
55     {ENUM_V12, "ENUM_V12", "12"},
56     {ENUM_V255, "ENUM_V255", "255"},
57     {0, NULL, NULL}
58   };
59
60   if (g_once_init_enter (&gtype)) {
61     GType tmp = g_enum_register_static ("GstTestEnum", values);
62     g_once_init_leave (&gtype, tmp);
63   }
64
65   return (GType) gtype;
66 }
67
68 /* local test element */
69
70 enum
71 {
72   PROP_INT = 1,
73   PROP_FLOAT,
74   PROP_DOUBLE,
75   PROP_BOOLEAN,
76   PROP_ENUM,
77   PROP_READONLY,
78   PROP_STATIC,
79   PROP_CONSTRUCTONLY,
80   PROP_COUNT
81 };
82
83 #define GST_TYPE_TEST_OBJ            (gst_test_obj_get_type ())
84 #define GST_TEST_OBJ(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_TEST_OBJ, GstTestObj))
85 #define GST_TEST_OBJ_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_TEST_OBJ, GstTestObjClass))
86 #define GST_IS_TEST_OBJ(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TEST_OBJ))
87 #define GST_IS_TEST_OBJ_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_TEST_OBJ))
88 #define GST_TEST_OBJ_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_TEST_OBJ, GstTestObjClass))
89
90 typedef struct _GstTestObj GstTestObj;
91 typedef struct _GstTestObjClass GstTestObjClass;
92
93 struct _GstTestObj
94 {
95   GstElement parent;
96   gint val_int;
97   gfloat val_float;
98   gdouble val_double;
99   gboolean val_boolean;
100   GstTestEnum val_enum;
101 };
102 struct _GstTestObjClass
103 {
104   GstElementClass parent_class;
105 };
106
107 static GType gst_test_obj_get_type (void);
108
109 static void
110 gst_test_obj_get_property (GObject * object,
111     guint property_id, GValue * value, GParamSpec * pspec)
112 {
113   GstTestObj *self = GST_TEST_OBJ (object);
114
115   switch (property_id) {
116     case PROP_INT:
117       g_value_set_int (value, self->val_int);
118       break;
119     case PROP_FLOAT:
120       g_value_set_float (value, self->val_float);
121       break;
122     case PROP_DOUBLE:
123       g_value_set_double (value, self->val_double);
124       break;
125     case PROP_BOOLEAN:
126       g_value_set_boolean (value, self->val_boolean);
127       break;
128     case PROP_ENUM:
129       g_value_set_enum (value, self->val_enum);
130       break;
131     default:
132       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
133       break;
134   }
135 }
136
137 static void
138 gst_test_obj_set_property (GObject * object,
139     guint property_id, const GValue * value, GParamSpec * pspec)
140 {
141   GstTestObj *self = GST_TEST_OBJ (object);
142
143   switch (property_id) {
144     case PROP_INT:
145       self->val_int = g_value_get_int (value);
146       GST_DEBUG ("test value int=%d", self->val_int);
147       break;
148     case PROP_FLOAT:
149       self->val_float = g_value_get_float (value);
150       GST_DEBUG ("test value float=%f", self->val_float);
151       break;
152     case PROP_DOUBLE:
153       self->val_double = g_value_get_double (value);
154       GST_DEBUG ("test value double=%lf", self->val_double);
155       break;
156     case PROP_BOOLEAN:
157       self->val_boolean = g_value_get_boolean (value);
158       GST_DEBUG ("test value boolean=%d", self->val_boolean);
159       break;
160     case PROP_ENUM:
161       self->val_enum = g_value_get_enum (value);
162       GST_DEBUG ("test value enum=%d", self->val_enum);
163       break;
164     case PROP_CONSTRUCTONLY:
165       break;
166     default:
167       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
168       break;
169   }
170 }
171
172 static void
173 gst_test_obj_class_init (GstTestObjClass * klass)
174 {
175   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
176
177   gobject_class->set_property = gst_test_obj_set_property;
178   gobject_class->get_property = gst_test_obj_get_property;
179
180   g_object_class_install_property (gobject_class, PROP_INT,
181       g_param_spec_int ("int",
182           "int prop",
183           "int number parameter",
184           0, 100, 0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
185
186   g_object_class_install_property (gobject_class, PROP_FLOAT,
187       g_param_spec_float ("float",
188           "float prop",
189           "float number parameter",
190           0.0, 100.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
191
192   g_object_class_install_property (gobject_class, PROP_DOUBLE,
193       g_param_spec_double ("double",
194           "double prop",
195           "double number parameter",
196           0.0, 100.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
197
198   g_object_class_install_property (gobject_class, PROP_BOOLEAN,
199       g_param_spec_boolean ("boolean",
200           "boolean prop",
201           "boolean parameter",
202           FALSE, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
203
204   g_object_class_install_property (gobject_class, PROP_ENUM,
205       g_param_spec_enum ("enum",
206           "enum prop",
207           "enum parameter",
208           GST_TYPE_TEST_ENUM, ENUM_V0,
209           G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
210
211   g_object_class_install_property (gobject_class, PROP_READONLY,
212       g_param_spec_int ("readonly",
213           "readonly prop",
214           "readonly parameter",
215           0, G_MAXINT, 0, G_PARAM_READABLE | GST_PARAM_CONTROLLABLE));
216
217   g_object_class_install_property (gobject_class, PROP_STATIC,
218       g_param_spec_int ("static",
219           "static prop",
220           "static parameter", 0, G_MAXINT, 0, G_PARAM_READWRITE));
221
222   g_object_class_install_property (gobject_class, PROP_CONSTRUCTONLY,
223       g_param_spec_int ("construct-only",
224           "construct-only prop",
225           "construct-only parameter",
226           0, G_MAXINT, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
227 }
228
229 static void
230 gst_test_obj_base_init (GstTestObjClass * klass)
231 {
232   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
233
234   gst_element_class_set_details_simple (element_class,
235       "test object for unit tests",
236       "Test", "Use in unit tests", "Stefan Sauer <ensonic@users.sf.net>");
237 }
238
239 static GType
240 gst_test_obj_get_type (void)
241 {
242   static volatile gsize test_obj_type = 0;
243
244   if (g_once_init_enter (&test_obj_type)) {
245     GType type;
246     static const GTypeInfo info = {
247       (guint16) sizeof (GstTestObjClass),
248       (GBaseInitFunc) gst_test_obj_base_init,   // base_init
249       NULL,                     // base_finalize
250       (GClassInitFunc) gst_test_obj_class_init, // class_init
251       NULL,                     // class_finalize
252       NULL,                     // class_data
253       (guint16) sizeof (GstTestObj),
254       0,                        // n_preallocs
255       NULL,                     // instance_init
256       NULL                      // value_table
257     };
258     type = g_type_register_static (GST_TYPE_ELEMENT, "GstTestObj", &info, 0);
259     g_once_init_leave (&test_obj_type, type);
260   }
261   return test_obj_type;
262 }
263
264 static void
265 setup (void)
266 {
267   gst_element_register (NULL, "testobj", GST_RANK_NONE, GST_TYPE_TEST_OBJ);
268 }
269
270 static void
271 teardown (void)
272 {
273 }
274
275
276 /* TESTS */
277
278 /* tests if we don't fail on empty interpolation controlsources */
279 GST_START_TEST (controller_controlsource_empty1)
280 {
281   GstElement *elem;
282   GstControlSource *cs;
283
284   elem = gst_element_factory_make ("testobj", NULL);
285
286   cs = gst_interpolation_control_source_new ();
287
288   fail_unless (gst_object_add_control_binding (GST_OBJECT (elem),
289           gst_direct_control_binding_new (GST_OBJECT (elem), "int", cs)));
290
291   /* don't fail on empty control point lists */
292   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
293
294   /* unref objects */
295   gst_object_unref (cs);
296   gst_object_unref (elem);
297 }
298
299 GST_END_TEST;
300
301 /* tests if we don't fail on interpolation controlsources that are empty again */
302 GST_START_TEST (controller_controlsource_empty2)
303 {
304   GstElement *elem;
305   GstControlSource *cs;
306   GstTimedValueControlSource *tvcs;
307
308   elem = gst_element_factory_make ("testobj", NULL);
309
310   cs = gst_interpolation_control_source_new ();
311
312   fail_unless (gst_object_add_control_binding (GST_OBJECT (elem),
313           gst_direct_control_binding_new (GST_OBJECT (elem), "int", cs)));
314
315   /* set control values */
316   tvcs = (GstTimedValueControlSource *) cs;
317   gst_timed_value_control_source_set (tvcs, 0 * GST_SECOND, 0);
318
319   /* ... and unset the value */
320   gst_timed_value_control_source_unset (tvcs, 0 * GST_SECOND);
321
322   /* don't fail on empty control point lists */
323   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
324
325   /* unref objects */
326   gst_object_unref (cs);
327   gst_object_unref (elem);
328 }
329
330 GST_END_TEST;
331
332 /* test timed value handling without interpolation */
333 GST_START_TEST (controller_interpolation_none)
334 {
335   GstControlSource *cs;
336   GstTimedValueControlSource *tvcs;
337   GstElement *elem;
338   gdouble v;
339
340   elem = gst_element_factory_make ("testobj", NULL);
341
342   /* new interpolation control source */
343   cs = gst_interpolation_control_source_new ();
344   tvcs = (GstTimedValueControlSource *) cs;
345
346   fail_unless (gst_object_add_control_binding (GST_OBJECT (elem),
347           gst_direct_control_binding_new (GST_OBJECT (elem), "int", cs)));
348
349   /* set interpolation mode */
350   g_object_set (cs, "mode", GST_INTERPOLATION_MODE_NONE, NULL);
351
352   /* set control values */
353   fail_unless (gst_timed_value_control_source_set (tvcs, 0 * GST_SECOND, 0.0));
354   fail_unless (gst_timed_value_control_source_set (tvcs, 2 * GST_SECOND, 1.0));
355
356   /* check values on control source directly */
357   fail_unless (gst_control_source_get_value (cs, 0 * GST_SECOND, &v));
358   fail_unless_equals_float (v, 0.0);
359   fail_unless (gst_control_source_get_value (cs, 1 * GST_SECOND, &v));
360   fail_unless_equals_float (v, 0.0);
361   fail_unless (gst_control_source_get_value (cs, 2 * GST_SECOND, &v));
362   fail_unless_equals_float (v, 1.0);
363   fail_unless (gst_control_source_get_value (cs, 3 * GST_SECOND, &v));
364   fail_unless_equals_float (v, 1.0);
365
366   /* now pull in values for some timestamps */
367   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
368   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
369   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
370   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
371   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND);
372   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
373   gst_object_sync_values (GST_OBJECT (elem), 3 * GST_SECOND);
374   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
375
376   gst_object_unref (cs);
377   gst_object_unref (elem);
378 }
379
380 GST_END_TEST;
381
382 /* test timed value handling with linear interpolation */
383 GST_START_TEST (controller_interpolation_linear)
384 {
385   GstControlSource *cs;
386   GstTimedValueControlSource *tvcs;
387   GstElement *elem;
388
389   elem = gst_element_factory_make ("testobj", NULL);
390
391   /* new interpolation control source */
392   cs = gst_interpolation_control_source_new ();
393   tvcs = (GstTimedValueControlSource *) cs;
394
395   fail_unless (gst_object_add_control_binding (GST_OBJECT (elem),
396           gst_direct_control_binding_new (GST_OBJECT (elem), "int", cs)));
397
398   /* set interpolation mode */
399   g_object_set (cs, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL);
400
401   /* set control values */
402   fail_unless (gst_timed_value_control_source_set (tvcs, 0 * GST_SECOND, 0.0));
403   fail_unless (gst_timed_value_control_source_set (tvcs, 2 * GST_SECOND, 1.0));
404
405   /* now pull in values for some timestamps */
406   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
407   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
408   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
409   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
410   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND);
411   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
412
413   gst_object_unref (cs);
414   gst_object_unref (elem);
415 }
416
417 GST_END_TEST;
418
419 /* test timed value handling with cubic interpolation */
420 GST_START_TEST (controller_interpolation_cubic)
421 {
422   GstControlSource *cs;
423   GstTimedValueControlSource *tvcs;
424   GstElement *elem;
425
426   elem = gst_element_factory_make ("testobj", NULL);
427
428   /* new interpolation control source */
429   cs = gst_interpolation_control_source_new ();
430   tvcs = (GstTimedValueControlSource *) cs;
431
432   fail_unless (gst_object_add_control_binding (GST_OBJECT (elem),
433           gst_direct_control_binding_new (GST_OBJECT (elem), "double", cs)));
434
435   /* set interpolation mode */
436   g_object_set (cs, "mode", GST_INTERPOLATION_MODE_CUBIC, NULL);
437
438   /* set control values */
439   fail_unless (gst_timed_value_control_source_set (tvcs, 0 * GST_SECOND, 0.0));
440   fail_unless (gst_timed_value_control_source_set (tvcs, 1 * GST_SECOND, 0.5));
441   fail_unless (gst_timed_value_control_source_set (tvcs, 2 * GST_SECOND, 0.2));
442   fail_unless (gst_timed_value_control_source_set (tvcs, 4 * GST_SECOND, 0.8));
443
444   /* now pull in values for some timestamps */
445   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
446   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 0.0);
447   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
448   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 50.0);
449   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND);
450   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 20.0);
451   gst_object_sync_values (GST_OBJECT (elem), 3 * GST_SECOND);
452   fail_unless (GST_TEST_OBJ (elem)->val_double > 20.0 &&
453       GST_TEST_OBJ (elem)->val_double < 80.0, NULL);
454   gst_object_sync_values (GST_OBJECT (elem), 4 * GST_SECOND);
455   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 80.0);
456   gst_object_sync_values (GST_OBJECT (elem), 5 * GST_SECOND);
457   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 80.0);
458
459   gst_object_unref (cs);
460   gst_object_unref (elem);
461 }
462
463 GST_END_TEST;
464
465 /* test timed value handling with cubic interpolation */
466 GST_START_TEST (controller_interpolation_cubic_too_few_cp)
467 {
468   GstControlSource *cs;
469   GstTimedValueControlSource *tvcs;
470   GstElement *elem;
471
472   elem = gst_element_factory_make ("testobj", NULL);
473
474   /* new interpolation control source */
475   cs = gst_interpolation_control_source_new ();
476   tvcs = (GstTimedValueControlSource *) cs;
477
478   fail_unless (gst_object_add_control_binding (GST_OBJECT (elem),
479           gst_direct_control_binding_new (GST_OBJECT (elem), "double", cs)));
480
481   /* set interpolation mode */
482   g_object_set (cs, "mode", GST_INTERPOLATION_MODE_CUBIC, NULL);
483
484   /* set 2 control values */
485   fail_unless (gst_timed_value_control_source_set (tvcs, 0 * GST_SECOND, 0.0));
486   fail_unless (gst_timed_value_control_source_set (tvcs, 2 * GST_SECOND, 0.4));
487
488   /* now pull in values for some timestamps and verify that it used linear
489    * interpolation as we don't gave enough control points
490    */
491   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
492   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 0.0);
493   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
494   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 20.0);
495   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND);
496   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 40.0);
497
498   gst_object_unref (cs);
499   gst_object_unref (elem);
500 }
501
502 GST_END_TEST;
503
504 /* test _unset() */
505 GST_START_TEST (controller_interpolation_unset)
506 {
507   GstControlSource *cs;
508   GstTimedValueControlSource *tvcs;
509   GstElement *elem;
510
511   elem = gst_element_factory_make ("testobj", NULL);
512
513   /* new interpolation control source */
514   cs = gst_interpolation_control_source_new ();
515   tvcs = (GstTimedValueControlSource *) cs;
516
517   fail_unless (gst_object_add_control_binding (GST_OBJECT (elem),
518           gst_direct_control_binding_new (GST_OBJECT (elem), "int", cs)));
519
520   /* set interpolation mode */
521   g_object_set (cs, "mode", GST_INTERPOLATION_MODE_NONE, NULL);
522
523   /* set control values */
524   fail_unless (gst_timed_value_control_source_set (tvcs, 0 * GST_SECOND, 0.0));
525   fail_unless (gst_timed_value_control_source_set (tvcs, 1 * GST_SECOND, 1.0));
526   fail_unless (gst_timed_value_control_source_set (tvcs, 2 * GST_SECOND, 0.5));
527
528   /* verify values */
529   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
530   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
531   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
532   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
533   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND);
534   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
535
536   /* unset second */
537   fail_unless (gst_timed_value_control_source_unset (tvcs, 1 * GST_SECOND));
538
539   /* verify value again */
540   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
541   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
542   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND);
543   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
544
545   /* unset all values, reset and try to unset again */
546   fail_unless (gst_timed_value_control_source_unset (tvcs, 0 * GST_SECOND));
547   fail_unless (gst_timed_value_control_source_unset (tvcs, 2 * GST_SECOND));
548   gst_timed_value_control_source_unset_all (tvcs);
549   fail_if (gst_timed_value_control_source_unset (tvcs, 2 * GST_SECOND));
550
551   gst_object_unref (cs);
552   gst_object_unref (elem);
553 }
554
555 GST_END_TEST;
556
557 /* test _unset_all() */
558 GST_START_TEST (controller_interpolation_unset_all)
559 {
560   GstControlSource *cs;
561   GstTimedValueControlSource *tvcs;
562   GstElement *elem;
563
564   elem = gst_element_factory_make ("testobj", NULL);
565
566   /* new interpolation control source */
567   cs = gst_interpolation_control_source_new ();
568   tvcs = (GstTimedValueControlSource *) cs;
569
570   fail_unless (gst_object_add_control_binding (GST_OBJECT (elem),
571           gst_direct_control_binding_new (GST_OBJECT (elem), "int", cs)));
572
573   /* set interpolation mode */
574   g_object_set (cs, "mode", GST_INTERPOLATION_MODE_NONE, NULL);
575
576   /* set control values */
577   fail_unless (gst_timed_value_control_source_set (tvcs, 0 * GST_SECOND, 0.0));
578   fail_unless (gst_timed_value_control_source_set (tvcs, 1 * GST_SECOND, 1.0));
579
580   /* verify values */
581   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
582   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
583   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
584   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
585
586   /* unset all */
587   gst_timed_value_control_source_unset_all (tvcs);
588   GST_TEST_OBJ (elem)->val_int = 0;
589
590   /* verify value again */
591   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
592   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
593
594   gst_object_unref (cs);
595   gst_object_unref (elem);
596 }
597
598 GST_END_TEST;
599
600 /* test retrieval of an array of values with get_value_array() */
601 GST_START_TEST (controller_interpolation_linear_value_array)
602 {
603   GstControlSource *cs;
604   GstTimedValueControlSource *tvcs;
605   GstElement *elem;
606   gdouble *raw_values;
607   GValue *g_values;
608   gint *values;
609
610   elem = gst_element_factory_make ("testobj", NULL);
611
612   /* new interpolation control source */
613   cs = gst_interpolation_control_source_new ();
614   tvcs = (GstTimedValueControlSource *) cs;
615
616   fail_unless (gst_object_add_control_binding (GST_OBJECT (elem),
617           gst_direct_control_binding_new (GST_OBJECT (elem), "int", cs)));
618
619   /* set interpolation mode */
620   g_object_set (cs, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL);
621
622   /* set control values */
623   fail_unless (gst_timed_value_control_source_set (tvcs, 0 * GST_SECOND, 0.0));
624   fail_unless (gst_timed_value_control_source_set (tvcs, 1 * GST_SECOND, 1.0));
625
626   /* now pull in raw-values for some timestamps */
627   raw_values = g_new (gdouble, 3);
628
629   fail_unless (gst_control_source_get_value_array (cs,
630           0, GST_SECOND / 2, 3, raw_values));
631   fail_unless_equals_float ((raw_values)[0], 0.0);
632   fail_unless_equals_float ((raw_values)[1], 0.5);
633   fail_unless_equals_float ((raw_values)[2], 1.0);
634
635   g_free (raw_values);
636
637   /* now pull in mapped GValues for some timestamps */
638   g_values = g_new0 (GValue, 3);
639
640   fail_unless (gst_object_get_g_value_array (GST_OBJECT (elem), "int",
641           0, GST_SECOND / 2, 3, g_values));
642   fail_unless_equals_int (g_value_get_int (&g_values[0]), 0);
643   fail_unless_equals_int (g_value_get_int (&g_values[1]), 50);
644   fail_unless_equals_int (g_value_get_int (&g_values[2]), 100);
645
646   g_free (g_values);
647
648   /* now pull in mapped values for some timestamps */
649   values = g_new0 (gint, 3);
650
651   fail_unless (gst_object_get_value_array (GST_OBJECT (elem), "int",
652           0, GST_SECOND / 2, 3, values));
653   fail_unless_equals_int (values[0], 0);
654   fail_unless_equals_int (values[1], 50);
655   fail_unless_equals_int (values[2], 100);
656
657   g_free (values);
658
659   gst_object_unref (cs);
660   gst_object_unref (elem);
661 }
662
663 GST_END_TEST;
664
665 /* test if values below minimum and above maximum are clipped */
666 GST_START_TEST (controller_interpolation_linear_invalid_values)
667 {
668   GstControlSource *cs;
669   GstTimedValueControlSource *tvcs;
670   GstElement *elem;
671
672   elem = gst_element_factory_make ("testobj", NULL);
673
674   /* new interpolation control source */
675   cs = gst_interpolation_control_source_new ();
676   tvcs = (GstTimedValueControlSource *) cs;
677
678   fail_unless (gst_object_add_control_binding (GST_OBJECT (elem),
679           gst_direct_control_binding_new (GST_OBJECT (elem), "float", cs)));
680
681   /* set interpolation mode */
682   g_object_set (cs, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL);
683
684   /* set control values */
685   fail_unless (gst_timed_value_control_source_set (tvcs, 0 * GST_SECOND, 2.0));
686   fail_unless (gst_timed_value_control_source_set (tvcs, 4 * GST_SECOND, -2.0));
687
688   /* now pull in values for some timestamps and see if clipping works */
689   /* 200.0 */
690   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
691   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_float, 100.0);
692   /* 100.0 */
693   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
694   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_float, 100.0);
695   /* 50.0 */
696   gst_object_sync_values (GST_OBJECT (elem),
697       1 * GST_SECOND + 500 * GST_MSECOND);
698   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_float, 50.0);
699   /* 0.0 */
700   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND);
701   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_float, 0.0);
702   /* -100.0 */
703   gst_object_sync_values (GST_OBJECT (elem), 3 * GST_SECOND);
704   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_float, 0.0);
705   /* -200.0 */
706   gst_object_sync_values (GST_OBJECT (elem), 4 * GST_SECOND);
707   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_float, 0.0);
708
709   gst_object_unref (cs);
710   gst_object_unref (elem);
711 }
712
713 GST_END_TEST;
714
715 GST_START_TEST (controller_interpolation_linear_default_values)
716 {
717   GstControlSource *cs;
718   GstTimedValueControlSource *tvcs;
719   GstElement *elem;
720
721   elem = gst_element_factory_make ("testobj", NULL);
722
723   /* new interpolation control source */
724   cs = gst_interpolation_control_source_new ();
725   tvcs = (GstTimedValueControlSource *) cs;
726
727   fail_unless (gst_object_add_control_binding (GST_OBJECT (elem),
728           gst_direct_control_binding_new (GST_OBJECT (elem), "int", cs)));
729
730   /* set interpolation mode */
731   g_object_set (cs, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL);
732
733   /* Should fail if no value was set yet
734    * FIXME: will not fail, as interpolation assumes val[0]=default_value if
735    * nothing else is set.
736    fail_if (gst_timed_value_control_source_set (tvcs, 1 * GST_SECOND, &val_int));
737    */
738
739   /* set control values */
740   fail_unless (gst_timed_value_control_source_set (tvcs, 1 * GST_SECOND, 0.0));
741   fail_unless (gst_timed_value_control_source_set (tvcs, 3 * GST_SECOND, 1.0));
742
743   /* now pull in values for some timestamps */
744   /* should give the value of the first control point for timestamps before it */
745   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
746   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
747   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
748   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
749   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND);
750   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
751   gst_object_sync_values (GST_OBJECT (elem), 3 * GST_SECOND);
752   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
753
754   /* set control values */
755   fail_unless (gst_timed_value_control_source_set (tvcs, 0 * GST_SECOND, 0.0));
756   fail_unless (gst_timed_value_control_source_set (tvcs, 2 * GST_SECOND, 1.0));
757
758   /* unset the old ones */
759   fail_unless (gst_timed_value_control_source_unset (tvcs, 1 * GST_SECOND));
760   fail_unless (gst_timed_value_control_source_unset (tvcs, 3 * GST_SECOND));
761
762   /* now pull in values for some timestamps */
763   /* should now give our value for timestamp 0 */
764   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
765   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
766   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
767   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
768   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND);
769   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
770
771   gst_object_unref (cs);
772   gst_object_unref (elem);
773 }
774
775 GST_END_TEST;
776
777 /* test gst_controller_set_disabled() with linear interpolation */
778 GST_START_TEST (controller_interpolation_linear_disabled)
779 {
780   GstControlSource *cs1, *cs2;
781   GstTimedValueControlSource *tvcs1, *tvcs2;
782   GstElement *elem;
783
784   elem = gst_element_factory_make ("testobj", NULL);
785
786   /* new interpolation control source */
787   cs1 = gst_interpolation_control_source_new ();
788   tvcs1 = (GstTimedValueControlSource *) cs1;
789
790   cs2 = gst_interpolation_control_source_new ();
791   tvcs2 = (GstTimedValueControlSource *) cs2;
792
793   fail_unless (gst_object_add_control_binding (GST_OBJECT (elem),
794           gst_direct_control_binding_new (GST_OBJECT (elem), "int", cs1)));
795   fail_unless (gst_object_add_control_binding (GST_OBJECT (elem),
796           gst_direct_control_binding_new (GST_OBJECT (elem), "double", cs2)));
797
798   /* set interpolation mode */
799   g_object_set (cs1, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL);
800   g_object_set (cs2, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL);
801
802   /* set control values */
803   fail_unless (gst_timed_value_control_source_set (tvcs1, 0 * GST_SECOND, 0.0));
804   fail_unless (gst_timed_value_control_source_set (tvcs1, 2 * GST_SECOND, 1.0));
805
806   /* set control values */
807   fail_unless (gst_timed_value_control_source_set (tvcs2, 0 * GST_SECOND, 0.2));
808   fail_unless (gst_timed_value_control_source_set (tvcs2, 2 * GST_SECOND, 0.4));
809
810   /* now pull in values for some timestamps */
811   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
812   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
813   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 20.0);
814   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
815   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
816   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 30.0);
817   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND);
818   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
819   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 40.0);
820
821   /* now pull in values for some timestamps, prop double disabled */
822   GST_TEST_OBJ (elem)->val_int = 0;
823   GST_TEST_OBJ (elem)->val_double = 0.0;
824   gst_object_set_control_binding_disabled (GST_OBJECT (elem), "double", TRUE);
825   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
826   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
827   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 0.0);
828   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
829   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
830   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 0.0);
831   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND);
832   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
833   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 0.0);
834
835   /* now pull in values for some timestamps, after enabling double again */
836   GST_TEST_OBJ (elem)->val_int = 0;
837   GST_TEST_OBJ (elem)->val_double = 0.0;
838   gst_object_set_control_binding_disabled (GST_OBJECT (elem), "double", FALSE);
839   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
840   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
841   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 20.0);
842   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
843   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
844   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 30.0);
845   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND);
846   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
847   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 40.0);
848
849   /* now pull in values for some timestamps, after disabling all props */
850   GST_TEST_OBJ (elem)->val_int = 0;
851   GST_TEST_OBJ (elem)->val_double = 0.0;
852   gst_object_set_control_bindings_disabled (GST_OBJECT (elem), TRUE);
853   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
854   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
855   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 0.0);
856   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
857   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
858   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 0.0);
859   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND);
860   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
861   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 0.0);
862
863   /* now pull in values for some timestamps, enabling double again */
864   GST_TEST_OBJ (elem)->val_int = 0;
865   GST_TEST_OBJ (elem)->val_double = 0.0;
866   gst_object_set_control_binding_disabled (GST_OBJECT (elem), "double", FALSE);
867   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
868   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
869   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 20.0);
870   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
871   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
872   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 30.0);
873   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND);
874   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
875   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 40.0);
876
877   /* now pull in values for some timestamps, enabling all */
878   GST_TEST_OBJ (elem)->val_int = 0;
879   GST_TEST_OBJ (elem)->val_double = 0.0;
880   gst_object_set_control_bindings_disabled (GST_OBJECT (elem), FALSE);
881   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
882   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
883   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 20.0);
884   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
885   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
886   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 30.0);
887   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND);
888   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
889   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 40.0);
890
891   gst_object_unref (cs1);
892   gst_object_unref (cs2);
893   gst_object_unref (elem);
894 }
895
896 GST_END_TEST;
897
898
899 GST_START_TEST (controller_interpolation_set_from_list)
900 {
901   GstControlSource *cs;
902   GstTimedValueControlSource *tvcs;
903   GstTimedValue *tval;
904   GstElement *elem;
905   GSList *list = NULL;
906
907   /* test that an invalid timestamp throws a warning of some sort */
908   elem = gst_element_factory_make ("testobj", NULL);
909
910   /* new interpolation control source */
911   cs = gst_interpolation_control_source_new ();
912   tvcs = (GstTimedValueControlSource *) cs;
913
914   fail_unless (gst_object_add_control_binding (GST_OBJECT (elem),
915           gst_direct_control_binding_new (GST_OBJECT (elem), "int", cs)));
916
917   /* set interpolation mode */
918   g_object_set (cs, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL);
919
920   /* set control value */
921   tval = g_new0 (GstTimedValue, 1);
922   tval->timestamp = GST_CLOCK_TIME_NONE;
923   tval->value = 0.0;
924
925   list = g_slist_append (list, tval);
926
927   fail_if (gst_timed_value_control_source_set_from_list (tvcs, list));
928
929   /* try again with a valid stamp, should work now */
930   tval->timestamp = 0;
931   fail_unless (gst_timed_value_control_source_set_from_list (tvcs, list));
932
933   /* allocated GstTimedValue now belongs to the controller, but list not */
934   g_free (tval);
935   g_slist_free (list);
936   gst_object_unref (cs);
937   gst_object_unref (elem);
938 }
939
940 GST_END_TEST;
941
942
943 /* test linear interpolation for ts < first control point */
944 GST_START_TEST (controller_interpolation_linear_before_ts0)
945 {
946   GstControlSource *cs;
947   GstTimedValueControlSource *tvcs;
948   GstElement *elem;
949
950   elem = gst_element_factory_make ("testobj", NULL);
951
952   /* new interpolation control source */
953   cs = gst_interpolation_control_source_new ();
954   tvcs = (GstTimedValueControlSource *) cs;
955
956   fail_unless (gst_object_add_control_binding (GST_OBJECT (elem),
957           gst_direct_control_binding_new (GST_OBJECT (elem), "int", cs)));
958
959   /* set interpolation mode */
960   g_object_set (cs, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL);
961
962   /* set control values */
963   fail_unless (gst_timed_value_control_source_set (tvcs, 2 * GST_SECOND, 1.0));
964   fail_unless (gst_timed_value_control_source_set (tvcs, 4 * GST_SECOND, 0.0));
965
966   /* now pull in values for some timestamps after first control point */
967   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND);
968   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
969   gst_object_sync_values (GST_OBJECT (elem), 3 * GST_SECOND);
970   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
971   gst_object_sync_values (GST_OBJECT (elem), 4 * GST_SECOND);
972   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
973
974   /* now pull in values for some timestamps before first control point */
975   GST_TEST_OBJ (elem)->val_int = 25;
976   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
977   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 25);
978   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
979   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 25);
980
981   gst_object_unref (cs);
982   gst_object_unref (elem);
983 }
984
985 GST_END_TEST;
986
987 /* test linear interpolation of enums */
988 GST_START_TEST (controller_interpolation_linear_enums)
989 {
990   GstControlSource *cs;
991   GstTimedValueControlSource *tvcs;
992   GstElement *elem;
993
994   elem = gst_element_factory_make ("testobj", NULL);
995
996   /* new interpolation control source */
997   cs = gst_interpolation_control_source_new ();
998   tvcs = (GstTimedValueControlSource *) cs;
999
1000   fail_unless (gst_object_add_control_binding (GST_OBJECT (elem),
1001           gst_direct_control_binding_new (GST_OBJECT (elem), "enum", cs)));
1002
1003   /* set interpolation mode */
1004   g_object_set (cs, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL);
1005
1006   /* set control values */
1007   fail_unless (gst_timed_value_control_source_set (tvcs, 0 * GST_SECOND, 0.0));
1008   fail_unless (gst_timed_value_control_source_set (tvcs, 4 * GST_SECOND, 1.0));
1009
1010   /* now pull in values going over the enum values */
1011   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
1012   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_enum, ENUM_V0);
1013   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
1014   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_enum, ENUM_V10);
1015   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND);
1016   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_enum, ENUM_V11);
1017   gst_object_sync_values (GST_OBJECT (elem), 3 * GST_SECOND);
1018   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_enum, ENUM_V12);
1019   gst_object_sync_values (GST_OBJECT (elem), 4 * GST_SECOND);
1020   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_enum, ENUM_V255);
1021
1022   gst_object_unref (cs);
1023   gst_object_unref (elem);
1024 }
1025
1026 GST_END_TEST;
1027
1028 /* test timed value counts */
1029 GST_START_TEST (controller_timed_value_count)
1030 {
1031   GstControlSource *cs;
1032   GstTimedValueControlSource *tvcs;
1033   GstElement *elem;
1034
1035   elem = gst_element_factory_make ("testobj", NULL);
1036
1037   /* new interpolation control source */
1038   cs = gst_interpolation_control_source_new ();
1039   tvcs = (GstTimedValueControlSource *) cs;
1040
1041   fail_unless (gst_object_add_control_binding (GST_OBJECT (elem),
1042           gst_direct_control_binding_new (GST_OBJECT (elem), "int", cs)));
1043
1044   /* set interpolation mode */
1045   g_object_set (cs, "mode", GST_INTERPOLATION_MODE_NONE, NULL);
1046
1047   fail_unless (gst_timed_value_control_source_get_count (tvcs) == 0);
1048
1049   /* set control values */
1050   fail_unless (gst_timed_value_control_source_set (tvcs, 0 * GST_SECOND, 0.0));
1051   fail_unless (gst_timed_value_control_source_get_count (tvcs) == 1);
1052   fail_unless (gst_timed_value_control_source_set (tvcs, 2 * GST_SECOND, 1.0));
1053   fail_unless (gst_timed_value_control_source_get_count (tvcs) == 2);
1054
1055   /* unset control values */
1056   fail_unless (gst_timed_value_control_source_unset (tvcs, 2 * GST_SECOND));
1057   fail_unless (gst_timed_value_control_source_get_count (tvcs) == 1);
1058   fail_unless (gst_timed_value_control_source_unset (tvcs, 0 * GST_SECOND));
1059   fail_unless (gst_timed_value_control_source_get_count (tvcs) == 0);
1060
1061   gst_object_unref (cs);
1062   gst_object_unref (elem);
1063 }
1064
1065 GST_END_TEST;
1066
1067
1068 /* test lfo control source with sine waveform */
1069 GST_START_TEST (controller_lfo_sine)
1070 {
1071   GstControlSource *cs;
1072   GstElement *elem;
1073
1074   elem = gst_element_factory_make ("testobj", NULL);
1075
1076   /* new lfo control source */
1077   cs = gst_lfo_control_source_new ();
1078
1079   fail_unless (gst_object_add_control_binding (GST_OBJECT (elem),
1080           gst_direct_control_binding_new (GST_OBJECT (elem), "int", cs)));
1081
1082   /* configure lfo */
1083   g_object_set (cs, "waveform", GST_LFO_WAVEFORM_SINE,
1084       "frequency", 1.0, "timeshift", (GstClockTime) 0,
1085       "amplitude", 0.5, "offset", 0.5, NULL);
1086
1087   /* now pull in values for some timestamps */
1088   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_MSECOND);
1089   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1090   gst_object_sync_values (GST_OBJECT (elem), 250 * GST_MSECOND);
1091   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1092   gst_object_sync_values (GST_OBJECT (elem), 500 * GST_MSECOND);
1093   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1094   gst_object_sync_values (GST_OBJECT (elem), 750 * GST_MSECOND);
1095   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1096   gst_object_sync_values (GST_OBJECT (elem), 1000 * GST_MSECOND);
1097   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1098   gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND);
1099   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1100   gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND);
1101   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1102   gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND);
1103   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1104   gst_object_sync_values (GST_OBJECT (elem), 2000 * GST_MSECOND);
1105   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1106   gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND);
1107   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1108   gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND);
1109   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1110   gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND);
1111   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1112
1113   gst_object_unref (cs);
1114   gst_object_unref (elem);
1115 }
1116
1117 GST_END_TEST;
1118
1119 /* test lfo control source with sine waveform and timeshift */
1120 GST_START_TEST (controller_lfo_sine_timeshift)
1121 {
1122   GstControlSource *cs;
1123   GstElement *elem;
1124
1125   elem = gst_element_factory_make ("testobj", NULL);
1126
1127   /* new lfo control source */
1128   cs = gst_lfo_control_source_new ();
1129
1130   fail_unless (gst_object_add_control_binding (GST_OBJECT (elem),
1131           gst_direct_control_binding_new (GST_OBJECT (elem), "int", cs)));
1132
1133   /* configure lfo */
1134   g_object_set (cs, "waveform", GST_LFO_WAVEFORM_SINE,
1135       "frequency", 1.0, "timeshift", 250 * GST_MSECOND,
1136       "amplitude", 0.5, "offset", 0.5, NULL);
1137
1138   /* now pull in values for some timestamps */
1139   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_MSECOND);
1140   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1141   gst_object_sync_values (GST_OBJECT (elem), 250 * GST_MSECOND);
1142   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1143   gst_object_sync_values (GST_OBJECT (elem), 500 * GST_MSECOND);
1144   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1145   gst_object_sync_values (GST_OBJECT (elem), 750 * GST_MSECOND);
1146   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1147   gst_object_sync_values (GST_OBJECT (elem), 1000 * GST_MSECOND);
1148   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1149   gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND);
1150   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1151   gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND);
1152   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1153   gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND);
1154   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1155   gst_object_sync_values (GST_OBJECT (elem), 2000 * GST_MSECOND);
1156   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1157   gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND);
1158   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1159   gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND);
1160   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1161   gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND);
1162   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1163
1164   gst_object_unref (cs);
1165   gst_object_unref (elem);
1166 }
1167
1168 GST_END_TEST;
1169
1170 /* test lfo control source with square waveform */
1171 GST_START_TEST (controller_lfo_square)
1172 {
1173   GstControlSource *cs;
1174   GstElement *elem;
1175
1176   elem = gst_element_factory_make ("testobj", NULL);
1177
1178   /* new lfo control source */
1179   cs = gst_lfo_control_source_new ();
1180
1181   fail_unless (gst_object_add_control_binding (GST_OBJECT (elem),
1182           gst_direct_control_binding_new (GST_OBJECT (elem), "int", cs)));
1183
1184   /* configure lfo */
1185   g_object_set (cs, "waveform", GST_LFO_WAVEFORM_SQUARE,
1186       "frequency", 1.0, "timeshift", (GstClockTime) 0,
1187       "amplitude", 0.5, "offset", 0.5, NULL);
1188
1189   /* now pull in values for some timestamps */
1190   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_MSECOND);
1191   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1192   gst_object_sync_values (GST_OBJECT (elem), 250 * GST_MSECOND);
1193   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1194   gst_object_sync_values (GST_OBJECT (elem), 500 * GST_MSECOND);
1195   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1196   gst_object_sync_values (GST_OBJECT (elem), 750 * GST_MSECOND);
1197   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1198   gst_object_sync_values (GST_OBJECT (elem), 1000 * GST_MSECOND);
1199   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1200   gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND);
1201   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1202   gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND);
1203   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1204   gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND);
1205   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1206   gst_object_sync_values (GST_OBJECT (elem), 2000 * GST_MSECOND);
1207   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1208   gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND);
1209   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1210   gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND);
1211   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1212   gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND);
1213   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1214
1215   gst_object_unref (cs);
1216   gst_object_unref (elem);
1217 }
1218
1219 GST_END_TEST;
1220
1221 /* test lfo control source with saw waveform */
1222 GST_START_TEST (controller_lfo_saw)
1223 {
1224   GstControlSource *cs;
1225   GstElement *elem;
1226
1227   elem = gst_element_factory_make ("testobj", NULL);
1228
1229   /* new lfo control source */
1230   cs = gst_lfo_control_source_new ();
1231
1232   fail_unless (gst_object_add_control_binding (GST_OBJECT (elem),
1233           gst_direct_control_binding_new (GST_OBJECT (elem), "int", cs)));
1234
1235   /* configure lfo */
1236   g_object_set (cs, "waveform", GST_LFO_WAVEFORM_SAW,
1237       "frequency", 1.0, "timeshift", (GstClockTime) 0,
1238       "amplitude", 0.5, "offset", 0.5, NULL);
1239
1240   /* now pull in values for some timestamps */
1241   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_MSECOND);
1242   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1243   gst_object_sync_values (GST_OBJECT (elem), 250 * GST_MSECOND);
1244   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 75);
1245   gst_object_sync_values (GST_OBJECT (elem), 500 * GST_MSECOND);
1246   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1247   gst_object_sync_values (GST_OBJECT (elem), 750 * GST_MSECOND);
1248   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 25);
1249   gst_object_sync_values (GST_OBJECT (elem), 1000 * GST_MSECOND);
1250   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1251   gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND);
1252   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 75);
1253   gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND);
1254   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1255   gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND);
1256   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 25);
1257   gst_object_sync_values (GST_OBJECT (elem), 2000 * GST_MSECOND);
1258   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1259   gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND);
1260   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 75);
1261   gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND);
1262   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1263   gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND);
1264   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 25);
1265
1266   gst_object_unref (cs);
1267   gst_object_unref (elem);
1268 }
1269
1270 GST_END_TEST;
1271
1272 /* test lfo control source with reverse saw waveform */
1273 GST_START_TEST (controller_lfo_rsaw)
1274 {
1275   GstControlSource *cs;
1276   GstElement *elem;
1277
1278   elem = gst_element_factory_make ("testobj", NULL);
1279
1280   /* new lfo control source */
1281   cs = gst_lfo_control_source_new ();
1282
1283   fail_unless (gst_object_add_control_binding (GST_OBJECT (elem),
1284           gst_direct_control_binding_new (GST_OBJECT (elem), "int", cs)));
1285
1286   /* configure lfo */
1287   g_object_set (cs, "waveform", GST_LFO_WAVEFORM_REVERSE_SAW,
1288       "frequency", 1.0, "timeshift", (GstClockTime) 0,
1289       "amplitude", 0.5, "offset", 0.5, NULL);
1290
1291   /* now pull in values for some timestamps */
1292   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_MSECOND);
1293   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1294   gst_object_sync_values (GST_OBJECT (elem), 250 * GST_MSECOND);
1295   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 25);
1296   gst_object_sync_values (GST_OBJECT (elem), 500 * GST_MSECOND);
1297   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1298   gst_object_sync_values (GST_OBJECT (elem), 750 * GST_MSECOND);
1299   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 75);
1300   gst_object_sync_values (GST_OBJECT (elem), 1000 * GST_MSECOND);
1301   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1302   gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND);
1303   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 25);
1304   gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND);
1305   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1306   gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND);
1307   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 75);
1308   gst_object_sync_values (GST_OBJECT (elem), 2000 * GST_MSECOND);
1309   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1310   gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND);
1311   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 25);
1312   gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND);
1313   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1314   gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND);
1315   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 75);
1316
1317   gst_object_unref (cs);
1318   gst_object_unref (elem);
1319 }
1320
1321 GST_END_TEST;
1322
1323 /* test lfo control source with saw waveform */
1324 GST_START_TEST (controller_lfo_triangle)
1325 {
1326   GstControlSource *cs;
1327   GstElement *elem;
1328
1329   elem = gst_element_factory_make ("testobj", NULL);
1330
1331   /* new lfo control source */
1332   cs = gst_lfo_control_source_new ();
1333
1334   fail_unless (gst_object_add_control_binding (GST_OBJECT (elem),
1335           gst_direct_control_binding_new (GST_OBJECT (elem), "int", cs)));
1336
1337   /* configure lfo */
1338   g_object_set (cs, "waveform", GST_LFO_WAVEFORM_TRIANGLE,
1339       "frequency", 1.0, "timeshift", (GstClockTime) 0,
1340       "amplitude", 0.5, "offset", 0.5, NULL);
1341
1342   /* now pull in values for some timestamps */
1343   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_MSECOND);
1344   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1345   gst_object_sync_values (GST_OBJECT (elem), 250 * GST_MSECOND);
1346   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1347   gst_object_sync_values (GST_OBJECT (elem), 500 * GST_MSECOND);
1348   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1349   gst_object_sync_values (GST_OBJECT (elem), 750 * GST_MSECOND);
1350   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1351   gst_object_sync_values (GST_OBJECT (elem), 1000 * GST_MSECOND);
1352   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1353   gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND);
1354   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1355   gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND);
1356   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1357   gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND);
1358   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1359   gst_object_sync_values (GST_OBJECT (elem), 2000 * GST_MSECOND);
1360   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1361   gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND);
1362   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1363   gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND);
1364   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1365   gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND);
1366   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1367
1368   gst_object_unref (cs);
1369   gst_object_unref (elem);
1370 }
1371
1372 GST_END_TEST;
1373
1374 /* test lfo control source with nothing set */
1375 GST_START_TEST (controller_lfo_none)
1376 {
1377   GstControlSource *cs;
1378   GstElement *elem;
1379
1380   elem = gst_element_factory_make ("testobj", NULL);
1381
1382   /* new lfo control source */
1383   cs = gst_lfo_control_source_new ();
1384
1385   fail_unless (gst_object_add_control_binding (GST_OBJECT (elem),
1386           gst_direct_control_binding_new (GST_OBJECT (elem), "int", cs)));
1387
1388   /* now pull in values for some timestamps */
1389   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_MSECOND);
1390   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1391   gst_object_sync_values (GST_OBJECT (elem), 250 * GST_MSECOND);
1392   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1393   gst_object_sync_values (GST_OBJECT (elem), 500 * GST_MSECOND);
1394   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1395   gst_object_sync_values (GST_OBJECT (elem), 750 * GST_MSECOND);
1396   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1397   gst_object_sync_values (GST_OBJECT (elem), 1000 * GST_MSECOND);
1398   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1399   gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND);
1400   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1401   gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND);
1402   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1403   gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND);
1404   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1405   gst_object_sync_values (GST_OBJECT (elem), 2000 * GST_MSECOND);
1406   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1407   gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND);
1408   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1409   gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND);
1410   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1411   gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND);
1412   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1413
1414   gst_object_unref (cs);
1415   gst_object_unref (elem);
1416 }
1417
1418 GST_END_TEST;
1419
1420 /* test timed value handling in trigger mode */
1421 GST_START_TEST (controller_trigger_exact)
1422 {
1423   GstControlSource *cs;
1424   GstTimedValueControlSource *tvcs;
1425   GstElement *elem;
1426   gdouble raw_val;
1427
1428   elem = gst_element_factory_make ("testobj", NULL);
1429
1430   /* new interpolation control source */
1431   cs = gst_trigger_control_source_new ();
1432   tvcs = (GstTimedValueControlSource *) cs;
1433
1434   fail_unless (gst_object_add_control_binding (GST_OBJECT (elem),
1435           gst_direct_control_binding_new (GST_OBJECT (elem), "int", cs)));
1436
1437   fail_if (gst_control_source_get_value (cs, 0 * GST_SECOND, &raw_val));
1438
1439   /* set control values */
1440   fail_unless (gst_timed_value_control_source_set (tvcs, 0 * GST_SECOND, 0.5));
1441   fail_unless (gst_timed_value_control_source_set (tvcs, 2 * GST_SECOND, 1.0));
1442
1443   /* now pull in values for some timestamps */
1444   fail_unless (gst_control_source_get_value (cs, 0 * GST_SECOND, &raw_val));
1445
1446   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
1447   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1448
1449   GST_TEST_OBJ (elem)->val_int = 0;
1450   fail_if (gst_control_source_get_value (cs, 1 * GST_SECOND, &raw_val));
1451   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
1452   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1453
1454   fail_unless (gst_control_source_get_value (cs, 2 * GST_SECOND, &raw_val));
1455   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND);
1456   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1457
1458   gst_object_unref (cs);
1459   gst_object_unref (elem);
1460 }
1461
1462 GST_END_TEST;
1463
1464 GST_START_TEST (controller_trigger_tolerance)
1465 {
1466   GstControlSource *cs;
1467   GstTimedValueControlSource *tvcs;
1468   GstElement *elem;
1469   gdouble raw_val;
1470
1471   elem = gst_element_factory_make ("testobj", NULL);
1472
1473   /* new interpolation control source */
1474   cs = gst_trigger_control_source_new ();
1475   tvcs = (GstTimedValueControlSource *) cs;
1476
1477   fail_unless (gst_object_add_control_binding (GST_OBJECT (elem),
1478           gst_direct_control_binding_new (GST_OBJECT (elem), "int", cs)));
1479
1480   g_object_set (cs, "tolerance", G_GINT64_CONSTANT (10), NULL);
1481
1482   fail_if (gst_control_source_get_value (cs, 0 * GST_SECOND, &raw_val));
1483
1484   /* set control values */
1485   fail_unless (gst_timed_value_control_source_set (tvcs, 0 * GST_SECOND, 0.5));
1486   fail_unless (gst_timed_value_control_source_set (tvcs, 2 * GST_SECOND, 1.0));
1487
1488   /* now pull in values for some timestamps */
1489   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
1490   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1491   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND + 5);
1492   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1493
1494   GST_TEST_OBJ (elem)->val_int = 0;
1495   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
1496   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1497
1498   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND - 5);
1499   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1500   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND);
1501   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1502
1503   gst_object_unref (cs);
1504   gst_object_unref (elem);
1505 }
1506
1507 GST_END_TEST;
1508
1509
1510 static Suite *
1511 gst_controller_suite (void)
1512 {
1513   Suite *s = suite_create ("Controller");
1514   TCase *tc = tcase_create ("general");
1515
1516   suite_add_tcase (s, tc);
1517   tcase_add_checked_fixture (tc, setup, teardown);
1518   tcase_add_test (tc, controller_controlsource_empty1);
1519   tcase_add_test (tc, controller_controlsource_empty2);
1520   tcase_add_test (tc, controller_interpolation_none);
1521   tcase_add_test (tc, controller_interpolation_linear);
1522   tcase_add_test (tc, controller_interpolation_cubic);
1523   tcase_add_test (tc, controller_interpolation_cubic_too_few_cp);
1524   tcase_add_test (tc, controller_interpolation_unset);
1525   tcase_add_test (tc, controller_interpolation_unset_all);
1526   tcase_add_test (tc, controller_interpolation_linear_value_array);
1527   tcase_add_test (tc, controller_interpolation_linear_invalid_values);
1528   tcase_add_test (tc, controller_interpolation_linear_default_values);
1529   tcase_add_test (tc, controller_interpolation_linear_disabled);
1530   tcase_add_test (tc, controller_interpolation_set_from_list);
1531   tcase_add_test (tc, controller_interpolation_linear_before_ts0);
1532   tcase_add_test (tc, controller_interpolation_linear_enums);
1533   tcase_add_test (tc, controller_timed_value_count);
1534   tcase_add_test (tc, controller_lfo_sine);
1535   tcase_add_test (tc, controller_lfo_sine_timeshift);
1536   tcase_add_test (tc, controller_lfo_square);
1537   tcase_add_test (tc, controller_lfo_saw);
1538   tcase_add_test (tc, controller_lfo_rsaw);
1539   tcase_add_test (tc, controller_lfo_triangle);
1540   tcase_add_test (tc, controller_lfo_none);
1541   tcase_add_test (tc, controller_trigger_exact);
1542   tcase_add_test (tc, controller_trigger_tolerance);
1543
1544   return s;
1545 }
1546
1547 GST_CHECK_MAIN (gst_controller);