From 39d6b7462f44b4eb55b46ee17ff5e5c7a3d77e5f Mon Sep 17 00:00:00 2001 From: Stefan Sauer Date: Thu, 22 Dec 2011 23:48:30 +0100 Subject: [PATCH] controller: move GValue handling from control-sources to -binding ControlSources are now gdouble based. A control source is mapped to a particullar GObject property using a ControlBinding. --- docs/gst/gstreamer-sections.txt | 6 +- docs/random/porting-to-0.11.txt | 14 +- gst/gstcontrolbinding.c | 195 ++- gst/gstcontrolbinding.h | 30 +- gst/gstcontrolsource.c | 52 +- gst/gstcontrolsource.h | 27 +- gst/gstobject.c | 20 +- gst/gstobject.h | 2 +- libs/gst/controller/Makefile.am | 5 - libs/gst/controller/gstinterpolation.c | 592 -------- .../gstinterpolationcontrolsource.c | 505 +++++-- .../gstinterpolationcontrolsourceprivate.h | 87 -- libs/gst/controller/gstlfocontrolsource.c | 1208 +++++------------ .../controller/gstlfocontrolsourceprivate.h | 64 - .../controller/gsttimedvaluecontrolsource.c | 201 +-- .../controller/gsttimedvaluecontrolsource.h | 37 +- libs/gst/controller/gsttriggercontrolsource.c | 397 ++---- tests/benchmarks/controller.c | 9 +- tests/check/libs/controller.c | 987 ++++++-------- tests/check/libs/gstlibscpp.cc | 3 +- tests/examples/controller/.gitignore | 3 +- tests/examples/controller/Makefile.am | 7 +- tests/examples/controller/audio-example.c | 25 +- tests/examples/controller/control-sources.c | 286 ++++ 24 files changed, 1908 insertions(+), 2854 deletions(-) delete mode 100644 libs/gst/controller/gstinterpolation.c delete mode 100644 libs/gst/controller/gstinterpolationcontrolsourceprivate.h delete mode 100644 libs/gst/controller/gstlfocontrolsourceprivate.h create mode 100644 tests/examples/controller/control-sources.c diff --git a/docs/gst/gstreamer-sections.txt b/docs/gst/gstreamer-sections.txt index 164e98e7ff..871e21052e 100644 --- a/docs/gst/gstreamer-sections.txt +++ b/docs/gst/gstreamer-sections.txt @@ -562,8 +562,11 @@ GST_USING_PRINTF_EXTENSION GstControlBinding GstControlBinding GstControlBindingClass +GstControlBindingConvert gst_control_binding_new gst_control_binding_sync_values +gst_control_binding_get_value +gst_control_binding_get_value_array gst_control_binding_get_control_source gst_control_binding_set_disabled gst_control_binding_is_disabled @@ -583,11 +586,9 @@ gst_control_binding_get_type GstControlSource GstControlSource GstControlSourceClass -GstControlSourceBind GstControlSourceGetValue GstControlSourceGetValueArray GstTimedValue -gst_control_source_bind gst_control_source_get_value gst_control_source_get_value_array @@ -1553,7 +1554,6 @@ gst_object_get_control_binding gst_object_get_control_source gst_object_set_control_source gst_object_get_value -gst_object_get_value_arrays gst_object_get_value_array gst_object_get_control_rate gst_object_set_control_rate diff --git a/docs/random/porting-to-0.11.txt b/docs/random/porting-to-0.11.txt index 14fccf6fd4..51e04de2d8 100644 --- a/docs/random/porting-to-0.11.txt +++ b/docs/random/porting-to-0.11.txt @@ -426,16 +426,20 @@ The 0.11 porting guide gst_tag_list_new_full*() have been renamed to gst_tag_list_new*(). * GstController: - has now been merged into GstObject. The control sources are in the - controller library still. + has now been merged into GstObject. It does not exists as a individual + object anymore. In addition core contains a GstControlSource base class and + the GstControlBinding. The actual control sources are in the controller + library as before. The 2nd big change is that control sources generate + a sequence of gdouble values and those are mapped to the property type and + value range by GstControlBindings. For plugins the effect is that gst_controller_init() is gone and gst_object_sync_values() is taking a GstObject * instead of GObject *. For applications the effect is larger. The whole gst_controller_* API is - gone and now available in simplified form under gst_object_*. There is no - more GstController object. Attach a control source to a property to control - it and attach NULL to un-control it. + gone and now available in simplified form under gst_object_*. ControlSources + are now attached via GstControlBinding to properties. There are no GValue + arguments used anymore when programming control sources. gst_controller_new* -> gst_object_set_control_source gst_controller_add_properties -> gst_object_set_control_source diff --git a/gst/gstcontrolbinding.c b/gst/gstcontrolbinding.c index 4bba851fd6..0bdb2fc258 100644 --- a/gst/gstcontrolbinding.c +++ b/gst/gstcontrolbinding.c @@ -33,6 +33,8 @@ #include "gstcontrolbinding.h" +#include + #define GST_CAT_DEFAULT control_binding_debug GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); @@ -66,8 +68,6 @@ gst_control_binding_dispose (GObject * object) GstControlBinding *self = GST_CONTROL_BINDING (object); if (self->csource) { - // FIXME: hack - self->csource->bound = FALSE; g_object_unref (self->csource); self->csource = NULL; } @@ -79,7 +79,35 @@ gst_control_binding_finalize (GObject * object) GstControlBinding *self = GST_CONTROL_BINDING (object); g_value_unset (&self->cur_value); - g_value_unset (&self->last_value); +} + +/* mapping functions */ +#define DEFINE_CONVERT(type,Type,TYPE) \ +static void \ +convert_to_##type (GstControlBinding *self, gdouble s, GValue *d) \ +{ \ + GParamSpec##Type *pspec = G_PARAM_SPEC_##TYPE (self->pspec); \ + g##type v; \ + \ + s = CLAMP (s, 0.0, 1.0); \ + v = pspec->minimum + (g##type) ((pspec->maximum - pspec->minimum) * s); \ + g_value_set_##type (d, v); \ +} + +DEFINE_CONVERT (int, Int, INT); +DEFINE_CONVERT (uint, UInt, UINT); +DEFINE_CONVERT (long, Long, LONG); +DEFINE_CONVERT (ulong, ULong, ULONG); +DEFINE_CONVERT (int64, Int64, INT64); +DEFINE_CONVERT (uint64, UInt64, UINT64); +DEFINE_CONVERT (float, Float, FLOAT); +DEFINE_CONVERT (double, Double, DOUBLE); + +static void +convert_to_boolean (GstControlBinding * self, gdouble s, GValue * d) +{ + s = CLAMP (s, 0.0, 1.0); + g_value_set_boolean (d, (gboolean) (s + 0.5)); } /** @@ -113,16 +141,59 @@ gst_control_binding_new (GstObject * object, const gchar * property_name, GST_PARAM_CONTROLLABLE | G_PARAM_CONSTRUCT_ONLY)) == (G_PARAM_WRITABLE | GST_PARAM_CONTROLLABLE), NULL); - if (gst_control_source_bind (csource, pspec)) { - if ((self = (GstControlBinding *) g_object_newv (GST_TYPE_CONTROL_BINDING, - 0, NULL))) { - self->pspec = pspec; - self->name = pspec->name; - self->csource = g_object_ref (csource); - self->disabled = FALSE; + if ((self = (GstControlBinding *) g_object_newv (GST_TYPE_CONTROL_BINDING, + 0, NULL))) { + GType type = G_PARAM_SPEC_VALUE_TYPE (pspec), base; - g_value_init (&self->cur_value, G_PARAM_SPEC_VALUE_TYPE (pspec)); - g_value_init (&self->last_value, G_PARAM_SPEC_VALUE_TYPE (pspec)); + // add pspec as a construction parameter and move below to construct() + self->pspec = pspec; + self->name = pspec->name; + self->csource = g_object_ref (csource); + self->disabled = FALSE; + + g_value_init (&self->cur_value, type); + + base = type = G_PARAM_SPEC_VALUE_TYPE (pspec); + while ((type = g_type_parent (type))) + base = type; + + GST_DEBUG_OBJECT (object, " using type %s", g_type_name (base)); + + // select mapping function + // FIXME: only select mapping if super class hasn't set any? + switch (base) { + case G_TYPE_INT: + self->convert = convert_to_int; + break; + case G_TYPE_UINT: + self->convert = convert_to_uint; + break; + case G_TYPE_LONG: + self->convert = convert_to_long; + break; + case G_TYPE_ULONG: + self->convert = convert_to_ulong; + break; + case G_TYPE_INT64: + self->convert = convert_to_int64; + break; + case G_TYPE_UINT64: + self->convert = convert_to_uint64; + break; + case G_TYPE_FLOAT: + self->convert = convert_to_float; + break; + case G_TYPE_DOUBLE: + self->convert = convert_to_double; + break; + case G_TYPE_BOOLEAN: + self->convert = convert_to_boolean; + break; + default: + // FIXME: return NULL? + GST_WARNING ("incomplete implementation for paramspec type '%s'", + G_PARAM_SPEC_TYPE_NAME (pspec)); + break; } } } else { @@ -154,7 +225,8 @@ gboolean gst_control_binding_sync_values (GstControlBinding * self, GstObject * object, GstClockTime timestamp, GstClockTime last_sync) { - GValue *value; + GValue *dst_val; + gdouble src_val; gboolean ret; g_return_val_if_fail (GST_IS_CONTROL_BINDING (self), FALSE); @@ -165,20 +237,24 @@ gst_control_binding_sync_values (GstControlBinding * self, GstObject * object, GST_LOG_OBJECT (object, "property '%s' at ts=%" G_GUINT64_FORMAT, self->name, timestamp); - value = &self->cur_value; - ret = gst_control_source_get_value (self->csource, timestamp, value); + dst_val = &self->cur_value; + ret = gst_control_source_get_value (self->csource, timestamp, &src_val); if (G_LIKELY (ret)) { + GST_LOG_OBJECT (object, " new value %lf", src_val); /* always set the value for first time, but then only if it changed * this should limit g_object_notify invocations. * FIXME: can we detect negative playback rates? */ - if ((timestamp < last_sync) || - gst_value_compare (value, &self->last_value) != GST_VALUE_EQUAL) { + if ((timestamp < last_sync) || (src_val != self->last_value)) { + GST_LOG_OBJECT (object, " mapping %s to value of type %s", self->name, + G_VALUE_TYPE_NAME (dst_val)); + /* run mapping function to convert gdouble to GValue */ + self->convert (self, src_val, dst_val); /* we can make this faster * http://bugzilla.gnome.org/show_bug.cgi?id=536939 */ - g_object_set_property ((GObject *) object, self->name, value); - g_value_copy (value, &self->last_value); + g_object_set_property ((GObject *) object, self->name, dst_val); + self->last_value = src_val; } } else { GST_DEBUG_OBJECT (object, "no control value for param %s", self->name); @@ -186,6 +262,87 @@ gst_control_binding_sync_values (GstControlBinding * self, GstObject * object, return (ret); } +/** + * gst_control_binding_get_value: + * @self: the control binding + * @timestamp: the time the control-change should be read from + * + * Gets the value for the given controlled property at the requested time. + * + * Returns: the GValue of the property at the given time, or %NULL if the + * property isn't controlled. + */ +GValue * +gst_control_binding_get_value (GstControlBinding * self, GstClockTime timestamp) +{ + GValue *dst_val = NULL; + gdouble src_val; + + g_return_val_if_fail (GST_IS_CONTROL_BINDING (self), NULL); + g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), NULL); + + /* get current value via control source */ + if (gst_control_source_get_value (self->csource, timestamp, &src_val)) { + dst_val = g_new0 (GValue, 1); + g_value_init (dst_val, G_PARAM_SPEC_VALUE_TYPE (self->pspec)); + self->convert (self, src_val, dst_val); + } + + return dst_val; +} + +/** + * gst_control_binding_get_value_array: + * @self: the control binding + * @timestamp: the time that should be processed + * @interval: the time spacing between subsequent values + * @n_values: the number of values + * @values: array to put control-values in + * + * Gets a number of values for the given controllered property starting at the + * requested time. The array @values need to hold enough space for @n_values of + * the same type as the objects property's type. + * + * This function is useful if one wants to e.g. draw a graph of the control + * curve or apply a control curve sample by sample. + * + * Returns: %TRUE if the given array could be filled, %FALSE otherwise + */ +gboolean +gst_control_binding_get_value_array (GstControlBinding * self, + GstClockTime timestamp, GstClockTime interval, guint n_values, + GValue * values) +{ + gint i; + gdouble *src_val; + gboolean res = FALSE; + GType type; + GstControlBindingConvert convert; + + g_return_val_if_fail (GST_IS_CONTROL_BINDING (self), FALSE); + g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE); + g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (interval), FALSE); + g_return_val_if_fail (values, FALSE); + + convert = self->convert; + type = G_PARAM_SPEC_VALUE_TYPE (self->pspec); + + src_val = g_new0 (gdouble, n_values); + if ((res = gst_control_source_get_value_array (self->csource, timestamp, + interval, n_values, src_val))) { + for (i = 0; i < n_values; i++) { + if (!isnan (src_val[i])) { + g_value_init (&values[i], type); + convert (self, src_val[i], &values[i]); + } + } + } + g_free (src_val); + return res; +} + + + /** * gst_control_binding_get_control_source: * @self: the control binding diff --git a/gst/gstcontrolbinding.h b/gst/gstcontrolbinding.h index e9ee23af74..64661abdc6 100644 --- a/gst/gstcontrolbinding.h +++ b/gst/gstcontrolbinding.h @@ -47,28 +47,44 @@ G_BEGIN_DECLS typedef struct _GstControlBinding GstControlBinding; typedef struct _GstControlBindingClass GstControlBindingClass; +/** + * GstControlBindingConvert: + * @self: the #GstControlBinding instance + * @src_value: the value returned by the cotnrol source + * @dest_value: the target GValue + * + * Function to map a control-value to the target GValue. + */ +typedef void (* GstControlBindingConvert) (GstControlBinding *self, gdouble src_value, GValue *dest_value); + /** * GstControlBinding: + * @name: name of the property of this binding * * The instance structure of #GstControlBinding. */ struct _GstControlBinding { GObject parent; - + /*< public >*/ - GParamSpec *pspec; /* GParamSpec for this property */ const gchar *name; /* name of the property */ - GstControlSource *csource; /* GstControlSource for this property */ - gboolean disabled; - GValue cur_value, last_value; /*< private >*/ + GParamSpec *pspec; /* GParamSpec for this property */ + GstControlSource *csource; /* GstControlSource for this property */ + gboolean disabled; + GValue cur_value; + gdouble last_value; + + GstControlBindingConvert convert; + gpointer _gst_reserved[GST_PADDING]; }; /** * GstControlBindingClass: * @parent_class: Parent class + * @convert: Class method to convert control-values * * The class structure of #GstControlBinding. */ @@ -90,6 +106,10 @@ GstControlBinding * gst_control_binding_new (GstObject * object, gboolean gst_control_binding_sync_values (GstControlBinding * self, GstObject *object, GstClockTime timestamp, GstClockTime last_sync); +GValue * gst_control_binding_get_value (GstControlBinding *binding, + GstClockTime timestamp); +gboolean gst_control_binding_get_value_array (GstControlBinding *binding, GstClockTime timestamp, + GstClockTime interval, guint n_values, GValue *values); GstControlSource * gst_control_binding_get_control_source (GstControlBinding * self); void gst_control_binding_set_disabled (GstControlBinding * self, gboolean disabled); gboolean gst_control_binding_is_disabled (GstControlBinding * self); diff --git a/gst/gstcontrolsource.c b/gst/gstcontrolsource.c index 85f242d5fc..a2b116120c 100644 --- a/gst/gstcontrolsource.c +++ b/gst/gstcontrolsource.c @@ -61,10 +61,6 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstControlSource, gst_control_source, static void gst_control_source_class_init (GstControlSourceClass * klass) { - //GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - /* Has to be implemented by children */ - klass->bind = NULL; } static void @@ -72,7 +68,6 @@ gst_control_source_init (GstControlSource * self) { self->get_value = NULL; self->get_value_array = NULL; - self->bound = FALSE; } /** @@ -87,7 +82,7 @@ gst_control_source_init (GstControlSource * self) */ gboolean gst_control_source_get_value (GstControlSource * self, GstClockTime timestamp, - GValue * value) + gdouble * value) { g_return_val_if_fail (GST_IS_CONTROL_SOURCE (self), FALSE); @@ -102,23 +97,19 @@ gst_control_source_get_value (GstControlSource * self, GstClockTime timestamp, /** * gst_control_source_get_value_array: * @self: the #GstControlSource object - * @timestamp: the time that should be processed + * @timestamp: the first timestamp + * @interval: the time steps + * @n_values: the number of values to fetch * @value_array: array to put control-values in * - * Gets an array of values for one element property. - * - * All fields of @value_array must be filled correctly. Especially the - * @value_array->values array must be big enough to keep the requested amount - * of values. - * - * The type of the values in the array is the same as the property's type. + * Gets an array of values for for this #GstControlSource. * * Returns: %TRUE if the given array could be filled, %FALSE otherwise */ gboolean gst_control_source_get_value_array (GstControlSource * self, GstClockTime timestamp, GstClockTime interval, guint n_values, - gpointer values) + gdouble * values) { g_return_val_if_fail (GST_IS_CONTROL_SOURCE (self), FALSE); @@ -129,34 +120,3 @@ gst_control_source_get_value_array (GstControlSource * self, return FALSE; } } - -/** - * gst_control_source_bind: - * @self: the #GstControlSource object - * @pspec: #GParamSpec for the property for which this #GstControlSource should generate values. - * - * Binds a #GstControlSource to a specific property. This must be called only once for a - * #GstControlSource. - * - * Returns: %TRUE if the #GstControlSource was bound correctly, %FALSE otherwise. - */ -gboolean -gst_control_source_bind (GstControlSource * self, GParamSpec * pspec) -{ - gboolean ret = FALSE; - - g_return_val_if_fail (GST_IS_CONTROL_SOURCE (self), FALSE); - g_return_val_if_fail (GST_CONTROL_SOURCE_GET_CLASS (self)->bind, FALSE); - g_return_val_if_fail (!self->bound, FALSE); - - ret = GST_CONTROL_SOURCE_GET_CLASS (self)->bind (self, pspec); - - if (ret) { - GST_DEBUG ("bound control source for param %s", pspec->name); - self->bound = TRUE; - } else { - GST_DEBUG ("failed to bind control source for param %s", pspec->name); - } - - return ret; -} diff --git a/gst/gstcontrolsource.h b/gst/gstcontrolsource.h index 5cd2dc6ebd..1dc4bb02e7 100644 --- a/gst/gstcontrolsource.h +++ b/gst/gstcontrolsource.h @@ -59,7 +59,7 @@ typedef struct _GstValueArray GstValueArray; struct _GstTimedValue { GstClockTime timestamp; - GValue value; + gdouble value; }; /** @@ -74,7 +74,7 @@ struct _GstTimedValue * */ typedef gboolean (* GstControlSourceGetValue) (GstControlSource *self, - GstClockTime timestamp, GValue *value); + GstClockTime timestamp, gdouble *value); /** * GstControlSourceGetValueArray @@ -90,18 +90,7 @@ typedef gboolean (* GstControlSourceGetValue) (GstControlSource *self, * */ typedef gboolean (* GstControlSourceGetValueArray) (GstControlSource *self, - GstClockTime timestamp, GstClockTime interval, guint n_values, gpointer values); - -/** - * GstControlSourceBind - * @self: the #GstControlSource instance - * @pspec: #GParamSpec that should be bound to - * - * Function for binding a #GstControlSource to a #GParamSpec. - * - * Returns: %TRUE if the property could be bound to the #GstControlSource, %FALSE otherwise. - */ -typedef gboolean (* GstControlSourceBind) (GstControlSource *self, GParamSpec *pspec); + GstClockTime timestamp, GstClockTime interval, guint n_values, gdouble *values); /** * GstControlSource: @@ -118,7 +107,6 @@ struct _GstControlSource { GstControlSourceGetValueArray get_value_array; /* Returns values for a property in a given timespan */ /*< private >*/ - gboolean bound; gpointer _gst_reserved[GST_PADDING]; }; @@ -134,8 +122,6 @@ struct _GstControlSourceClass { GObjectClass parent_class; - GstControlSourceBind bind; /* Binds the GstControlSource to a specific GParamSpec */ - /*< private >*/ gpointer _gst_reserved[GST_PADDING]; }; @@ -144,13 +130,10 @@ GType gst_control_source_get_type (void); /* Functions */ gboolean gst_control_source_get_value (GstControlSource *self, GstClockTime timestamp, - GValue *value); + gdouble *value); gboolean gst_control_source_get_value_array (GstControlSource *self, GstClockTime timestamp, GstClockTime interval, guint n_values, - gpointer values); - -gboolean gst_control_source_bind (GstControlSource *self, GParamSpec *pspec); - + gdouble *values); G_END_DECLS #endif /* __GST_CONTROL_SOURCE_H__ */ diff --git a/gst/gstobject.c b/gst/gstobject.c index 5b098fe8ac..ef42e88a7c 100644 --- a/gst/gstobject.c +++ b/gst/gstobject.c @@ -1109,6 +1109,8 @@ gst_object_sync_values (GstObject * object, GstClockTime timestamp) g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE); GST_LOG_OBJECT (object, "sync_values"); + if (!object->control_bindings) + return TRUE; /* FIXME: this deadlocks */ /* GST_OBJECT_LOCK (object); */ @@ -1353,7 +1355,7 @@ gst_object_get_control_source (GstObject * object, const gchar * property_name) * @property_name: the name of the property to get * @timestamp: the time the control-change should be read from * - * Gets the value for the given controllered property at the requested time. + * Gets the value for the given controlled property at the requested time. * * Returns: the GValue of the property at the given time, or %NULL if the * property isn't controlled. @@ -1371,14 +1373,7 @@ gst_object_get_value (GstObject * object, const gchar * property_name, GST_OBJECT_LOCK (object); if ((binding = gst_object_find_control_binding (object, property_name))) { - val = g_new0 (GValue, 1); - g_value_init (val, G_PARAM_SPEC_VALUE_TYPE (binding->pspec)); - - /* get current value via control source */ - if (!gst_control_source_get_value (binding->csource, timestamp, val)) { - g_free (val); - val = NULL; - } + val = gst_control_binding_get_value (binding, timestamp); } GST_OBJECT_UNLOCK (object); @@ -1406,7 +1401,7 @@ gst_object_get_value (GstObject * object, const gchar * property_name, gboolean gst_object_get_value_array (GstObject * object, const gchar * property_name, GstClockTime timestamp, GstClockTime interval, guint n_values, - gpointer values) + GValue * values) { gboolean res = FALSE; GstControlBinding *binding; @@ -1419,8 +1414,9 @@ gst_object_get_value_array (GstObject * object, const gchar * property_name, GST_OBJECT_LOCK (object); if ((binding = gst_object_find_control_binding (object, property_name))) { - res = gst_control_source_get_value_array (binding->csource, timestamp, - interval, n_values, values); + /* FIXME: use binding: */ + res = gst_control_binding_get_value_array (binding, timestamp, interval, + n_values, values); } GST_OBJECT_UNLOCK (object); return res; diff --git a/gst/gstobject.h b/gst/gstobject.h index ec7925e7ef..193301dde1 100644 --- a/gst/gstobject.h +++ b/gst/gstobject.h @@ -257,7 +257,7 @@ GValue * gst_object_get_value (GstObject * object, const gchar GstClockTime timestamp); gboolean gst_object_get_value_array (GstObject * object, const gchar * property_name, GstClockTime timestamp, GstClockTime interval, - guint n_values, gpointer values); + guint n_values, GValue *values); GstClockTime gst_object_get_control_rate (GstObject * object); void gst_object_set_control_rate (GstObject * object, GstClockTime control_rate); diff --git a/libs/gst/controller/Makefile.am b/libs/gst/controller/Makefile.am index 793caadfa7..e095192403 100644 --- a/libs/gst/controller/Makefile.am +++ b/libs/gst/controller/Makefile.am @@ -7,13 +7,8 @@ libgstcontroller_@GST_MAJORMINOR@_include_HEADERS = \ gsttriggercontrolsource.h \ gstlfocontrolsource.h -noinst_HEADERS = \ - gstinterpolationcontrolsourceprivate.h \ - gstlfocontrolsourceprivate.h - libgstcontroller_@GST_MAJORMINOR@_la_SOURCES = \ gsttimedvaluecontrolsource.c \ - gstinterpolation.c \ gstinterpolationcontrolsource.c \ gsttriggercontrolsource.c \ gstlfocontrolsource.c diff --git a/libs/gst/controller/gstinterpolation.c b/libs/gst/controller/gstinterpolation.c deleted file mode 100644 index 10704fa4b5..0000000000 --- a/libs/gst/controller/gstinterpolation.c +++ /dev/null @@ -1,592 +0,0 @@ -/* GStreamer - * - * Copyright (C) <2005> Stefan Kost - * Copyright (C) 2007-2010 Sebastian Dröge - * - * gstinterpolation.c: Interpolation methods for dynamic properties - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "gstinterpolationcontrolsource.h" -#include "gstinterpolationcontrolsourceprivate.h" - -#define GST_CAT_DEFAULT controller_debug -GST_DEBUG_CATEGORY_EXTERN (GST_CAT_DEFAULT); - -#define EMPTY(x) (x) - -/* steps-like (no-)interpolation, default */ -/* just returns the value for the most recent key-frame */ -static inline const GValue * -_interpolate_none_get (GstTimedValueControlSource * self, GSequenceIter * iter) -{ - const GValue *ret; - - if (iter) { - GstControlPoint *cp = g_sequence_get (iter); - - ret = &cp->value; - } else { - ret = &self->default_value; - } - return ret; -} - -#define DEFINE_NONE_GET_FUNC_COMPARABLE(type) \ -static inline const GValue * \ -_interpolate_none_get_##type (GstTimedValueControlSource *self, GSequenceIter *iter) \ -{ \ - const GValue *ret; \ - \ - if (iter) { \ - GstControlPoint *cp = g_sequence_get (iter); \ - g##type ret_val = g_value_get_##type (&cp->value); \ - \ - if (g_value_get_##type (&self->minimum_value) > ret_val) \ - ret = &self->minimum_value; \ - else if (g_value_get_##type (&self->maximum_value) < ret_val) \ - ret = &self->maximum_value; \ - else \ - ret = &cp->value; \ - } else { \ - ret = &self->default_value; \ - } \ - return ret; \ -} - -#define DEFINE_NONE_GET(type,ctype,get_func) \ -static gboolean \ -interpolate_none_get_##type (GstTimedValueControlSource *self, GstClockTime timestamp, GValue *value) \ -{ \ - const GValue *ret; \ - GSequenceIter *iter; \ - \ - g_mutex_lock (self->lock); \ - \ - iter = gst_timed_value_control_source_find_control_point_iter (self, timestamp); \ - ret = get_func (self, iter); \ - g_value_copy (ret, value); \ - g_mutex_unlock (self->lock); \ - return TRUE; \ -} \ -\ -static gboolean \ -interpolate_none_get_##type##_value_array (GstTimedValueControlSource *self, \ - GstClockTime timestamp, GstClockTime interval, guint n_values, gpointer _values) \ -{ \ - guint i; \ - GstClockTime ts = timestamp; \ - GstClockTime next_ts = 0; \ - ctype *values = (ctype *) _values; \ - const GValue *ret_val = NULL; \ - ctype ret = 0; \ - GSequenceIter *iter1 = NULL, *iter2 = NULL; \ - \ - g_mutex_lock (self->lock); \ - for(i = 0; i < n_values; i++) { \ - if (!ret_val || ts >= next_ts) { \ - iter1 = gst_timed_value_control_source_find_control_point_iter (self, ts); \ - if (!iter1) { \ - if (G_LIKELY (self->values)) \ - iter2 = g_sequence_get_begin_iter (self->values); \ - else \ - iter2 = NULL; \ - } else { \ - iter2 = g_sequence_iter_next (iter1); \ - } \ - \ - if (iter2 && !g_sequence_iter_is_end (iter2)) { \ - GstControlPoint *cp; \ - \ - cp = g_sequence_get (iter2); \ - next_ts = cp->timestamp; \ - } else { \ - next_ts = GST_CLOCK_TIME_NONE; \ - } \ - \ - ret_val = get_func (self, iter1); \ - ret = g_value_get_##type (ret_val); \ - } \ - *values = ret; \ - ts += interval; \ - values++; \ - } \ - g_mutex_unlock (self->lock); \ - return TRUE; \ -} - -DEFINE_NONE_GET_FUNC_COMPARABLE (int); -DEFINE_NONE_GET (int, gint, _interpolate_none_get_int); -DEFINE_NONE_GET_FUNC_COMPARABLE (uint); -DEFINE_NONE_GET (uint, guint, _interpolate_none_get_uint); -DEFINE_NONE_GET_FUNC_COMPARABLE (long); -DEFINE_NONE_GET (long, glong, _interpolate_none_get_long); -DEFINE_NONE_GET_FUNC_COMPARABLE (ulong); -DEFINE_NONE_GET (ulong, gulong, _interpolate_none_get_ulong); -DEFINE_NONE_GET_FUNC_COMPARABLE (int64); -DEFINE_NONE_GET (int64, gint64, _interpolate_none_get_int64); -DEFINE_NONE_GET_FUNC_COMPARABLE (uint64); -DEFINE_NONE_GET (uint64, guint64, _interpolate_none_get_uint64); -DEFINE_NONE_GET_FUNC_COMPARABLE (float); -DEFINE_NONE_GET (float, gfloat, _interpolate_none_get_float); -DEFINE_NONE_GET_FUNC_COMPARABLE (double); -DEFINE_NONE_GET (double, gdouble, _interpolate_none_get_double); - -DEFINE_NONE_GET (boolean, gboolean, _interpolate_none_get); -DEFINE_NONE_GET (enum, gint, _interpolate_none_get); -DEFINE_NONE_GET (string, const gchar *, _interpolate_none_get); - -static GstInterpolateMethod interpolate_none = { - (GstControlSourceGetValue) interpolate_none_get_int, - (GstControlSourceGetValueArray) interpolate_none_get_int_value_array, - (GstControlSourceGetValue) interpolate_none_get_uint, - (GstControlSourceGetValueArray) interpolate_none_get_uint_value_array, - (GstControlSourceGetValue) interpolate_none_get_long, - (GstControlSourceGetValueArray) interpolate_none_get_long_value_array, - (GstControlSourceGetValue) interpolate_none_get_ulong, - (GstControlSourceGetValueArray) interpolate_none_get_ulong_value_array, - (GstControlSourceGetValue) interpolate_none_get_int64, - (GstControlSourceGetValueArray) interpolate_none_get_int64_value_array, - (GstControlSourceGetValue) interpolate_none_get_uint64, - (GstControlSourceGetValueArray) interpolate_none_get_uint64_value_array, - (GstControlSourceGetValue) interpolate_none_get_float, - (GstControlSourceGetValueArray) interpolate_none_get_float_value_array, - (GstControlSourceGetValue) interpolate_none_get_double, - (GstControlSourceGetValueArray) interpolate_none_get_double_value_array, - (GstControlSourceGetValue) interpolate_none_get_boolean, - (GstControlSourceGetValueArray) interpolate_none_get_boolean_value_array, - (GstControlSourceGetValue) interpolate_none_get_enum, - (GstControlSourceGetValueArray) interpolate_none_get_enum_value_array, - (GstControlSourceGetValue) interpolate_none_get_string, - (GstControlSourceGetValueArray) interpolate_none_get_string_value_array -}; - - -/* linear interpolation */ -/* smoothes inbetween values */ -#define DEFINE_LINEAR_GET(vtype, round, convert) \ -static inline void \ -_interpolate_linear_internal_##vtype (GstClockTime timestamp1, g##vtype value1, GstClockTime timestamp2, g##vtype value2, GstClockTime timestamp, g##vtype min, g##vtype max, g##vtype *ret) \ -{ \ - if (GST_CLOCK_TIME_IS_VALID (timestamp2)) { \ - gdouble slope; \ - \ - slope = ((gdouble) convert (value2) - (gdouble) convert (value1)) / gst_guint64_to_gdouble (timestamp2 - timestamp1); \ - \ - if (round) \ - *ret = (g##vtype) (convert (value1) + gst_guint64_to_gdouble (timestamp - timestamp1) * slope + 0.5); \ - else \ - *ret = (g##vtype) (convert (value1) + gst_guint64_to_gdouble (timestamp - timestamp1) * slope); \ - } else { \ - *ret = value1; \ - } \ - *ret = CLAMP (*ret, min, max); \ -} \ -\ -static gboolean \ -interpolate_linear_get_##vtype (GstTimedValueControlSource *self, GstClockTime timestamp, GValue *value) \ -{ \ - g##vtype ret, min, max; \ - GSequenceIter *iter; \ - GstControlPoint *cp1, *cp2 = NULL, cp = {0, }; \ - \ - g_mutex_lock (self->lock); \ - \ - min = g_value_get_##vtype (&self->minimum_value); \ - max = g_value_get_##vtype (&self->maximum_value); \ - \ - iter = gst_timed_value_control_source_find_control_point_iter (self, timestamp); \ - if (iter) { \ - cp1 = g_sequence_get (iter); \ - iter = g_sequence_iter_next (iter); \ - } else { \ - cp.timestamp = G_GUINT64_CONSTANT(0); \ - g_value_init (&cp.value, self->type); \ - g_value_copy (&self->default_value, &cp.value); \ - cp1 = &cp; \ - if (G_LIKELY (self->values)) \ - iter = g_sequence_get_begin_iter (self->values); \ - } \ - if (iter && !g_sequence_iter_is_end (iter)) \ - cp2 = g_sequence_get (iter); \ - \ - _interpolate_linear_internal_##vtype (cp1->timestamp, g_value_get_##vtype (&cp1->value), (cp2 ? cp2->timestamp : GST_CLOCK_TIME_NONE), (cp2 ? g_value_get_##vtype (&cp2->value) : 0), timestamp, min, max, &ret); \ - g_value_set_##vtype (value, ret); \ - g_mutex_unlock (self->lock); \ - if (cp1 == &cp) \ - g_value_unset (&cp.value); \ - return TRUE; \ -} \ -\ -static gboolean \ -interpolate_linear_get_##vtype##_value_array (GstTimedValueControlSource *self, \ - GstClockTime timestamp, GstClockTime interval, guint n_values, gpointer _values) \ -{ \ - guint i; \ - GstClockTime ts = timestamp; \ - GstClockTime next_ts = 0; \ - g##vtype *values = (g##vtype *) _values; \ - GSequenceIter *iter1, *iter2 = NULL; \ - GstControlPoint *cp1 = NULL, *cp2 = NULL, cp = {0, }; \ - g##vtype val1 = 0, val2 = 0, min, max; \ - \ - g_mutex_lock (self->lock); \ - \ - cp.timestamp = G_GUINT64_CONSTANT(0); \ - g_value_init (&cp.value, self->type); \ - g_value_copy (&self->default_value, &cp.value); \ - \ - min = g_value_get_##vtype (&self->minimum_value); \ - max = g_value_get_##vtype (&self->maximum_value); \ - \ - for(i = 0; i < n_values; i++) { \ - if (timestamp >= next_ts) { \ - iter1 = gst_timed_value_control_source_find_control_point_iter (self, ts); \ - if (!iter1) { \ - cp1 = &cp; \ - if (G_LIKELY (self->values)) \ - iter2 = g_sequence_get_begin_iter (self->values); \ - else \ - iter2 = NULL; \ - } else { \ - cp1 = g_sequence_get (iter1); \ - iter2 = g_sequence_iter_next (iter1); \ - } \ - \ - if (iter2 && !g_sequence_iter_is_end (iter2)) { \ - cp2 = g_sequence_get (iter2); \ - next_ts = cp2->timestamp; \ - } else { \ - next_ts = GST_CLOCK_TIME_NONE; \ - } \ - val1 = g_value_get_##vtype (&cp1->value); \ - if (cp2) \ - val2 = g_value_get_##vtype (&cp2->value); \ - } \ - _interpolate_linear_internal_##vtype (cp1->timestamp, val1, (cp2 ? cp2->timestamp : GST_CLOCK_TIME_NONE), (cp2 ? val2 : 0), ts, min, max, values); \ - ts += interval; \ - values++; \ - } \ - g_mutex_unlock (self->lock); \ - g_value_unset (&cp.value); \ - return TRUE; \ -} - -DEFINE_LINEAR_GET (int, TRUE, EMPTY); -DEFINE_LINEAR_GET (uint, TRUE, EMPTY); -DEFINE_LINEAR_GET (long, TRUE, EMPTY); -DEFINE_LINEAR_GET (ulong, TRUE, EMPTY); -DEFINE_LINEAR_GET (int64, TRUE, EMPTY); -DEFINE_LINEAR_GET (uint64, TRUE, gst_guint64_to_gdouble); -DEFINE_LINEAR_GET (float, FALSE, EMPTY); -DEFINE_LINEAR_GET (double, FALSE, EMPTY); - -static GstInterpolateMethod interpolate_linear = { - (GstControlSourceGetValue) interpolate_linear_get_int, - (GstControlSourceGetValueArray) interpolate_linear_get_int_value_array, - (GstControlSourceGetValue) interpolate_linear_get_uint, - (GstControlSourceGetValueArray) interpolate_linear_get_uint_value_array, - (GstControlSourceGetValue) interpolate_linear_get_long, - (GstControlSourceGetValueArray) interpolate_linear_get_long_value_array, - (GstControlSourceGetValue) interpolate_linear_get_ulong, - (GstControlSourceGetValueArray) interpolate_linear_get_ulong_value_array, - (GstControlSourceGetValue) interpolate_linear_get_int64, - (GstControlSourceGetValueArray) interpolate_linear_get_int64_value_array, - (GstControlSourceGetValue) interpolate_linear_get_uint64, - (GstControlSourceGetValueArray) interpolate_linear_get_uint64_value_array, - (GstControlSourceGetValue) interpolate_linear_get_float, - (GstControlSourceGetValueArray) interpolate_linear_get_float_value_array, - (GstControlSourceGetValue) interpolate_linear_get_double, - (GstControlSourceGetValueArray) interpolate_linear_get_double_value_array, - (GstControlSourceGetValue) NULL, - (GstControlSourceGetValueArray) NULL, - (GstControlSourceGetValue) NULL, - (GstControlSourceGetValueArray) NULL, - (GstControlSourceGetValue) NULL, - (GstControlSourceGetValueArray) NULL -}; - -/* square interpolation */ - -/* cubic interpolation */ - -/* The following functions implement a natural cubic spline interpolator. - * For details look at http://en.wikipedia.org/wiki/Spline_interpolation - * - * Instead of using a real matrix with n^2 elements for the linear system - * of equations we use three arrays o, p, q to hold the tridiagonal matrix - * as following to save memory: - * - * p[0] q[0] 0 0 0 - * o[1] p[1] q[1] 0 0 - * 0 o[2] p[2] q[2] . - * . . . . . - */ - -#define DEFINE_CUBIC_GET(vtype,round, convert) \ -static void \ -_interpolate_cubic_update_cache_##vtype (GstTimedValueControlSource *self) \ -{ \ - gint i, n = self->nvalues; \ - gdouble *o = g_new0 (gdouble, n); \ - gdouble *p = g_new0 (gdouble, n); \ - gdouble *q = g_new0 (gdouble, n); \ - \ - gdouble *h = g_new0 (gdouble, n); \ - gdouble *b = g_new0 (gdouble, n); \ - gdouble *z = g_new0 (gdouble, n); \ - \ - GSequenceIter *iter; \ - GstControlPoint *cp; \ - GstClockTime x, x_next; \ - g##vtype y_prev, y, y_next; \ - \ - /* Fill linear system of equations */ \ - iter = g_sequence_get_begin_iter (self->values); \ - cp = g_sequence_get (iter); \ - x = cp->timestamp; \ - y = g_value_get_##vtype (&cp->value); \ - \ - p[0] = 1.0; \ - \ - iter = g_sequence_iter_next (iter); \ - cp = g_sequence_get (iter); \ - x_next = cp->timestamp; \ - y_next = g_value_get_##vtype (&cp->value); \ - h[0] = gst_guint64_to_gdouble (x_next - x); \ - \ - for (i = 1; i < n-1; i++) { \ - /* Shuffle x and y values */ \ - y_prev = y; \ - x = x_next; \ - y = y_next; \ - iter = g_sequence_iter_next (iter); \ - cp = g_sequence_get (iter); \ - x_next = cp->timestamp; \ - y_next = g_value_get_##vtype (&cp->value); \ - \ - h[i] = gst_guint64_to_gdouble (x_next - x); \ - o[i] = h[i-1]; \ - p[i] = 2.0 * (h[i-1] + h[i]); \ - q[i] = h[i]; \ - b[i] = convert (y_next - y) / h[i] - convert (y - y_prev) / h[i-1]; \ - } \ - p[n-1] = 1.0; \ - \ - /* Use Gauss elimination to set everything below the \ - * diagonal to zero */ \ - for (i = 1; i < n-1; i++) { \ - gdouble a = o[i] / p[i-1]; \ - p[i] -= a * q[i-1]; \ - b[i] -= a * b[i-1]; \ - } \ - \ - /* Solve everything else from bottom to top */ \ - for (i = n-2; i > 0; i--) \ - z[i] = (b[i] - q[i] * z[i+1]) / p[i]; \ - \ - /* Save cache next in the GstControlPoint */ \ - \ - iter = g_sequence_get_begin_iter (self->values); \ - for (i = 0; i < n; i++) { \ - cp = g_sequence_get (iter); \ - cp->cache.cubic.h = h[i]; \ - cp->cache.cubic.z = z[i]; \ - iter = g_sequence_iter_next (iter); \ - } \ - \ - /* Free our temporary arrays */ \ - g_free (o); \ - g_free (p); \ - g_free (q); \ - g_free (h); \ - g_free (b); \ - g_free (z); \ -} \ -\ -static inline void \ -_interpolate_cubic_get_##vtype (GstTimedValueControlSource *self, GstControlPoint *cp1, g##vtype value1, GstControlPoint *cp2, g##vtype value2, GstClockTime timestamp, g##vtype min, g##vtype max, g##vtype *ret) \ -{ \ - if (!self->valid_cache) { \ - _interpolate_cubic_update_cache_##vtype (self); \ - self->valid_cache = TRUE; \ - } \ - \ - if (cp2) { \ - gdouble diff1, diff2; \ - gdouble out; \ - \ - diff1 = gst_guint64_to_gdouble (timestamp - cp1->timestamp); \ - diff2 = gst_guint64_to_gdouble (cp2->timestamp - timestamp); \ - \ - out = (cp2->cache.cubic.z * diff1 * diff1 * diff1 + cp1->cache.cubic.z * diff2 * diff2 * diff2) / cp1->cache.cubic.h; \ - out += (convert (value2) / cp1->cache.cubic.h - cp1->cache.cubic.h * cp2->cache.cubic.z) * diff1; \ - out += (convert (value1) / cp1->cache.cubic.h - cp1->cache.cubic.h * cp1->cache.cubic.z) * diff2; \ - \ - if (round) \ - *ret = (g##vtype) (out + 0.5); \ - else \ - *ret = (g##vtype) out; \ - } \ - else { \ - *ret = value1; \ - } \ - *ret = CLAMP (*ret, min, max); \ -} \ -\ -static gboolean \ -interpolate_cubic_get_##vtype (GstTimedValueControlSource *self, GstClockTime timestamp, GValue *value) \ -{ \ - g##vtype ret, min, max; \ - GSequenceIter *iter; \ - GstControlPoint *cp1, *cp2 = NULL, cp = {0, }; \ - \ - if (self->nvalues <= 2) \ - return interpolate_linear_get_##vtype (self, timestamp, value); \ - \ - g_mutex_lock (self->lock); \ - \ - min = g_value_get_##vtype (&self->minimum_value); \ - max = g_value_get_##vtype (&self->maximum_value); \ - \ - iter = gst_timed_value_control_source_find_control_point_iter (self, timestamp); \ - if (iter) { \ - cp1 = g_sequence_get (iter); \ - iter = g_sequence_iter_next (iter); \ - } else { \ - cp.timestamp = G_GUINT64_CONSTANT(0); \ - g_value_init (&cp.value, self->type); \ - g_value_copy (&self->default_value, &cp.value); \ - cp1 = &cp; \ - if (G_LIKELY (self->values)) \ - iter = g_sequence_get_begin_iter (self->values); \ - } \ - if (iter && !g_sequence_iter_is_end (iter)) \ - cp2 = g_sequence_get (iter); \ - \ - _interpolate_cubic_get_##vtype (self, cp1, g_value_get_##vtype (&cp1->value), cp2, (cp2 ? g_value_get_##vtype (&cp2->value) : 0), timestamp, min, max, &ret); \ - g_value_set_##vtype (value, ret); \ - g_mutex_unlock (self->lock); \ - if (cp1 == &cp) \ - g_value_unset (&cp.value); \ - return TRUE; \ -} \ -\ -static gboolean \ -interpolate_cubic_get_##vtype##_value_array (GstTimedValueControlSource *self, \ - GstClockTime timestamp, GstClockTime interval, guint n_values, gpointer _values) \ -{ \ - guint i; \ - GstClockTime ts = timestamp; \ - GstClockTime next_ts = 0; \ - g##vtype *values = (g##vtype *) _values; \ - GSequenceIter *iter1, *iter2 = NULL; \ - GstControlPoint *cp1 = NULL, *cp2 = NULL, cp = {0, }; \ - g##vtype val1 = 0, val2 = 0, min, max; \ - \ - if (self->nvalues <= 2) \ - return interpolate_linear_get_##vtype##_value_array (self, timestamp, interval, n_values, values); \ - \ - g_mutex_lock (self->lock); \ - \ - cp.timestamp = G_GUINT64_CONSTANT(0); \ - g_value_init (&cp.value, self->type); \ - g_value_copy (&self->default_value, &cp.value); \ - \ - min = g_value_get_##vtype (&self->minimum_value); \ - max = g_value_get_##vtype (&self->maximum_value); \ - \ - for(i = 0; i < n_values; i++) { \ - if (timestamp >= next_ts) { \ - iter1 = gst_timed_value_control_source_find_control_point_iter (self, ts); \ - if (!iter1) { \ - cp1 = &cp; \ - if (G_LIKELY (self->values)) \ - iter2 = g_sequence_get_begin_iter (self->values); \ - else \ - iter2 = NULL; \ - } else { \ - cp1 = g_sequence_get (iter1); \ - iter2 = g_sequence_iter_next (iter1); \ - } \ - \ - if (iter2 && !g_sequence_iter_is_end (iter2)) { \ - cp2 = g_sequence_get (iter2); \ - next_ts = cp2->timestamp; \ - } else { \ - next_ts = GST_CLOCK_TIME_NONE; \ - } \ - val1 = g_value_get_##vtype (&cp1->value); \ - if (cp2) \ - val2 = g_value_get_##vtype (&cp2->value); \ - } \ - _interpolate_cubic_get_##vtype (self, cp1, val1, cp2, val2, timestamp, min, max, values); \ - ts += interval; \ - values++; \ - } \ - g_mutex_unlock (self->lock); \ - g_value_unset (&cp.value); \ - return TRUE; \ -} - -DEFINE_CUBIC_GET (int, TRUE, EMPTY); -DEFINE_CUBIC_GET (uint, TRUE, EMPTY); -DEFINE_CUBIC_GET (long, TRUE, EMPTY); -DEFINE_CUBIC_GET (ulong, TRUE, EMPTY); -DEFINE_CUBIC_GET (int64, TRUE, EMPTY); -DEFINE_CUBIC_GET (uint64, TRUE, gst_guint64_to_gdouble); -DEFINE_CUBIC_GET (float, FALSE, EMPTY); -DEFINE_CUBIC_GET (double, FALSE, EMPTY); - -static GstInterpolateMethod interpolate_cubic = { - (GstControlSourceGetValue) interpolate_cubic_get_int, - (GstControlSourceGetValueArray) interpolate_cubic_get_int_value_array, - (GstControlSourceGetValue) interpolate_cubic_get_uint, - (GstControlSourceGetValueArray) interpolate_cubic_get_uint_value_array, - (GstControlSourceGetValue) interpolate_cubic_get_long, - (GstControlSourceGetValueArray) interpolate_cubic_get_long_value_array, - (GstControlSourceGetValue) interpolate_cubic_get_ulong, - (GstControlSourceGetValueArray) interpolate_cubic_get_ulong_value_array, - (GstControlSourceGetValue) interpolate_cubic_get_int64, - (GstControlSourceGetValueArray) interpolate_cubic_get_int64_value_array, - (GstControlSourceGetValue) interpolate_cubic_get_uint64, - (GstControlSourceGetValueArray) interpolate_cubic_get_uint64_value_array, - (GstControlSourceGetValue) interpolate_cubic_get_float, - (GstControlSourceGetValueArray) interpolate_cubic_get_float_value_array, - (GstControlSourceGetValue) interpolate_cubic_get_double, - (GstControlSourceGetValueArray) interpolate_cubic_get_double_value_array, - (GstControlSourceGetValue) NULL, - (GstControlSourceGetValueArray) NULL, - (GstControlSourceGetValue) NULL, - (GstControlSourceGetValueArray) NULL, - (GstControlSourceGetValue) NULL, - (GstControlSourceGetValueArray) NULL -}; - -/* register all interpolation methods */ -GstInterpolateMethod *priv_gst_interpolation_methods[] = { - &interpolate_none, - &interpolate_linear, - &interpolate_cubic -}; - -guint priv_gst_num_interpolation_methods = -G_N_ELEMENTS (priv_gst_interpolation_methods); diff --git a/libs/gst/controller/gstinterpolationcontrolsource.c b/libs/gst/controller/gstinterpolationcontrolsource.c index ad8c50dd06..cdda5267e1 100644 --- a/libs/gst/controller/gstinterpolationcontrolsource.c +++ b/libs/gst/controller/gstinterpolationcontrolsource.c @@ -40,12 +40,419 @@ #include #include "gstinterpolationcontrolsource.h" -#include "gstinterpolationcontrolsourceprivate.h" #include "gst/glib-compat-private.h" +#include + #define GST_CAT_DEFAULT controller_debug GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); +/* steps-like (no-)interpolation, default */ +/* just returns the value for the most recent key-frame */ +static inline const gdouble +_interpolate_none (GstTimedValueControlSource * self, GSequenceIter * iter) +{ + GstControlPoint *cp = g_sequence_get (iter); + + return cp->value; +} + +static gboolean +interpolate_none_get (GstTimedValueControlSource * self, GstClockTime timestamp, + gdouble * value) +{ + gboolean ret = FALSE; + GSequenceIter *iter; + + g_mutex_lock (self->lock); + + iter = + gst_timed_value_control_source_find_control_point_iter (self, timestamp); + if (iter) { + *value = _interpolate_none (self, iter); + ret = TRUE; + } + g_mutex_unlock (self->lock); + return ret; +} + +static gboolean +interpolate_none_get_value_array (GstTimedValueControlSource * self, + GstClockTime timestamp, GstClockTime interval, guint n_values, + gdouble * values) +{ + gboolean ret = FALSE; + guint i; + GstClockTime ts = timestamp; + GstClockTime next_ts = 0; + gdouble val; + GSequenceIter *iter1 = NULL, *iter2 = NULL; + + g_mutex_lock (self->lock); + for (i = 0; i < n_values; i++) { + val = FP_NAN; + if (ts >= next_ts) { + iter1 = gst_timed_value_control_source_find_control_point_iter (self, ts); + if (!iter1) { + if (G_LIKELY (self->values)) + iter2 = g_sequence_get_begin_iter (self->values); + else + iter2 = NULL; + } else { + iter2 = g_sequence_iter_next (iter1); + } + + if (iter2 && !g_sequence_iter_is_end (iter2)) { + GstControlPoint *cp; + + cp = g_sequence_get (iter2); + next_ts = cp->timestamp; + } else { + next_ts = GST_CLOCK_TIME_NONE; + } + + if (iter1) { + val = _interpolate_none (self, iter1); + ret = TRUE; + } + } + *values = val; + ts += interval; + values++; + } + g_mutex_unlock (self->lock); + return ret; +} + + + +/* linear interpolation */ +/* smoothes inbetween values */ +static inline gdouble +_interpolate_linear (GstClockTime timestamp1, gdouble value1, + GstClockTime timestamp2, gdouble value2, GstClockTime timestamp) +{ + if (GST_CLOCK_TIME_IS_VALID (timestamp2)) { + gdouble slope; + + slope = + (value2 - value1) / gst_guint64_to_gdouble (timestamp2 - timestamp1); + return value1 + (gst_guint64_to_gdouble (timestamp - timestamp1) * slope); + } else { + return value1; + } +} + +static gboolean +interpolate_linear_get (GstTimedValueControlSource * self, + GstClockTime timestamp, gdouble * value) +{ + gboolean ret = FALSE; + GSequenceIter *iter; + GstControlPoint *cp1, *cp2; + + g_mutex_lock (self->lock); + + iter = + gst_timed_value_control_source_find_control_point_iter (self, timestamp); + if (iter) { + cp1 = g_sequence_get (iter); + iter = g_sequence_iter_next (iter); + if (iter && !g_sequence_iter_is_end (iter)) { + cp2 = g_sequence_get (iter); + } else { + cp2 = NULL; + } + + *value = _interpolate_linear (cp1->timestamp, cp1->value, + (cp2 ? cp2->timestamp : GST_CLOCK_TIME_NONE), + (cp2 ? cp2->value : 0.0), timestamp); + ret = TRUE; + } + g_mutex_unlock (self->lock); + return ret; +} + +static gboolean +interpolate_linear_get_value_array (GstTimedValueControlSource * self, + GstClockTime timestamp, GstClockTime interval, guint n_values, + gdouble * values) +{ + gboolean ret = FALSE; + guint i; + GstClockTime ts = timestamp; + GstClockTime next_ts = 0; + gdouble val; + GSequenceIter *iter1, *iter2 = NULL; + GstControlPoint *cp1 = NULL, *cp2 = NULL; + + g_mutex_lock (self->lock); + + for (i = 0; i < n_values; i++) { + val = FP_NAN; + if (ts >= next_ts) { + cp1 = cp2 = NULL; + iter1 = gst_timed_value_control_source_find_control_point_iter (self, ts); + if (!iter1) { + if (G_LIKELY (self->values)) + iter2 = g_sequence_get_begin_iter (self->values); + else + iter2 = NULL; + } else { + cp1 = g_sequence_get (iter1); + iter2 = g_sequence_iter_next (iter1); + } + + if (iter2 && !g_sequence_iter_is_end (iter2)) { + cp2 = g_sequence_get (iter2); + next_ts = cp2->timestamp; + } else { + next_ts = GST_CLOCK_TIME_NONE; + } + } + if (cp1) { + val = _interpolate_linear (cp1->timestamp, cp1->value, + (cp2 ? cp2->timestamp : GST_CLOCK_TIME_NONE), + (cp2 ? cp2->value : 0.0), ts); + ret = TRUE; + } + *values = val; + ts += interval; + values++; + } + g_mutex_unlock (self->lock); + return ret; +} + + + +/* cubic interpolation */ + +/* The following functions implement a natural cubic spline interpolator. + * For details look at http://en.wikipedia.org/wiki/Spline_interpolation + * + * Instead of using a real matrix with n^2 elements for the linear system + * of equations we use three arrays o, p, q to hold the tridiagonal matrix + * as following to save memory: + * + * p[0] q[0] 0 0 0 + * o[1] p[1] q[1] 0 0 + * 0 o[2] p[2] q[2] . + * . . . . . + */ + +static void +_interpolate_cubic_update_cache (GstTimedValueControlSource * self) +{ + gint i, n = self->nvalues; + gdouble *o = g_new0 (gdouble, n); + gdouble *p = g_new0 (gdouble, n); + gdouble *q = g_new0 (gdouble, n); + + gdouble *h = g_new0 (gdouble, n); + gdouble *b = g_new0 (gdouble, n); + gdouble *z = g_new0 (gdouble, n); + + GSequenceIter *iter; + GstControlPoint *cp; + GstClockTime x, x_next; + gdouble y_prev, y, y_next; + + /* Fill linear system of equations */ + iter = g_sequence_get_begin_iter (self->values); + cp = g_sequence_get (iter); + x = cp->timestamp; + y = cp->value; + + p[0] = 1.0; + + iter = g_sequence_iter_next (iter); + cp = g_sequence_get (iter); + x_next = cp->timestamp; + y_next = cp->value; + h[0] = gst_guint64_to_gdouble (x_next - x); + + for (i = 1; i < n - 1; i++) { + /* Shuffle x and y values */ + y_prev = y; + x = x_next; + y = y_next; + iter = g_sequence_iter_next (iter); + cp = g_sequence_get (iter); + x_next = cp->timestamp; + y_next = cp->value; + + h[i] = gst_guint64_to_gdouble (x_next - x); + o[i] = h[i - 1]; + p[i] = 2.0 * (h[i - 1] + h[i]); + q[i] = h[i]; + b[i] = (y_next - y) / h[i] - (y - y_prev) / h[i - 1]; + } + p[n - 1] = 1.0; + + /* Use Gauss elimination to set everything below the diagonal to zero */ + for (i = 1; i < n - 1; i++) { + gdouble a = o[i] / p[i - 1]; + p[i] -= a * q[i - 1]; + b[i] -= a * b[i - 1]; + } + + /* Solve everything else from bottom to top */ + for (i = n - 2; i > 0; i--) + z[i] = (b[i] - q[i] * z[i + 1]) / p[i]; + + /* Save cache next in the GstControlPoint */ + + iter = g_sequence_get_begin_iter (self->values); + for (i = 0; i < n; i++) { + cp = g_sequence_get (iter); + cp->cache.cubic.h = h[i]; + cp->cache.cubic.z = z[i]; + iter = g_sequence_iter_next (iter); + } + + /* Free our temporary arrays */ + g_free (o); + g_free (p); + g_free (q); + g_free (h); + g_free (b); + g_free (z); +} + +static inline gdouble +_interpolate_cubic (GstTimedValueControlSource * self, GstControlPoint * cp1, + gdouble value1, GstControlPoint * cp2, gdouble value2, + GstClockTime timestamp) +{ + if (!self->valid_cache) { + _interpolate_cubic_update_cache (self); + self->valid_cache = TRUE; + } + + if (cp2) { + gdouble diff1, diff2; + gdouble out; + + diff1 = gst_guint64_to_gdouble (timestamp - cp1->timestamp); + diff2 = gst_guint64_to_gdouble (cp2->timestamp - timestamp); + + out = + (cp2->cache.cubic.z * diff1 * diff1 * diff1 + + cp1->cache.cubic.z * diff2 * diff2 * diff2) / cp1->cache.cubic.h; + out += + (value2 / cp1->cache.cubic.h - + cp1->cache.cubic.h * cp2->cache.cubic.z) * diff1; + out += + (value1 / cp1->cache.cubic.h - + cp1->cache.cubic.h * cp1->cache.cubic.z) * diff2; + return out; + } else { + return value1; + } +} + +static gboolean +interpolate_cubic_get (GstTimedValueControlSource * self, + GstClockTime timestamp, gdouble * value) +{ + gboolean ret = FALSE; + GSequenceIter *iter; + GstControlPoint *cp1, *cp2 = NULL; + + if (self->nvalues <= 2) + return interpolate_linear_get (self, timestamp, value); + + g_mutex_lock (self->lock); + + iter = + gst_timed_value_control_source_find_control_point_iter (self, timestamp); + if (iter) { + cp1 = g_sequence_get (iter); + iter = g_sequence_iter_next (iter); + if (iter && !g_sequence_iter_is_end (iter)) { + cp2 = g_sequence_get (iter); + } else { + cp2 = NULL; + } + *value = _interpolate_cubic (self, cp1, cp1->value, cp2, + (cp2 ? cp2->value : 0.0), timestamp); + ret = TRUE; + } + g_mutex_unlock (self->lock); + return ret; +} + +static gboolean +interpolate_cubic_get_value_array (GstTimedValueControlSource * self, + GstClockTime timestamp, GstClockTime interval, guint n_values, + gdouble * values) +{ + gboolean ret = FALSE; + guint i; + GstClockTime ts = timestamp; + GstClockTime next_ts = 0; + gdouble val; + GSequenceIter *iter1, *iter2 = NULL; + GstControlPoint *cp1 = NULL, *cp2 = NULL; + + if (self->nvalues <= 2) + return interpolate_linear_get_value_array (self, timestamp, interval, + n_values, values); + + g_mutex_lock (self->lock); + + for (i = 0; i < n_values; i++) { + val = FP_NAN; + if (ts >= next_ts) { + cp1 = cp2 = NULL; + iter1 = gst_timed_value_control_source_find_control_point_iter (self, ts); + if (!iter1) { + if (G_LIKELY (self->values)) + iter2 = g_sequence_get_begin_iter (self->values); + else + iter2 = NULL; + } else { + cp1 = g_sequence_get (iter1); + iter2 = g_sequence_iter_next (iter1); + } + + if (iter2 && !g_sequence_iter_is_end (iter2)) { + cp2 = g_sequence_get (iter2); + next_ts = cp2->timestamp; + } else { + next_ts = GST_CLOCK_TIME_NONE; + } + if (cp1) { + val = _interpolate_cubic (self, cp1, cp1->value, cp2, + (cp2 ? cp2->value : 0.0), timestamp); + ret = TRUE; + } + } + *values = val; + ts += interval; + values++; + } + g_mutex_unlock (self->lock); + return ret; +} + +static struct +{ + GstControlSourceGetValue get; + GstControlSourceGetValueArray get_value_array; +} interpolation_modes[] = { + { + (GstControlSourceGetValue) interpolate_none_get, + (GstControlSourceGetValueArray) interpolate_none_get_value_array}, { + (GstControlSourceGetValue) interpolate_linear_get, + (GstControlSourceGetValueArray) interpolate_linear_get_value_array}, { + (GstControlSourceGetValue) interpolate_cubic_get, + (GstControlSourceGetValueArray) interpolate_cubic_get_value_array} +}; + +static const guint num_interpolation_modes = G_N_ELEMENTS (interpolation_modes); + enum { PROP_MODE = 1 @@ -101,105 +508,24 @@ static gboolean gst_interpolation_control_source_set_interpolation_mode (GstInterpolationControlSource * self, GstInterpolationMode mode) { - gboolean ret = TRUE; GstControlSource *csource = GST_CONTROL_SOURCE (self); - if (mode >= priv_gst_num_interpolation_methods - || priv_gst_interpolation_methods[mode] == NULL) { + if (mode >= num_interpolation_modes && (int) mode < 0) { GST_WARNING ("interpolation mode %d invalid or not implemented yet", mode); return FALSE; } GST_TIMED_VALUE_CONTROL_SOURCE_LOCK (self); - switch (gst_timed_value_control_source_get_base_value_type ( - (GstTimedValueControlSource *) self)) { - case G_TYPE_INT: - csource->get_value = priv_gst_interpolation_methods[mode]->get_int; - csource->get_value_array = - priv_gst_interpolation_methods[mode]->get_int_value_array; - break; - case G_TYPE_UINT: - csource->get_value = priv_gst_interpolation_methods[mode]->get_uint; - csource->get_value_array = - priv_gst_interpolation_methods[mode]->get_uint_value_array; - break; - case G_TYPE_LONG: - csource->get_value = priv_gst_interpolation_methods[mode]->get_long; - csource->get_value_array = - priv_gst_interpolation_methods[mode]->get_long_value_array; - break; - case G_TYPE_ULONG: - csource->get_value = priv_gst_interpolation_methods[mode]->get_ulong; - csource->get_value_array = - priv_gst_interpolation_methods[mode]->get_ulong_value_array; - break; - case G_TYPE_INT64: - csource->get_value = priv_gst_interpolation_methods[mode]->get_int64; - csource->get_value_array = - priv_gst_interpolation_methods[mode]->get_int64_value_array; - break; - case G_TYPE_UINT64: - csource->get_value = priv_gst_interpolation_methods[mode]->get_uint64; - csource->get_value_array = - priv_gst_interpolation_methods[mode]->get_uint64_value_array; - break; - case G_TYPE_FLOAT: - csource->get_value = priv_gst_interpolation_methods[mode]->get_float; - csource->get_value_array = - priv_gst_interpolation_methods[mode]->get_float_value_array; - break; - case G_TYPE_DOUBLE: - csource->get_value = priv_gst_interpolation_methods[mode]->get_double; - csource->get_value_array = - priv_gst_interpolation_methods[mode]->get_double_value_array; - break; - case G_TYPE_BOOLEAN: - csource->get_value = priv_gst_interpolation_methods[mode]->get_boolean; - csource->get_value_array = - priv_gst_interpolation_methods[mode]->get_boolean_value_array; - break; - case G_TYPE_ENUM: - csource->get_value = priv_gst_interpolation_methods[mode]->get_enum; - csource->get_value_array = - priv_gst_interpolation_methods[mode]->get_enum_value_array; - break; - case G_TYPE_STRING: - csource->get_value = priv_gst_interpolation_methods[mode]->get_string; - csource->get_value_array = - priv_gst_interpolation_methods[mode]->get_string_value_array; - break; - default: - ret = FALSE; - break; - } + csource->get_value = interpolation_modes[mode].get; + csource->get_value_array = interpolation_modes[mode].get_value_array; - /* Incomplete implementation */ - if (!csource->get_value || !csource->get_value_array) { - ret = FALSE; - } gst_timed_value_control_invalidate_cache ((GstTimedValueControlSource *) csource); self->priv->interpolation_mode = mode; GST_TIMED_VALUE_CONTROL_SOURCE_UNLOCK (self); - return ret; -} - -static gboolean -gst_interpolation_control_source_bind (GstControlSource * csource, - GParamSpec * pspec) -{ - if (GST_CONTROL_SOURCE_CLASS - (gst_interpolation_control_source_parent_class)->bind (csource, pspec)) { - GstInterpolationControlSource *self = - GST_INTERPOLATION_CONTROL_SOURCE (csource); - - if (gst_interpolation_control_source_set_interpolation_mode (self, - self->priv->interpolation_mode)) - return TRUE; - } - return FALSE; + return TRUE; } static void @@ -208,7 +534,8 @@ gst_interpolation_control_source_init (GstInterpolationControlSource * self) self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GST_TYPE_INTERPOLATION_CONTROL_SOURCE, GstInterpolationControlSourcePrivate); - self->priv->interpolation_mode = GST_INTERPOLATION_MODE_NONE; + gst_interpolation_control_source_set_interpolation_mode (self, + GST_INTERPOLATION_MODE_NONE); } static void @@ -251,7 +578,7 @@ gst_interpolation_control_source_class_init (GstInterpolationControlSourceClass * klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GstControlSourceClass *csource_class = GST_CONTROL_SOURCE_CLASS (klass); + //GstControlSourceClass *csource_class = GST_CONTROL_SOURCE_CLASS (klass); g_type_class_add_private (klass, sizeof (GstInterpolationControlSourcePrivate)); @@ -259,8 +586,6 @@ gst_interpolation_control_source_class_init (GstInterpolationControlSourceClass gobject_class->set_property = gst_interpolation_control_source_set_property; gobject_class->get_property = gst_interpolation_control_source_get_property; - csource_class->bind = gst_interpolation_control_source_bind; - g_object_class_install_property (gobject_class, PROP_MODE, g_param_spec_enum ("mode", "Mode", "Interpolation mode", GST_TYPE_INTERPOLATION_MODE, GST_INTERPOLATION_MODE_NONE, diff --git a/libs/gst/controller/gstinterpolationcontrolsourceprivate.h b/libs/gst/controller/gstinterpolationcontrolsourceprivate.h deleted file mode 100644 index 5447121f1a..0000000000 --- a/libs/gst/controller/gstinterpolationcontrolsourceprivate.h +++ /dev/null @@ -1,87 +0,0 @@ -/* GStreamer - * - * Copyright (C) 2007 Sebastian Dröge - * - * gstinterpolationcontrolsourceprivate.h: Private declarations for the - * GstInterpolationControlSource - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_INTERPOLATION_CONTROL_SOURCE_PRIVATE_H__ -#define __GST_INTERPOLATION_CONTROL_SOURCE_PRIVATE_H__ - -/** - * GstInterpolateMethod: - * - * Function pointer structure to do user-defined interpolation methods - */ -typedef struct _GstInterpolateMethod -{ - GstControlSourceGetValue get_int; - GstControlSourceGetValueArray get_int_value_array; - GstControlSourceGetValue get_uint; - GstControlSourceGetValueArray get_uint_value_array; - GstControlSourceGetValue get_long; - GstControlSourceGetValueArray get_long_value_array; - GstControlSourceGetValue get_ulong; - GstControlSourceGetValueArray get_ulong_value_array; - GstControlSourceGetValue get_int64; - GstControlSourceGetValueArray get_int64_value_array; - GstControlSourceGetValue get_uint64; - GstControlSourceGetValueArray get_uint64_value_array; - GstControlSourceGetValue get_float; - GstControlSourceGetValueArray get_float_value_array; - GstControlSourceGetValue get_double; - GstControlSourceGetValueArray get_double_value_array; - GstControlSourceGetValue get_boolean; - GstControlSourceGetValueArray get_boolean_value_array; - GstControlSourceGetValue get_enum; - GstControlSourceGetValueArray get_enum_value_array; - GstControlSourceGetValue get_string; - GstControlSourceGetValueArray get_string_value_array; -} GstInterpolateMethod; - -/** - * GstControlPoint: - * - * a internal structure for value+time and various temporary - * values used for interpolation. This "inherits" from - * GstTimedValue. - */ -typedef struct _GstControlPoint -{ - /* fields from GstTimedValue. DO NOT CHANGE! */ - GstClockTime timestamp; /* timestamp of the value change */ - GValue value; /* the new value */ - - /* internal fields */ - - /* Caches for the interpolators */ - union { - struct { - gdouble h; - gdouble z; - } cubic; - } cache; - -} GstControlPoint; - -extern GstInterpolateMethod *priv_gst_interpolation_methods[]; -extern guint priv_gst_num_interpolation_methods; - -#endif /* __GST_INTERPOLATION_CONTROL_SOURCE_PRIVATE_H__ */ - diff --git a/libs/gst/controller/gstlfocontrolsource.c b/libs/gst/controller/gstlfocontrolsource.c index 409f3119bb..7ebd525f3e 100644 --- a/libs/gst/controller/gstlfocontrolsource.c +++ b/libs/gst/controller/gstlfocontrolsource.c @@ -41,7 +41,6 @@ #include #include "gstlfocontrolsource.h" -#include "gstlfocontrolsourceprivate.h" #include "gst/glib-compat-private.h" @@ -50,8 +49,15 @@ #define GST_CAT_DEFAULT controller_debug GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); - -#define EMPTY(x) (x) +struct _GstLFOControlSourcePrivate +{ + GstLFOWaveform waveform; + gdouble frequency; + GstClockTime period; + GstClockTime timeshift; + gdouble amplitude; + gdouble offset; +}; /* FIXME: as % in C is not the modulo operator we need here for * negative numbers implement our own. Are there better ways? */ @@ -67,509 +73,358 @@ _calculate_pos (GstClockTime timestamp, GstClockTime timeshift, return timestamp % period; } -#define DEFINE_SINE(type,round,convert) \ -static inline g##type \ -_sine_get_##type (GstLFOControlSource *self, g##type max, g##type min, gdouble amp, gdouble off, GstClockTime timeshift, GstClockTime period, gdouble frequency, GstClockTime timestamp) \ -{ \ - gdouble ret; \ - GstClockTime pos = _calculate_pos (timestamp, timeshift, period); \ - \ - ret = sin (2.0 * M_PI * (frequency / GST_SECOND) * gst_guint64_to_gdouble (pos)); \ - ret *= amp; \ - ret += off; \ - \ - if (round) \ - ret += 0.5; \ - \ - return (g##type) CLAMP (ret, convert (min), convert (max)); \ -} \ -\ -static gboolean \ -waveform_sine_get_##type (GstLFOControlSource *self, GstClockTime timestamp, \ - GValue *value) \ -{ \ - g##type ret, max, min; \ - gdouble amp, off, frequency; \ - GstClockTime timeshift, period; \ - \ - g_mutex_lock (self->lock); \ - max = g_value_get_##type (&self->priv->maximum_value); \ - min = g_value_get_##type (&self->priv->minimum_value); \ - amp = convert (g_value_get_##type (&self->priv->amplitude)); \ - off = convert (g_value_get_##type (&self->priv->offset)); \ - timeshift = self->priv->timeshift; \ - period = self->priv->period; \ - frequency = self->priv->frequency; \ - \ - ret = _sine_get_##type (self, max, min, amp, off, timeshift, period, frequency, timestamp); \ - g_value_set_##type (value, ret); \ - g_mutex_unlock (self->lock); \ - return TRUE; \ -} \ -\ -static gboolean \ -waveform_sine_get_##type##_value_array (GstLFOControlSource *self, \ - GstClockTime timestamp, GstClockTime interval, guint n_values, gpointer *_values) \ -{ \ - guint i; \ - GstClockTime ts = timestamp; \ - g##type *values = (g##type *) _values; \ - g##type max, min; \ - gdouble amp, off, frequency; \ - GstClockTime timeshift, period; \ - \ - g_mutex_lock (self->lock); \ - max = g_value_get_##type (&self->priv->maximum_value); \ - min = g_value_get_##type (&self->priv->minimum_value); \ - amp = convert (g_value_get_##type (&self->priv->amplitude)); \ - off = convert (g_value_get_##type (&self->priv->offset)); \ - timeshift = self->priv->timeshift; \ - period = self->priv->period; \ - frequency = self->priv->frequency; \ - \ - for(i = 0; i < n_values; i++) { \ - *values = _sine_get_##type (self, max, min, amp, off, timeshift, period, frequency, ts); \ - ts += interval; \ - values++; \ - } \ - g_mutex_unlock (self->lock); \ - return TRUE; \ +static inline gdouble +_sine_get (GstLFOControlSource * self, gdouble amp, gdouble off, + GstClockTime timeshift, GstClockTime period, gdouble frequency, + GstClockTime timestamp) +{ + GstClockTime pos = _calculate_pos (timestamp, timeshift, period); + gdouble ret; + + ret = + sin (2.0 * M_PI * (frequency / GST_SECOND) * + gst_guint64_to_gdouble (pos)); + ret *= amp; + ret += off; + + return ret; } -DEFINE_SINE (int, TRUE, EMPTY); -DEFINE_SINE (uint, TRUE, EMPTY); -DEFINE_SINE (long, TRUE, EMPTY); -DEFINE_SINE (ulong, TRUE, EMPTY); -DEFINE_SINE (int64, TRUE, EMPTY); -DEFINE_SINE (uint64, TRUE, gst_guint64_to_gdouble); -DEFINE_SINE (float, FALSE, EMPTY); -DEFINE_SINE (double, FALSE, EMPTY); +static gboolean +waveform_sine_get (GstLFOControlSource * self, GstClockTime timestamp, + gdouble * value) +{ + GstLFOControlSourcePrivate *priv = self->priv; + gdouble amp, off, frequency; + GstClockTime timeshift, period; -static GstWaveformImplementation waveform_sine = { - (GstControlSourceGetValue) waveform_sine_get_int, - (GstControlSourceGetValueArray) waveform_sine_get_int_value_array, - (GstControlSourceGetValue) waveform_sine_get_uint, - (GstControlSourceGetValueArray) waveform_sine_get_uint_value_array, - (GstControlSourceGetValue) waveform_sine_get_long, - (GstControlSourceGetValueArray) waveform_sine_get_long_value_array, - (GstControlSourceGetValue) waveform_sine_get_ulong, - (GstControlSourceGetValueArray) waveform_sine_get_ulong_value_array, - (GstControlSourceGetValue) waveform_sine_get_int64, - (GstControlSourceGetValueArray) waveform_sine_get_int64_value_array, - (GstControlSourceGetValue) waveform_sine_get_uint64, - (GstControlSourceGetValueArray) waveform_sine_get_uint64_value_array, - (GstControlSourceGetValue) waveform_sine_get_float, - (GstControlSourceGetValueArray) waveform_sine_get_float_value_array, - (GstControlSourceGetValue) waveform_sine_get_double, - (GstControlSourceGetValueArray) waveform_sine_get_double_value_array -}; + g_mutex_lock (self->lock); + amp = priv->amplitude; + off = priv->offset; + timeshift = priv->timeshift; + period = priv->period; + frequency = priv->frequency; -#define DEFINE_SQUARE(type,round, convert) \ -\ -static inline g##type \ -_square_get_##type (GstLFOControlSource *self, g##type max, g##type min, gdouble amp, gdouble off, GstClockTime timeshift, GstClockTime period, gdouble frequency, GstClockTime timestamp) \ -{ \ - GstClockTime pos = _calculate_pos (timestamp, timeshift, period); \ - gdouble ret; \ - \ - if (pos >= period / 2) \ - ret = amp; \ - else \ - ret = - amp; \ - \ - ret += off; \ - \ - if (round) \ - ret += 0.5; \ - \ - return (g##type) CLAMP (ret, convert (min), convert (max)); \ -} \ -\ -static gboolean \ -waveform_square_get_##type (GstLFOControlSource *self, GstClockTime timestamp, \ - GValue *value) \ -{ \ - g##type ret, max, min; \ - gdouble amp, off, frequency; \ - GstClockTime timeshift, period; \ - \ - g_mutex_lock (self->lock); \ - max = g_value_get_##type (&self->priv->maximum_value); \ - min = g_value_get_##type (&self->priv->minimum_value); \ - amp = convert (g_value_get_##type (&self->priv->amplitude)); \ - off = convert (g_value_get_##type (&self->priv->offset)); \ - timeshift = self->priv->timeshift; \ - period = self->priv->period; \ - frequency = self->priv->frequency; \ - \ - ret = _square_get_##type (self, max, min, amp, off, timeshift, period, frequency, timestamp); \ - g_value_set_##type (value, ret); \ - g_mutex_unlock (self->lock); \ - return TRUE; \ -} \ -\ -static gboolean \ -waveform_square_get_##type##_value_array (GstLFOControlSource *self, \ - GstClockTime timestamp, GstClockTime interval, guint n_values, gpointer *_values) \ -{ \ - guint i; \ - GstClockTime ts = timestamp; \ - g##type *values = (g##type *) _values; \ - g##type max, min; \ - gdouble amp, off, frequency; \ - GstClockTime timeshift, period; \ - \ - g_mutex_lock (self->lock); \ - max = g_value_get_##type (&self->priv->maximum_value); \ - min = g_value_get_##type (&self->priv->minimum_value); \ - amp = convert (g_value_get_##type (&self->priv->amplitude)); \ - off = convert (g_value_get_##type (&self->priv->offset)); \ - timeshift = self->priv->timeshift; \ - period = self->priv->period; \ - frequency = self->priv->frequency; \ - \ - for(i = 0; i < n_values; i++) { \ - *values = _square_get_##type (self, max, min, amp, off, timeshift, period, frequency, ts); \ - ts += interval; \ - values++; \ - } \ - g_mutex_unlock (self->lock); \ - return TRUE; \ + *value = _sine_get (self, amp, off, timeshift, period, frequency, timestamp); + g_mutex_unlock (self->lock); + return TRUE; } -DEFINE_SQUARE (int, TRUE, EMPTY); -DEFINE_SQUARE (uint, TRUE, EMPTY); -DEFINE_SQUARE (long, TRUE, EMPTY); -DEFINE_SQUARE (ulong, TRUE, EMPTY); -DEFINE_SQUARE (int64, TRUE, EMPTY); -DEFINE_SQUARE (uint64, TRUE, gst_guint64_to_gdouble); -DEFINE_SQUARE (float, FALSE, EMPTY); -DEFINE_SQUARE (double, FALSE, EMPTY); +static gboolean +waveform_sine_get_value_array (GstLFOControlSource * self, + GstClockTime timestamp, GstClockTime interval, guint n_values, + gdouble * values) +{ + GstLFOControlSourcePrivate *priv = self->priv; + guint i; + GstClockTime ts = timestamp; + gdouble amp, off, frequency; + GstClockTime timeshift, period; -static GstWaveformImplementation waveform_square = { - (GstControlSourceGetValue) waveform_square_get_int, - (GstControlSourceGetValueArray) waveform_square_get_int_value_array, - (GstControlSourceGetValue) waveform_square_get_uint, - (GstControlSourceGetValueArray) waveform_square_get_uint_value_array, - (GstControlSourceGetValue) waveform_square_get_long, - (GstControlSourceGetValueArray) waveform_square_get_long_value_array, - (GstControlSourceGetValue) waveform_square_get_ulong, - (GstControlSourceGetValueArray) waveform_square_get_ulong_value_array, - (GstControlSourceGetValue) waveform_square_get_int64, - (GstControlSourceGetValueArray) waveform_square_get_int64_value_array, - (GstControlSourceGetValue) waveform_square_get_uint64, - (GstControlSourceGetValueArray) waveform_square_get_uint64_value_array, - (GstControlSourceGetValue) waveform_square_get_float, - (GstControlSourceGetValueArray) waveform_square_get_float_value_array, - (GstControlSourceGetValue) waveform_square_get_double, - (GstControlSourceGetValueArray) waveform_square_get_double_value_array -}; + g_mutex_lock (self->lock); + amp = priv->amplitude; + off = priv->offset; + timeshift = priv->timeshift; + period = priv->period; + frequency = priv->frequency; -#define DEFINE_SAW(type,round,convert) \ -\ -static inline g##type \ -_saw_get_##type (GstLFOControlSource *self, g##type max, g##type min, gdouble amp, gdouble off, GstClockTime timeshift, GstClockTime period, gdouble frequency, GstClockTime timestamp) \ -{ \ - GstClockTime pos = _calculate_pos (timestamp, timeshift, period); \ - gdouble ret; \ - \ - ret = - ((gst_guint64_to_gdouble (pos) - gst_guint64_to_gdouble (period) / 2.0) * ((2.0 * amp) / gst_guint64_to_gdouble (period)));\ - \ - ret += off; \ - \ - if (round) \ - ret += 0.5; \ - \ - return (g##type) CLAMP (ret, convert (min), convert (max)); \ -} \ -\ -static gboolean \ -waveform_saw_get_##type (GstLFOControlSource *self, GstClockTime timestamp, \ - GValue *value) \ -{ \ - g##type ret, max, min; \ - gdouble amp, off, frequency; \ - GstClockTime timeshift, period; \ - \ - g_mutex_lock (self->lock); \ - max = g_value_get_##type (&self->priv->maximum_value); \ - min = g_value_get_##type (&self->priv->minimum_value); \ - amp = convert (g_value_get_##type (&self->priv->amplitude)); \ - off = convert (g_value_get_##type (&self->priv->offset)); \ - timeshift = self->priv->timeshift; \ - period = self->priv->period; \ - frequency = self->priv->frequency; \ - \ - ret = _saw_get_##type (self, max, min, amp, off, timeshift, period, frequency, timestamp); \ - g_value_set_##type (value, ret); \ - g_mutex_unlock (self->lock); \ - return TRUE; \ -} \ -\ -static gboolean \ -waveform_saw_get_##type##_value_array (GstLFOControlSource *self, \ - GstClockTime timestamp, GstClockTime interval, guint n_values, gpointer *_values) \ -{ \ - guint i; \ - GstClockTime ts = timestamp; \ - g##type *values = (g##type *) _values; \ - g##type max, min; \ - gdouble amp, off, frequency; \ - GstClockTime timeshift, period; \ - \ - g_mutex_lock (self->lock); \ - max = g_value_get_##type (&self->priv->maximum_value); \ - min = g_value_get_##type (&self->priv->minimum_value); \ - amp = convert (g_value_get_##type (&self->priv->amplitude)); \ - off = convert (g_value_get_##type (&self->priv->offset)); \ - timeshift = self->priv->timeshift; \ - period = self->priv->period; \ - frequency = self->priv->frequency; \ - \ - for(i = 0; i < n_values; i++) { \ - *values = _saw_get_##type (self, max, min, amp, off, timeshift, period, frequency, ts); \ - ts += interval; \ - values++; \ - } \ - g_mutex_unlock (self->lock); \ - return TRUE; \ + for (i = 0; i < n_values; i++) { + *values = _sine_get (self, amp, off, timeshift, period, frequency, ts); + ts += interval; + values++; + } + g_mutex_unlock (self->lock); + return TRUE; } -DEFINE_SAW (int, TRUE, EMPTY); -DEFINE_SAW (uint, TRUE, EMPTY); -DEFINE_SAW (long, TRUE, EMPTY); -DEFINE_SAW (ulong, TRUE, EMPTY); -DEFINE_SAW (int64, TRUE, EMPTY); -DEFINE_SAW (uint64, TRUE, gst_guint64_to_gdouble); -DEFINE_SAW (float, FALSE, EMPTY); -DEFINE_SAW (double, FALSE, EMPTY); -static GstWaveformImplementation waveform_saw = { - (GstControlSourceGetValue) waveform_saw_get_int, - (GstControlSourceGetValueArray) waveform_saw_get_int_value_array, - (GstControlSourceGetValue) waveform_saw_get_uint, - (GstControlSourceGetValueArray) waveform_saw_get_uint_value_array, - (GstControlSourceGetValue) waveform_saw_get_long, - (GstControlSourceGetValueArray) waveform_saw_get_long_value_array, - (GstControlSourceGetValue) waveform_saw_get_ulong, - (GstControlSourceGetValueArray) waveform_saw_get_ulong_value_array, - (GstControlSourceGetValue) waveform_saw_get_int64, - (GstControlSourceGetValueArray) waveform_saw_get_int64_value_array, - (GstControlSourceGetValue) waveform_saw_get_uint64, - (GstControlSourceGetValueArray) waveform_saw_get_uint64_value_array, - (GstControlSourceGetValue) waveform_saw_get_float, - (GstControlSourceGetValueArray) waveform_saw_get_float_value_array, - (GstControlSourceGetValue) waveform_saw_get_double, - (GstControlSourceGetValueArray) waveform_saw_get_double_value_array -}; +static inline gdouble +_square_get (GstLFOControlSource * self, gdouble amp, gdouble off, + GstClockTime timeshift, GstClockTime period, gdouble frequency, + GstClockTime timestamp) +{ + GstClockTime pos = _calculate_pos (timestamp, timeshift, period); + gdouble ret; -#define DEFINE_RSAW(type,round,convert) \ -\ -static inline g##type \ -_rsaw_get_##type (GstLFOControlSource *self, g##type max, g##type min, gdouble amp, gdouble off, GstClockTime timeshift, GstClockTime period, gdouble frequency, GstClockTime timestamp) \ -{ \ - GstClockTime pos = _calculate_pos (timestamp, timeshift, period); \ - gdouble ret; \ - \ - ret = ((gst_guint64_to_gdouble (pos) - gst_guint64_to_gdouble (period) / 2.0) * ((2.0 * amp) / gst_guint64_to_gdouble (period)));\ - \ - ret += off; \ - \ - if (round) \ - ret += 0.5; \ - \ - return (g##type) CLAMP (ret, convert (min), convert (max)); \ -} \ -\ -static gboolean \ -waveform_rsaw_get_##type (GstLFOControlSource *self, GstClockTime timestamp, \ - GValue *value) \ -{ \ - g##type ret, max, min; \ - gdouble amp, off, frequency; \ - GstClockTime timeshift, period; \ - \ - g_mutex_lock (self->lock); \ - max = g_value_get_##type (&self->priv->maximum_value); \ - min = g_value_get_##type (&self->priv->minimum_value); \ - amp = convert (g_value_get_##type (&self->priv->amplitude)); \ - off = convert (g_value_get_##type (&self->priv->offset)); \ - timeshift = self->priv->timeshift; \ - period = self->priv->period; \ - frequency = self->priv->frequency; \ - \ - ret = _rsaw_get_##type (self, max, min, amp, off, timeshift, period, frequency, timestamp); \ - g_value_set_##type (value, ret); \ - g_mutex_unlock (self->lock); \ - return TRUE; \ -} \ -\ -static gboolean \ -waveform_rsaw_get_##type##_value_array (GstLFOControlSource *self, \ - GstClockTime timestamp, GstClockTime interval, guint n_values, gpointer *_values) \ -{ \ - guint i; \ - GstClockTime ts = timestamp; \ - g##type *values = (g##type *) _values; \ - g##type max, min; \ - gdouble amp, off, frequency; \ - GstClockTime timeshift, period; \ - \ - g_mutex_lock (self->lock); \ - max = g_value_get_##type (&self->priv->maximum_value); \ - min = g_value_get_##type (&self->priv->minimum_value); \ - amp = convert (g_value_get_##type (&self->priv->amplitude)); \ - off = convert (g_value_get_##type (&self->priv->offset)); \ - timeshift = self->priv->timeshift; \ - period = self->priv->period; \ - frequency = self->priv->frequency; \ - \ - for(i = 0; i < n_values; i++) { \ - *values = _rsaw_get_##type (self, max, min, amp, off, timeshift, period, frequency, ts); \ - ts += interval; \ - values++; \ - } \ - g_mutex_unlock (self->lock); \ - return TRUE; \ + if (pos >= period / 2) + ret = amp; + else + ret = -amp; + ret += off; + + return ret; } -DEFINE_RSAW (int, TRUE, EMPTY); -DEFINE_RSAW (uint, TRUE, EMPTY); -DEFINE_RSAW (long, TRUE, EMPTY); -DEFINE_RSAW (ulong, TRUE, EMPTY); -DEFINE_RSAW (int64, TRUE, EMPTY); -DEFINE_RSAW (uint64, TRUE, gst_guint64_to_gdouble); -DEFINE_RSAW (float, FALSE, EMPTY); -DEFINE_RSAW (double, FALSE, EMPTY); +static gboolean +waveform_square_get (GstLFOControlSource * self, GstClockTime timestamp, + gdouble * value) +{ + GstLFOControlSourcePrivate *priv = self->priv; + gdouble amp, off, frequency; + GstClockTime timeshift, period; -static GstWaveformImplementation waveform_rsaw = { - (GstControlSourceGetValue) waveform_rsaw_get_int, - (GstControlSourceGetValueArray) waveform_rsaw_get_int_value_array, - (GstControlSourceGetValue) waveform_rsaw_get_uint, - (GstControlSourceGetValueArray) waveform_rsaw_get_uint_value_array, - (GstControlSourceGetValue) waveform_rsaw_get_long, - (GstControlSourceGetValueArray) waveform_rsaw_get_long_value_array, - (GstControlSourceGetValue) waveform_rsaw_get_ulong, - (GstControlSourceGetValueArray) waveform_rsaw_get_ulong_value_array, - (GstControlSourceGetValue) waveform_rsaw_get_int64, - (GstControlSourceGetValueArray) waveform_rsaw_get_int64_value_array, - (GstControlSourceGetValue) waveform_rsaw_get_uint64, - (GstControlSourceGetValueArray) waveform_rsaw_get_uint64_value_array, - (GstControlSourceGetValue) waveform_rsaw_get_float, - (GstControlSourceGetValueArray) waveform_rsaw_get_float_value_array, - (GstControlSourceGetValue) waveform_rsaw_get_double, - (GstControlSourceGetValueArray) waveform_rsaw_get_double_value_array -}; + g_mutex_lock (self->lock); + amp = priv->amplitude; + off = priv->offset; + timeshift = priv->timeshift; + period = priv->period; + frequency = priv->frequency; -#define DEFINE_TRIANGLE(type,round,convert) \ -\ -static inline g##type \ -_triangle_get_##type (GstLFOControlSource *self, g##type max, g##type min, gdouble amp, gdouble off, GstClockTime timeshift, GstClockTime period, gdouble frequency, GstClockTime timestamp) \ -{ \ - GstClockTime pos = _calculate_pos (timestamp, timeshift, period); \ - gdouble ret; \ - \ - if (gst_guint64_to_gdouble (pos) <= gst_guint64_to_gdouble (period) / 4.0) \ - ret = gst_guint64_to_gdouble (pos) * ((4.0 * amp) / gst_guint64_to_gdouble (period)); \ - else if (gst_guint64_to_gdouble (pos) <= (3.0 * gst_guint64_to_gdouble (period)) / 4.0) \ - ret = -(gst_guint64_to_gdouble (pos) - gst_guint64_to_gdouble (period) / 2.0) * ((4.0 * amp) / gst_guint64_to_gdouble (period)); \ - else \ - ret = gst_guint64_to_gdouble (period) - gst_guint64_to_gdouble (pos) * ((4.0 * amp) / gst_guint64_to_gdouble (period)); \ - \ - ret += off; \ - \ - if (round) \ - ret += 0.5; \ - \ - return (g##type) CLAMP (ret, convert (min), convert (max)); \ -} \ -\ -static gboolean \ -waveform_triangle_get_##type (GstLFOControlSource *self, GstClockTime timestamp, \ - GValue *value) \ -{ \ - g##type ret, max, min; \ - gdouble amp, off, frequency; \ - GstClockTime timeshift, period; \ - \ - g_mutex_lock (self->lock); \ - max = g_value_get_##type (&self->priv->maximum_value); \ - min = g_value_get_##type (&self->priv->minimum_value); \ - amp = convert (g_value_get_##type (&self->priv->amplitude)); \ - off = convert (g_value_get_##type (&self->priv->offset)); \ - timeshift = self->priv->timeshift; \ - period = self->priv->period; \ - frequency = self->priv->frequency; \ - \ - ret = _triangle_get_##type (self, max, min, amp, off, timeshift, period, frequency, timestamp); \ - g_value_set_##type (value, ret); \ - g_mutex_unlock (self->lock); \ - return TRUE; \ -} \ -\ -static gboolean \ -waveform_triangle_get_##type##_value_array (GstLFOControlSource *self, \ - GstClockTime timestamp, GstClockTime interval, guint n_values, gpointer *_values) \ -{ \ - guint i; \ - GstClockTime ts = timestamp; \ - g##type *values = (g##type *) _values; \ - g##type max, min; \ - gdouble amp, off, frequency; \ - GstClockTime timeshift, period; \ - \ - g_mutex_lock (self->lock); \ - max = g_value_get_##type (&self->priv->maximum_value); \ - min = g_value_get_##type (&self->priv->minimum_value); \ - amp = convert (g_value_get_##type (&self->priv->amplitude)); \ - off = convert (g_value_get_##type (&self->priv->offset)); \ - timeshift = self->priv->timeshift; \ - period = self->priv->period; \ - frequency = self->priv->frequency; \ - \ - for(i = 0; i < n_values; i++) { \ - *values = _triangle_get_##type (self, max, min, amp, off, timeshift, period, frequency, ts); \ - ts += interval; \ - values++; \ - } \ - g_mutex_unlock (self->lock); \ - return TRUE; \ + *value = + _square_get (self, amp, off, timeshift, period, frequency, timestamp); + g_mutex_unlock (self->lock); + return TRUE; } -DEFINE_TRIANGLE (int, TRUE, EMPTY); -DEFINE_TRIANGLE (uint, TRUE, EMPTY); -DEFINE_TRIANGLE (long, TRUE, EMPTY); -DEFINE_TRIANGLE (ulong, TRUE, EMPTY); -DEFINE_TRIANGLE (int64, TRUE, EMPTY); -DEFINE_TRIANGLE (uint64, TRUE, gst_guint64_to_gdouble); -DEFINE_TRIANGLE (float, FALSE, EMPTY); -DEFINE_TRIANGLE (double, FALSE, EMPTY); +static gboolean +waveform_square_get_value_array (GstLFOControlSource * self, + GstClockTime timestamp, GstClockTime interval, guint n_values, + gdouble * values) +{ + GstLFOControlSourcePrivate *priv = self->priv; + guint i; + GstClockTime ts = timestamp; + gdouble amp, off, frequency; + GstClockTime timeshift, period; -static GstWaveformImplementation waveform_triangle = { - (GstControlSourceGetValue) waveform_triangle_get_int, - (GstControlSourceGetValueArray) waveform_triangle_get_int_value_array, - (GstControlSourceGetValue) waveform_triangle_get_uint, - (GstControlSourceGetValueArray) waveform_triangle_get_uint_value_array, - (GstControlSourceGetValue) waveform_triangle_get_long, - (GstControlSourceGetValueArray) waveform_triangle_get_long_value_array, - (GstControlSourceGetValue) waveform_triangle_get_ulong, - (GstControlSourceGetValueArray) waveform_triangle_get_ulong_value_array, - (GstControlSourceGetValue) waveform_triangle_get_int64, - (GstControlSourceGetValueArray) waveform_triangle_get_int64_value_array, - (GstControlSourceGetValue) waveform_triangle_get_uint64, - (GstControlSourceGetValueArray) waveform_triangle_get_uint64_value_array, - (GstControlSourceGetValue) waveform_triangle_get_float, - (GstControlSourceGetValueArray) waveform_triangle_get_float_value_array, - (GstControlSourceGetValue) waveform_triangle_get_double, - (GstControlSourceGetValueArray) waveform_triangle_get_double_value_array -}; + g_mutex_lock (self->lock); + amp = priv->amplitude; + off = priv->offset; + timeshift = priv->timeshift; + period = priv->period; + frequency = priv->frequency; -static GstWaveformImplementation *waveforms[] = { - &waveform_sine, - &waveform_square, - &waveform_saw, - &waveform_rsaw, - &waveform_triangle + for (i = 0; i < n_values; i++) { + *values = _square_get (self, amp, off, timeshift, period, frequency, ts); + ts += interval; + values++; + } + g_mutex_unlock (self->lock); + return TRUE; +} + +static inline gdouble +_saw_get (GstLFOControlSource * self, gdouble amp, gdouble off, + GstClockTime timeshift, GstClockTime period, gdouble frequency, + GstClockTime timestamp) +{ + GstClockTime pos = _calculate_pos (timestamp, timeshift, period); + gdouble ret; + + ret = + -((gst_guint64_to_gdouble (pos) - + gst_guint64_to_gdouble (period) / 2.0) * ((2.0 * amp) / + gst_guint64_to_gdouble (period))); + ret += off; + + return ret; +} + +static gboolean +waveform_saw_get (GstLFOControlSource * self, GstClockTime timestamp, + gdouble * value) +{ + GstLFOControlSourcePrivate *priv = self->priv; + gdouble amp, off, frequency; + GstClockTime timeshift, period; + + g_mutex_lock (self->lock); + amp = priv->amplitude; + off = priv->offset; + timeshift = priv->timeshift; + period = priv->period; + frequency = priv->frequency; + + *value = _saw_get (self, amp, off, timeshift, period, frequency, timestamp); + g_mutex_unlock (self->lock); + return TRUE; +} + +static gboolean +waveform_saw_get_value_array (GstLFOControlSource * self, + GstClockTime timestamp, GstClockTime interval, guint n_values, + gdouble * values) +{ + GstLFOControlSourcePrivate *priv = self->priv; + guint i; + GstClockTime ts = timestamp; + gdouble amp, off, frequency; + GstClockTime timeshift, period; + + g_mutex_lock (self->lock); + amp = priv->amplitude; + off = priv->offset; + timeshift = priv->timeshift; + period = priv->period; + frequency = priv->frequency; + + for (i = 0; i < n_values; i++) { + *values = _saw_get (self, amp, off, timeshift, period, frequency, ts); + ts += interval; + values++; + } + g_mutex_unlock (self->lock); + return TRUE; +} + +static inline gdouble +_rsaw_get (GstLFOControlSource * self, gdouble amp, gdouble off, + GstClockTime timeshift, GstClockTime period, gdouble frequency, + GstClockTime timestamp) +{ + GstClockTime pos = _calculate_pos (timestamp, timeshift, period); + gdouble ret; + + ret = + ((gst_guint64_to_gdouble (pos) - + gst_guint64_to_gdouble (period) / 2.0) * ((2.0 * amp) / + gst_guint64_to_gdouble (period))); + ret += off; + + return ret; +} + +static gboolean +waveform_rsaw_get (GstLFOControlSource * self, GstClockTime timestamp, + gdouble * value) +{ + GstLFOControlSourcePrivate *priv = self->priv; + gdouble amp, off, frequency; + GstClockTime timeshift, period; + + g_mutex_lock (self->lock); + amp = priv->amplitude; + off = priv->offset; + timeshift = priv->timeshift; + period = priv->period; + frequency = priv->frequency; + + *value = _rsaw_get (self, amp, off, timeshift, period, frequency, timestamp); + g_mutex_unlock (self->lock); + return TRUE; +} + +static gboolean +waveform_rsaw_get_value_array (GstLFOControlSource * self, + GstClockTime timestamp, GstClockTime interval, guint n_values, + gdouble * values) +{ + GstLFOControlSourcePrivate *priv = self->priv; + guint i; + GstClockTime ts = timestamp; + gdouble amp, off, frequency; + GstClockTime timeshift, period; + + g_mutex_lock (self->lock); + amp = priv->amplitude; + off = priv->offset; + timeshift = priv->timeshift; + period = priv->period; + frequency = priv->frequency; + + for (i = 0; i < n_values; i++) { + *values = _rsaw_get (self, amp, off, timeshift, period, frequency, ts); + ts += interval; + values++; + } + g_mutex_unlock (self->lock); + return TRUE; +} + + +static inline gdouble +_triangle_get (GstLFOControlSource * self, gdouble amp, gdouble off, + GstClockTime timeshift, GstClockTime period, gdouble frequency, + GstClockTime timestamp) +{ + GstClockTime pos = _calculate_pos (timestamp, timeshift, period); + gdouble ret; + + if (gst_guint64_to_gdouble (pos) <= gst_guint64_to_gdouble (period) / 4.0) + ret = + gst_guint64_to_gdouble (pos) * ((4.0 * amp) / + gst_guint64_to_gdouble (period)); + else if (gst_guint64_to_gdouble (pos) <= + (3.0 * gst_guint64_to_gdouble (period)) / 4.0) + ret = + -(gst_guint64_to_gdouble (pos) - + gst_guint64_to_gdouble (period) / 2.0) * ((4.0 * amp) / + gst_guint64_to_gdouble (period)); + else + ret = + gst_guint64_to_gdouble (period) - + gst_guint64_to_gdouble (pos) * ((4.0 * amp) / + gst_guint64_to_gdouble (period)); + + ret += off; + + return ret; +} + +static gboolean +waveform_triangle_get (GstLFOControlSource * self, GstClockTime timestamp, + gdouble * value) +{ + GstLFOControlSourcePrivate *priv = self->priv; + gdouble amp, off, frequency; + GstClockTime timeshift, period; + + g_mutex_lock (self->lock); + amp = priv->amplitude; + off = priv->offset; + timeshift = priv->timeshift; + period = priv->period; + frequency = priv->frequency; + + *value = + _triangle_get (self, amp, off, timeshift, period, frequency, timestamp); + g_mutex_unlock (self->lock); + return TRUE; +} + +static gboolean +waveform_triangle_get_value_array (GstLFOControlSource * self, + GstClockTime timestamp, GstClockTime interval, guint n_values, + gdouble * values) +{ + GstLFOControlSourcePrivate *priv = self->priv; + guint i; + GstClockTime ts = timestamp; + gdouble amp, off, frequency; + GstClockTime timeshift, period; + + g_mutex_lock (self->lock); + amp = priv->amplitude; + off = priv->offset; + timeshift = priv->timeshift; + period = priv->period; + frequency = priv->frequency; + + for (i = 0; i < n_values; i++) { + *values = _triangle_get (self, amp, off, timeshift, period, frequency, ts); + ts += interval; + values++; + } + g_mutex_unlock (self->lock); + return TRUE; +} + +static struct +{ + GstControlSourceGetValue get; + GstControlSourceGetValueArray get_value_array; +} waveforms[] = { + { + (GstControlSourceGetValue) waveform_sine_get, + (GstControlSourceGetValueArray) waveform_sine_get_value_array}, { + (GstControlSourceGetValue) waveform_square_get, + (GstControlSourceGetValueArray) waveform_square_get_value_array}, { + (GstControlSourceGetValue) waveform_saw_get, + (GstControlSourceGetValueArray) waveform_saw_get_value_array}, { + (GstControlSourceGetValue) waveform_rsaw_get, + (GstControlSourceGetValueArray) waveform_rsaw_get_value_array}, { + (GstControlSourceGetValue) waveform_triangle_get, + (GstControlSourceGetValueArray) waveform_triangle_get_value_array} }; static const guint num_waveforms = G_N_ELEMENTS (waveforms); @@ -622,18 +477,6 @@ gst_lfo_control_source_reset (GstLFOControlSource * self) csource->get_value = NULL; csource->get_value_array = NULL; - - self->priv->type = self->priv->base = G_TYPE_INVALID; - - if (G_IS_VALUE (&self->priv->minimum_value)) - g_value_unset (&self->priv->minimum_value); - if (G_IS_VALUE (&self->priv->maximum_value)) - g_value_unset (&self->priv->maximum_value); - - if (G_IS_VALUE (&self->priv->amplitude)) - g_value_unset (&self->priv->amplitude); - if (G_IS_VALUE (&self->priv->offset)) - g_value_unset (&self->priv->offset); } /** @@ -654,282 +497,18 @@ gst_lfo_control_source_set_waveform (GstLFOControlSource * self, GstLFOWaveform waveform) { GstControlSource *csource = GST_CONTROL_SOURCE (self); - gboolean ret = TRUE; if (waveform >= num_waveforms || (int) waveform < 0) { GST_WARNING ("waveform %d invalid or not implemented yet", waveform); return FALSE; } - if (self->priv->base == G_TYPE_INVALID) { - GST_WARNING ("not bound to a property yet"); - return FALSE; - } + csource->get_value = waveforms[waveform].get; + csource->get_value_array = waveforms[waveform].get_value_array; - switch (self->priv->base) { - case G_TYPE_INT: - csource->get_value = waveforms[waveform]->get_int; - csource->get_value_array = waveforms[waveform]->get_int_value_array; - break; - case G_TYPE_UINT:{ - csource->get_value = waveforms[waveform]->get_uint; - csource->get_value_array = waveforms[waveform]->get_uint_value_array; - break; - } - case G_TYPE_LONG:{ - csource->get_value = waveforms[waveform]->get_long; - csource->get_value_array = waveforms[waveform]->get_long_value_array; - break; - } - case G_TYPE_ULONG:{ - csource->get_value = waveforms[waveform]->get_ulong; - csource->get_value_array = waveforms[waveform]->get_ulong_value_array; - break; - } - case G_TYPE_INT64:{ - csource->get_value = waveforms[waveform]->get_int64; - csource->get_value_array = waveforms[waveform]->get_int64_value_array; - break; - } - case G_TYPE_UINT64:{ - csource->get_value = waveforms[waveform]->get_uint64; - csource->get_value_array = waveforms[waveform]->get_uint64_value_array; - break; - } - case G_TYPE_FLOAT:{ - csource->get_value = waveforms[waveform]->get_float; - csource->get_value_array = waveforms[waveform]->get_float_value_array; - break; - } - case G_TYPE_DOUBLE:{ - csource->get_value = waveforms[waveform]->get_double; - csource->get_value_array = waveforms[waveform]->get_double_value_array; - break; - } - default: - ret = FALSE; - break; - } + self->priv->waveform = waveform; - if (ret) - self->priv->waveform = waveform; - else - GST_WARNING ("incomplete implementation for type '%s'", - GST_STR_NULL (g_type_name (self->priv->type))); - - return ret; -} - -static gboolean -gst_lfo_control_source_bind (GstControlSource * source, GParamSpec * pspec) -{ - GType type, base; - GstLFOControlSource *self = GST_LFO_CONTROL_SOURCE (source); - gboolean ret = TRUE; - - /* get the fundamental base type */ - self->priv->type = base = type = G_PARAM_SPEC_VALUE_TYPE (pspec); - while ((type = g_type_parent (type))) - base = type; - - self->priv->base = base; - /* restore type */ - type = self->priv->type; - - switch (base) { - case G_TYPE_INT:{ - GParamSpecInt *tpspec = G_PARAM_SPEC_INT (pspec); - - g_value_init (&self->priv->minimum_value, type); - g_value_set_int (&self->priv->minimum_value, tpspec->minimum); - g_value_init (&self->priv->maximum_value, type); - g_value_set_int (&self->priv->maximum_value, tpspec->maximum); - - if (!G_IS_VALUE (&self->priv->amplitude)) { - g_value_init (&self->priv->amplitude, type); - g_value_set_int (&self->priv->amplitude, 0); - } - - if (!G_IS_VALUE (&self->priv->offset)) { - g_value_init (&self->priv->offset, type); - g_value_set_int (&self->priv->offset, tpspec->default_value); - } - break; - } - case G_TYPE_UINT:{ - GParamSpecUInt *tpspec = G_PARAM_SPEC_UINT (pspec); - - g_value_init (&self->priv->minimum_value, type); - g_value_set_uint (&self->priv->minimum_value, tpspec->minimum); - g_value_init (&self->priv->maximum_value, type); - g_value_set_uint (&self->priv->maximum_value, tpspec->maximum); - - if (!G_IS_VALUE (&self->priv->amplitude)) { - g_value_init (&self->priv->amplitude, type); - g_value_set_uint (&self->priv->amplitude, 0); - } - - if (!G_IS_VALUE (&self->priv->offset)) { - g_value_init (&self->priv->offset, type); - g_value_set_uint (&self->priv->offset, tpspec->default_value); - } - break; - } - case G_TYPE_LONG:{ - GParamSpecLong *tpspec = G_PARAM_SPEC_LONG (pspec); - - g_value_init (&self->priv->minimum_value, type); - g_value_set_long (&self->priv->minimum_value, tpspec->minimum); - g_value_init (&self->priv->maximum_value, type); - g_value_set_long (&self->priv->maximum_value, tpspec->maximum); - if (!G_IS_VALUE (&self->priv->amplitude)) { - g_value_init (&self->priv->amplitude, type); - g_value_set_long (&self->priv->amplitude, 0); - } - - if (!G_IS_VALUE (&self->priv->offset)) { - g_value_init (&self->priv->offset, type); - g_value_set_long (&self->priv->offset, tpspec->default_value); - } - break; - } - case G_TYPE_ULONG:{ - GParamSpecULong *tpspec = G_PARAM_SPEC_ULONG (pspec); - - g_value_init (&self->priv->minimum_value, type); - g_value_set_ulong (&self->priv->minimum_value, tpspec->minimum); - g_value_init (&self->priv->maximum_value, type); - g_value_set_ulong (&self->priv->maximum_value, tpspec->maximum); - if (!G_IS_VALUE (&self->priv->amplitude)) { - g_value_init (&self->priv->amplitude, type); - g_value_set_ulong (&self->priv->amplitude, 0); - } - - if (!G_IS_VALUE (&self->priv->offset)) { - g_value_init (&self->priv->offset, type); - g_value_set_ulong (&self->priv->offset, tpspec->default_value); - } - break; - } - case G_TYPE_INT64:{ - GParamSpecInt64 *tpspec = G_PARAM_SPEC_INT64 (pspec); - - g_value_init (&self->priv->minimum_value, type); - g_value_set_int64 (&self->priv->minimum_value, tpspec->minimum); - g_value_init (&self->priv->maximum_value, type); - g_value_set_int64 (&self->priv->maximum_value, tpspec->maximum); - if (!G_IS_VALUE (&self->priv->amplitude)) { - g_value_init (&self->priv->amplitude, type); - g_value_set_int64 (&self->priv->amplitude, 0); - } - - if (!G_IS_VALUE (&self->priv->offset)) { - g_value_init (&self->priv->offset, type); - g_value_set_int64 (&self->priv->offset, tpspec->default_value); - } - break; - } - case G_TYPE_UINT64:{ - GParamSpecUInt64 *tpspec = G_PARAM_SPEC_UINT64 (pspec); - - g_value_init (&self->priv->minimum_value, type); - g_value_set_uint64 (&self->priv->minimum_value, tpspec->minimum); - g_value_init (&self->priv->maximum_value, type); - g_value_set_uint64 (&self->priv->maximum_value, tpspec->maximum); - if (!G_IS_VALUE (&self->priv->amplitude)) { - g_value_init (&self->priv->amplitude, type); - g_value_set_uint64 (&self->priv->amplitude, 0); - } - - if (!G_IS_VALUE (&self->priv->offset)) { - g_value_init (&self->priv->offset, type); - g_value_set_uint64 (&self->priv->offset, tpspec->default_value); - } - break; - } - case G_TYPE_FLOAT:{ - GParamSpecFloat *tpspec = G_PARAM_SPEC_FLOAT (pspec); - - g_value_init (&self->priv->minimum_value, type); - g_value_set_float (&self->priv->minimum_value, tpspec->minimum); - g_value_init (&self->priv->maximum_value, type); - g_value_set_float (&self->priv->maximum_value, tpspec->maximum); - if (!G_IS_VALUE (&self->priv->amplitude)) { - g_value_init (&self->priv->amplitude, type); - g_value_set_float (&self->priv->amplitude, 0.0); - } - - if (!G_IS_VALUE (&self->priv->offset)) { - g_value_init (&self->priv->offset, type); - g_value_set_float (&self->priv->offset, tpspec->default_value); - } - break; - } - case G_TYPE_DOUBLE:{ - GParamSpecDouble *tpspec = G_PARAM_SPEC_DOUBLE (pspec); - - g_value_init (&self->priv->minimum_value, type); - g_value_set_double (&self->priv->minimum_value, tpspec->minimum); - g_value_init (&self->priv->maximum_value, type); - g_value_set_double (&self->priv->maximum_value, tpspec->maximum); - if (!G_IS_VALUE (&self->priv->amplitude)) { - g_value_init (&self->priv->amplitude, type); - g_value_set_double (&self->priv->amplitude, 0.0); - } - - if (!G_IS_VALUE (&self->priv->offset)) { - g_value_init (&self->priv->offset, type); - g_value_set_double (&self->priv->offset, tpspec->default_value); - } - break; - } - default: - GST_WARNING ("incomplete implementation for paramspec type '%s'", - G_PARAM_SPEC_TYPE_NAME (pspec)); - ret = FALSE; - break; - } - - if (ret) { - GValue amp = { 0, } - , off = { - 0,}; - - /* This should never fail unless the user already set amplitude or offset - * with an incompatible type before _bind () */ - if (!g_value_type_transformable (G_VALUE_TYPE (&self->priv->amplitude), - base) - || !g_value_type_transformable (G_VALUE_TYPE (&self->priv->offset), - base)) { - GST_WARNING ("incompatible types for amplitude or offset"); - gst_lfo_control_source_reset (self); - return FALSE; - } - - /* Generate copies and transform to the correct type */ - g_value_init (&, base); - g_value_transform (&self->priv->amplitude, &); - g_value_init (&off, base); - g_value_transform (&self->priv->offset, &off); - - ret = gst_lfo_control_source_set_waveform (self, self->priv->waveform); - - g_value_unset (&self->priv->amplitude); - g_value_init (&self->priv->amplitude, self->priv->base); - g_value_transform (&, &self->priv->amplitude); - - g_value_unset (&self->priv->offset); - g_value_init (&self->priv->offset, self->priv->base); - g_value_transform (&off, &self->priv->offset); - - g_value_unset (&); - g_value_unset (&off); - } - - if (!ret) - gst_lfo_control_source_reset (self); - - return ret; + return TRUE; } static void @@ -938,7 +517,8 @@ gst_lfo_control_source_init (GstLFOControlSource * self) self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GST_TYPE_LFO_CONTROL_SOURCE, GstLFOControlSourcePrivate); - self->priv->waveform = GST_LFO_WAVEFORM_SINE; + self->priv->waveform = gst_lfo_control_source_set_waveform (self, + GST_LFO_WAVEFORM_SINE); self->priv->frequency = 1.0; self->priv->period = GST_SECOND / self->priv->frequency; self->priv->timeshift = 0; @@ -987,58 +567,16 @@ gst_lfo_control_source_set_property (GObject * object, guint prop_id, self->priv->timeshift = g_value_get_uint64 (value); g_mutex_unlock (self->lock); break; - case PROP_AMPLITUDE:{ - GValue *val = g_value_get_boxed (value); - - if (self->priv->type != G_TYPE_INVALID) { - g_return_if_fail (g_value_type_transformable (self->priv->type, - G_VALUE_TYPE (val))); - - g_mutex_lock (self->lock); - if (G_IS_VALUE (&self->priv->amplitude)) - g_value_unset (&self->priv->amplitude); - - g_value_init (&self->priv->amplitude, self->priv->type); - g_value_transform (val, &self->priv->amplitude); - g_mutex_unlock (self->lock); - } else { - g_mutex_lock (self->lock); - if (G_IS_VALUE (&self->priv->amplitude)) - g_value_unset (&self->priv->amplitude); - - g_value_init (&self->priv->amplitude, G_VALUE_TYPE (val)); - g_value_copy (val, &self->priv->amplitude); - g_mutex_unlock (self->lock); - } - + case PROP_AMPLITUDE: + g_mutex_lock (self->lock); + self->priv->amplitude = g_value_get_double (value); + g_mutex_unlock (self->lock); break; - } - case PROP_OFFSET:{ - GValue *val = g_value_get_boxed (value); - - if (self->priv->type != G_TYPE_INVALID) { - g_return_if_fail (g_value_type_transformable (self->priv->type, - G_VALUE_TYPE (val))); - - g_mutex_lock (self->lock); - if (G_IS_VALUE (&self->priv->offset)) - g_value_unset (&self->priv->offset); - - g_value_init (&self->priv->offset, self->priv->type); - g_value_transform (val, &self->priv->offset); - g_mutex_unlock (self->lock); - } else { - g_mutex_lock (self->lock); - if (G_IS_VALUE (&self->priv->offset)) - g_value_unset (&self->priv->offset); - - g_value_init (&self->priv->offset, G_VALUE_TYPE (val)); - g_value_copy (val, &self->priv->offset); - g_mutex_unlock (self->lock); - } - + case PROP_OFFSET: + g_mutex_lock (self->lock); + self->priv->offset = g_value_get_double (value); + g_mutex_unlock (self->lock); break; - } default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1062,10 +600,10 @@ gst_lfo_control_source_get_property (GObject * object, guint prop_id, g_value_set_uint64 (value, self->priv->timeshift); break; case PROP_AMPLITUDE: - g_value_set_boxed (value, &self->priv->amplitude); + g_value_set_double (value, self->priv->amplitude); break; case PROP_OFFSET: - g_value_set_boxed (value, &self->priv->offset); + g_value_set_double (value, self->priv->offset); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -1077,7 +615,6 @@ static void gst_lfo_control_source_class_init (GstLFOControlSourceClass * klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GstControlSourceClass *csource_class = GST_CONTROL_SOURCE_CLASS (klass); g_type_class_add_private (klass, sizeof (GstLFOControlSourcePrivate)); @@ -1085,14 +622,11 @@ gst_lfo_control_source_class_init (GstLFOControlSourceClass * klass) gobject_class->set_property = gst_lfo_control_source_set_property; gobject_class->get_property = gst_lfo_control_source_get_property; - csource_class->bind = gst_lfo_control_source_bind; - /** * GstLFOControlSource:waveform * * Specifies the waveform that should be used for this #GstLFOControlSource. - * - **/ + */ g_object_class_install_property (gobject_class, PROP_WAVEFORM, g_param_spec_enum ("waveform", "Waveform", "Waveform", GST_TYPE_LFO_WAVEFORM, GST_LFO_WAVEFORM_SINE, @@ -1104,8 +638,7 @@ gst_lfo_control_source_class_init (GstLFOControlSourceClass * klass) * Specifies the frequency that should be used for the waveform * of this #GstLFOControlSource. It should be large enough * so that the period is longer than one nanosecond. - * - **/ + */ g_object_class_install_property (gobject_class, PROP_FREQUENCY, g_param_spec_double ("frequency", "Frequency", "Frequency of the waveform", 0.0, G_MAXDOUBLE, 1.0, @@ -1120,7 +653,7 @@ gst_lfo_control_source_class_init (GstLFOControlSourceClass * klass) * To get a n nanosecond shift to the left use * "(GST_SECOND / frequency) - n". * - **/ + */ g_object_class_install_property (gobject_class, PROP_TIMESHIFT, g_param_spec_uint64 ("timeshift", "Timeshift", "Timeshift of the waveform to the right", 0, G_MAXUINT64, 0, @@ -1130,23 +663,18 @@ gst_lfo_control_source_class_init (GstLFOControlSourceClass * klass) * GstLFOControlSource:amplitude * * Specifies the amplitude for the waveform of this #GstLFOControlSource. - * - * It should be given as a #GValue with a type that can be transformed - * to the type of the bound property. - **/ + */ g_object_class_install_property (gobject_class, PROP_AMPLITUDE, - g_param_spec_boxed ("amplitude", "Amplitude", "Amplitude of the waveform", - G_TYPE_VALUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_param_spec_double ("amplitude", "Amplitude", + "Amplitude of the waveform", 0.0, G_MAXDOUBLE, 1.0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); /** * GstLFOControlSource:offset * - * Specifies the offset for the waveform of this #GstLFOControlSource. - * - * It should be given as a #GValue with a type that can be transformed - * to the type of the bound property. - **/ + * Specifies the value offset for the waveform of this #GstLFOControlSource. + */ g_object_class_install_property (gobject_class, PROP_OFFSET, - g_param_spec_boxed ("offset", "Offset", "Offset of the waveform", - G_TYPE_VALUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_param_spec_double ("offset", "Offset", "Offset of the waveform", + 0.0, G_MAXDOUBLE, 1.0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); } diff --git a/libs/gst/controller/gstlfocontrolsourceprivate.h b/libs/gst/controller/gstlfocontrolsourceprivate.h deleted file mode 100644 index cf29a1d5c6..0000000000 --- a/libs/gst/controller/gstlfocontrolsourceprivate.h +++ /dev/null @@ -1,64 +0,0 @@ -/* GStreamer - * - * Copyright (C) 2007 Sebastian Dröge - * - * gstlfocontrolsourceprivate.h: Private declarations for the - * GstLFOControlSource - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_LFO_CONTROL_SOURCE_PRIVATE_H__ -#define __GST_LFO_CONTROL_SOURCE_PRIVATE_H__ - -typedef struct _GstWaveformImplementation -{ - GstControlSourceGetValue get_int; - GstControlSourceGetValueArray get_int_value_array; - GstControlSourceGetValue get_uint; - GstControlSourceGetValueArray get_uint_value_array; - GstControlSourceGetValue get_long; - GstControlSourceGetValueArray get_long_value_array; - GstControlSourceGetValue get_ulong; - GstControlSourceGetValueArray get_ulong_value_array; - GstControlSourceGetValue get_int64; - GstControlSourceGetValueArray get_int64_value_array; - GstControlSourceGetValue get_uint64; - GstControlSourceGetValueArray get_uint64_value_array; - GstControlSourceGetValue get_float; - GstControlSourceGetValueArray get_float_value_array; - GstControlSourceGetValue get_double; - GstControlSourceGetValueArray get_double_value_array; -} GstWaveformImplementation; - -struct _GstLFOControlSourcePrivate -{ - GType type; /* type of the handled property */ - GType base; /* base-type of the handled property */ - - GValue minimum_value; /* min value for the handled property */ - GValue maximum_value; /* max value for the handled property */ - - GstLFOWaveform waveform; - gdouble frequency; - GstClockTime period; - GstClockTime timeshift; - GValue amplitude; - GValue offset; -}; - -#endif /* __GST_LFO_CONTROL_SOURCE_PRIVATE_H__ */ - diff --git a/libs/gst/controller/gsttimedvaluecontrolsource.c b/libs/gst/controller/gsttimedvaluecontrolsource.c index 2c248d503e..6174df6478 100644 --- a/libs/gst/controller/gsttimedvaluecontrolsource.c +++ b/libs/gst/controller/gsttimedvaluecontrolsource.c @@ -39,7 +39,6 @@ #include #include "gstinterpolationcontrolsource.h" -#include "gstinterpolationcontrolsourceprivate.h" #include "gst/glib-compat-private.h" #define GST_CAT_DEFAULT controller_debug @@ -64,7 +63,6 @@ gst_control_point_free (GstControlPoint * cp) { g_return_if_fail (cp); - g_value_unset (&cp->value); g_slice_free (GstControlPoint, cp); } @@ -76,15 +74,6 @@ gst_timed_value_control_source_reset (GstTimedValueControlSource * self) csource->get_value = NULL; csource->get_value_array = NULL; - self->type = self->base = G_TYPE_INVALID; - - if (G_IS_VALUE (&self->default_value)) - g_value_unset (&self->default_value); - if (G_IS_VALUE (&self->minimum_value)) - g_value_unset (&self->minimum_value); - if (G_IS_VALUE (&self->maximum_value)) - g_value_unset (&self->maximum_value); - if (self->values) { g_sequence_free (self->values); self->values = NULL; @@ -94,154 +83,6 @@ gst_timed_value_control_source_reset (GstTimedValueControlSource * self) self->valid_cache = FALSE; } -static gboolean -gst_timed_value_control_source_bind (GstControlSource * source, - GParamSpec * pspec) -{ - GType type, base; - GstTimedValueControlSource *self = (GstTimedValueControlSource *) source; - gboolean ret = TRUE; - - if (self->type != G_TYPE_INVALID) { - gst_timed_value_control_source_reset (self); - } - - /* get the fundamental base type */ - self->type = base = type = G_PARAM_SPEC_VALUE_TYPE (pspec); - while ((type = g_type_parent (type))) - base = type; - - self->base = base; - /* restore type */ - type = self->type; - - switch (base) { - case G_TYPE_INT:{ - GParamSpecInt *tpspec = G_PARAM_SPEC_INT (pspec); - - g_value_init (&self->default_value, type); - g_value_set_int (&self->default_value, tpspec->default_value); - g_value_init (&self->minimum_value, type); - g_value_set_int (&self->minimum_value, tpspec->minimum); - g_value_init (&self->maximum_value, type); - g_value_set_int (&self->maximum_value, tpspec->maximum); - break; - } - case G_TYPE_UINT:{ - GParamSpecUInt *tpspec = G_PARAM_SPEC_UINT (pspec); - - g_value_init (&self->default_value, type); - g_value_set_uint (&self->default_value, tpspec->default_value); - g_value_init (&self->minimum_value, type); - g_value_set_uint (&self->minimum_value, tpspec->minimum); - g_value_init (&self->maximum_value, type); - g_value_set_uint (&self->maximum_value, tpspec->maximum); - break; - } - case G_TYPE_LONG:{ - GParamSpecLong *tpspec = G_PARAM_SPEC_LONG (pspec); - - g_value_init (&self->default_value, type); - g_value_set_long (&self->default_value, tpspec->default_value); - g_value_init (&self->minimum_value, type); - g_value_set_long (&self->minimum_value, tpspec->minimum); - g_value_init (&self->maximum_value, type); - g_value_set_long (&self->maximum_value, tpspec->maximum); - break; - } - case G_TYPE_ULONG:{ - GParamSpecULong *tpspec = G_PARAM_SPEC_ULONG (pspec); - - g_value_init (&self->default_value, type); - g_value_set_ulong (&self->default_value, tpspec->default_value); - g_value_init (&self->minimum_value, type); - g_value_set_ulong (&self->minimum_value, tpspec->minimum); - g_value_init (&self->maximum_value, type); - g_value_set_ulong (&self->maximum_value, tpspec->maximum); - break; - } - case G_TYPE_INT64:{ - GParamSpecInt64 *tpspec = G_PARAM_SPEC_INT64 (pspec); - - g_value_init (&self->default_value, type); - g_value_set_int64 (&self->default_value, tpspec->default_value); - g_value_init (&self->minimum_value, type); - g_value_set_int64 (&self->minimum_value, tpspec->minimum); - g_value_init (&self->maximum_value, type); - g_value_set_int64 (&self->maximum_value, tpspec->maximum); - break; - } - case G_TYPE_UINT64:{ - GParamSpecUInt64 *tpspec = G_PARAM_SPEC_UINT64 (pspec); - - g_value_init (&self->default_value, type); - g_value_set_uint64 (&self->default_value, tpspec->default_value); - g_value_init (&self->minimum_value, type); - g_value_set_uint64 (&self->minimum_value, tpspec->minimum); - g_value_init (&self->maximum_value, type); - g_value_set_uint64 (&self->maximum_value, tpspec->maximum); - break; - } - case G_TYPE_FLOAT:{ - GParamSpecFloat *tpspec = G_PARAM_SPEC_FLOAT (pspec); - - g_value_init (&self->default_value, type); - g_value_set_float (&self->default_value, tpspec->default_value); - g_value_init (&self->minimum_value, type); - g_value_set_float (&self->minimum_value, tpspec->minimum); - g_value_init (&self->maximum_value, type); - g_value_set_float (&self->maximum_value, tpspec->maximum); - break; - } - case G_TYPE_DOUBLE:{ - GParamSpecDouble *tpspec = G_PARAM_SPEC_DOUBLE (pspec); - - g_value_init (&self->default_value, type); - g_value_set_double (&self->default_value, tpspec->default_value); - g_value_init (&self->minimum_value, type); - g_value_set_double (&self->minimum_value, tpspec->minimum); - g_value_init (&self->maximum_value, type); - g_value_set_double (&self->maximum_value, tpspec->maximum); - break; - } - case G_TYPE_BOOLEAN:{ - GParamSpecBoolean *tpspec = G_PARAM_SPEC_BOOLEAN (pspec); - - g_value_init (&self->default_value, type); - g_value_set_boolean (&self->default_value, tpspec->default_value); - break; - } - case G_TYPE_ENUM:{ - GParamSpecEnum *tpspec = G_PARAM_SPEC_ENUM (pspec); - - g_value_init (&self->default_value, type); - g_value_set_enum (&self->default_value, tpspec->default_value); - break; - } - case G_TYPE_STRING:{ - GParamSpecString *tpspec = G_PARAM_SPEC_STRING (pspec); - - g_value_init (&self->default_value, type); - g_value_set_string (&self->default_value, tpspec->default_value); - break; - } - default: - GST_WARNING ("incomplete implementation for paramspec type '%s'", - G_PARAM_SPEC_TYPE_NAME (pspec)); - ret = FALSE; - break; - } - - if (ret) { - self->valid_cache = FALSE; - self->nvalues = 0; - } else { - gst_timed_value_control_source_reset (self); - } - - return ret; -} - /* * gst_control_point_compare: * @p1: a pointer to a #GstControlPoint @@ -278,22 +119,21 @@ gst_control_point_find (gconstpointer p1, gconstpointer p2) static GstControlPoint * _make_new_cp (GstTimedValueControlSource * self, GstClockTime timestamp, - const GValue * value) + const gdouble value) { GstControlPoint *cp; /* create a new GstControlPoint */ cp = g_slice_new0 (GstControlPoint); cp->timestamp = timestamp; - g_value_init (&cp->value, self->type); - g_value_copy (value, &cp->value); + cp->value = value; return cp; } static void gst_timed_value_control_source_set_internal (GstTimedValueControlSource * - self, GstClockTime timestamp, const GValue * value) + self, GstClockTime timestamp, const gdouble value) { GSequenceIter *iter; @@ -311,13 +151,13 @@ gst_timed_value_control_source_set_internal (GstTimedValueControlSource * /* If the timestamp is the same just update the control point value */ if (cp->timestamp == timestamp) { /* update control point */ - g_value_reset (&cp->value); - g_value_copy (value, &cp->value); + cp->value = value; goto done; } } } else { self->values = g_sequence_new ((GDestroyNotify) gst_control_point_free); + GST_INFO ("create new timed value sequence"); } /* sort new cp into the prop->values list */ @@ -377,12 +217,10 @@ GSequenceIter *gst_timed_value_control_source_find_control_point_iter */ gboolean gst_timed_value_control_source_set (GstTimedValueControlSource * self, - GstClockTime timestamp, const GValue * value) + GstClockTime timestamp, const gdouble value) { g_return_val_if_fail (GST_IS_TIMED_VALUE_CONTROL_SOURCE (self), FALSE); g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE); - g_return_val_if_fail (G_IS_VALUE (value), FALSE); - g_return_val_if_fail (G_VALUE_TYPE (value) == self->type, FALSE); g_mutex_lock (self->lock); gst_timed_value_control_source_set_internal (self, timestamp, value); @@ -416,15 +254,10 @@ gst_timed_value_control_source_set_from_list (GstTimedValueControlSource * if (!GST_CLOCK_TIME_IS_VALID (tv->timestamp)) { GST_WARNING ("GstTimedValued with invalid timestamp passed to %s", GST_FUNCTION); - } else if (!G_IS_VALUE (&tv->value)) { - GST_WARNING ("GstTimedValued with invalid value passed to %s", - GST_FUNCTION); - } else if (G_VALUE_TYPE (&tv->value) != self->type) { - GST_WARNING ("incompatible value type for property"); } else { g_mutex_lock (self->lock); gst_timed_value_control_source_set_internal (self, tv->timestamp, - &tv->value); + tv->value); g_mutex_unlock (self->lock); res = TRUE; } @@ -546,23 +379,6 @@ gst_timed_value_control_source_get_count (GstTimedValueControlSource * self) return self->nvalues; } -/** - * gst_timed_value_control_source_get_base_value_type: - * @self: the #GstTimedValueControlSource - * - * Get the base #GType of the property value. - * - * Returns: the #GType, %G_TYPE_INVALID if not yet known. - */ -GType -gst_timed_value_control_source_get_base_value_type (GstTimedValueControlSource * - self) -{ - g_return_val_if_fail (GST_IS_TIMED_VALUE_CONTROL_SOURCE (self), - G_TYPE_INVALID); - return self->base; -} - /** * gst_timed_value_control_invalidate_cache: * @self: the #GstTimedValueControlSource @@ -600,8 +416,7 @@ gst_timed_value_control_source_class_init (GstTimedValueControlSourceClass * klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GstControlSourceClass *csource_class = GST_CONTROL_SOURCE_CLASS (klass); + //GstControlSourceClass *csource_class = GST_CONTROL_SOURCE_CLASS (klass); gobject_class->finalize = gst_timed_value_control_source_finalize; - csource_class->bind = gst_timed_value_control_source_bind; } diff --git a/libs/gst/controller/gsttimedvaluecontrolsource.h b/libs/gst/controller/gsttimedvaluecontrolsource.h index b8645e6d19..53a91d1444 100644 --- a/libs/gst/controller/gsttimedvaluecontrolsource.h +++ b/libs/gst/controller/gsttimedvaluecontrolsource.h @@ -49,6 +49,32 @@ typedef struct _GstTimedValueControlSource GstTimedValueControlSource; typedef struct _GstTimedValueControlSourceClass GstTimedValueControlSourceClass; typedef struct _GstTimedValueControlSourcePrivate GstTimedValueControlSourcePrivate; +/** + * GstControlPoint: + * + * a internal structure for value+time and various temporary + * values used for interpolation. This "inherits" from + * GstTimedValue. + */ +typedef struct _GstControlPoint +{ + /* fields from GstTimedValue. DO NOT CHANGE! */ + GstClockTime timestamp; /* timestamp of the value change */ + gdouble value; /* the new value */ + + /* internal fields */ + + /* Caches for the interpolators */ + // FIXME: we should not have this here already ... + union { + struct { + gdouble h; + gdouble z; + } cubic; + } cache; + +} GstControlPoint; + /** * GstTimedValueControlSource: * @@ -60,13 +86,6 @@ struct _GstTimedValueControlSource { /*< protected >*/ GMutex *lock; - GType type; /* type of the handled property */ - GType base; /* base-type of the handled property */ - - GValue default_value; /* default value for the handled property */ - GValue minimum_value; /* min value for the handled property */ - GValue maximum_value; /* max value for the handled property */ - GSequence *values; /* List of GstControlPoint */ gint nvalues; /* Number of control points */ gboolean valid_cache; @@ -97,7 +116,7 @@ GSequenceIter * gst_timed_value_control_source_find_control_point_iter ( gboolean gst_timed_value_control_source_set (GstTimedValueControlSource * self, GstClockTime timestamp, - const GValue * value); + const gdouble value); gboolean gst_timed_value_control_source_set_from_list (GstTimedValueControlSource * self, const GSList * timedvalues); gboolean gst_timed_value_control_source_unset (GstTimedValueControlSource * self, @@ -105,8 +124,6 @@ gboolean gst_timed_value_control_source_unset (GstTimedValueCont void gst_timed_value_control_source_unset_all (GstTimedValueControlSource *self); GList * gst_timed_value_control_source_get_all (GstTimedValueControlSource * self); gint gst_timed_value_control_source_get_count (GstTimedValueControlSource * self); -GType gst_timed_value_control_source_get_base_value_type ( - GstTimedValueControlSource * self); void gst_timed_value_control_invalidate_cache (GstTimedValueControlSource * self); G_END_DECLS diff --git a/libs/gst/controller/gsttriggercontrolsource.c b/libs/gst/controller/gsttriggercontrolsource.c index f6ca815198..3044cf18b9 100644 --- a/libs/gst/controller/gsttriggercontrolsource.c +++ b/libs/gst/controller/gsttriggercontrolsource.c @@ -40,12 +40,128 @@ #include #include "gsttriggercontrolsource.h" -#include "gstinterpolationcontrolsourceprivate.h" #include "gst/glib-compat-private.h" +#include + #define GST_CAT_DEFAULT controller_debug GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); +struct _GstTriggerControlSourcePrivate +{ + gint64 tolerance; +}; + +/* control point accessors */ + +/* returns the default value of the property, except for times with specific values */ +/* needed for one-shot events, such as notes and triggers */ + +static inline const gdouble +_interpolate_trigger (GstTimedValueControlSource * self, GSequenceIter * iter, + GstClockTime timestamp) +{ + GstControlPoint *cp; + gint64 tolerance = ((GstTriggerControlSource *) self)->priv->tolerance; + gboolean found = FALSE; + + cp = g_sequence_get (iter); + if (GST_CLOCK_DIFF (cp->timestamp, timestamp) <= tolerance) { + found = TRUE; + } else { + if ((iter = g_sequence_iter_next (iter))) { + cp = g_sequence_get (iter); + if (GST_CLOCK_DIFF (timestamp, cp->timestamp) <= tolerance) { + found = TRUE; + } + } + } + if (found) { + return cp->value; + } +} + +static gboolean +interpolate_trigger_get (GstTimedValueControlSource * self, + GstClockTime timestamp, gdouble * value) +{ + gboolean ret = FALSE; + GSequenceIter *iter; + + g_mutex_lock (self->lock); + + iter = + gst_timed_value_control_source_find_control_point_iter (self, timestamp); + if (iter) { + *value = _interpolate_trigger (self, iter, timestamp); + ret = TRUE; + } + g_mutex_unlock (self->lock); + return ret; +} + +static gboolean +interpolate_trigger_get_value_array (GstTimedValueControlSource * self, + GstClockTime timestamp, GstClockTime interval, guint n_values, + gdouble * values) +{ + gboolean ret = FALSE; + guint i; + GstClockTime ts = timestamp; + GstClockTime next_ts = 0; + gdouble val; + GSequenceIter *iter1 = NULL, *iter2 = NULL; + gboolean triggered = FALSE; + + g_mutex_lock (self->lock); + for (i = 0; i < n_values; i++) { + val = FP_NAN; + if (ts >= next_ts) { + iter1 = gst_timed_value_control_source_find_control_point_iter (self, ts); + if (!iter1) { + if (G_LIKELY (self->values)) + iter2 = g_sequence_get_begin_iter (self->values); + else + iter2 = NULL; + } else { + iter2 = g_sequence_iter_next (iter1); + } + + if (iter2 && !g_sequence_iter_is_end (iter2)) { + GstControlPoint *cp; + + cp = g_sequence_get (iter2); + next_ts = cp->timestamp; + } else { + next_ts = GST_CLOCK_TIME_NONE; + } + + if (iter1) { + val = _interpolate_trigger (self, iter1, ts); + ret = TRUE; + } else { + g_mutex_unlock (self->lock); + return FALSE; + } + triggered = TRUE; + } else if (triggered) { + if (iter1) { + val = _interpolate_trigger (self, iter1, ts); + ret = TRUE; + } else { + g_mutex_unlock (self->lock); + return FALSE; + } + triggered = FALSE; + } + *values = val; + ts += interval; + values++; + } + g_mutex_unlock (self->lock); + return ret; +} + enum { PROP_TOLERANCE = 1, @@ -58,181 +174,6 @@ enum G_DEFINE_TYPE_WITH_CODE (GstTriggerControlSource, gst_trigger_control_source, GST_TYPE_TIMED_VALUE_CONTROL_SOURCE, _do_init); -struct _GstTriggerControlSourcePrivate -{ - gint64 tolerance; -}; - -/* control point accessors */ - -/* returns the default value of the property, except for times with specific values */ -/* needed for one-shot events, such as notes and triggers */ -static inline const GValue * -_interpolate_trigger_get (GstTimedValueControlSource * self, - GSequenceIter * iter, GstClockTime timestamp) -{ - GstControlPoint *cp; - - /* check if there is a value at the registered timestamp */ - if (iter) { - gint64 tolerance = ((GstTriggerControlSource *) self)->priv->tolerance; - cp = g_sequence_get (iter); - if (GST_CLOCK_DIFF (cp->timestamp, timestamp) <= tolerance) { - return &cp->value; - } else { - if ((iter = g_sequence_iter_next (iter))) { - cp = g_sequence_get (iter); - if (GST_CLOCK_DIFF (timestamp, cp->timestamp) <= tolerance) { - return &cp->value; - } - } - } - } - if (self->nvalues > 0) - return &self->default_value; - else - return NULL; -} - -#define DEFINE_TRIGGER_GET_FUNC_COMPARABLE(type) \ -static inline const GValue * \ -_interpolate_trigger_get_##type (GstTimedValueControlSource *self, GSequenceIter *iter, GstClockTime timestamp) \ -{ \ - GstControlPoint *cp; \ - \ - /* check if there is a value at the registered timestamp */ \ - if (iter) { \ - gint64 tolerance = ((GstTriggerControlSource *)self)->priv->tolerance; \ - gboolean found = FALSE; \ - cp = g_sequence_get (iter); \ - if (GST_CLOCK_DIFF (cp->timestamp,timestamp) <= tolerance ) { \ - found = TRUE; \ - } else { \ - if ((iter = g_sequence_iter_next (iter))) { \ - cp = g_sequence_get (iter); \ - if (GST_CLOCK_DIFF (timestamp, cp->timestamp) <= tolerance) { \ - found = TRUE; \ - } \ - } \ - } \ - if (found) { \ - g##type ret = g_value_get_##type (&cp->value); \ - if (g_value_get_##type (&self->minimum_value) > ret) \ - return &self->minimum_value; \ - else if (g_value_get_##type (&self->maximum_value) < ret) \ - return &self->maximum_value; \ - else \ - return &cp->value; \ - } \ - } \ - \ - if (self->nvalues > 0) \ - return &self->default_value; \ - else \ - return NULL; \ -} - -#define DEFINE_TRIGGER_GET(type, ctype, get_func) \ -static gboolean \ -interpolate_trigger_get_##type (GstTimedValueControlSource *self, GstClockTime timestamp, GValue *value) \ -{ \ - const GValue *ret; \ - GSequenceIter *iter; \ - \ - g_mutex_lock (self->lock); \ - \ - iter = gst_timed_value_control_source_find_control_point_iter (self, timestamp); \ - ret = get_func (self, iter, timestamp); \ - if (!ret) { \ - g_mutex_unlock (self->lock); \ - return FALSE; \ - } \ - \ - g_value_copy (ret, value); \ - g_mutex_unlock (self->lock); \ - return TRUE; \ -} \ -\ -static gboolean \ -interpolate_trigger_get_##type##_value_array (GstTimedValueControlSource *self, \ - GstClockTime timestamp, GstClockTime interval, guint n_values, gpointer _values) \ -{ \ - guint i; \ - GstClockTime ts = timestamp; \ - GstClockTime next_ts = 0; \ - ctype *values = (ctype *) _values; \ - const GValue *ret_val = NULL; \ - ctype ret = 0; \ - GSequenceIter *iter1 = NULL, *iter2 = NULL; \ - gboolean triggered = FALSE; \ - \ - g_mutex_lock (self->lock); \ - for(i = 0; i < n_values; i++) { \ - if (!ret_val || ts >= next_ts) { \ - iter1 = gst_timed_value_control_source_find_control_point_iter (self, ts); \ - if (!iter1) { \ - if (G_LIKELY (self->values)) \ - iter2 = g_sequence_get_begin_iter (self->values); \ - else \ - iter2 = NULL; \ - } else { \ - iter2 = g_sequence_iter_next (iter1); \ - } \ - \ - if (iter2 && !g_sequence_iter_is_end (iter2)) { \ - GstControlPoint *cp; \ - \ - cp = g_sequence_get (iter2); \ - next_ts = cp->timestamp; \ - } else { \ - next_ts = GST_CLOCK_TIME_NONE; \ - } \ - \ - ret_val = get_func (self, iter1, ts); \ - if (!ret_val) { \ - g_mutex_unlock (self->lock); \ - return FALSE; \ - } \ - ret = g_value_get_##type (ret_val); \ - triggered = TRUE; \ - } else if (triggered) { \ - ret_val = get_func (self, iter1, ts); \ - if (!ret_val) { \ - g_mutex_unlock (self->lock); \ - return FALSE; \ - } \ - ret = g_value_get_##type (ret_val); \ - triggered = FALSE; \ - } \ - *values = ret; \ - ts += interval; \ - values++; \ - } \ - g_mutex_unlock (self->lock); \ - return TRUE; \ -} - -DEFINE_TRIGGER_GET_FUNC_COMPARABLE (int); -DEFINE_TRIGGER_GET (int, gint, _interpolate_trigger_get_int); -DEFINE_TRIGGER_GET_FUNC_COMPARABLE (uint); -DEFINE_TRIGGER_GET (uint, guint, _interpolate_trigger_get_uint); -DEFINE_TRIGGER_GET_FUNC_COMPARABLE (long); -DEFINE_TRIGGER_GET (long, glong, _interpolate_trigger_get_long); -DEFINE_TRIGGER_GET_FUNC_COMPARABLE (ulong); -DEFINE_TRIGGER_GET (ulong, gulong, _interpolate_trigger_get_ulong); -DEFINE_TRIGGER_GET_FUNC_COMPARABLE (int64); -DEFINE_TRIGGER_GET (int64, gint64, _interpolate_trigger_get_int64); -DEFINE_TRIGGER_GET_FUNC_COMPARABLE (uint64); -DEFINE_TRIGGER_GET (uint64, guint64, _interpolate_trigger_get_uint64); -DEFINE_TRIGGER_GET_FUNC_COMPARABLE (float); -DEFINE_TRIGGER_GET (float, gfloat, _interpolate_trigger_get_float); -DEFINE_TRIGGER_GET_FUNC_COMPARABLE (double); -DEFINE_TRIGGER_GET (double, gdouble, _interpolate_trigger_get_double); - -DEFINE_TRIGGER_GET (boolean, gboolean, _interpolate_trigger_get); -DEFINE_TRIGGER_GET (enum, gint, _interpolate_trigger_get); -DEFINE_TRIGGER_GET (string, const gchar *, _interpolate_trigger_get); - /** * gst_trigger_control_source_new: * @@ -246,107 +187,18 @@ gst_trigger_control_source_new (void) return g_object_newv (GST_TYPE_TRIGGER_CONTROL_SOURCE, 0, NULL); } -static gboolean -gst_trigger_control_source_bind (GstControlSource * csource, GParamSpec * pspec) -{ - if (GST_CONTROL_SOURCE_CLASS - (gst_trigger_control_source_parent_class)->bind (csource, pspec)) { - gboolean ret = TRUE; - - GST_TIMED_VALUE_CONTROL_SOURCE_LOCK (csource); - switch (gst_timed_value_control_source_get_base_value_type ( - (GstTimedValueControlSource *) csource)) { - case G_TYPE_INT: - csource->get_value = - (GstControlSourceGetValue) interpolate_trigger_get_int; - csource->get_value_array = (GstControlSourceGetValueArray) - interpolate_trigger_get_int_value_array; - break; - case G_TYPE_UINT: - csource->get_value = - (GstControlSourceGetValue) interpolate_trigger_get_uint; - csource->get_value_array = (GstControlSourceGetValueArray) - interpolate_trigger_get_uint_value_array; - break; - case G_TYPE_LONG: - csource->get_value = - (GstControlSourceGetValue) interpolate_trigger_get_long; - csource->get_value_array = (GstControlSourceGetValueArray) - interpolate_trigger_get_long_value_array; - break; - case G_TYPE_ULONG: - csource->get_value = - (GstControlSourceGetValue) interpolate_trigger_get_ulong; - csource->get_value_array = (GstControlSourceGetValueArray) - interpolate_trigger_get_ulong_value_array; - break; - case G_TYPE_INT64: - csource->get_value = - (GstControlSourceGetValue) interpolate_trigger_get_int64; - csource->get_value_array = (GstControlSourceGetValueArray) - interpolate_trigger_get_int64_value_array; - break; - case G_TYPE_UINT64: - csource->get_value = - (GstControlSourceGetValue) interpolate_trigger_get_uint64; - csource->get_value_array = (GstControlSourceGetValueArray) - interpolate_trigger_get_uint64_value_array; - break; - case G_TYPE_FLOAT: - csource->get_value = - (GstControlSourceGetValue) interpolate_trigger_get_float; - csource->get_value_array = (GstControlSourceGetValueArray) - interpolate_trigger_get_float_value_array; - break; - case G_TYPE_DOUBLE: - csource->get_value = - (GstControlSourceGetValue) interpolate_trigger_get_double; - csource->get_value_array = (GstControlSourceGetValueArray) - interpolate_trigger_get_double_value_array; - break; - case G_TYPE_BOOLEAN: - csource->get_value = - (GstControlSourceGetValue) interpolate_trigger_get_boolean; - csource->get_value_array = (GstControlSourceGetValueArray) - interpolate_trigger_get_boolean_value_array; - break; - case G_TYPE_ENUM: - csource->get_value = - (GstControlSourceGetValue) interpolate_trigger_get_enum; - csource->get_value_array = (GstControlSourceGetValueArray) - interpolate_trigger_get_enum_value_array; - break; - case G_TYPE_STRING: - csource->get_value = - (GstControlSourceGetValue) interpolate_trigger_get_string; - csource->get_value_array = (GstControlSourceGetValueArray) - interpolate_trigger_get_string_value_array; - break; - default: - ret = FALSE; - break; - } - - /* Incomplete implementation */ - if (!csource->get_value || !csource->get_value_array) { - ret = FALSE; - } - gst_timed_value_control_invalidate_cache ((GstTimedValueControlSource *) - csource); - - GST_TIMED_VALUE_CONTROL_SOURCE_UNLOCK (csource); - - return ret; - } - return FALSE; -} - static void gst_trigger_control_source_init (GstTriggerControlSource * self) { + GstControlSource *csource = (GstControlSource *) self; + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GST_TYPE_TRIGGER_CONTROL_SOURCE, GstTriggerControlSourcePrivate); + + csource->get_value = (GstControlSourceGetValue) interpolate_trigger_get; + csource->get_value_array = (GstControlSourceGetValueArray) + interpolate_trigger_get_value_array; } static void @@ -387,15 +239,12 @@ static void gst_trigger_control_source_class_init (GstTriggerControlSourceClass * klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GstControlSourceClass *csource_class = GST_CONTROL_SOURCE_CLASS (klass); g_type_class_add_private (klass, sizeof (GstTriggerControlSourcePrivate)); gobject_class->set_property = gst_trigger_control_source_set_property; gobject_class->get_property = gst_trigger_control_source_get_property; - csource_class->bind = gst_trigger_control_source_bind; - g_object_class_install_property (gobject_class, PROP_TOLERANCE, g_param_spec_int64 ("tolerance", "Tolerance", "Amount of ns a control time can be off to still trigger", diff --git a/tests/benchmarks/controller.c b/tests/benchmarks/controller.c index 77ad899fd8..692ed12420 100644 --- a/tests/benchmarks/controller.c +++ b/tests/benchmarks/controller.c @@ -115,7 +115,6 @@ main (gint argc, gchar * argv[]) gst_object_set_control_source (GST_OBJECT (src), "freq", GST_CONTROL_SOURCE (csource)); g_object_set (csource, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL); - g_value_init (&freq, G_TYPE_DOUBLE); /* set control values, we set them in a linear order as we would when loading @@ -124,9 +123,8 @@ main (gint argc, gchar * argv[]) bt = gst_util_get_timestamp (); for (i = 0; i < NUM_CP; i++) { - g_value_set_double (&freq, g_random_double_range (50.0, 3000.0)); gst_timed_value_control_source_set ((GstTimedValueControlSource *) csource, - i * tick, &freq); + i * tick, g_random_double_range (50.0, 3000.0)); } ct = gst_util_get_timestamp (); @@ -142,9 +140,8 @@ main (gint argc, gchar * argv[]) for (i = 0; i < 100; i++) { j = g_random_int_range (0, NUM_CP - 1); - g_value_set_double (&freq, g_random_double_range (50.0, 3000.0)); gst_timed_value_control_source_set ((GstTimedValueControlSource *) csource, - j * tick, &freq); + j * tick, g_random_double_range (50.0, 3000.0)); } ct = gst_util_get_timestamp (); @@ -159,7 +156,7 @@ main (gint argc, gchar * argv[]) bt = gst_util_get_timestamp (); gst_control_source_get_value_array (GST_CONTROL_SOURCE (csource), 0, - sample_duration, BLOCK_SIZE * NUM_CP, (gpointer) values); + sample_duration, BLOCK_SIZE * NUM_CP, values); ct = gst_util_get_timestamp (); g_free (values); elapsed = GST_CLOCK_DIFF (bt, ct); diff --git a/tests/check/libs/controller.c b/tests/check/libs/controller.c index 26a3c9dd38..435b70dc5d 100644 --- a/tests/check/libs/controller.c +++ b/tests/check/libs/controller.c @@ -30,18 +30,18 @@ #include #include -/* LOCAL TEST ELEMENT */ +/* local test element */ enum { - ARG_ULONG = 1, - ARG_FLOAT, - ARG_DOUBLE, - ARG_BOOLEAN, - ARG_READONLY, - ARG_STATIC, - ARG_CONSTRUCTONLY, - ARG_COUNT + PROP_INT = 1, + PROP_FLOAT, + PROP_DOUBLE, + PROP_BOOLEAN, + PROP_READONLY, + PROP_STATIC, + PROP_CONSTRUCTONLY, + PROP_COUNT }; #define GST_TYPE_TEST_MONO_SOURCE (gst_test_mono_source_get_type ()) @@ -57,7 +57,7 @@ typedef struct _GstTestMonoSourceClass GstTestMonoSourceClass; struct _GstTestMonoSource { GstElement parent; - gulong val_ulong; + gint val_int; gfloat val_float; gdouble val_double; gboolean val_boolean; @@ -76,16 +76,16 @@ gst_test_mono_source_get_property (GObject * object, GstTestMonoSource *self = GST_TEST_MONO_SOURCE (object); switch (property_id) { - case ARG_ULONG: - g_value_set_ulong (value, self->val_ulong); + case PROP_INT: + g_value_set_int (value, self->val_int); break; - case ARG_FLOAT: + case PROP_FLOAT: g_value_set_float (value, self->val_float); break; - case ARG_DOUBLE: + case PROP_DOUBLE: g_value_set_double (value, self->val_double); break; - case ARG_BOOLEAN: + case PROP_BOOLEAN: g_value_set_boolean (value, self->val_boolean); break; default: @@ -101,23 +101,23 @@ gst_test_mono_source_set_property (GObject * object, GstTestMonoSource *self = GST_TEST_MONO_SOURCE (object); switch (property_id) { - case ARG_ULONG: - self->val_ulong = g_value_get_ulong (value); - GST_DEBUG ("test value ulong=%lu", self->val_ulong); + case PROP_INT: + self->val_int = g_value_get_int (value); + GST_DEBUG ("test value int=%d", self->val_int); break; - case ARG_FLOAT: + case PROP_FLOAT: self->val_float = g_value_get_float (value); GST_DEBUG ("test value float=%f", self->val_float); break; - case ARG_DOUBLE: + case PROP_DOUBLE: self->val_double = g_value_get_double (value); - GST_DEBUG ("test value double=%f", self->val_double); + GST_DEBUG ("test value double=%lf", self->val_double); break; - case ARG_BOOLEAN: + case PROP_BOOLEAN: self->val_boolean = g_value_get_boolean (value); GST_DEBUG ("test value boolean=%d", self->val_boolean); break; - case ARG_CONSTRUCTONLY: + case PROP_CONSTRUCTONLY: break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); @@ -133,47 +133,47 @@ gst_test_mono_source_class_init (GstTestMonoSourceClass * klass) gobject_class->set_property = gst_test_mono_source_set_property; gobject_class->get_property = gst_test_mono_source_get_property; - g_object_class_install_property (gobject_class, ARG_ULONG, - g_param_spec_ulong ("ulong", - "ulong prop", - "ulong number parameter for the test_mono_source", - 0, G_MAXULONG, 0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE)); + g_object_class_install_property (gobject_class, PROP_INT, + g_param_spec_int ("int", + "int prop", + "int number parameter for the test_mono_source", + 0, 100, 0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE)); - g_object_class_install_property (gobject_class, ARG_FLOAT, + g_object_class_install_property (gobject_class, PROP_FLOAT, g_param_spec_float ("float", "float prop", "float number parameter for the test_mono_source", 0.0, 100.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE)); - g_object_class_install_property (gobject_class, ARG_DOUBLE, + g_object_class_install_property (gobject_class, PROP_DOUBLE, g_param_spec_double ("double", "double prop", "double number parameter for the test_mono_source", 0.0, 100.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE)); - g_object_class_install_property (gobject_class, ARG_BOOLEAN, + g_object_class_install_property (gobject_class, PROP_BOOLEAN, g_param_spec_boolean ("boolean", "boolean prop", "boolean parameter for the test_mono_source", FALSE, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE)); - g_object_class_install_property (gobject_class, ARG_READONLY, - g_param_spec_ulong ("readonly", + g_object_class_install_property (gobject_class, PROP_READONLY, + g_param_spec_int ("readonly", "readonly prop", "readonly parameter for the test_mono_source", - 0, G_MAXULONG, 0, G_PARAM_READABLE | GST_PARAM_CONTROLLABLE)); + 0, G_MAXINT, 0, G_PARAM_READABLE | GST_PARAM_CONTROLLABLE)); - g_object_class_install_property (gobject_class, ARG_STATIC, - g_param_spec_ulong ("static", + g_object_class_install_property (gobject_class, PROP_STATIC, + g_param_spec_int ("static", "static prop", "static parameter for the test_mono_source", - 0, G_MAXULONG, 0, G_PARAM_READWRITE)); + 0, G_MAXINT, 0, G_PARAM_READWRITE)); - g_object_class_install_property (gobject_class, ARG_CONSTRUCTONLY, - g_param_spec_ulong ("construct-only", + g_object_class_install_property (gobject_class, PROP_CONSTRUCTONLY, + g_param_spec_int ("construct-only", "construct-only prop", "construct-only parameter for the test_mono_source", - 0, G_MAXULONG, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + 0, G_MAXINT, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); } static void @@ -236,7 +236,7 @@ GST_START_TEST (controller_new_fail1) GstInterpolationControlSource *cs; gboolean res; - elem = gst_element_factory_make ("fakesrc", "test_source"); + elem = gst_element_factory_make ("fakesrc", NULL); cs = gst_interpolation_control_source_new (); /* that property should not exist */ @@ -257,7 +257,7 @@ GST_START_TEST (controller_new_fail2) GstInterpolationControlSource *cs; gboolean res; - elem = gst_element_factory_make ("testmonosource", "test_source"); + elem = gst_element_factory_make ("testmonosource", NULL); cs = gst_interpolation_control_source_new (); /* that property should exist and but is readonly */ @@ -278,7 +278,7 @@ GST_START_TEST (controller_new_fail3) GstInterpolationControlSource *cs; gboolean res; - elem = gst_element_factory_make ("testmonosource", "test_source"); + elem = gst_element_factory_make ("testmonosource", NULL); cs = gst_interpolation_control_source_new (); /* that property should exist and but is not controlable */ @@ -299,7 +299,7 @@ GST_START_TEST (controller_new_fail4) GstInterpolationControlSource *cs; gboolean res; - elem = gst_element_factory_make ("testmonosource", "test_source"); + elem = gst_element_factory_make ("testmonosource", NULL); cs = gst_interpolation_control_source_new (); /* that property should exist and but is construct-only */ @@ -322,11 +322,11 @@ GST_START_TEST (controller_new_okay1) GstInterpolationControlSource *cs; gboolean res; - elem = gst_element_factory_make ("testmonosource", "test_source"); + elem = gst_element_factory_make ("testmonosource", NULL); cs = gst_interpolation_control_source_new (); /* that property should exist and should be controllable */ - res = gst_object_set_control_source (GST_OBJECT (elem), "ulong", + res = gst_object_set_control_source (GST_OBJECT (elem), "int", GST_CONTROL_SOURCE (cs)); fail_unless (res == TRUE, NULL); @@ -343,12 +343,12 @@ GST_START_TEST (controller_new_okay2) GstInterpolationControlSource *cs1, *cs2; gboolean res; - elem = gst_element_factory_make ("testmonosource", "test_source"); + elem = gst_element_factory_make ("testmonosource", NULL); cs1 = gst_interpolation_control_source_new (); cs2 = gst_interpolation_control_source_new (); /* these properties should exist and should be controllable */ - res = gst_object_set_control_source (GST_OBJECT (elem), "ulong", + res = gst_object_set_control_source (GST_OBJECT (elem), "int", GST_CONTROL_SOURCE (cs1)); fail_unless (res == TRUE, NULL); @@ -370,27 +370,27 @@ GST_START_TEST (controller_param_twice) GstInterpolationControlSource *cs; gboolean res; - elem = gst_element_factory_make ("testmonosource", "test_source"); + elem = gst_element_factory_make ("testmonosource", NULL); cs = gst_interpolation_control_source_new (); /* that property should exist and should be controllable */ - res = gst_object_set_control_source (GST_OBJECT (elem), "ulong", + res = gst_object_set_control_source (GST_OBJECT (elem), "int", GST_CONTROL_SOURCE (cs)); fail_unless (res, NULL); /* setting it again will just unset the old and set it again * this might cause some trouble with binding the control source again */ - res = gst_object_set_control_source (GST_OBJECT (elem), "ulong", + res = gst_object_set_control_source (GST_OBJECT (elem), "int", GST_CONTROL_SOURCE (cs)); fail_unless (res, NULL); /* it should have been added at least once, let remove it */ - res = gst_object_set_control_source (GST_OBJECT (elem), "ulong", NULL); + res = gst_object_set_control_source (GST_OBJECT (elem), "int", NULL); fail_unless (res, NULL); /* removing it again should not work */ - res = gst_object_set_control_source (GST_OBJECT (elem), "ulong", NULL); + res = gst_object_set_control_source (GST_OBJECT (elem), "int", NULL); fail_unless (!res, NULL); g_object_unref (cs); @@ -423,17 +423,17 @@ GST_START_TEST (controller_controlsource_refcounts) GstElement *elem; GstControlSource *csource, *test_csource; - elem = gst_element_factory_make ("testmonosource", "test_source"); + elem = gst_element_factory_make ("testmonosource", NULL); csource = (GstControlSource *) gst_interpolation_control_source_new (); fail_unless (csource != NULL, NULL); fail_unless_equals_int (G_OBJECT (csource)->ref_count, 1); - fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "ulong", + fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", csource)); fail_unless_equals_int (G_OBJECT (csource)->ref_count, 2); - test_csource = gst_object_get_control_source (GST_OBJECT (elem), "ulong"); + test_csource = gst_object_get_control_source (GST_OBJECT (elem), "int"); fail_unless (test_csource != NULL, NULL); fail_unless (test_csource == csource); fail_unless_equals_int (G_OBJECT (csource)->ref_count, 3); @@ -451,12 +451,12 @@ GST_START_TEST (controller_controlsource_empty1) GstElement *elem; GstControlSource *csource; - elem = gst_element_factory_make ("testmonosource", "test_source"); + elem = gst_element_factory_make ("testmonosource", NULL); csource = (GstControlSource *) gst_interpolation_control_source_new (); fail_unless (csource != NULL, NULL); - fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "ulong", + fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", csource)); /* don't fail on empty control point lists */ @@ -474,25 +474,22 @@ GST_START_TEST (controller_controlsource_empty2) { GstElement *elem; GstInterpolationControlSource *csource; - GValue val = { 0, }; + GstTimedValueControlSource *cs; - elem = gst_element_factory_make ("testmonosource", "test_source"); + elem = gst_element_factory_make ("testmonosource", NULL); csource = gst_interpolation_control_source_new (); fail_unless (csource != NULL, NULL); - fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "ulong", + fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", (GstControlSource *) csource)); /* set control values */ - g_value_init (&val, G_TYPE_ULONG); - g_value_set_ulong (&val, 0); - gst_timed_value_control_source_set ((GstTimedValueControlSource *) csource, - 0 * GST_SECOND, &val); + cs = (GstTimedValueControlSource *) csource; + gst_timed_value_control_source_set (cs, 0 * GST_SECOND, 0); /* ... and unset the value */ - gst_timed_value_control_source_unset ((GstTimedValueControlSource *) csource, - 0 * GST_SECOND); + gst_timed_value_control_source_unset (cs, 0 * GST_SECOND); /* don't fail on empty control point lists */ gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND); @@ -508,17 +505,17 @@ GST_END_TEST; GST_START_TEST (controller_interpolate_none) { GstInterpolationControlSource *csource; + GstTimedValueControlSource *cs; GstElement *elem; gboolean res; - GValue val_ulong = { 0, }; - elem = gst_element_factory_make ("testmonosource", "test_source"); + elem = gst_element_factory_make ("testmonosource", NULL); - /* Get interpolation control source */ + /* new interpolation control source */ csource = gst_interpolation_control_source_new (); fail_unless (csource != NULL); - fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "ulong", + fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", GST_CONTROL_SOURCE (csource))); /* set interpolation mode */ @@ -528,29 +525,23 @@ GST_START_TEST (controller_interpolate_none) (GstTimedValueControlSource *) csource) == 0); /* set control values */ - g_value_init (&val_ulong, G_TYPE_ULONG); - g_value_set_ulong (&val_ulong, 0); - res = gst_timed_value_control_source_set ((GstTimedValueControlSource *) - csource, 0 * GST_SECOND, &val_ulong); + cs = (GstTimedValueControlSource *) csource; + res = gst_timed_value_control_source_set (cs, 0 * GST_SECOND, 0.0); fail_unless (res, NULL); - fail_unless (gst_timed_value_control_source_get_count ( - (GstTimedValueControlSource *) csource) == 1); - g_value_set_ulong (&val_ulong, 100); - res = gst_timed_value_control_source_set ((GstTimedValueControlSource *) - csource, 2 * GST_SECOND, &val_ulong); + fail_unless (gst_timed_value_control_source_get_count (cs) == 1); + res = gst_timed_value_control_source_set (cs, 2 * GST_SECOND, 1.0); fail_unless (res, NULL); - fail_unless (gst_timed_value_control_source_get_count ( - (GstTimedValueControlSource *) csource) == 2); + fail_unless (gst_timed_value_control_source_get_count (cs) == 2); g_object_unref (csource); /* now pull in values for some timestamps */ gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 100); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 100); gst_object_unref (elem); } @@ -561,42 +552,38 @@ GST_END_TEST; GST_START_TEST (controller_interpolate_linear) { GstInterpolationControlSource *csource; + GstTimedValueControlSource *cs; GstElement *elem; gboolean res; - GValue val_ulong = { 0, }; - elem = gst_element_factory_make ("testmonosource", "test_source"); + elem = gst_element_factory_make ("testmonosource", NULL); - /* Get interpolation control source */ + /* new interpolation control source */ csource = gst_interpolation_control_source_new (); fail_unless (csource != NULL); - fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "ulong", + fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", GST_CONTROL_SOURCE (csource))); /* set interpolation mode */ g_object_set (csource, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL); /* set control values */ - g_value_init (&val_ulong, G_TYPE_ULONG); - g_value_set_ulong (&val_ulong, 0); - res = gst_timed_value_control_source_set ((GstTimedValueControlSource *) - csource, 0 * GST_SECOND, &val_ulong); + cs = (GstTimedValueControlSource *) csource; + res = gst_timed_value_control_source_set (cs, 0 * GST_SECOND, 0); fail_unless (res, NULL); - g_value_set_ulong (&val_ulong, 100); - res = gst_timed_value_control_source_set ((GstTimedValueControlSource *) - csource, 2 * GST_SECOND, &val_ulong); + res = gst_timed_value_control_source_set (cs, 2 * GST_SECOND, 1.0); fail_unless (res, NULL); g_object_unref (csource); /* now pull in values for some timestamps */ gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 50); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 50); gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 100); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 100); gst_object_unref (elem); } @@ -607,13 +594,13 @@ GST_END_TEST; GST_START_TEST (controller_interpolate_cubic) { GstInterpolationControlSource *csource; + GstTimedValueControlSource *cs; GstElement *elem; gboolean res; - GValue val_double = { 0, }; - elem = gst_element_factory_make ("testmonosource", "test_source"); + elem = gst_element_factory_make ("testmonosource", NULL); - /* Get interpolation control source */ + /* new interpolation control source */ csource = gst_interpolation_control_source_new (); fail_unless (csource != NULL); @@ -624,22 +611,14 @@ GST_START_TEST (controller_interpolate_cubic) g_object_set (csource, "mode", GST_INTERPOLATION_MODE_CUBIC, NULL); /* set control values */ - g_value_init (&val_double, G_TYPE_DOUBLE); - g_value_set_double (&val_double, 0.0); - res = gst_timed_value_control_source_set ((GstTimedValueControlSource *) - csource, 0 * GST_SECOND, &val_double); + cs = (GstTimedValueControlSource *) csource; + res = gst_timed_value_control_source_set (cs, 0 * GST_SECOND, 0.0); fail_unless (res, NULL); - g_value_set_double (&val_double, 5.0); - res = gst_timed_value_control_source_set ((GstTimedValueControlSource *) - csource, 1 * GST_SECOND, &val_double); + res = gst_timed_value_control_source_set (cs, 1 * GST_SECOND, 0.5); fail_unless (res, NULL); - g_value_set_double (&val_double, 2.0); - res = gst_timed_value_control_source_set ((GstTimedValueControlSource *) - csource, 2 * GST_SECOND, &val_double); + res = gst_timed_value_control_source_set (cs, 2 * GST_SECOND, 0.2); fail_unless (res, NULL); - g_value_set_double (&val_double, 8.0); - res = gst_timed_value_control_source_set ((GstTimedValueControlSource *) - csource, 4 * GST_SECOND, &val_double); + res = gst_timed_value_control_source_set (cs, 4 * GST_SECOND, 0.8); fail_unless (res, NULL); g_object_unref (csource); @@ -648,16 +627,16 @@ GST_START_TEST (controller_interpolate_cubic) gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND); fail_unless_equals_float (GST_TEST_MONO_SOURCE (elem)->val_double, 0.0); gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND); - fail_unless_equals_float (GST_TEST_MONO_SOURCE (elem)->val_double, 5.0); + fail_unless_equals_float (GST_TEST_MONO_SOURCE (elem)->val_double, 50.0); gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND); - fail_unless_equals_float (GST_TEST_MONO_SOURCE (elem)->val_double, 2.0); + fail_unless_equals_float (GST_TEST_MONO_SOURCE (elem)->val_double, 20.0); gst_object_sync_values (GST_OBJECT (elem), 3 * GST_SECOND); - fail_unless (GST_TEST_MONO_SOURCE (elem)->val_double > 2.0 && - GST_TEST_MONO_SOURCE (elem)->val_double < 8.0, NULL); + fail_unless (GST_TEST_MONO_SOURCE (elem)->val_double > 20.0 && + GST_TEST_MONO_SOURCE (elem)->val_double < 80.0, NULL); gst_object_sync_values (GST_OBJECT (elem), 4 * GST_SECOND); - fail_unless_equals_float (GST_TEST_MONO_SOURCE (elem)->val_double, 8.0); + fail_unless_equals_float (GST_TEST_MONO_SOURCE (elem)->val_double, 80.0); gst_object_sync_values (GST_OBJECT (elem), 5 * GST_SECOND); - fail_unless_equals_float (GST_TEST_MONO_SOURCE (elem)->val_double, 8.0); + fail_unless_equals_float (GST_TEST_MONO_SOURCE (elem)->val_double, 80.0); gst_object_unref (elem); } @@ -668,13 +647,13 @@ GST_END_TEST; GST_START_TEST (controller_interpolate_cubic_too_few_cp) { GstInterpolationControlSource *csource; + GstTimedValueControlSource *cs; GstElement *elem; gboolean res; - GValue val_double = { 0, }; - elem = gst_element_factory_make ("testmonosource", "test_source"); + elem = gst_element_factory_make ("testmonosource", NULL); - /* Get interpolation control source */ + /* new interpolation control source */ csource = gst_interpolation_control_source_new (); fail_unless (csource != NULL); @@ -685,14 +664,10 @@ GST_START_TEST (controller_interpolate_cubic_too_few_cp) g_object_set (csource, "mode", GST_INTERPOLATION_MODE_CUBIC, NULL); /* set 2 control values */ - g_value_init (&val_double, G_TYPE_DOUBLE); - g_value_set_double (&val_double, 0.0); - res = gst_timed_value_control_source_set ((GstTimedValueControlSource *) - csource, 0 * GST_SECOND, &val_double); + cs = (GstTimedValueControlSource *) csource; + res = gst_timed_value_control_source_set (cs, 0 * GST_SECOND, 0.0); fail_unless (res, NULL); - g_value_set_double (&val_double, 4.0); - res = gst_timed_value_control_source_set ((GstTimedValueControlSource *) - csource, 2 * GST_SECOND, &val_double); + res = gst_timed_value_control_source_set (cs, 2 * GST_SECOND, 0.4); fail_unless (res, NULL); g_object_unref (csource); @@ -703,9 +678,9 @@ GST_START_TEST (controller_interpolate_cubic_too_few_cp) gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND); fail_unless_equals_float (GST_TEST_MONO_SOURCE (elem)->val_double, 0.0); gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND); - fail_unless_equals_float (GST_TEST_MONO_SOURCE (elem)->val_double, 2.0); + fail_unless_equals_float (GST_TEST_MONO_SOURCE (elem)->val_double, 20.0); gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND); - fail_unless_equals_float (GST_TEST_MONO_SOURCE (elem)->val_double, 4.0); + fail_unless_equals_float (GST_TEST_MONO_SOURCE (elem)->val_double, 40.0); gst_object_unref (elem); } @@ -716,65 +691,54 @@ GST_END_TEST; GST_START_TEST (controller_interpolation_unset) { GstInterpolationControlSource *csource; + GstTimedValueControlSource *cs; GstElement *elem; gboolean res; - GValue val_ulong = { 0, }; - elem = gst_element_factory_make ("testmonosource", "test_source"); + elem = gst_element_factory_make ("testmonosource", NULL); - /* Get interpolation control source */ + /* new interpolation control source */ csource = gst_interpolation_control_source_new (); fail_unless (csource != NULL); - fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "ulong", + fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", GST_CONTROL_SOURCE (csource))); /* set interpolation mode */ g_object_set (csource, "mode", GST_INTERPOLATION_MODE_NONE, NULL); /* set control values */ - g_value_init (&val_ulong, G_TYPE_ULONG); - g_value_set_ulong (&val_ulong, 0); - res = gst_timed_value_control_source_set ((GstTimedValueControlSource *) - csource, 0 * GST_SECOND, &val_ulong); + cs = (GstTimedValueControlSource *) csource; + res = gst_timed_value_control_source_set (cs, 0 * GST_SECOND, 0.0); fail_unless (res, NULL); - g_value_set_ulong (&val_ulong, 100); - res = gst_timed_value_control_source_set ((GstTimedValueControlSource *) - csource, 1 * GST_SECOND, &val_ulong); + res = gst_timed_value_control_source_set (cs, 1 * GST_SECOND, 1.0); fail_unless (res, NULL); - g_value_set_ulong (&val_ulong, 50); - res = gst_timed_value_control_source_set ((GstTimedValueControlSource *) - csource, 2 * GST_SECOND, &val_ulong); + res = gst_timed_value_control_source_set (cs, 2 * GST_SECOND, 0.5); fail_unless (res, NULL); /* verify values */ gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 100); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 100); gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 50); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 50); /* unset second */ - res = gst_timed_value_control_source_unset ((GstTimedValueControlSource *) - csource, 1 * GST_SECOND); + res = gst_timed_value_control_source_unset (cs, 1 * GST_SECOND); fail_unless (res, NULL); /* verify value again */ gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 50); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 50); /* unset all values, reset and try to unset again */ - fail_unless (gst_timed_value_control_source_unset ((GstTimedValueControlSource - *) csource, 0 * GST_SECOND)); - fail_unless (gst_timed_value_control_source_unset ((GstTimedValueControlSource - *) csource, 2 * GST_SECOND)); - gst_timed_value_control_source_unset_all ((GstTimedValueControlSource *) - csource); - fail_if (gst_timed_value_control_source_unset ((GstTimedValueControlSource *) - csource, 2 * GST_SECOND)); + fail_unless (gst_timed_value_control_source_unset (cs, 0 * GST_SECOND)); + fail_unless (gst_timed_value_control_source_unset (cs, 2 * GST_SECOND)); + gst_timed_value_control_source_unset_all (cs); + fail_if (gst_timed_value_control_source_unset (cs, 2 * GST_SECOND)); g_object_unref (csource); @@ -787,48 +751,44 @@ GST_END_TEST; GST_START_TEST (controller_interpolation_unset_all) { GstInterpolationControlSource *csource; + GstTimedValueControlSource *cs; GstElement *elem; gboolean res; - GValue val_ulong = { 0, }; - elem = gst_element_factory_make ("testmonosource", "test_source"); + elem = gst_element_factory_make ("testmonosource", NULL); - /* Get interpolation control source */ + /* new interpolation control source */ csource = gst_interpolation_control_source_new (); fail_unless (csource != NULL); - fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "ulong", + fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", GST_CONTROL_SOURCE (csource))); /* set interpolation mode */ g_object_set (csource, "mode", GST_INTERPOLATION_MODE_NONE, NULL); /* set control values */ - g_value_init (&val_ulong, G_TYPE_ULONG); - g_value_set_ulong (&val_ulong, 0); - res = gst_timed_value_control_source_set ((GstTimedValueControlSource *) - csource, 0 * GST_SECOND, &val_ulong); + cs = (GstTimedValueControlSource *) csource; + res = gst_timed_value_control_source_set (cs, 0 * GST_SECOND, 0.0); fail_unless (res, NULL); - g_value_set_ulong (&val_ulong, 100); - res = gst_timed_value_control_source_set ((GstTimedValueControlSource *) - csource, 1 * GST_SECOND, &val_ulong); + res = gst_timed_value_control_source_set (cs, 1 * GST_SECOND, 1.0); fail_unless (res, NULL); /* verify values */ gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 100); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 100); /* unset all */ - gst_timed_value_control_source_unset_all ((GstTimedValueControlSource *) - csource); + gst_timed_value_control_source_unset_all (cs); + GST_TEST_MONO_SOURCE (elem)->val_int = 0; g_object_unref (csource); /* verify value again */ gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_unref (elem); } @@ -839,46 +799,55 @@ GST_END_TEST; GST_START_TEST (controller_interpolation_linear_value_array) { GstInterpolationControlSource *csource; + GstTimedValueControlSource *cs; GstElement *elem; gboolean res; - GValue val_ulong = { 0, }; - gulong *values; + gdouble *raw_values; + GValue *g_values; - elem = gst_element_factory_make ("testmonosource", "test_source"); + elem = gst_element_factory_make ("testmonosource", NULL); - /* Get interpolation control source */ + /* new interpolation control source */ csource = gst_interpolation_control_source_new (); fail_unless (csource != NULL); - fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "ulong", + fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", GST_CONTROL_SOURCE (csource))); /* set interpolation mode */ g_object_set (csource, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL); /* set control values */ - g_value_init (&val_ulong, G_TYPE_ULONG); - g_value_set_ulong (&val_ulong, 0); - res = gst_timed_value_control_source_set ((GstTimedValueControlSource *) - csource, 0 * GST_SECOND, &val_ulong); + cs = (GstTimedValueControlSource *) csource; + res = gst_timed_value_control_source_set (cs, 0 * GST_SECOND, 0.0); fail_unless (res, NULL); - g_value_set_ulong (&val_ulong, 100); - res = gst_timed_value_control_source_set ((GstTimedValueControlSource *) - csource, 2 * GST_SECOND, &val_ulong); + res = gst_timed_value_control_source_set (cs, 2 * GST_SECOND, 1.0); fail_unless (res, NULL); - /* now pull in values for some timestamps */ - values = g_new (gulong, 3); + /* now pull in raw-values for some timestamps */ + raw_values = g_new (gdouble, 3); fail_unless (gst_control_source_get_value_array (GST_CONTROL_SOURCE (csource), - 0, GST_SECOND, 3, (gpointer) values)); - fail_unless_equals_int ((values)[0], 0); - fail_unless_equals_int ((values)[1], 50); - fail_unless_equals_int ((values)[2], 100); + 0, GST_SECOND, 3, raw_values)); + fail_unless_equals_float ((raw_values)[0], 0.0); + fail_unless_equals_float ((raw_values)[1], 0.5); + fail_unless_equals_float ((raw_values)[2], 1.0); + + g_free (raw_values); + + /* now pull in mapped values for some timestamps */ + g_values = g_new0 (GValue, 3); + + fail_unless (gst_object_get_value_array (GST_OBJECT (elem), "int", + 0, GST_SECOND, 3, g_values)); + fail_unless_equals_int (g_value_get_int (&g_values[0]), 0); + fail_unless_equals_int (g_value_get_int (&g_values[1]), 50); + fail_unless_equals_int (g_value_get_int (&g_values[2]), 100); + + g_free (g_values); g_object_unref (csource); - g_free (values); gst_object_unref (elem); } @@ -888,13 +857,13 @@ GST_END_TEST; GST_START_TEST (controller_interpolation_linear_invalid_values) { GstInterpolationControlSource *csource; + GstTimedValueControlSource *cs; GstElement *elem; gboolean res; - GValue val_float = { 0, }; - elem = gst_element_factory_make ("testmonosource", "test_source"); + elem = gst_element_factory_make ("testmonosource", NULL); - /* Get interpolation control source */ + /* new interpolation control source */ csource = gst_interpolation_control_source_new (); fail_unless (csource != NULL); @@ -905,14 +874,10 @@ GST_START_TEST (controller_interpolation_linear_invalid_values) g_object_set (csource, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL); /* set control values */ - g_value_init (&val_float, G_TYPE_FLOAT); - g_value_set_float (&val_float, 200.0); - res = gst_timed_value_control_source_set ((GstTimedValueControlSource *) - csource, 0 * GST_SECOND, &val_float); + cs = (GstTimedValueControlSource *) csource; + res = gst_timed_value_control_source_set (cs, 0 * GST_SECOND, 2.0); fail_unless (res, NULL); - g_value_set_float (&val_float, -200.0); - res = gst_timed_value_control_source_set ((GstTimedValueControlSource *) - csource, 4 * GST_SECOND, &val_float); + res = gst_timed_value_control_source_set (cs, 4 * GST_SECOND, -2.0); fail_unless (res, NULL); g_object_unref (csource); @@ -946,78 +911,67 @@ GST_END_TEST; GST_START_TEST (controller_interpolation_linear_default_values) { GstInterpolationControlSource *csource; + GstTimedValueControlSource *cs; GstElement *elem; gboolean res; - GValue val_ulong = { 0, }; - elem = gst_element_factory_make ("testmonosource", "test_source"); + elem = gst_element_factory_make ("testmonosource", NULL); - /* Get interpolation control source */ + /* new interpolation control source */ csource = gst_interpolation_control_source_new (); fail_unless (csource != NULL); - fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "ulong", + fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", GST_CONTROL_SOURCE (csource))); /* set interpolation mode */ g_object_set (csource, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL); - g_value_init (&val_ulong, G_TYPE_ULONG); - /* Should fail if no value was set yet * FIXME: will not fail, as interpolation assumes val[0]=default_value if * nothing else is set. fail_if (gst_control_source_get_value (GST_CONTROL_SOURCE (csource), - 1 * GST_SECOND, &val_ulong)); + 1 * GST_SECOND, &val_int)); */ /* set control values */ - g_value_set_ulong (&val_ulong, 0); - res = gst_timed_value_control_source_set ((GstTimedValueControlSource *) - csource, 1 * GST_SECOND, &val_ulong); + cs = (GstTimedValueControlSource *) csource; + res = gst_timed_value_control_source_set (cs, 1 * GST_SECOND, 0.0); fail_unless (res, NULL); - g_value_set_ulong (&val_ulong, 100); - res = gst_timed_value_control_source_set ((GstTimedValueControlSource *) - csource, 3 * GST_SECOND, &val_ulong); + res = gst_timed_value_control_source_set (cs, 3 * GST_SECOND, 1.0); fail_unless (res, NULL); /* now pull in values for some timestamps */ /* should give the value of the first control point for timestamps before it */ gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 50); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 50); gst_object_sync_values (GST_OBJECT (elem), 3 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 100); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 100); /* set control values */ - g_value_set_ulong (&val_ulong, 0); - res = gst_timed_value_control_source_set ((GstTimedValueControlSource *) - csource, 0 * GST_SECOND, &val_ulong); + res = gst_timed_value_control_source_set (cs, 0 * GST_SECOND, 0.0); fail_unless (res, NULL); - g_value_set_ulong (&val_ulong, 100); - res = gst_timed_value_control_source_set ((GstTimedValueControlSource *) - csource, 2 * GST_SECOND, &val_ulong); + res = gst_timed_value_control_source_set (cs, 2 * GST_SECOND, 1.0); fail_unless (res, NULL); /* unset the old ones */ - res = gst_timed_value_control_source_unset ((GstTimedValueControlSource *) - csource, 1 * GST_SECOND); + res = gst_timed_value_control_source_unset (cs, 1 * GST_SECOND); fail_unless (res, NULL); - res = gst_timed_value_control_source_unset ((GstTimedValueControlSource *) - csource, 3 * GST_SECOND); + res = gst_timed_value_control_source_unset (cs, 3 * GST_SECOND); fail_unless (res, NULL); /* now pull in values for some timestamps */ /* should now give our value for timestamp 0 */ gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 50); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 50); gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 100); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 100); g_object_unref (csource); @@ -1029,136 +983,126 @@ GST_END_TEST; /* test gst_controller_set_disabled() with linear interpolation */ GST_START_TEST (controller_interpolate_linear_disabled) { - GstInterpolationControlSource *csource, *csource2; + GstInterpolationControlSource *csource1, *csource2; + GstTimedValueControlSource *cs; GstElement *elem; gboolean res; - GValue val_ulong = { 0, } - , val_double = { - 0,}; - elem = gst_element_factory_make ("testmonosource", "test_source"); + elem = gst_element_factory_make ("testmonosource", NULL); - /* Get interpolation control source */ - csource = gst_interpolation_control_source_new (); + /* new interpolation control source */ + csource1 = gst_interpolation_control_source_new (); csource2 = gst_interpolation_control_source_new (); - fail_unless (csource != NULL); - fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "ulong", - GST_CONTROL_SOURCE (csource))); + fail_unless (csource1 != NULL); + fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", + GST_CONTROL_SOURCE (csource1))); fail_unless (csource2 != NULL); fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "double", GST_CONTROL_SOURCE (csource2))); /* set interpolation mode */ - g_object_set (csource, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL); + g_object_set (csource1, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL); g_object_set (csource2, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL); /* set control values */ - g_value_init (&val_ulong, G_TYPE_ULONG); - g_value_set_ulong (&val_ulong, 0); - res = gst_timed_value_control_source_set ((GstTimedValueControlSource *) - csource, 0 * GST_SECOND, &val_ulong); + cs = (GstTimedValueControlSource *) csource1; + res = gst_timed_value_control_source_set (cs, 0 * GST_SECOND, 0.0); fail_unless (res, NULL); - g_value_set_ulong (&val_ulong, 100); - res = gst_timed_value_control_source_set ((GstTimedValueControlSource *) - csource, 2 * GST_SECOND, &val_ulong); + res = gst_timed_value_control_source_set (cs, 2 * GST_SECOND, 1.0); fail_unless (res, NULL); - g_object_unref (csource); + g_object_unref (csource1); -/* set control values */ - g_value_init (&val_double, G_TYPE_DOUBLE); - g_value_set_double (&val_double, 2.0); - res = gst_timed_value_control_source_set ((GstTimedValueControlSource *) - csource2, 0 * GST_SECOND, &val_double); + /* set control values */ + cs = (GstTimedValueControlSource *) csource2; + res = gst_timed_value_control_source_set (cs, 0 * GST_SECOND, 0.2); fail_unless (res, NULL); - g_value_set_double (&val_double, 4.0); - res = gst_timed_value_control_source_set ((GstTimedValueControlSource *) - csource2, 2 * GST_SECOND, &val_double); + res = gst_timed_value_control_source_set (cs, 2 * GST_SECOND, 0.4); fail_unless (res, NULL); - g_object_unref (G_OBJECT (csource2)); + g_object_unref (csource2); /* now pull in values for some timestamps */ gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); - fail_unless (GST_TEST_MONO_SOURCE (elem)->val_double == 2.0, NULL); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); + fail_unless_equals_float (GST_TEST_MONO_SOURCE (elem)->val_double, 20.0); gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 50); - fail_unless (GST_TEST_MONO_SOURCE (elem)->val_double == 3.0, NULL); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 50); + fail_unless_equals_float (GST_TEST_MONO_SOURCE (elem)->val_double, 30.0); gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 100); - fail_unless (GST_TEST_MONO_SOURCE (elem)->val_double == 4.0, NULL); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 100); + fail_unless_equals_float (GST_TEST_MONO_SOURCE (elem)->val_double, 40.0); /* now pull in values for some timestamps, prop double disabled */ - GST_TEST_MONO_SOURCE (elem)->val_ulong = 0; + GST_TEST_MONO_SOURCE (elem)->val_int = 0; GST_TEST_MONO_SOURCE (elem)->val_double = 0.0; gst_object_set_control_binding_disabled (GST_OBJECT (elem), "double", TRUE); gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); - fail_unless (GST_TEST_MONO_SOURCE (elem)->val_double == 0.0, NULL); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); + fail_unless_equals_float (GST_TEST_MONO_SOURCE (elem)->val_double, 0.0); gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 50); - fail_unless (GST_TEST_MONO_SOURCE (elem)->val_double == 0.0, NULL); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 50); + fail_unless_equals_float (GST_TEST_MONO_SOURCE (elem)->val_double, 0.0); gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 100); - fail_unless (GST_TEST_MONO_SOURCE (elem)->val_double == 0.0, NULL); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 100); + fail_unless_equals_float (GST_TEST_MONO_SOURCE (elem)->val_double, 0.0); /* now pull in values for some timestamps, after enabling double again */ - GST_TEST_MONO_SOURCE (elem)->val_ulong = 0; + GST_TEST_MONO_SOURCE (elem)->val_int = 0; GST_TEST_MONO_SOURCE (elem)->val_double = 0.0; gst_object_set_control_binding_disabled (GST_OBJECT (elem), "double", FALSE); gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); - fail_unless (GST_TEST_MONO_SOURCE (elem)->val_double == 2.0, NULL); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); + fail_unless_equals_float (GST_TEST_MONO_SOURCE (elem)->val_double, 20.0); gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 50); - fail_unless (GST_TEST_MONO_SOURCE (elem)->val_double == 3.0, NULL); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 50); + fail_unless_equals_float (GST_TEST_MONO_SOURCE (elem)->val_double, 30.0); gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 100); - fail_unless (GST_TEST_MONO_SOURCE (elem)->val_double == 4.0, NULL); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 100); + fail_unless_equals_float (GST_TEST_MONO_SOURCE (elem)->val_double, 40.0); /* now pull in values for some timestamps, after disabling all props */ - GST_TEST_MONO_SOURCE (elem)->val_ulong = 0; + GST_TEST_MONO_SOURCE (elem)->val_int = 0; GST_TEST_MONO_SOURCE (elem)->val_double = 0.0; gst_object_set_control_bindings_disabled (GST_OBJECT (elem), TRUE); gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); - fail_unless (GST_TEST_MONO_SOURCE (elem)->val_double == 0.0, NULL); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); + fail_unless_equals_float (GST_TEST_MONO_SOURCE (elem)->val_double, 0.0); gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); - fail_unless (GST_TEST_MONO_SOURCE (elem)->val_double == 0.0, NULL); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); + fail_unless_equals_float (GST_TEST_MONO_SOURCE (elem)->val_double, 0.0); gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); - fail_unless (GST_TEST_MONO_SOURCE (elem)->val_double == 0.0, NULL); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); + fail_unless_equals_float (GST_TEST_MONO_SOURCE (elem)->val_double, 0.0); /* now pull in values for some timestamps, enabling double again */ - GST_TEST_MONO_SOURCE (elem)->val_ulong = 0; + GST_TEST_MONO_SOURCE (elem)->val_int = 0; GST_TEST_MONO_SOURCE (elem)->val_double = 0.0; gst_object_set_control_binding_disabled (GST_OBJECT (elem), "double", FALSE); gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); - fail_unless (GST_TEST_MONO_SOURCE (elem)->val_double == 2.0, NULL); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); + fail_unless_equals_float (GST_TEST_MONO_SOURCE (elem)->val_double, 20.0); gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); - fail_unless (GST_TEST_MONO_SOURCE (elem)->val_double == 3.0, NULL); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); + fail_unless_equals_float (GST_TEST_MONO_SOURCE (elem)->val_double, 30.0); gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); - fail_unless (GST_TEST_MONO_SOURCE (elem)->val_double == 4.0, NULL); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); + fail_unless_equals_float (GST_TEST_MONO_SOURCE (elem)->val_double, 40.0); /* now pull in values for some timestamps, enabling all */ - GST_TEST_MONO_SOURCE (elem)->val_ulong = 0; + GST_TEST_MONO_SOURCE (elem)->val_int = 0; GST_TEST_MONO_SOURCE (elem)->val_double = 0.0; gst_object_set_control_bindings_disabled (GST_OBJECT (elem), FALSE); gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); - fail_unless (GST_TEST_MONO_SOURCE (elem)->val_double == 2.0, NULL); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); + fail_unless_equals_float (GST_TEST_MONO_SOURCE (elem)->val_double, 20.0); gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 50); - fail_unless (GST_TEST_MONO_SOURCE (elem)->val_double == 3.0, NULL); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 50); + fail_unless_equals_float (GST_TEST_MONO_SOURCE (elem)->val_double, 30.0); gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 100); - fail_unless (GST_TEST_MONO_SOURCE (elem)->val_double == 4.0, NULL); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 100); + fail_unless_equals_float (GST_TEST_MONO_SOURCE (elem)->val_double, 40.0); gst_object_unref (elem); } @@ -1174,13 +1118,13 @@ GST_START_TEST (controller_interpolation_set_from_list) GSList *list = NULL; /* test that an invalid timestamp throws a warning of some sort */ - elem = gst_element_factory_make ("testmonosource", "test_source"); + elem = gst_element_factory_make ("testmonosource", NULL); - /* Get interpolation control source */ + /* new interpolation control source */ csource = gst_interpolation_control_source_new (); fail_unless (csource != NULL); - fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "ulong", + fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", GST_CONTROL_SOURCE (csource))); /* set interpolation mode */ @@ -1189,8 +1133,7 @@ GST_START_TEST (controller_interpolation_set_from_list) /* set control value */ tval = g_new0 (GstTimedValue, 1); tval->timestamp = GST_CLOCK_TIME_NONE; - g_value_init (&tval->value, G_TYPE_ULONG); - g_value_set_ulong (&tval->value, 0); + tval->value = 0.0; list = g_slist_append (list, tval); @@ -1205,7 +1148,6 @@ GST_START_TEST (controller_interpolation_set_from_list) g_object_unref (csource); /* allocated GstTimedValue now belongs to the controller, but list not */ - g_value_unset (&tval->value); g_free (tval); g_slist_free (list); gst_object_unref (elem); @@ -1218,48 +1160,45 @@ GST_END_TEST; GST_START_TEST (controller_interpolate_linear_before_ts0) { GstInterpolationControlSource *csource; + GstTimedValueControlSource *cs; GstElement *elem; gboolean res; - GValue val_ulong = { 0, }; - elem = gst_element_factory_make ("testmonosource", "test_source"); + elem = gst_element_factory_make ("testmonosource", NULL); - /* Get interpolation control source */ + /* new interpolation control source */ csource = gst_interpolation_control_source_new (); fail_unless (csource != NULL); - fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "ulong", + fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", GST_CONTROL_SOURCE (csource))); /* set interpolation mode */ g_object_set (csource, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL); /* set control values */ - g_value_init (&val_ulong, G_TYPE_ULONG); - g_value_set_ulong (&val_ulong, 100); - res = gst_timed_value_control_source_set ((GstTimedValueControlSource *) - csource, 2 * GST_SECOND, &val_ulong); + cs = (GstTimedValueControlSource *) csource; + res = gst_timed_value_control_source_set (cs, 2 * GST_SECOND, 1.0); fail_unless (res, NULL); - g_value_set_ulong (&val_ulong, 0); - res = gst_timed_value_control_source_set ((GstTimedValueControlSource *) - csource, 4 * GST_SECOND, &val_ulong); + res = gst_timed_value_control_source_set (cs, 4 * GST_SECOND, 0.0); fail_unless (res, NULL); g_object_unref (csource); /* now pull in values for some timestamps after first control point */ gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 100); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 100); gst_object_sync_values (GST_OBJECT (elem), 3 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 50); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 50); gst_object_sync_values (GST_OBJECT (elem), 4 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); /* now pull in values for some timestamps before first control point */ + GST_TEST_MONO_SOURCE (elem)->val_int = 25; gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 50); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 25); gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 25); gst_object_unref (elem); } @@ -1270,17 +1209,17 @@ GST_END_TEST; GST_START_TEST (controller_interpolation_cp_count) { GstInterpolationControlSource *csource; + GstTimedValueControlSource *cs; GstElement *elem; gboolean res; - GValue val_ulong = { 0, }; - elem = gst_element_factory_make ("testmonosource", "test_source"); + elem = gst_element_factory_make ("testmonosource", NULL); - /* Get interpolation control source */ + /* new interpolation control source */ csource = gst_interpolation_control_source_new (); fail_unless (csource != NULL); - fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "ulong", + fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", GST_CONTROL_SOURCE (csource))); /* set interpolation mode */ @@ -1290,32 +1229,22 @@ GST_START_TEST (controller_interpolation_cp_count) (GstTimedValueControlSource *) csource) == 0); /* set control values */ - g_value_init (&val_ulong, G_TYPE_ULONG); - g_value_set_ulong (&val_ulong, 0); - res = gst_timed_value_control_source_set ((GstTimedValueControlSource *) - csource, 0 * GST_SECOND, &val_ulong); + cs = (GstTimedValueControlSource *) csource; + res = gst_timed_value_control_source_set (cs, 0 * GST_SECOND, 0.0); fail_unless (res, NULL); - fail_unless (gst_timed_value_control_source_get_count ( - (GstTimedValueControlSource *) csource) == 1); - g_value_set_ulong (&val_ulong, 100); - res = gst_timed_value_control_source_set ((GstTimedValueControlSource *) - csource, 2 * GST_SECOND, &val_ulong); + fail_unless (gst_timed_value_control_source_get_count (cs) == 1); + res = gst_timed_value_control_source_set (cs, 2 * GST_SECOND, 1.0); fail_unless (res, NULL); - fail_unless (gst_timed_value_control_source_get_count ( - (GstTimedValueControlSource *) csource) == 2); + fail_unless (gst_timed_value_control_source_get_count (cs) == 2); /* now unset control values */ - res = gst_timed_value_control_source_unset ((GstTimedValueControlSource *) - csource, 2 * GST_SECOND); + res = gst_timed_value_control_source_unset (cs, 2 * GST_SECOND); fail_unless (res, NULL); - fail_unless (gst_timed_value_control_source_get_count ( - (GstTimedValueControlSource *) csource) == 1); + fail_unless (gst_timed_value_control_source_get_count (cs) == 1); - res = gst_timed_value_control_source_unset ((GstTimedValueControlSource *) - csource, 0 * GST_SECOND); + res = gst_timed_value_control_source_unset (cs, 0 * GST_SECOND); fail_unless (res, NULL); - fail_unless (gst_timed_value_control_source_get_count ( - (GstTimedValueControlSource *) csource) == 0); + fail_unless (gst_timed_value_control_source_get_count (cs) == 0); g_object_unref (csource); @@ -1329,56 +1258,48 @@ GST_START_TEST (controller_lfo_sine) { GstLFOControlSource *csource; GstElement *elem; - GValue amp = { 0, }; - GValue off = { 0, }; - elem = gst_element_factory_make ("testmonosource", "test_source"); + elem = gst_element_factory_make ("testmonosource", NULL); - /* Get interpolation control source */ + /* new lfo control source */ csource = gst_lfo_control_source_new (); fail_unless (csource != NULL); - fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "ulong", + fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", GST_CONTROL_SOURCE (csource))); - /* set amplitude and offset values */ - g_value_init (&, G_TYPE_ULONG); - g_value_init (&off, G_TYPE_ULONG); - g_value_set_ulong (&, 100); - g_value_set_ulong (&off, 100); - - /* set waveform mode */ + /* configure lfo */ g_object_set (csource, "waveform", GST_LFO_WAVEFORM_SINE, "frequency", 1.0, "timeshift", (GstClockTime) 0, - "amplitude", &, "offset", &off, NULL); + "amplitude", 0.5, "offset", 0.5, NULL); g_object_unref (csource); /* now pull in values for some timestamps */ gst_object_sync_values (GST_OBJECT (elem), 0 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 100); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 50); gst_object_sync_values (GST_OBJECT (elem), 250 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 200); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 100); gst_object_sync_values (GST_OBJECT (elem), 500 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 100); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 50); gst_object_sync_values (GST_OBJECT (elem), 750 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_sync_values (GST_OBJECT (elem), 1000 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 100); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 50); gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 200); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 100); gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 100); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 50); gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_sync_values (GST_OBJECT (elem), 2000 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 100); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 50); gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 200); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 100); gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 100); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 50); gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_unref (elem); } @@ -1390,56 +1311,48 @@ GST_START_TEST (controller_lfo_sine_timeshift) { GstLFOControlSource *csource; GstElement *elem; - GValue amp = { 0, }; - GValue off = { 0, }; - elem = gst_element_factory_make ("testmonosource", "test_source"); + elem = gst_element_factory_make ("testmonosource", NULL); - /* Get interpolation control source */ + /* new lfo control source */ csource = gst_lfo_control_source_new (); fail_unless (csource != NULL); - fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "ulong", + fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", GST_CONTROL_SOURCE (csource))); - /* set amplitude and offset values */ - g_value_init (&, G_TYPE_ULONG); - g_value_init (&off, G_TYPE_ULONG); - g_value_set_ulong (&, 100); - g_value_set_ulong (&off, 100); - - /* set waveform mode */ + /* configure lfo */ g_object_set (csource, "waveform", GST_LFO_WAVEFORM_SINE, "frequency", 1.0, "timeshift", 250 * GST_MSECOND, - "amplitude", &, "offset", &off, NULL); + "amplitude", 0.5, "offset", 0.5, NULL); g_object_unref (csource); /* now pull in values for some timestamps */ gst_object_sync_values (GST_OBJECT (elem), 0 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_sync_values (GST_OBJECT (elem), 250 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 100); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 50); gst_object_sync_values (GST_OBJECT (elem), 500 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 200); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 100); gst_object_sync_values (GST_OBJECT (elem), 750 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 100); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 50); gst_object_sync_values (GST_OBJECT (elem), 1000 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 100); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 50); gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 200); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 100); gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 100); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 50); gst_object_sync_values (GST_OBJECT (elem), 2000 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 100); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 50); gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 200); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 100); gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 100); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 50); gst_object_unref (elem); } @@ -1451,56 +1364,48 @@ GST_START_TEST (controller_lfo_square) { GstLFOControlSource *csource; GstElement *elem; - GValue amp = { 0, }; - GValue off = { 0, }; - elem = gst_element_factory_make ("testmonosource", "test_source"); + elem = gst_element_factory_make ("testmonosource", NULL); - /* Get interpolation control source */ + /* new lfo control source */ csource = gst_lfo_control_source_new (); fail_unless (csource != NULL); - fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "ulong", + fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", GST_CONTROL_SOURCE (csource))); - /* set amplitude and offset values */ - g_value_init (&, G_TYPE_ULONG); - g_value_init (&off, G_TYPE_ULONG); - g_value_set_ulong (&, 100); - g_value_set_ulong (&off, 100); - - /* set waveform mode */ + /* configure lfo */ g_object_set (csource, "waveform", GST_LFO_WAVEFORM_SQUARE, "frequency", 1.0, "timeshift", (GstClockTime) 0, - "amplitude", &, "offset", &off, NULL); + "amplitude", 0.5, "offset", 0.5, NULL); g_object_unref (csource); /* now pull in values for some timestamps */ gst_object_sync_values (GST_OBJECT (elem), 0 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_sync_values (GST_OBJECT (elem), 250 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_sync_values (GST_OBJECT (elem), 500 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 200); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 100); gst_object_sync_values (GST_OBJECT (elem), 750 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 200); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 100); gst_object_sync_values (GST_OBJECT (elem), 1000 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 200); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 100); gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 200); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 100); gst_object_sync_values (GST_OBJECT (elem), 2000 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 200); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 100); gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 200); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 100); gst_object_unref (elem); } @@ -1512,56 +1417,48 @@ GST_START_TEST (controller_lfo_saw) { GstLFOControlSource *csource; GstElement *elem; - GValue amp = { 0, }; - GValue off = { 0, }; - elem = gst_element_factory_make ("testmonosource", "test_source"); + elem = gst_element_factory_make ("testmonosource", NULL); - /* Get interpolation control source */ + /* new lfo control source */ csource = gst_lfo_control_source_new (); fail_unless (csource != NULL); - fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "ulong", + fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", GST_CONTROL_SOURCE (csource))); - /* set amplitude and offset values */ - g_value_init (&, G_TYPE_ULONG); - g_value_init (&off, G_TYPE_ULONG); - g_value_set_ulong (&, 100); - g_value_set_ulong (&off, 100); - - /* set waveform mode */ + /* configure lfo */ g_object_set (csource, "waveform", GST_LFO_WAVEFORM_SAW, "frequency", 1.0, "timeshift", (GstClockTime) 0, - "amplitude", &, "offset", &off, NULL); + "amplitude", 0.5, "offset", 0.5, NULL); g_object_unref (csource); /* now pull in values for some timestamps */ gst_object_sync_values (GST_OBJECT (elem), 0 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 200); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 100); gst_object_sync_values (GST_OBJECT (elem), 250 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 150); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 75); gst_object_sync_values (GST_OBJECT (elem), 500 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 100); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 50); gst_object_sync_values (GST_OBJECT (elem), 750 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 50); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 25); gst_object_sync_values (GST_OBJECT (elem), 1000 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 200); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 100); gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 150); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 75); gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 100); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 50); gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 50); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 25); gst_object_sync_values (GST_OBJECT (elem), 2000 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 200); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 100); gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 150); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 75); gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 100); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 50); gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 50); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 25); gst_object_unref (elem); } @@ -1573,56 +1470,48 @@ GST_START_TEST (controller_lfo_rsaw) { GstLFOControlSource *csource; GstElement *elem; - GValue amp = { 0, }; - GValue off = { 0, }; - elem = gst_element_factory_make ("testmonosource", "test_source"); + elem = gst_element_factory_make ("testmonosource", NULL); - /* Get interpolation control source */ + /* new lfo control source */ csource = gst_lfo_control_source_new (); fail_unless (csource != NULL); - fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "ulong", + fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", GST_CONTROL_SOURCE (csource))); - /* set amplitude and offset values */ - g_value_init (&, G_TYPE_ULONG); - g_value_init (&off, G_TYPE_ULONG); - g_value_set_ulong (&, 100); - g_value_set_ulong (&off, 100); - - /* set waveform mode */ + /* configure lfo */ g_object_set (csource, "waveform", GST_LFO_WAVEFORM_REVERSE_SAW, "frequency", 1.0, "timeshift", (GstClockTime) 0, - "amplitude", &, "offset", &off, NULL); + "amplitude", 0.5, "offset", 0.5, NULL); g_object_unref (csource); /* now pull in values for some timestamps */ gst_object_sync_values (GST_OBJECT (elem), 0 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_sync_values (GST_OBJECT (elem), 250 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 50); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 25); gst_object_sync_values (GST_OBJECT (elem), 500 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 100); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 50); gst_object_sync_values (GST_OBJECT (elem), 750 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 150); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 75); gst_object_sync_values (GST_OBJECT (elem), 1000 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 50); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 25); gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 100); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 50); gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 150); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 75); gst_object_sync_values (GST_OBJECT (elem), 2000 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 50); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 25); gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 100); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 50); gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 150); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 75); gst_object_unref (elem); } @@ -1634,56 +1523,48 @@ GST_START_TEST (controller_lfo_triangle) { GstLFOControlSource *csource; GstElement *elem; - GValue amp = { 0, }; - GValue off = { 0, }; - elem = gst_element_factory_make ("testmonosource", "test_source"); + elem = gst_element_factory_make ("testmonosource", NULL); - /* Get interpolation control source */ + /* new lfo control source */ csource = gst_lfo_control_source_new (); fail_unless (csource != NULL); - fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "ulong", + fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", GST_CONTROL_SOURCE (csource))); - /* set amplitude and offset values */ - g_value_init (&, G_TYPE_ULONG); - g_value_init (&off, G_TYPE_ULONG); - g_value_set_ulong (&, 100); - g_value_set_ulong (&off, 100); - - /* set waveform mode */ + /* configure lfo */ g_object_set (csource, "waveform", GST_LFO_WAVEFORM_TRIANGLE, "frequency", 1.0, "timeshift", (GstClockTime) 0, - "amplitude", &, "offset", &off, NULL); + "amplitude", 0.5, "offset", 0.5, NULL); g_object_unref (csource); /* now pull in values for some timestamps */ gst_object_sync_values (GST_OBJECT (elem), 0 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 100); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 50); gst_object_sync_values (GST_OBJECT (elem), 250 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 200); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 100); gst_object_sync_values (GST_OBJECT (elem), 500 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 100); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 50); gst_object_sync_values (GST_OBJECT (elem), 750 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_sync_values (GST_OBJECT (elem), 1000 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 100); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 50); gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 200); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 100); gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 100); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 50); gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_sync_values (GST_OBJECT (elem), 2000 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 100); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 50); gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 200); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 100); gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 100); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 50); gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_unref (elem); } @@ -1696,42 +1577,42 @@ GST_START_TEST (controller_lfo_none) GstLFOControlSource *csource; GstElement *elem; - elem = gst_element_factory_make ("testmonosource", "test_source"); + elem = gst_element_factory_make ("testmonosource", NULL); - /* Get interpolation control source */ + /* new lfo control source */ csource = gst_lfo_control_source_new (); fail_unless (csource != NULL); - fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "ulong", + fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", GST_CONTROL_SOURCE (csource))); g_object_unref (csource); /* now pull in values for some timestamps */ gst_object_sync_values (GST_OBJECT (elem), 0 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_sync_values (GST_OBJECT (elem), 250 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_sync_values (GST_OBJECT (elem), 500 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_sync_values (GST_OBJECT (elem), 750 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_sync_values (GST_OBJECT (elem), 1000 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_sync_values (GST_OBJECT (elem), 2000 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_unref (elem); } @@ -1742,47 +1623,41 @@ GST_END_TEST; GST_START_TEST (controller_trigger_exact) { GstTriggerControlSource *csource; + GstControlSource *cs; + GstTimedValueControlSource *tvcs; GstElement *elem; gboolean res; - GValue val_ulong = { 0, }; + gdouble raw_val; - elem = gst_element_factory_make ("testmonosource", "test_source"); + elem = gst_element_factory_make ("testmonosource", NULL); - /* Get interpolation control source */ + /* new interpolation control source */ csource = gst_trigger_control_source_new (); + tvcs = (GstTimedValueControlSource *) csource; + cs = (GstControlSource *) csource; fail_unless (csource != NULL); - fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "ulong", - GST_CONTROL_SOURCE (csource))); + fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", cs)); - g_value_init (&val_ulong, G_TYPE_ULONG); - fail_if (gst_control_source_get_value (GST_CONTROL_SOURCE (csource), - 0 * GST_SECOND, &val_ulong)); + fail_if (gst_control_source_get_value (cs, 0 * GST_SECOND, &raw_val)); /* set control values */ - g_value_set_ulong (&val_ulong, 50); - res = gst_timed_value_control_source_set ((GstTimedValueControlSource *) - csource, 0 * GST_SECOND, &val_ulong); + res = gst_timed_value_control_source_set (tvcs, 0 * GST_SECOND, 0.5); fail_unless (res, NULL); - g_value_set_ulong (&val_ulong, 100); - res = gst_timed_value_control_source_set ((GstTimedValueControlSource *) - csource, 2 * GST_SECOND, &val_ulong); + res = gst_timed_value_control_source_set (tvcs, 2 * GST_SECOND, 1.0); fail_unless (res, NULL); /* now pull in values for some timestamps */ - fail_unless (gst_control_source_get_value (GST_CONTROL_SOURCE (csource), - 0 * GST_SECOND, &val_ulong)); + fail_unless (gst_control_source_get_value (cs, 0 * GST_SECOND, &raw_val)); gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 50); - fail_unless (gst_control_source_get_value (GST_CONTROL_SOURCE (csource), - 1 * GST_SECOND, &val_ulong)); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 50); + fail_unless (gst_control_source_get_value (cs, 1 * GST_SECOND, &raw_val)); gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); - fail_unless (gst_control_source_get_value (GST_CONTROL_SOURCE (csource), - 2 * GST_SECOND, &val_ulong)); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); + fail_unless (gst_control_source_get_value (cs, 2 * GST_SECOND, &raw_val)); gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 100); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 100); g_object_unref (csource); gst_object_unref (elem); @@ -1793,47 +1668,45 @@ GST_END_TEST; GST_START_TEST (controller_trigger_tolerance) { GstTriggerControlSource *csource; + GstControlSource *cs; + GstTimedValueControlSource *tvcs; GstElement *elem; gboolean res; - GValue val_ulong = { 0, }; + gdouble raw_val; - elem = gst_element_factory_make ("testmonosource", "test_source"); + elem = gst_element_factory_make ("testmonosource", NULL); - /* Get interpolation control source */ + /* new interpolation control source */ csource = gst_trigger_control_source_new (); + tvcs = (GstTimedValueControlSource *) csource; + cs = (GstControlSource *) csource; fail_unless (csource != NULL); - fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "ulong", + fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", GST_CONTROL_SOURCE (csource))); g_object_set (csource, "tolerance", G_GINT64_CONSTANT (10), NULL); - g_value_init (&val_ulong, G_TYPE_ULONG); - fail_if (gst_control_source_get_value (GST_CONTROL_SOURCE (csource), - 0 * GST_SECOND, &val_ulong)); + fail_if (gst_control_source_get_value (cs, 0 * GST_SECOND, &raw_val)); /* set control values */ - g_value_set_ulong (&val_ulong, 50); - res = gst_timed_value_control_source_set ((GstTimedValueControlSource *) - csource, 0 * GST_SECOND, &val_ulong); + res = gst_timed_value_control_source_set (tvcs, 0 * GST_SECOND, 0.5); fail_unless (res, NULL); - g_value_set_ulong (&val_ulong, 100); - res = gst_timed_value_control_source_set ((GstTimedValueControlSource *) - csource, 2 * GST_SECOND, &val_ulong); + res = gst_timed_value_control_source_set (tvcs, 2 * GST_SECOND, 1.0); fail_unless (res, NULL); /* now pull in values for some timestamps */ gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 50); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 50); gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND + 5); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 50); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 50); gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 0); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 0); gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND - 5); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 100); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 100); gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND); - fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_ulong, 100); + fail_unless_equals_int (GST_TEST_MONO_SOURCE (elem)->val_int, 100); g_object_unref (csource); gst_object_unref (elem); diff --git a/tests/check/libs/gstlibscpp.cc b/tests/check/libs/gstlibscpp.cc index 3e41bf518c..6ea6de5fea 100644 --- a/tests/check/libs/gstlibscpp.cc +++ b/tests/check/libs/gstlibscpp.cc @@ -36,9 +36,8 @@ #include #include -#include #include -#include +#include #include diff --git a/tests/examples/controller/.gitignore b/tests/examples/controller/.gitignore index 0c0ec9f371..bbd65fff05 100644 --- a/tests/examples/controller/.gitignore +++ b/tests/examples/controller/.gitignore @@ -1,5 +1,6 @@ audio-example +control-sources *.bb *.bbg *.da -audio_example-audio-example.gcno +*.gcno diff --git a/tests/examples/controller/Makefile.am b/tests/examples/controller/Makefile.am index 98c1b65c28..c983f460c8 100644 --- a/tests/examples/controller/Makefile.am +++ b/tests/examples/controller/Makefile.am @@ -1,7 +1,8 @@ -noinst_PROGRAMS = audio-example +noinst_PROGRAMS = audio-example control-sources -audio_example_CFLAGS = $(GST_OBJ_CFLAGS) -I$(top_builddir)/libs -audio_example_LDADD = \ +AM_CFLAGS = $(GST_OBJ_CFLAGS) -I$(top_builddir)/libs + +LDADD = \ $(top_builddir)/libs/gst/controller/libgstcontroller-@GST_MAJORMINOR@.la \ $(GST_OBJ_LIBS) diff --git a/tests/examples/controller/audio-example.c b/tests/examples/controller/audio-example.c index cb347da745..f6047c5f45 100644 --- a/tests/examples/controller/audio-example.c +++ b/tests/examples/controller/audio-example.c @@ -17,10 +17,10 @@ main (gint argc, gchar ** argv) GstElement *src, *sink; GstElement *bin; GstInterpolationControlSource *csource1, *csource2; + GstTimedValueControlSource *cs; GstClock *clock; GstClockID clock_id; GstClockReturn wait_ret; - GValue vol = { 0, }; gst_init (&argc, &argv); @@ -62,25 +62,16 @@ main (gint argc, gchar ** argv) g_object_set (csource2, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL); /* set control values */ - g_value_init (&vol, G_TYPE_DOUBLE); - g_value_set_double (&vol, 0.0); - gst_timed_value_control_source_set ((GstTimedValueControlSource *) csource1, - 0 * GST_SECOND, &vol); - g_value_set_double (&vol, 1.0); - gst_timed_value_control_source_set ((GstTimedValueControlSource *) csource1, - 5 * GST_SECOND, &vol); + cs = (GstTimedValueControlSource *) csource1; + gst_timed_value_control_source_set (cs, 0 * GST_SECOND, 0.0); + gst_timed_value_control_source_set (cs, 5 * GST_SECOND, 1.0); g_object_unref (csource1); - g_value_set_double (&vol, 220.0); - gst_timed_value_control_source_set ((GstTimedValueControlSource *) csource2, - 0 * GST_SECOND, &vol); - g_value_set_double (&vol, 3520.0); - gst_timed_value_control_source_set ((GstTimedValueControlSource *) csource2, - 3 * GST_SECOND, &vol); - g_value_set_double (&vol, 440.0); - gst_timed_value_control_source_set ((GstTimedValueControlSource *) csource2, - 6 * GST_SECOND, &vol); + cs = (GstTimedValueControlSource *) csource2; + gst_timed_value_control_source_set (cs, 0 * GST_SECOND, 220.0); + gst_timed_value_control_source_set (cs, 3 * GST_SECOND, 3520.0); + gst_timed_value_control_source_set (cs, 6 * GST_SECOND, 440.0); g_object_unref (csource2); diff --git a/tests/examples/controller/control-sources.c b/tests/examples/controller/control-sources.c new file mode 100644 index 0000000000..71c7b5d6b8 --- /dev/null +++ b/tests/examples/controller/control-sources.c @@ -0,0 +1,286 @@ +/* + * control-sources.c + * + * Generates a datafile for various control sources. + * + * Needs gnuplot for plotting. + * plot "ctrl_interpolation.dat" using 1:2 with points title 'none', "" using 1:3 with points title 'linear', "" using 1:4 with points title 'cubic' + * plot "ctrl_lfo.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' + */ + +#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 for the TEST_OBJ", + 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 for the TEST_OBJ", + 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 for the TEST_OBJ", + 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 for the TEST_OBJ", + 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; + GstInterpolationControlSource *ics; + GstTimedValueControlSource *tvcs; + GstControlSource *cs; + gint t, i1, i2, i3; + FILE *f; + + e = (GstObject *) gst_element_factory_make ("testobj", NULL); + + ics = gst_interpolation_control_source_new (); + tvcs = (GstTimedValueControlSource *) ics; + cs = (GstControlSource *) ics; + + gst_object_set_control_source (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); + + if (!(f = fopen ("ctrl_interpolation.dat", "w"))) + exit (-1); + fprintf (f, "# Time None Linear Cubic\n"); + + for (t = 0; t < 40; t++) { + g_object_set (ics, "mode", GST_INTERPOLATION_MODE_NONE, NULL); + gst_object_sync_values (e, t * GST_SECOND); + i1 = GST_TEST_OBJ (e)->val_int; + + g_object_set (ics, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL); + gst_object_sync_values (e, t * GST_SECOND); + i2 = GST_TEST_OBJ (e)->val_int; + + g_object_set (ics, "mode", GST_INTERPOLATION_MODE_CUBIC, NULL); + gst_object_sync_values (e, t * GST_SECOND); + i3 = GST_TEST_OBJ (e)->val_int; + + fprintf (f, "%d %d %d %d\n", t, i1, i2, i3); + } + + fclose (f); + + gst_object_unref (e); +} + +static void +test_lfo (void) +{ + GstObject *e; + GstLFOControlSource *lfocs; + GstControlSource *cs; + gint t, i1, i2, i3, i4; + FILE *f; + + e = (GstObject *) gst_element_factory_make ("testobj", NULL); + + lfocs = gst_lfo_control_source_new (); + cs = (GstControlSource *) lfocs; + + gst_object_set_control_source (e, "int", cs); + + g_object_set (lfocs, + "frequency", (gdouble) 0.05, + "timeshift", (GstClockTime) 0, + "amplitude", (gdouble) 0.5, "offset", (gdouble) 0.5, NULL); + + if (!(f = fopen ("ctrl_lfo.dat", "w"))) + exit (-1); + fprintf (f, "# Time Sine Saw Square Triangle\n"); + + for (t = 0; t < 40; t++) { + g_object_set (lfocs, "waveform", GST_LFO_WAVEFORM_SINE, NULL); + gst_object_sync_values (e, t * GST_SECOND); + i1 = GST_TEST_OBJ (e)->val_int; + + g_object_set (lfocs, "waveform", GST_LFO_WAVEFORM_SAW, NULL); + gst_object_sync_values (e, t * GST_SECOND); + i2 = GST_TEST_OBJ (e)->val_int; + + g_object_set (lfocs, "waveform", GST_LFO_WAVEFORM_SQUARE, NULL); + gst_object_sync_values (e, t * GST_SECOND); + i3 = GST_TEST_OBJ (e)->val_int; + + g_object_set (lfocs, "waveform", GST_LFO_WAVEFORM_TRIANGLE, NULL); + gst_object_sync_values (e, t * GST_SECOND); + i4 = GST_TEST_OBJ (e)->val_int; + + fprintf (f, "%d %d %d %d %d\n", t, i1, i2, i3, i4); + } + + fclose (f); + + 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 (); + + return 0; +}