/* * control-sources.c * * Generates a datafile for various control sources. * * Needs gnuplot for plotting. * 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' * 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' * plot "ctrl_cl1.dat" using 1:2 with points title 'sine', "ctrl_cl2.dat" using 1:2 with lines title 'sine' */ #include #include #include #include #include #include /* local test element */ enum { PROP_INT = 1, PROP_FLOAT, PROP_DOUBLE, PROP_BOOLEAN, PROP_COUNT }; #define GST_TYPE_TEST_OBJ (gst_test_obj_get_type ()) #define GST_TEST_OBJ(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_TEST_OBJ, GstTestObj)) #define GST_TEST_OBJ_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_TEST_OBJ, GstTestObjClass)) #define GST_IS_TEST_OBJ(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TEST_OBJ)) #define GST_IS_TEST_OBJ_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_TEST_OBJ)) #define GST_TEST_OBJ_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_TEST_OBJ, GstTestObjClass)) typedef struct _GstTestObj GstTestObj; typedef struct _GstTestObjClass GstTestObjClass; struct _GstTestObj { GstElement parent; gint val_int; gfloat val_float; gdouble val_double; gboolean val_boolean; }; struct _GstTestObjClass { GstElementClass parent_class; }; static GType gst_test_obj_get_type (void); static void gst_test_obj_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) { GstTestObj *self = GST_TEST_OBJ (object); switch (property_id) { case PROP_INT: g_value_set_int (value, self->val_int); break; case PROP_FLOAT: g_value_set_float (value, self->val_float); break; case PROP_DOUBLE: g_value_set_double (value, self->val_double); break; case PROP_BOOLEAN: g_value_set_boolean (value, self->val_boolean); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void gst_test_obj_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec) { GstTestObj *self = GST_TEST_OBJ (object); switch (property_id) { case PROP_INT: self->val_int = g_value_get_int (value); GST_DEBUG ("test value int=%d", self->val_int); break; case PROP_FLOAT: self->val_float = g_value_get_float (value); GST_DEBUG ("test value float=%f", self->val_float); break; case PROP_DOUBLE: self->val_double = g_value_get_double (value); GST_DEBUG ("test value double=%f", self->val_double); break; case PROP_BOOLEAN: self->val_boolean = g_value_get_boolean (value); GST_DEBUG ("test value boolean=%d", self->val_boolean); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void gst_test_obj_class_init (GstTestObjClass * klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); gobject_class->set_property = gst_test_obj_set_property; gobject_class->get_property = gst_test_obj_get_property; g_object_class_install_property (gobject_class, PROP_INT, g_param_spec_int ("int", "int prop", "int number parameter", 0, 100, 0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE)); g_object_class_install_property (gobject_class, PROP_FLOAT, g_param_spec_float ("float", "float prop", "float number parameter", 0.0, 100.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE)); g_object_class_install_property (gobject_class, PROP_DOUBLE, g_param_spec_double ("double", "double prop", "double number parameter", 0.0, 100.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE)); g_object_class_install_property (gobject_class, PROP_BOOLEAN, g_param_spec_boolean ("boolean", "boolean prop", "boolean parameter", FALSE, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE)); } static void gst_test_obj_base_init (GstTestObjClass * klass) { GstElementClass *element_class = GST_ELEMENT_CLASS (klass); gst_element_class_set_details_simple (element_class, "test object for unit tests", "Test", "Use in unit tests", "Stefan Sauer "); } static GType gst_test_obj_get_type (void) { static volatile gsize TEST_OBJ_type = 0; if (g_once_init_enter (&TEST_OBJ_type)) { GType type; static const GTypeInfo info = { (guint16) sizeof (GstTestObjClass), (GBaseInitFunc) gst_test_obj_base_init, // base_init NULL, // base_finalize (GClassInitFunc) gst_test_obj_class_init, // class_init NULL, // class_finalize NULL, // class_data (guint16) sizeof (GstTestObj), 0, // n_preallocs NULL, // instance_init NULL // value_table }; type = g_type_register_static (GST_TYPE_ELEMENT, "GstTestObj", &info, 0); g_once_init_leave (&TEST_OBJ_type, type); } return TEST_OBJ_type; } static void test_interpolation (void) { GstObject *e; GstTimedValueControlSource *tvcs; GstControlSource *cs; gint t, i1, i2, i3; GValue *v1, *v2, *v3; gint n_values; FILE *f; e = (GstObject *) gst_element_factory_make ("testobj", NULL); cs = gst_interpolation_control_source_new (); tvcs = (GstTimedValueControlSource *) cs; gst_object_add_control_binding (e, gst_direct_control_binding_new (e, "int", cs)); gst_timed_value_control_source_set (tvcs, 0 * GST_SECOND, 0.0); gst_timed_value_control_source_set (tvcs, 10 * GST_SECOND, 1.0); gst_timed_value_control_source_set (tvcs, 20 * GST_SECOND, 0.5); gst_timed_value_control_source_set (tvcs, 30 * GST_SECOND, 0.2); /* test single values */ if (!(f = fopen ("ctrl_i1.dat", "w"))) exit (-1); fprintf (f, "# Time None Linear Cubic\n"); for (t = 0; t < 40; t++) { g_object_set (cs, "mode", GST_INTERPOLATION_MODE_NONE, NULL); gst_object_sync_values (e, t * GST_SECOND); i1 = GST_TEST_OBJ (e)->val_int; g_object_set (cs, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL); gst_object_sync_values (e, t * GST_SECOND); i2 = GST_TEST_OBJ (e)->val_int; g_object_set (cs, "mode", GST_INTERPOLATION_MODE_CUBIC, NULL); gst_object_sync_values (e, t * GST_SECOND); i3 = GST_TEST_OBJ (e)->val_int; fprintf (f, "%4.1f %d %d %d\n", (gfloat) t, i1, i2, i3); } fclose (f); /* test value arrays */ if (!(f = fopen ("ctrl_i2.dat", "w"))) exit (-1); fprintf (f, "# Time None Linear Cubic\n"); n_values = 40 * 10; g_object_set (cs, "mode", GST_INTERPOLATION_MODE_NONE, NULL); v1 = g_new0 (GValue, n_values); gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v1); g_object_set (cs, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL); v2 = g_new0 (GValue, n_values); gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v2); g_object_set (cs, "mode", GST_INTERPOLATION_MODE_CUBIC, NULL); v3 = g_new0 (GValue, n_values); gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v3); for (t = 0; t < n_values; t++) { i1 = g_value_get_int (&v1[t]); i2 = g_value_get_int (&v2[t]); i3 = g_value_get_int (&v3[t]); fprintf (f, "%4.1f %d %d %d\n", (gfloat) t / 10.0, i1, i2, i3); g_value_unset (&v1[t]); g_value_unset (&v2[t]); g_value_unset (&v3[t]); } g_free (v1); g_free (v2); g_free (v3); fclose (f); gst_object_unref (cs); gst_object_unref (e); } static void test_lfo (void) { GstObject *e; GstControlSource *cs; gint t, i1, i2, i3, i4, i5; GValue *v1, *v2, *v3, *v4, *v5; gint n_values; FILE *f; e = (GstObject *) gst_element_factory_make ("testobj", NULL); cs = gst_lfo_control_source_new (); gst_object_add_control_binding (e, gst_direct_control_binding_new (e, "int", cs)); g_object_set (cs, "frequency", (gdouble) 0.05, "timeshift", (GstClockTime) 0, "amplitude", (gdouble) 0.5, "offset", (gdouble) 0.5, NULL); /* test single values */ if (!(f = fopen ("ctrl_l1.dat", "w"))) exit (-1); fprintf (f, "# Time Sine Square Saw RevSaw Triangle\n"); for (t = 0; t < 40; t++) { g_object_set (cs, "waveform", GST_LFO_WAVEFORM_SINE, NULL); gst_object_sync_values (e, t * GST_SECOND); i1 = GST_TEST_OBJ (e)->val_int; g_object_set (cs, "waveform", GST_LFO_WAVEFORM_SQUARE, NULL); gst_object_sync_values (e, t * GST_SECOND); i2 = GST_TEST_OBJ (e)->val_int; g_object_set (cs, "waveform", GST_LFO_WAVEFORM_SAW, NULL); gst_object_sync_values (e, t * GST_SECOND); i3 = GST_TEST_OBJ (e)->val_int; g_object_set (cs, "waveform", GST_LFO_WAVEFORM_REVERSE_SAW, NULL); gst_object_sync_values (e, t * GST_SECOND); i4 = GST_TEST_OBJ (e)->val_int; g_object_set (cs, "waveform", GST_LFO_WAVEFORM_TRIANGLE, NULL); gst_object_sync_values (e, t * GST_SECOND); i5 = GST_TEST_OBJ (e)->val_int; fprintf (f, "%4.1f %d %d %d %d %d\n", (gfloat) t, i1, i2, i3, i4, i5); } fclose (f); /* test value arrays */ if (!(f = fopen ("ctrl_l2.dat", "w"))) exit (-1); fprintf (f, "# Time Sine Square Saw RevSaw Triangle\n"); n_values = 40 * 10; g_object_set (cs, "waveform", GST_LFO_WAVEFORM_SINE, NULL); v1 = g_new0 (GValue, n_values); gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v1); g_object_set (cs, "waveform", GST_LFO_WAVEFORM_SQUARE, NULL); v2 = g_new0 (GValue, n_values); gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v2); g_object_set (cs, "waveform", GST_LFO_WAVEFORM_SAW, NULL); v3 = g_new0 (GValue, n_values); gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v3); g_object_set (cs, "waveform", GST_LFO_WAVEFORM_REVERSE_SAW, NULL); v4 = g_new0 (GValue, n_values); gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v4); g_object_set (cs, "waveform", GST_LFO_WAVEFORM_TRIANGLE, NULL); v5 = g_new0 (GValue, n_values); gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v5); for (t = 0; t < n_values; t++) { i1 = g_value_get_int (&v1[t]); i2 = g_value_get_int (&v2[t]); i3 = g_value_get_int (&v3[t]); i4 = g_value_get_int (&v4[t]); i5 = g_value_get_int (&v5[t]); fprintf (f, "%4.1f %d %d %d %d %d\n", (gfloat) t / 10.0, i1, i2, i3, i4, i5); g_value_unset (&v1[t]); g_value_unset (&v2[t]); g_value_unset (&v3[t]); g_value_unset (&v4[t]); g_value_unset (&v5[t]); } g_free (v1); g_free (v2); g_free (v3); g_free (v4); g_free (v5); fclose (f); gst_object_unref (cs); gst_object_unref (e); } static void test_chained_lfo (void) { GstObject *e; GstControlSource *cs1, *cs2; gint t, i1; GValue *v1; gint n_values; FILE *f; e = (GstObject *) gst_element_factory_make ("testobj", NULL); cs1 = gst_lfo_control_source_new (); gst_object_add_control_binding (e, gst_direct_control_binding_new (e, "int", cs1)); g_object_set (cs1, "waveform", GST_LFO_WAVEFORM_SINE, "frequency", (gdouble) 0.05, "timeshift", (GstClockTime) 0, "offset", (gdouble) 0.5, NULL); cs2 = gst_lfo_control_source_new (); gst_object_add_control_binding ((GstObject *) cs1, gst_direct_control_binding_new ((GstObject *) cs1, "amplitude", cs2)); g_object_set (cs2, "waveform", GST_LFO_WAVEFORM_SINE, "frequency", (gdouble) 0.05, "timeshift", (GstClockTime) 0, "amplitude", (gdouble) 0.5, "offset", (gdouble) 0.5, NULL); /* test single values */ if (!(f = fopen ("ctrl_cl1.dat", "w"))) exit (-1); fprintf (f, "# Time Sine\n"); for (t = 0; t < 40; t++) { gst_object_sync_values (e, t * GST_SECOND); i1 = GST_TEST_OBJ (e)->val_int; fprintf (f, "%4.1f %d\n", (gfloat) t, i1); } fclose (f); /* test value arrays */ if (!(f = fopen ("ctrl_cl2.dat", "w"))) exit (-1); fprintf (f, "# Time Sine\n"); n_values = 40 * 10; v1 = g_new0 (GValue, n_values); gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v1); for (t = 0; t < n_values; t++) { i1 = g_value_get_int (&v1[t]); fprintf (f, "%4.1f %d\n", (gfloat) t / 10.0, i1); g_value_unset (&v1[t]); } g_free (v1); fclose (f); gst_object_unref (cs1); gst_object_unref (cs2); gst_object_unref (e); } gint main (gint argc, gchar ** argv) { gst_init (&argc, &argv); gst_element_register (NULL, "testobj", GST_RANK_NONE, GST_TYPE_TEST_OBJ); test_interpolation (); test_lfo (); test_chained_lfo (); return 0; }