controller: rename control-bindings
[platform/upstream/gstreamer.git] / tests / examples / controller / control-sources.c
1 /* 
2  * control-sources.c
3  *
4  * Generates a datafile for various control sources.
5  *
6  * Needs gnuplot for plotting.
7  * plot "ctrl_i1.dat" using 1:2 with points title 'none', "" using 1:3 with points title 'linear', "" using 1:4 with points title 'cubic', "ctrl_i2.dat" using 1:2 with lines title 'none', "" using 1:3 with lines title 'linear', "" using 1:4 with lines title 'cubic'
8  * plot "ctrl_l1.dat" using 1:2 with points title 'sine', "" using 1:3 with points title 'square', "" using 1:4 with points title 'saw', "" using 1:5 with points title 'revsaw', "" using 1:6 with points title 'triangle', "ctrl_l2.dat" using 1:2 with lines title 'sine', "" using 1:3 with lines title 'square', "" using 1:4 with lines title 'saw', "" using 1:5 with lines title 'revsaw', "" using 1:6 with lines title 'triangle'
9  * plot "ctrl_cl1.dat" using 1:2 with points title 'sine', "ctrl_cl2.dat" using 1:2 with lines title 'sine'
10  */
11
12 #include <stdio.h>
13 #include <stdlib.h>
14
15 #include <gst/gst.h>
16 #include <gst/controller/gstinterpolationcontrolsource.h>
17 #include <gst/controller/gstlfocontrolsource.h>
18 #include <gst/controller/gstdirectcontrolbinding.h>
19
20 /* local test element */
21
22 enum
23 {
24   PROP_INT = 1,
25   PROP_FLOAT,
26   PROP_DOUBLE,
27   PROP_BOOLEAN,
28   PROP_COUNT
29 };
30
31 #define GST_TYPE_TEST_OBJ            (gst_test_obj_get_type ())
32 #define GST_TEST_OBJ(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_TEST_OBJ, GstTestObj))
33 #define GST_TEST_OBJ_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_TEST_OBJ, GstTestObjClass))
34 #define GST_IS_TEST_OBJ(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TEST_OBJ))
35 #define GST_IS_TEST_OBJ_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_TEST_OBJ))
36 #define GST_TEST_OBJ_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_TEST_OBJ, GstTestObjClass))
37
38 typedef struct _GstTestObj GstTestObj;
39 typedef struct _GstTestObjClass GstTestObjClass;
40
41 struct _GstTestObj
42 {
43   GstElement parent;
44   gint val_int;
45   gfloat val_float;
46   gdouble val_double;
47   gboolean val_boolean;
48 };
49 struct _GstTestObjClass
50 {
51   GstElementClass parent_class;
52 };
53
54 static GType gst_test_obj_get_type (void);
55
56 static void
57 gst_test_obj_get_property (GObject * object,
58     guint property_id, GValue * value, GParamSpec * pspec)
59 {
60   GstTestObj *self = GST_TEST_OBJ (object);
61
62   switch (property_id) {
63     case PROP_INT:
64       g_value_set_int (value, self->val_int);
65       break;
66     case PROP_FLOAT:
67       g_value_set_float (value, self->val_float);
68       break;
69     case PROP_DOUBLE:
70       g_value_set_double (value, self->val_double);
71       break;
72     case PROP_BOOLEAN:
73       g_value_set_boolean (value, self->val_boolean);
74       break;
75     default:
76       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
77       break;
78   }
79 }
80
81 static void
82 gst_test_obj_set_property (GObject * object,
83     guint property_id, const GValue * value, GParamSpec * pspec)
84 {
85   GstTestObj *self = GST_TEST_OBJ (object);
86
87   switch (property_id) {
88     case PROP_INT:
89       self->val_int = g_value_get_int (value);
90       GST_DEBUG ("test value int=%d", self->val_int);
91       break;
92     case PROP_FLOAT:
93       self->val_float = g_value_get_float (value);
94       GST_DEBUG ("test value float=%f", self->val_float);
95       break;
96     case PROP_DOUBLE:
97       self->val_double = g_value_get_double (value);
98       GST_DEBUG ("test value double=%f", self->val_double);
99       break;
100     case PROP_BOOLEAN:
101       self->val_boolean = g_value_get_boolean (value);
102       GST_DEBUG ("test value boolean=%d", self->val_boolean);
103       break;
104     default:
105       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
106       break;
107   }
108 }
109
110 static void
111 gst_test_obj_class_init (GstTestObjClass * klass)
112 {
113   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
114
115   gobject_class->set_property = gst_test_obj_set_property;
116   gobject_class->get_property = gst_test_obj_get_property;
117
118   g_object_class_install_property (gobject_class, PROP_INT,
119       g_param_spec_int ("int",
120           "int prop",
121           "int number parameter",
122           0, 100, 0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
123
124   g_object_class_install_property (gobject_class, PROP_FLOAT,
125       g_param_spec_float ("float",
126           "float prop",
127           "float number parameter",
128           0.0, 100.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
129
130   g_object_class_install_property (gobject_class, PROP_DOUBLE,
131       g_param_spec_double ("double",
132           "double prop",
133           "double number parameter",
134           0.0, 100.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
135
136   g_object_class_install_property (gobject_class, PROP_BOOLEAN,
137       g_param_spec_boolean ("boolean",
138           "boolean prop",
139           "boolean parameter",
140           FALSE, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
141 }
142
143 static void
144 gst_test_obj_base_init (GstTestObjClass * klass)
145 {
146   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
147
148   gst_element_class_set_details_simple (element_class,
149       "test object for unit tests",
150       "Test", "Use in unit tests", "Stefan Sauer <ensonic@users.sf.net>");
151 }
152
153 static GType
154 gst_test_obj_get_type (void)
155 {
156   static volatile gsize TEST_OBJ_type = 0;
157
158   if (g_once_init_enter (&TEST_OBJ_type)) {
159     GType type;
160     static const GTypeInfo info = {
161       (guint16) sizeof (GstTestObjClass),
162       (GBaseInitFunc) gst_test_obj_base_init,   // base_init
163       NULL,                     // base_finalize
164       (GClassInitFunc) gst_test_obj_class_init, // class_init
165       NULL,                     // class_finalize
166       NULL,                     // class_data
167       (guint16) sizeof (GstTestObj),
168       0,                        // n_preallocs
169       NULL,                     // instance_init
170       NULL                      // value_table
171     };
172     type = g_type_register_static (GST_TYPE_ELEMENT, "GstTestObj", &info, 0);
173     g_once_init_leave (&TEST_OBJ_type, type);
174   }
175   return TEST_OBJ_type;
176 }
177
178 static void
179 test_interpolation (void)
180 {
181   GstObject *e;
182   GstInterpolationControlSource *ics;
183   GstTimedValueControlSource *tvcs;
184   GstControlSource *cs;
185   gint t, i1, i2, i3;
186   GValue *v1, *v2, *v3;
187   gint n_values;
188   FILE *f;
189
190   e = (GstObject *) gst_element_factory_make ("testobj", NULL);
191
192   ics = gst_interpolation_control_source_new ();
193   tvcs = (GstTimedValueControlSource *) ics;
194   cs = (GstControlSource *) ics;
195
196   gst_object_add_control_binding (e, gst_direct_control_binding_new (e, "int",
197           cs));
198
199   gst_timed_value_control_source_set (tvcs, 0 * GST_SECOND, 0.0);
200   gst_timed_value_control_source_set (tvcs, 10 * GST_SECOND, 1.0);
201   gst_timed_value_control_source_set (tvcs, 20 * GST_SECOND, 0.5);
202   gst_timed_value_control_source_set (tvcs, 30 * GST_SECOND, 0.2);
203
204   /* test single values */
205   if (!(f = fopen ("ctrl_i1.dat", "w")))
206     exit (-1);
207   fprintf (f, "# Time None Linear Cubic\n");
208
209   for (t = 0; t < 40; t++) {
210     g_object_set (ics, "mode", GST_INTERPOLATION_MODE_NONE, NULL);
211     gst_object_sync_values (e, t * GST_SECOND);
212     i1 = GST_TEST_OBJ (e)->val_int;
213
214     g_object_set (ics, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL);
215     gst_object_sync_values (e, t * GST_SECOND);
216     i2 = GST_TEST_OBJ (e)->val_int;
217
218     g_object_set (ics, "mode", GST_INTERPOLATION_MODE_CUBIC, NULL);
219     gst_object_sync_values (e, t * GST_SECOND);
220     i3 = GST_TEST_OBJ (e)->val_int;
221
222     fprintf (f, "%4.1f %d %d %d\n", (gfloat) t, i1, i2, i3);
223   }
224
225   fclose (f);
226
227   /* test value arrays */
228   if (!(f = fopen ("ctrl_i2.dat", "w")))
229     exit (-1);
230   fprintf (f, "# Time None Linear Cubic\n");
231   n_values = 40 * 10;
232
233   g_object_set (ics, "mode", GST_INTERPOLATION_MODE_NONE, NULL);
234   v1 = g_new0 (GValue, n_values);
235   gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v1);
236
237   g_object_set (ics, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL);
238   v2 = g_new0 (GValue, n_values);
239   gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v2);
240
241   g_object_set (ics, "mode", GST_INTERPOLATION_MODE_CUBIC, NULL);
242   v3 = g_new0 (GValue, n_values);
243   gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v3);
244
245   for (t = 0; t < n_values; t++) {
246     i1 = g_value_get_int (&v1[t]);
247     i2 = g_value_get_int (&v2[t]);
248     i3 = g_value_get_int (&v3[t]);
249     fprintf (f, "%4.1f %d %d %d\n", (gfloat) t / 10.0, i1, i2, i3);
250     g_value_unset (&v1[t]);
251     g_value_unset (&v2[t]);
252     g_value_unset (&v3[t]);
253   }
254   g_free (v1);
255   g_free (v2);
256   g_free (v3);
257
258   fclose (f);
259
260   gst_object_unref (ics);
261   gst_object_unref (e);
262 }
263
264 static void
265 test_lfo (void)
266 {
267   GstObject *e;
268   GstLFOControlSource *lfocs;
269   GstControlSource *cs;
270   gint t, i1, i2, i3, i4, i5;
271   GValue *v1, *v2, *v3, *v4, *v5;
272   gint n_values;
273   FILE *f;
274
275   e = (GstObject *) gst_element_factory_make ("testobj", NULL);
276
277   lfocs = gst_lfo_control_source_new ();
278   cs = (GstControlSource *) lfocs;
279
280   gst_object_add_control_binding (e, gst_direct_control_binding_new (e, "int",
281           cs));
282
283   g_object_set (lfocs,
284       "frequency", (gdouble) 0.05,
285       "timeshift", (GstClockTime) 0,
286       "amplitude", (gdouble) 0.5, "offset", (gdouble) 0.5, NULL);
287
288   /* test single values */
289   if (!(f = fopen ("ctrl_l1.dat", "w")))
290     exit (-1);
291   fprintf (f, "# Time Sine Square Saw RevSaw Triangle\n");
292
293   for (t = 0; t < 40; t++) {
294     g_object_set (lfocs, "waveform", GST_LFO_WAVEFORM_SINE, NULL);
295     gst_object_sync_values (e, t * GST_SECOND);
296     i1 = GST_TEST_OBJ (e)->val_int;
297
298     g_object_set (lfocs, "waveform", GST_LFO_WAVEFORM_SQUARE, NULL);
299     gst_object_sync_values (e, t * GST_SECOND);
300     i2 = GST_TEST_OBJ (e)->val_int;
301
302     g_object_set (lfocs, "waveform", GST_LFO_WAVEFORM_SAW, NULL);
303     gst_object_sync_values (e, t * GST_SECOND);
304     i3 = GST_TEST_OBJ (e)->val_int;
305
306     g_object_set (lfocs, "waveform", GST_LFO_WAVEFORM_REVERSE_SAW, NULL);
307     gst_object_sync_values (e, t * GST_SECOND);
308     i4 = GST_TEST_OBJ (e)->val_int;
309
310     g_object_set (lfocs, "waveform", GST_LFO_WAVEFORM_TRIANGLE, NULL);
311     gst_object_sync_values (e, t * GST_SECOND);
312     i5 = GST_TEST_OBJ (e)->val_int;
313
314     fprintf (f, "%4.1f %d %d %d %d %d\n", (gfloat) t, i1, i2, i3, i4, i5);
315   }
316
317   fclose (f);
318
319   /* test value arrays */
320   if (!(f = fopen ("ctrl_l2.dat", "w")))
321     exit (-1);
322   fprintf (f, "# Time Sine Square Saw RevSaw Triangle\n");
323   n_values = 40 * 10;
324
325   g_object_set (lfocs, "waveform", GST_LFO_WAVEFORM_SINE, NULL);
326   v1 = g_new0 (GValue, n_values);
327   gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v1);
328
329   g_object_set (lfocs, "waveform", GST_LFO_WAVEFORM_SQUARE, NULL);
330   v2 = g_new0 (GValue, n_values);
331   gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v2);
332
333   g_object_set (lfocs, "waveform", GST_LFO_WAVEFORM_SAW, NULL);
334   v3 = g_new0 (GValue, n_values);
335   gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v3);
336
337   g_object_set (lfocs, "waveform", GST_LFO_WAVEFORM_REVERSE_SAW, NULL);
338   v4 = g_new0 (GValue, n_values);
339   gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v4);
340
341   g_object_set (lfocs, "waveform", GST_LFO_WAVEFORM_TRIANGLE, NULL);
342   v5 = g_new0 (GValue, n_values);
343   gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v5);
344
345   for (t = 0; t < n_values; t++) {
346     i1 = g_value_get_int (&v1[t]);
347     i2 = g_value_get_int (&v2[t]);
348     i3 = g_value_get_int (&v3[t]);
349     i4 = g_value_get_int (&v4[t]);
350     i5 = g_value_get_int (&v5[t]);
351     fprintf (f, "%4.1f %d %d %d %d %d\n", (gfloat) t / 10.0, i1, i2, i3, i4,
352         i5);
353     g_value_unset (&v1[t]);
354     g_value_unset (&v2[t]);
355     g_value_unset (&v3[t]);
356     g_value_unset (&v4[t]);
357     g_value_unset (&v5[t]);
358   }
359   g_free (v1);
360   g_free (v2);
361   g_free (v3);
362   g_free (v4);
363   g_free (v5);
364
365   fclose (f);
366
367   gst_object_unref (lfocs);
368   gst_object_unref (e);
369 }
370
371 static void
372 test_chained_lfo (void)
373 {
374   GstObject *e;
375   GstLFOControlSource *lfocs1, *lfocs2;
376   GstControlSource *cs1, *cs2;
377   gint t, i1;
378   GValue *v1;
379   gint n_values;
380   FILE *f;
381
382   e = (GstObject *) gst_element_factory_make ("testobj", NULL);
383
384   lfocs1 = gst_lfo_control_source_new ();
385   cs1 = (GstControlSource *) lfocs1;
386
387   gst_object_add_control_binding (e, gst_direct_control_binding_new (e, "int",
388           cs1));
389
390   g_object_set (lfocs1,
391       "waveform", GST_LFO_WAVEFORM_SINE,
392       "frequency", (gdouble) 0.05,
393       "timeshift", (GstClockTime) 0, "offset", (gdouble) 0.5, NULL);
394
395   lfocs2 = gst_lfo_control_source_new ();
396   cs2 = (GstControlSource *) lfocs2;
397
398   gst_object_add_control_binding ((GstObject *) lfocs1,
399       gst_direct_control_binding_new ((GstObject *) lfocs1, "amplitude", cs2));
400
401   g_object_set (lfocs2,
402       "waveform", GST_LFO_WAVEFORM_SINE,
403       "frequency", (gdouble) 0.05,
404       "timeshift", (GstClockTime) 0,
405       "amplitude", (gdouble) 0.5, "offset", (gdouble) 0.5, NULL);
406
407   /* test single values */
408   if (!(f = fopen ("ctrl_cl1.dat", "w")))
409     exit (-1);
410   fprintf (f, "# Time Sine\n");
411
412   for (t = 0; t < 40; t++) {
413     gst_object_sync_values (e, t * GST_SECOND);
414     i1 = GST_TEST_OBJ (e)->val_int;
415
416     fprintf (f, "%4.1f %d\n", (gfloat) t, i1);
417   }
418
419   fclose (f);
420
421   /* test value arrays */
422   if (!(f = fopen ("ctrl_cl2.dat", "w")))
423     exit (-1);
424   fprintf (f, "# Time Sine\n");
425   n_values = 40 * 10;
426
427   v1 = g_new0 (GValue, n_values);
428   gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v1);
429
430   for (t = 0; t < n_values; t++) {
431     i1 = g_value_get_int (&v1[t]);
432     fprintf (f, "%4.1f %d\n", (gfloat) t / 10.0, i1);
433     g_value_unset (&v1[t]);
434   }
435   g_free (v1);
436
437   fclose (f);
438
439   gst_object_unref (lfocs1);
440   gst_object_unref (lfocs2);
441   gst_object_unref (e);
442 }
443
444 gint
445 main (gint argc, gchar ** argv)
446 {
447   gst_init (&argc, &argv);
448
449   gst_element_register (NULL, "testobj", GST_RANK_NONE, GST_TYPE_TEST_OBJ);
450
451   test_interpolation ();
452   test_lfo ();
453
454   test_chained_lfo ();
455
456   return 0;
457 }