Merge remote-tracking branch 'origin/0.10'
[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   GstTimedValueControlSource *tvcs;
183   GstControlSource *cs;
184   gint t, i1, i2, i3;
185   GValue *v1, *v2, *v3;
186   gint n_values;
187   FILE *f;
188
189   e = (GstObject *) gst_element_factory_make ("testobj", NULL);
190
191   cs = gst_interpolation_control_source_new ();
192   tvcs = (GstTimedValueControlSource *) cs;
193
194   gst_object_add_control_binding (e, gst_direct_control_binding_new (e, "int",
195           cs));
196
197   gst_timed_value_control_source_set (tvcs, 0 * GST_SECOND, 0.0);
198   gst_timed_value_control_source_set (tvcs, 10 * GST_SECOND, 1.0);
199   gst_timed_value_control_source_set (tvcs, 20 * GST_SECOND, 0.5);
200   gst_timed_value_control_source_set (tvcs, 30 * GST_SECOND, 0.2);
201
202   /* test single values */
203   if (!(f = fopen ("ctrl_i1.dat", "w")))
204     exit (-1);
205   fprintf (f, "# Time None Linear Cubic\n");
206
207   for (t = 0; t < 40; t++) {
208     g_object_set (cs, "mode", GST_INTERPOLATION_MODE_NONE, NULL);
209     gst_object_sync_values (e, t * GST_SECOND);
210     i1 = GST_TEST_OBJ (e)->val_int;
211
212     g_object_set (cs, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL);
213     gst_object_sync_values (e, t * GST_SECOND);
214     i2 = GST_TEST_OBJ (e)->val_int;
215
216     g_object_set (cs, "mode", GST_INTERPOLATION_MODE_CUBIC, NULL);
217     gst_object_sync_values (e, t * GST_SECOND);
218     i3 = GST_TEST_OBJ (e)->val_int;
219
220     fprintf (f, "%4.1f %d %d %d\n", (gfloat) t, i1, i2, i3);
221   }
222
223   fclose (f);
224
225   /* test value arrays */
226   if (!(f = fopen ("ctrl_i2.dat", "w")))
227     exit (-1);
228   fprintf (f, "# Time None Linear Cubic\n");
229   n_values = 40 * 10;
230
231   g_object_set (cs, "mode", GST_INTERPOLATION_MODE_NONE, NULL);
232   v1 = g_new0 (GValue, n_values);
233   gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v1);
234
235   g_object_set (cs, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL);
236   v2 = g_new0 (GValue, n_values);
237   gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v2);
238
239   g_object_set (cs, "mode", GST_INTERPOLATION_MODE_CUBIC, NULL);
240   v3 = g_new0 (GValue, n_values);
241   gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v3);
242
243   for (t = 0; t < n_values; t++) {
244     i1 = g_value_get_int (&v1[t]);
245     i2 = g_value_get_int (&v2[t]);
246     i3 = g_value_get_int (&v3[t]);
247     fprintf (f, "%4.1f %d %d %d\n", (gfloat) t / 10.0, i1, i2, i3);
248     g_value_unset (&v1[t]);
249     g_value_unset (&v2[t]);
250     g_value_unset (&v3[t]);
251   }
252   g_free (v1);
253   g_free (v2);
254   g_free (v3);
255
256   fclose (f);
257
258   gst_object_unref (cs);
259   gst_object_unref (e);
260 }
261
262 static void
263 test_lfo (void)
264 {
265   GstObject *e;
266   GstControlSource *cs;
267   gint t, i1, i2, i3, i4, i5;
268   GValue *v1, *v2, *v3, *v4, *v5;
269   gint n_values;
270   FILE *f;
271
272   e = (GstObject *) gst_element_factory_make ("testobj", NULL);
273
274   cs = gst_lfo_control_source_new ();
275
276   gst_object_add_control_binding (e, gst_direct_control_binding_new (e, "int",
277           cs));
278
279   g_object_set (cs,
280       "frequency", (gdouble) 0.05,
281       "timeshift", (GstClockTime) 0,
282       "amplitude", (gdouble) 0.5, "offset", (gdouble) 0.5, NULL);
283
284   /* test single values */
285   if (!(f = fopen ("ctrl_l1.dat", "w")))
286     exit (-1);
287   fprintf (f, "# Time Sine Square Saw RevSaw Triangle\n");
288
289   for (t = 0; t < 40; t++) {
290     g_object_set (cs, "waveform", GST_LFO_WAVEFORM_SINE, NULL);
291     gst_object_sync_values (e, t * GST_SECOND);
292     i1 = GST_TEST_OBJ (e)->val_int;
293
294     g_object_set (cs, "waveform", GST_LFO_WAVEFORM_SQUARE, NULL);
295     gst_object_sync_values (e, t * GST_SECOND);
296     i2 = GST_TEST_OBJ (e)->val_int;
297
298     g_object_set (cs, "waveform", GST_LFO_WAVEFORM_SAW, NULL);
299     gst_object_sync_values (e, t * GST_SECOND);
300     i3 = GST_TEST_OBJ (e)->val_int;
301
302     g_object_set (cs, "waveform", GST_LFO_WAVEFORM_REVERSE_SAW, NULL);
303     gst_object_sync_values (e, t * GST_SECOND);
304     i4 = GST_TEST_OBJ (e)->val_int;
305
306     g_object_set (cs, "waveform", GST_LFO_WAVEFORM_TRIANGLE, NULL);
307     gst_object_sync_values (e, t * GST_SECOND);
308     i5 = GST_TEST_OBJ (e)->val_int;
309
310     fprintf (f, "%4.1f %d %d %d %d %d\n", (gfloat) t, i1, i2, i3, i4, i5);
311   }
312
313   fclose (f);
314
315   /* test value arrays */
316   if (!(f = fopen ("ctrl_l2.dat", "w")))
317     exit (-1);
318   fprintf (f, "# Time Sine Square Saw RevSaw Triangle\n");
319   n_values = 40 * 10;
320
321   g_object_set (cs, "waveform", GST_LFO_WAVEFORM_SINE, NULL);
322   v1 = g_new0 (GValue, n_values);
323   gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v1);
324
325   g_object_set (cs, "waveform", GST_LFO_WAVEFORM_SQUARE, NULL);
326   v2 = g_new0 (GValue, n_values);
327   gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v2);
328
329   g_object_set (cs, "waveform", GST_LFO_WAVEFORM_SAW, NULL);
330   v3 = g_new0 (GValue, n_values);
331   gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v3);
332
333   g_object_set (cs, "waveform", GST_LFO_WAVEFORM_REVERSE_SAW, NULL);
334   v4 = g_new0 (GValue, n_values);
335   gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v4);
336
337   g_object_set (cs, "waveform", GST_LFO_WAVEFORM_TRIANGLE, NULL);
338   v5 = g_new0 (GValue, n_values);
339   gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v5);
340
341   for (t = 0; t < n_values; t++) {
342     i1 = g_value_get_int (&v1[t]);
343     i2 = g_value_get_int (&v2[t]);
344     i3 = g_value_get_int (&v3[t]);
345     i4 = g_value_get_int (&v4[t]);
346     i5 = g_value_get_int (&v5[t]);
347     fprintf (f, "%4.1f %d %d %d %d %d\n", (gfloat) t / 10.0, i1, i2, i3, i4,
348         i5);
349     g_value_unset (&v1[t]);
350     g_value_unset (&v2[t]);
351     g_value_unset (&v3[t]);
352     g_value_unset (&v4[t]);
353     g_value_unset (&v5[t]);
354   }
355   g_free (v1);
356   g_free (v2);
357   g_free (v3);
358   g_free (v4);
359   g_free (v5);
360
361   fclose (f);
362
363   gst_object_unref (cs);
364   gst_object_unref (e);
365 }
366
367 static void
368 test_chained_lfo (void)
369 {
370   GstObject *e;
371   GstControlSource *cs1, *cs2;
372   gint t, i1;
373   GValue *v1;
374   gint n_values;
375   FILE *f;
376
377   e = (GstObject *) gst_element_factory_make ("testobj", NULL);
378
379   cs1 = gst_lfo_control_source_new ();
380
381   gst_object_add_control_binding (e, gst_direct_control_binding_new (e, "int",
382           cs1));
383
384   g_object_set (cs1,
385       "waveform", GST_LFO_WAVEFORM_SINE,
386       "frequency", (gdouble) 0.05,
387       "timeshift", (GstClockTime) 0, "offset", (gdouble) 0.5, NULL);
388
389   cs2 = gst_lfo_control_source_new ();
390
391   gst_object_add_control_binding ((GstObject *) cs1,
392       gst_direct_control_binding_new ((GstObject *) cs1, "amplitude", cs2));
393
394   g_object_set (cs2,
395       "waveform", GST_LFO_WAVEFORM_SINE,
396       "frequency", (gdouble) 0.05,
397       "timeshift", (GstClockTime) 0,
398       "amplitude", (gdouble) 0.5, "offset", (gdouble) 0.5, NULL);
399
400   /* test single values */
401   if (!(f = fopen ("ctrl_cl1.dat", "w")))
402     exit (-1);
403   fprintf (f, "# Time Sine\n");
404
405   for (t = 0; t < 40; t++) {
406     gst_object_sync_values (e, t * GST_SECOND);
407     i1 = GST_TEST_OBJ (e)->val_int;
408
409     fprintf (f, "%4.1f %d\n", (gfloat) t, i1);
410   }
411
412   fclose (f);
413
414   /* test value arrays */
415   if (!(f = fopen ("ctrl_cl2.dat", "w")))
416     exit (-1);
417   fprintf (f, "# Time Sine\n");
418   n_values = 40 * 10;
419
420   v1 = g_new0 (GValue, n_values);
421   gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v1);
422
423   for (t = 0; t < n_values; t++) {
424     i1 = g_value_get_int (&v1[t]);
425     fprintf (f, "%4.1f %d\n", (gfloat) t / 10.0, i1);
426     g_value_unset (&v1[t]);
427   }
428   g_free (v1);
429
430   fclose (f);
431
432   gst_object_unref (cs1);
433   gst_object_unref (cs2);
434   gst_object_unref (e);
435 }
436
437 gint
438 main (gint argc, gchar ** argv)
439 {
440   gst_init (&argc, &argv);
441
442   gst_element_register (NULL, "testobj", GST_RANK_NONE, GST_TYPE_TEST_OBJ);
443
444   test_interpolation ();
445   test_lfo ();
446
447   test_chained_lfo ();
448
449   return 0;
450 }