controller: also test array functions
[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  */
10
11 #include <stdio.h>
12 #include <stdlib.h>
13
14 #include <gst/gst.h>
15 #include <gst/controller/gstinterpolationcontrolsource.h>
16 #include <gst/controller/gstlfocontrolsource.h>
17
18 /* local test element */
19
20 enum
21 {
22   PROP_INT = 1,
23   PROP_FLOAT,
24   PROP_DOUBLE,
25   PROP_BOOLEAN,
26   PROP_COUNT
27 };
28
29 #define GST_TYPE_TEST_OBJ            (gst_test_obj_get_type ())
30 #define GST_TEST_OBJ(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_TEST_OBJ, GstTestObj))
31 #define GST_TEST_OBJ_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_TEST_OBJ, GstTestObjClass))
32 #define GST_IS_TEST_OBJ(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TEST_OBJ))
33 #define GST_IS_TEST_OBJ_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_TEST_OBJ))
34 #define GST_TEST_OBJ_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_TEST_OBJ, GstTestObjClass))
35
36 typedef struct _GstTestObj GstTestObj;
37 typedef struct _GstTestObjClass GstTestObjClass;
38
39 struct _GstTestObj
40 {
41   GstElement parent;
42   gint val_int;
43   gfloat val_float;
44   gdouble val_double;
45   gboolean val_boolean;
46 };
47 struct _GstTestObjClass
48 {
49   GstElementClass parent_class;
50 };
51
52 static GType gst_test_obj_get_type (void);
53
54 static void
55 gst_test_obj_get_property (GObject * object,
56     guint property_id, GValue * value, GParamSpec * pspec)
57 {
58   GstTestObj *self = GST_TEST_OBJ (object);
59
60   switch (property_id) {
61     case PROP_INT:
62       g_value_set_int (value, self->val_int);
63       break;
64     case PROP_FLOAT:
65       g_value_set_float (value, self->val_float);
66       break;
67     case PROP_DOUBLE:
68       g_value_set_double (value, self->val_double);
69       break;
70     case PROP_BOOLEAN:
71       g_value_set_boolean (value, self->val_boolean);
72       break;
73     default:
74       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
75       break;
76   }
77 }
78
79 static void
80 gst_test_obj_set_property (GObject * object,
81     guint property_id, const GValue * value, GParamSpec * pspec)
82 {
83   GstTestObj *self = GST_TEST_OBJ (object);
84
85   switch (property_id) {
86     case PROP_INT:
87       self->val_int = g_value_get_int (value);
88       GST_DEBUG ("test value int=%d", self->val_int);
89       break;
90     case PROP_FLOAT:
91       self->val_float = g_value_get_float (value);
92       GST_DEBUG ("test value float=%f", self->val_float);
93       break;
94     case PROP_DOUBLE:
95       self->val_double = g_value_get_double (value);
96       GST_DEBUG ("test value double=%f", self->val_double);
97       break;
98     case PROP_BOOLEAN:
99       self->val_boolean = g_value_get_boolean (value);
100       GST_DEBUG ("test value boolean=%d", self->val_boolean);
101       break;
102     default:
103       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
104       break;
105   }
106 }
107
108 static void
109 gst_test_obj_class_init (GstTestObjClass * klass)
110 {
111   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
112
113   gobject_class->set_property = gst_test_obj_set_property;
114   gobject_class->get_property = gst_test_obj_get_property;
115
116   g_object_class_install_property (gobject_class, PROP_INT,
117       g_param_spec_int ("int",
118           "int prop",
119           "int number parameter for the TEST_OBJ",
120           0, 100, 0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
121
122   g_object_class_install_property (gobject_class, PROP_FLOAT,
123       g_param_spec_float ("float",
124           "float prop",
125           "float number parameter for the TEST_OBJ",
126           0.0, 100.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
127
128   g_object_class_install_property (gobject_class, PROP_DOUBLE,
129       g_param_spec_double ("double",
130           "double prop",
131           "double number parameter for the TEST_OBJ",
132           0.0, 100.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
133
134   g_object_class_install_property (gobject_class, PROP_BOOLEAN,
135       g_param_spec_boolean ("boolean",
136           "boolean prop",
137           "boolean parameter for the TEST_OBJ",
138           FALSE, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
139 }
140
141 static void
142 gst_test_obj_base_init (GstTestObjClass * klass)
143 {
144   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
145
146   gst_element_class_set_details_simple (element_class,
147       "test object for unit tests",
148       "Test", "Use in unit tests", "Stefan Sauer <ensonic@users.sf.net>");
149 }
150
151 static GType
152 gst_test_obj_get_type (void)
153 {
154   static volatile gsize TEST_OBJ_type = 0;
155
156   if (g_once_init_enter (&TEST_OBJ_type)) {
157     GType type;
158     static const GTypeInfo info = {
159       (guint16) sizeof (GstTestObjClass),
160       (GBaseInitFunc) gst_test_obj_base_init,   // base_init
161       NULL,                     // base_finalize
162       (GClassInitFunc) gst_test_obj_class_init, // class_init
163       NULL,                     // class_finalize
164       NULL,                     // class_data
165       (guint16) sizeof (GstTestObj),
166       0,                        // n_preallocs
167       NULL,                     // instance_init
168       NULL                      // value_table
169     };
170     type = g_type_register_static (GST_TYPE_ELEMENT, "GstTestObj", &info, 0);
171     g_once_init_leave (&TEST_OBJ_type, type);
172   }
173   return TEST_OBJ_type;
174 }
175
176 static void
177 test_interpolation (void)
178 {
179   GstObject *e;
180   GstInterpolationControlSource *ics;
181   GstTimedValueControlSource *tvcs;
182   GstControlSource *cs;
183   gint t, i1, i2, i3;
184   GValue *v1, *v2, *v3;
185   gint n_values;
186   FILE *f;
187
188   e = (GstObject *) gst_element_factory_make ("testobj", NULL);
189
190   ics = gst_interpolation_control_source_new ();
191   tvcs = (GstTimedValueControlSource *) ics;
192   cs = (GstControlSource *) ics;
193
194   gst_object_set_control_source (e, "int", cs);
195
196   gst_timed_value_control_source_set (tvcs, 0 * GST_SECOND, 0.0);
197   gst_timed_value_control_source_set (tvcs, 10 * GST_SECOND, 1.0);
198   gst_timed_value_control_source_set (tvcs, 20 * GST_SECOND, 0.5);
199   gst_timed_value_control_source_set (tvcs, 30 * GST_SECOND, 0.2);
200
201   /* test single values */
202   if (!(f = fopen ("ctrl_i1.dat", "w")))
203     exit (-1);
204   fprintf (f, "# Time None Linear Cubic\n");
205
206   for (t = 0; t < 40; t++) {
207     g_object_set (ics, "mode", GST_INTERPOLATION_MODE_NONE, NULL);
208     gst_object_sync_values (e, t * GST_SECOND);
209     i1 = GST_TEST_OBJ (e)->val_int;
210
211     g_object_set (ics, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL);
212     gst_object_sync_values (e, t * GST_SECOND);
213     i2 = GST_TEST_OBJ (e)->val_int;
214
215     g_object_set (ics, "mode", GST_INTERPOLATION_MODE_CUBIC, NULL);
216     gst_object_sync_values (e, t * GST_SECOND);
217     i3 = GST_TEST_OBJ (e)->val_int;
218
219     fprintf (f, "%4.1f %d %d %d\n", (gfloat) t, i1, i2, i3);
220   }
221
222   fclose (f);
223
224   /* test value arrays */
225   if (!(f = fopen ("ctrl_i2.dat", "w")))
226     exit (-1);
227   fprintf (f, "# Time None Linear Cubic\n");
228   n_values = 40 * 10;
229
230   g_object_set (ics, "mode", GST_INTERPOLATION_MODE_NONE, NULL);
231   v1 = g_new0 (GValue, n_values);
232   gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v1);
233
234   g_object_set (ics, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL);
235   v2 = g_new0 (GValue, n_values);
236   gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v2);
237
238   g_object_set (ics, "mode", GST_INTERPOLATION_MODE_CUBIC, NULL);
239   v3 = g_new0 (GValue, n_values);
240   gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v3);
241
242   for (t = 0; t < n_values; t++) {
243     i1 = g_value_get_int (&v1[t]);
244     i2 = g_value_get_int (&v2[t]);
245     i3 = g_value_get_int (&v3[t]);
246     fprintf (f, "%4.1f %d %d %d\n", (gfloat) t / 10.0, i1, i2, i3);
247     g_value_unset (&v1[t]);
248     g_value_unset (&v2[t]);
249     g_value_unset (&v3[t]);
250   }
251   g_free (v1);
252   g_free (v2);
253   g_free (v3);
254
255   fclose (f);
256
257   gst_object_unref (ics);
258   gst_object_unref (e);
259 }
260
261 static void
262 test_lfo (void)
263 {
264   GstObject *e;
265   GstLFOControlSource *lfocs;
266   GstControlSource *cs;
267   gint t, i1, i2, i3, i4;
268   GValue *v1, *v2, *v3, *v4;
269   gint n_values;
270   FILE *f;
271
272   e = (GstObject *) gst_element_factory_make ("testobj", NULL);
273
274   lfocs = gst_lfo_control_source_new ();
275   cs = (GstControlSource *) lfocs;
276
277   gst_object_set_control_source (e, "int", cs);
278
279   g_object_set (lfocs,
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 Saw Square Triangle\n");
288
289   for (t = 0; t < 40; t++) {
290     g_object_set (lfocs, "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 (lfocs, "waveform", GST_LFO_WAVEFORM_SAW, NULL);
295     gst_object_sync_values (e, t * GST_SECOND);
296     i2 = 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     i3 = GST_TEST_OBJ (e)->val_int;
301
302     g_object_set (lfocs, "waveform", GST_LFO_WAVEFORM_TRIANGLE, NULL);
303     gst_object_sync_values (e, t * GST_SECOND);
304     i4 = GST_TEST_OBJ (e)->val_int;
305
306     fprintf (f, "%4.1f %d %d %d %d\n", (gfloat) t, i1, i2, i3, i4);
307   }
308
309   fclose (f);
310
311   /* test value arrays */
312   if (!(f = fopen ("ctrl_l2.dat", "w")))
313     exit (-1);
314   fprintf (f, "# Time Sine Saw Square Triangle\n");
315   n_values = 40 * 10;
316
317   g_object_set (lfocs, "waveform", GST_LFO_WAVEFORM_SINE, NULL);
318   v1 = g_new0 (GValue, n_values);
319   gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v1);
320
321   g_object_set (lfocs, "waveform", GST_LFO_WAVEFORM_SAW, NULL);
322   v2 = g_new0 (GValue, n_values);
323   gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v2);
324
325   g_object_set (lfocs, "waveform", GST_LFO_WAVEFORM_SQUARE, NULL);
326   v3 = g_new0 (GValue, n_values);
327   gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v3);
328
329   g_object_set (lfocs, "waveform", GST_LFO_WAVEFORM_TRIANGLE, NULL);
330   v4 = g_new0 (GValue, n_values);
331   gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v4);
332
333   for (t = 0; t < n_values; t++) {
334     i1 = g_value_get_int (&v1[t]);
335     i2 = g_value_get_int (&v2[t]);
336     i3 = g_value_get_int (&v3[t]);
337     i4 = g_value_get_int (&v4[t]);
338     fprintf (f, "%4.1f %d %d %d %d\n", (gfloat) t / 10.0, i1, i2, i3, i4);
339     g_value_unset (&v1[t]);
340     g_value_unset (&v2[t]);
341     g_value_unset (&v3[t]);
342     g_value_unset (&v4[t]);
343   }
344   g_free (v1);
345   g_free (v2);
346   g_free (v3);
347
348   fclose (f);
349
350   gst_object_unref (lfocs);
351   gst_object_unref (e);
352 }
353
354
355 gint
356 main (gint argc, gchar ** argv)
357 {
358   gst_init (&argc, &argv);
359
360   gst_element_register (NULL, "testobj", GST_RANK_NONE, GST_TYPE_TEST_OBJ);
361
362   test_interpolation ();
363   test_lfo ();
364
365   return 0;
366 }