lfocontrolsource: make chainable
[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 'saw', "" using 1:4 with points title 'square', "" using 1:5 with points title 'triangle', "ctrl_l2.dat" using 1:2 with lines title 'sine', "" using 1:3 with lines title 'saw', "" using 1:4 with lines title 'square', "" using 1:5 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
19 /* local test element */
20
21 enum
22 {
23   PROP_INT = 1,
24   PROP_FLOAT,
25   PROP_DOUBLE,
26   PROP_BOOLEAN,
27   PROP_COUNT
28 };
29
30 #define GST_TYPE_TEST_OBJ            (gst_test_obj_get_type ())
31 #define GST_TEST_OBJ(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_TEST_OBJ, GstTestObj))
32 #define GST_TEST_OBJ_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_TEST_OBJ, GstTestObjClass))
33 #define GST_IS_TEST_OBJ(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TEST_OBJ))
34 #define GST_IS_TEST_OBJ_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_TEST_OBJ))
35 #define GST_TEST_OBJ_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_TEST_OBJ, GstTestObjClass))
36
37 typedef struct _GstTestObj GstTestObj;
38 typedef struct _GstTestObjClass GstTestObjClass;
39
40 struct _GstTestObj
41 {
42   GstElement parent;
43   gint val_int;
44   gfloat val_float;
45   gdouble val_double;
46   gboolean val_boolean;
47 };
48 struct _GstTestObjClass
49 {
50   GstElementClass parent_class;
51 };
52
53 static GType gst_test_obj_get_type (void);
54
55 static void
56 gst_test_obj_get_property (GObject * object,
57     guint property_id, GValue * value, GParamSpec * pspec)
58 {
59   GstTestObj *self = GST_TEST_OBJ (object);
60
61   switch (property_id) {
62     case PROP_INT:
63       g_value_set_int (value, self->val_int);
64       break;
65     case PROP_FLOAT:
66       g_value_set_float (value, self->val_float);
67       break;
68     case PROP_DOUBLE:
69       g_value_set_double (value, self->val_double);
70       break;
71     case PROP_BOOLEAN:
72       g_value_set_boolean (value, self->val_boolean);
73       break;
74     default:
75       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
76       break;
77   }
78 }
79
80 static void
81 gst_test_obj_set_property (GObject * object,
82     guint property_id, const GValue * value, GParamSpec * pspec)
83 {
84   GstTestObj *self = GST_TEST_OBJ (object);
85
86   switch (property_id) {
87     case PROP_INT:
88       self->val_int = g_value_get_int (value);
89       GST_DEBUG ("test value int=%d", self->val_int);
90       break;
91     case PROP_FLOAT:
92       self->val_float = g_value_get_float (value);
93       GST_DEBUG ("test value float=%f", self->val_float);
94       break;
95     case PROP_DOUBLE:
96       self->val_double = g_value_get_double (value);
97       GST_DEBUG ("test value double=%f", self->val_double);
98       break;
99     case PROP_BOOLEAN:
100       self->val_boolean = g_value_get_boolean (value);
101       GST_DEBUG ("test value boolean=%d", self->val_boolean);
102       break;
103     default:
104       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
105       break;
106   }
107 }
108
109 static void
110 gst_test_obj_class_init (GstTestObjClass * klass)
111 {
112   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
113
114   gobject_class->set_property = gst_test_obj_set_property;
115   gobject_class->get_property = gst_test_obj_get_property;
116
117   g_object_class_install_property (gobject_class, PROP_INT,
118       g_param_spec_int ("int",
119           "int prop",
120           "int number parameter for the TEST_OBJ",
121           0, 100, 0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
122
123   g_object_class_install_property (gobject_class, PROP_FLOAT,
124       g_param_spec_float ("float",
125           "float prop",
126           "float number parameter for the TEST_OBJ",
127           0.0, 100.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
128
129   g_object_class_install_property (gobject_class, PROP_DOUBLE,
130       g_param_spec_double ("double",
131           "double prop",
132           "double number parameter for the TEST_OBJ",
133           0.0, 100.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
134
135   g_object_class_install_property (gobject_class, PROP_BOOLEAN,
136       g_param_spec_boolean ("boolean",
137           "boolean prop",
138           "boolean parameter for the TEST_OBJ",
139           FALSE, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
140 }
141
142 static void
143 gst_test_obj_base_init (GstTestObjClass * klass)
144 {
145   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
146
147   gst_element_class_set_details_simple (element_class,
148       "test object for unit tests",
149       "Test", "Use in unit tests", "Stefan Sauer <ensonic@users.sf.net>");
150 }
151
152 static GType
153 gst_test_obj_get_type (void)
154 {
155   static volatile gsize TEST_OBJ_type = 0;
156
157   if (g_once_init_enter (&TEST_OBJ_type)) {
158     GType type;
159     static const GTypeInfo info = {
160       (guint16) sizeof (GstTestObjClass),
161       (GBaseInitFunc) gst_test_obj_base_init,   // base_init
162       NULL,                     // base_finalize
163       (GClassInitFunc) gst_test_obj_class_init, // class_init
164       NULL,                     // class_finalize
165       NULL,                     // class_data
166       (guint16) sizeof (GstTestObj),
167       0,                        // n_preallocs
168       NULL,                     // instance_init
169       NULL                      // value_table
170     };
171     type = g_type_register_static (GST_TYPE_ELEMENT, "GstTestObj", &info, 0);
172     g_once_init_leave (&TEST_OBJ_type, type);
173   }
174   return TEST_OBJ_type;
175 }
176
177 static void
178 test_interpolation (void)
179 {
180   GstObject *e;
181   GstInterpolationControlSource *ics;
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   ics = gst_interpolation_control_source_new ();
192   tvcs = (GstTimedValueControlSource *) ics;
193   cs = (GstControlSource *) ics;
194
195   gst_object_set_control_source (e, "int", 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 (ics, "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 (ics, "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 (ics, "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 (ics, "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 (ics, "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 (ics, "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 (ics);
259   gst_object_unref (e);
260 }
261
262 static void
263 test_lfo (void)
264 {
265   GstObject *e;
266   GstLFOControlSource *lfocs;
267   GstControlSource *cs;
268   gint t, i1, i2, i3, i4;
269   GValue *v1, *v2, *v3, *v4;
270   gint n_values;
271   FILE *f;
272
273   e = (GstObject *) gst_element_factory_make ("testobj", NULL);
274
275   lfocs = gst_lfo_control_source_new ();
276   cs = (GstControlSource *) lfocs;
277
278   gst_object_set_control_source (e, "int", cs);
279
280   g_object_set (lfocs,
281       "frequency", (gdouble) 0.05,
282       "timeshift", (GstClockTime) 0,
283       "amplitude", (gdouble) 0.5, "offset", (gdouble) 0.5, NULL);
284
285   /* test single values */
286   if (!(f = fopen ("ctrl_l1.dat", "w")))
287     exit (-1);
288   fprintf (f, "# Time Sine Saw Square Triangle\n");
289
290   for (t = 0; t < 40; t++) {
291     g_object_set (lfocs, "waveform", GST_LFO_WAVEFORM_SINE, NULL);
292     gst_object_sync_values (e, t * GST_SECOND);
293     i1 = GST_TEST_OBJ (e)->val_int;
294
295     g_object_set (lfocs, "waveform", GST_LFO_WAVEFORM_SAW, NULL);
296     gst_object_sync_values (e, t * GST_SECOND);
297     i2 = GST_TEST_OBJ (e)->val_int;
298
299     g_object_set (lfocs, "waveform", GST_LFO_WAVEFORM_SQUARE, NULL);
300     gst_object_sync_values (e, t * GST_SECOND);
301     i3 = GST_TEST_OBJ (e)->val_int;
302
303     g_object_set (lfocs, "waveform", GST_LFO_WAVEFORM_TRIANGLE, NULL);
304     gst_object_sync_values (e, t * GST_SECOND);
305     i4 = GST_TEST_OBJ (e)->val_int;
306
307     fprintf (f, "%4.1f %d %d %d %d\n", (gfloat) t, i1, i2, i3, i4);
308   }
309
310   fclose (f);
311
312   /* test value arrays */
313   if (!(f = fopen ("ctrl_l2.dat", "w")))
314     exit (-1);
315   fprintf (f, "# Time Sine Saw Square Triangle\n");
316   n_values = 40 * 10;
317
318   g_object_set (lfocs, "waveform", GST_LFO_WAVEFORM_SINE, NULL);
319   v1 = g_new0 (GValue, n_values);
320   gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v1);
321
322   g_object_set (lfocs, "waveform", GST_LFO_WAVEFORM_SAW, NULL);
323   v2 = g_new0 (GValue, n_values);
324   gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v2);
325
326   g_object_set (lfocs, "waveform", GST_LFO_WAVEFORM_SQUARE, NULL);
327   v3 = g_new0 (GValue, n_values);
328   gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v3);
329
330   g_object_set (lfocs, "waveform", GST_LFO_WAVEFORM_TRIANGLE, NULL);
331   v4 = g_new0 (GValue, n_values);
332   gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v4);
333
334   for (t = 0; t < n_values; t++) {
335     i1 = g_value_get_int (&v1[t]);
336     i2 = g_value_get_int (&v2[t]);
337     i3 = g_value_get_int (&v3[t]);
338     i4 = g_value_get_int (&v4[t]);
339     fprintf (f, "%4.1f %d %d %d %d\n", (gfloat) t / 10.0, i1, i2, i3, i4);
340     g_value_unset (&v1[t]);
341     g_value_unset (&v2[t]);
342     g_value_unset (&v3[t]);
343     g_value_unset (&v4[t]);
344   }
345   g_free (v1);
346   g_free (v2);
347   g_free (v3);
348   g_free (v4);
349
350   fclose (f);
351
352   gst_object_unref (lfocs);
353   gst_object_unref (e);
354 }
355
356 static void
357 test_chained_lfo (void)
358 {
359   GstObject *e;
360   GstLFOControlSource *lfocs1, *lfocs2;
361   GstControlSource *cs1, *cs2;
362   gint t, i1;
363   GValue *v1;
364   gint n_values;
365   FILE *f;
366
367   e = (GstObject *) gst_element_factory_make ("testobj", NULL);
368
369   lfocs1 = gst_lfo_control_source_new ();
370   cs1 = (GstControlSource *) lfocs1;
371
372   gst_object_set_control_source (e, "int", cs1);
373
374   g_object_set (lfocs1,
375       "waveform", GST_LFO_WAVEFORM_SINE,
376       "frequency", (gdouble) 0.05,
377       "timeshift", (GstClockTime) 0, "offset", (gdouble) 0.5, NULL);
378
379   lfocs2 = gst_lfo_control_source_new ();
380   cs2 = (GstControlSource *) lfocs2;
381
382   gst_object_set_control_source ((GstObject *) lfocs1, "amplitude", cs2);
383
384   g_object_set (lfocs2,
385       "waveform", GST_LFO_WAVEFORM_SINE,
386       "frequency", (gdouble) 0.05,
387       "timeshift", (GstClockTime) 0,
388       "amplitude", (gdouble) 0.5, "offset", (gdouble) 0.5, NULL);
389
390   /* test single values */
391   if (!(f = fopen ("ctrl_cl1.dat", "w")))
392     exit (-1);
393   fprintf (f, "# Time Sine\n");
394
395   for (t = 0; t < 40; t++) {
396     gst_object_sync_values (e, t * GST_SECOND);
397     i1 = GST_TEST_OBJ (e)->val_int;
398
399     fprintf (f, "%4.1f %d\n", (gfloat) t, i1);
400   }
401
402   fclose (f);
403
404   /* test value arrays */
405   if (!(f = fopen ("ctrl_cl2.dat", "w")))
406     exit (-1);
407   fprintf (f, "# Time Sine\n");
408   n_values = 40 * 10;
409
410   v1 = g_new0 (GValue, n_values);
411   gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v1);
412
413   for (t = 0; t < n_values; t++) {
414     i1 = g_value_get_int (&v1[t]);
415     fprintf (f, "%4.1f %d\n", (gfloat) t / 10.0, i1);
416     g_value_unset (&v1[t]);
417   }
418   g_free (v1);
419
420   fclose (f);
421
422   gst_object_unref (lfocs1);
423   gst_object_unref (lfocs2);
424   gst_object_unref (e);
425 }
426
427 gint
428 main (gint argc, gchar ** argv)
429 {
430   gst_init (&argc, &argv);
431
432   gst_element_register (NULL, "testobj", GST_RANK_NONE, GST_TYPE_TEST_OBJ);
433
434   test_interpolation ();
435   test_lfo ();
436
437   test_chained_lfo ();
438
439   return 0;
440 }