added unitconvert which has a registry of Units of Measurement and an api to convert one unit to another.

Original commit message from CVS:
added unitconvert which has a registry of Units of Measurement and an api to convert one unit to another.
Any required dparam now needs to specify what unit it represents so that an app can convert it to some other unit for presentation/other purposes.

Also added GST_DPMAN_PROCESS_CHUNK macro for elements which don't process their audio one sample at a time (ie, ladspa).
This commit is contained in:
Steve Baker 2002-04-14 10:08:21 +00:00
parent 1da7fc3498
commit a15b5ccc6d
9 changed files with 559 additions and 57 deletions

View file

@ -8,6 +8,7 @@ libgstcontrolinclude_HEADERS = \
dparammanager.h \
dparam.h \
dparam_smooth.h \
unitconvert.h \
dparamcommon.h \
dplinearinterp.h
@ -16,6 +17,7 @@ libgstcontrol_la_SOURCES = \
dparammanager.c \
dparam.c \
dparam_smooth.c \
unitconvert.c \
dplinearinterp.c
libgstcontrol_la_CFLAGS = $(GST_CFLAGS) -finline-functions -ffast-math

View file

@ -22,21 +22,29 @@
#include <gst/gst.h>
#include <gst/control/control.h>
static void
gst_control_init_common()
{
_gst_dpman_initialize ();
_gst_unitconv_initialize ();
}
void
gst_control_init (int *argc, char **argv[]) {
_gst_dpman_initialize ();
gst_control_init_common();
}
static gboolean
plugin_init (GModule *module, GstPlugin *plugin)
{
gst_plugin_set_longname (plugin, "Dynamic Parameters");
return TRUE;
gst_control_init_common();
gst_plugin_set_longname (plugin, "Dynamic Parameters");
return TRUE;
}
GstPluginDesc plugin_desc = {
GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"gstcontrol",
plugin_init
GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"gstcontrol",
plugin_init
};

View file

@ -30,6 +30,7 @@ extern "C" {
#include <gst/control/dparam.h>
#include <gst/control/dparam_smooth.h>
#include <gst/control/dplinearinterp.h>
#include <gst/control/unitconvert.h>
void gst_control_init (int *argc, char **argv[]);

View file

@ -37,8 +37,6 @@ enum {
ARG_VALUE_FLOAT,
ARG_VALUE_INT,
ARG_VALUE_INT64,
ARG_IS_LOG,
ARG_IS_RATE,
};
GType
@ -89,15 +87,6 @@ gst_dparam_class_init (GstDParamClass *klass)
"The value that should be changed if gint64 is the type",
G_MININT64, G_MAXINT64, 0, G_PARAM_READWRITE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_IS_LOG,
g_param_spec_boolean("is_log","Is a Log Value",
"This dparam should be interpreted on a log scale",
FALSE, G_PARAM_READABLE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_IS_RATE,
g_param_spec_boolean("is_rate","Is a sample rate proportion",
"This dparam value represents a proportion of the sample rate (eg half of the sample rate will be 0.5)",
FALSE, G_PARAM_READABLE));
gobject_class->dispose = gst_dparam_dispose;
/*gstobject_class->save_thyself = gst_dparam_save_thyself; */
@ -141,13 +130,7 @@ gst_dparam_get_property (GObject *object, guint prop_id, GValue *value, GParamSp
g_return_if_fail(GST_IS_DPARAM(object));
dparam = GST_DPARAM(object);
switch (prop_id) {
case ARG_IS_LOG:
g_value_set_boolean (value, dparam->is_log);
break;
case ARG_IS_RATE:
g_value_set_boolean (value, dparam->is_rate);
break;
switch (prop_id) {
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -237,7 +220,7 @@ gst_dparam_dispose (GObject *object)
*
*/
void
gst_dparam_attach (GstDParam *dparam, GstDParamManager *manager, GParamSpec *param_spec, gboolean is_log, gboolean is_rate)
gst_dparam_attach (GstDParam *dparam, GstDParamManager *manager, GParamSpec *param_spec, gchar *unit_name)
{
g_return_if_fail (dparam != NULL);
@ -245,13 +228,14 @@ gst_dparam_attach (GstDParam *dparam, GstDParamManager *manager, GParamSpec *par
g_return_if_fail (manager != NULL);
g_return_if_fail (GST_IS_DPMAN (manager));
g_return_if_fail (param_spec != NULL);
g_return_if_fail (unit_name != NULL);
g_return_if_fail (G_IS_PARAM_SPEC (param_spec));
GST_DPARAM_NAME(dparam) = g_param_spec_get_name(param_spec);
GST_DPARAM_PARAM_SPEC(dparam) = param_spec;
GST_DPARAM_MANAGER(dparam) = manager;
dparam->is_log = is_log;
dparam->is_rate = is_rate;
GST_DPARAM_UNIT_NAME(dparam) = unit_name;
GST_DPARAM_IS_LOG(dparam) = gst_unitconv_unit_is_logarithmic(unit_name);
GST_DEBUG(GST_CAT_PARAMS, "attaching %s to dparam %p",GST_DPARAM_NAME (dparam),dparam);
}

View file

@ -42,8 +42,8 @@ extern "C" {
#define GST_DPARAM_PARAM_SPEC(dparam) ((dparam)->param_spec)
#define GST_DPARAM_MANAGER(dparam) ((dparam)->manager)
#define GST_DPARAM_TYPE(dparam) ((dparam)->type)
#define GST_DPARAM_UNIT_NAME(dparam) ((dparam)->unit_name)
#define GST_DPARAM_IS_LOG(dparam) ((dparam)->is_log)
#define GST_DPARAM_IS_RATE(dparam) ((dparam)->is_rate)
#define GST_DPARAM_META_VALUES(dparam) ((dparam)->meta_values)
#define GST_DPARAM_META_PARAM_SPECS(dparam) ((dparam)->meta_param_specs)
#define GST_DPARAM_LOCK(dparam) (g_mutex_lock((dparam)->lock))
@ -76,8 +76,8 @@ struct _GstDParam {
gboolean ready_for_update;
gint64 next_update_timestamp;
gchar *unit_name;
gboolean is_log;
gboolean is_rate;
};
struct _GstDParamClass {
@ -89,7 +89,7 @@ struct _GstDParamClass {
GType gst_dparam_get_type (void);
GstDParam* gst_dparam_new (GType type);
void gst_dparam_attach (GstDParam *dparam, GstDParamManager *manager, GParamSpec *param_spec, gboolean is_log, gboolean is_rate);
void gst_dparam_attach (GstDParam *dparam, GstDParamManager *manager, GParamSpec *param_spec, gchar *unit_name);
void gst_dparam_detach (GstDParam *dparam);
void gst_dparam_do_update_default (GstDParam *dparam, gint64 timestamp, GValue *value);

View file

@ -24,6 +24,8 @@
#include <gst/gstinfo.h>
static GHashTable *_element_registry;
static gboolean _gst_dpman_init_done = FALSE;
enum {
NEW_REQUIRED_DPARAM,
LAST_SIGNAL
@ -32,7 +34,7 @@ enum {
static void gst_dpman_class_init (GstDParamManagerClass *klass);
static void gst_dpman_init (GstDParamManager *dpman);
static void gst_dpman_dispose (GObject *object);
static GstDParamWrapper* gst_dpman_new_wrapper(GstDParamManager *dpman, GParamSpec *param_spec, gboolean is_log, gboolean is_rate, GstDPMUpdateMethod update_method);
static GstDParamWrapper* gst_dpman_new_wrapper(GstDParamManager *dpman, GParamSpec *param_spec, gchar *unit_name, GstDPMUpdateMethod update_method);
static GstDParamWrapper* gst_dpman_get_wrapper(GstDParamManager *dpman, gchar *dparam_name);
static void gst_dpman_state_change (GstElement *element, gint old_state, gint new_state, GstDParamManager *dpman);
static void gst_dpman_caps_changed (GstPad *pad, GstCaps *caps, GstDParamManager *dpman);
@ -46,6 +48,10 @@ static guint gst_dpman_signals[LAST_SIGNAL] = { 0 };
void
_gst_dpman_initialize()
{
if (_gst_dpman_init_done) return;
_gst_dpman_init_done = TRUE;
_element_registry = g_hash_table_new(NULL,NULL);
}
GType
@ -91,7 +97,6 @@ gst_dpman_class_init (GstDParamManagerClass *klass)
gst_dpman_register_mode (klass, "disabled",
gst_dpman_preprocess_noop, gst_dpman_process_noop, NULL, NULL);
_element_registry = g_hash_table_new(NULL,NULL);
gst_dpman_signals[NEW_REQUIRED_DPARAM] =
g_signal_new ("new_required_dparam", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST,
@ -157,8 +162,7 @@ gst_dpman_dispose (GObject *object)
gboolean
gst_dpman_add_required_dparam_callback (GstDParamManager *dpman,
GParamSpec *param_spec,
gboolean is_log,
gboolean is_rate,
gchar *unit_name,
GstDPMUpdateFunction update_func,
gpointer update_data)
{
@ -168,7 +172,7 @@ gst_dpman_add_required_dparam_callback (GstDParamManager *dpman,
g_return_val_if_fail (GST_IS_DPMAN (dpman), FALSE);
g_return_val_if_fail (update_func != NULL, FALSE);
dpwrap = gst_dpman_new_wrapper(dpman, param_spec, is_log, is_rate, GST_DPMAN_CALLBACK);
dpwrap = gst_dpman_new_wrapper(dpman, param_spec, unit_name, GST_DPMAN_CALLBACK);
g_return_val_if_fail (dpwrap != NULL, FALSE);
@ -192,8 +196,7 @@ gst_dpman_add_required_dparam_callback (GstDParamManager *dpman,
gboolean
gst_dpman_add_required_dparam_direct (GstDParamManager *dpman,
GParamSpec *param_spec,
gboolean is_log,
gboolean is_rate,
gchar *unit_name,
gpointer update_data)
{
GstDParamWrapper* dpwrap;
@ -202,7 +205,7 @@ gst_dpman_add_required_dparam_direct (GstDParamManager *dpman,
g_return_val_if_fail (GST_IS_DPMAN (dpman), FALSE);
g_return_val_if_fail (update_data != NULL, FALSE);
dpwrap = gst_dpman_new_wrapper(dpman, param_spec, is_log, is_rate, GST_DPMAN_DIRECT);
dpwrap = gst_dpman_new_wrapper(dpman, param_spec, unit_name, GST_DPMAN_DIRECT);
g_return_val_if_fail (dpwrap != NULL, FALSE);
@ -226,8 +229,7 @@ gst_dpman_add_required_dparam_direct (GstDParamManager *dpman,
gboolean
gst_dpman_add_required_dparam_array (GstDParamManager *dpman,
GParamSpec *param_spec,
gboolean is_log,
gboolean is_rate,
gchar *unit_name,
gpointer update_data)
{
GstDParamWrapper* dpwrap;
@ -236,7 +238,7 @@ gst_dpman_add_required_dparam_array (GstDParamManager *dpman,
g_return_val_if_fail (GST_IS_DPMAN (dpman), FALSE);
g_return_val_if_fail (update_data != NULL, FALSE);
dpwrap = gst_dpman_new_wrapper(dpman, param_spec, is_log, is_rate, GST_DPMAN_ARRAY);
dpwrap = gst_dpman_new_wrapper(dpman, param_spec, unit_name, GST_DPMAN_ARRAY);
g_return_val_if_fail (dpwrap != NULL, FALSE);
@ -304,7 +306,7 @@ gst_dpman_attach_dparam (GstDParamManager *dpman, gchar *dparam_name, GstDParam
g_return_val_if_fail(dpwrap->value != NULL, FALSE);
dpwrap->dparam = dparam;
gst_dparam_attach(dparam, dpman, dpwrap->param_spec, dpwrap->is_log, dpwrap->is_rate);
gst_dparam_attach(dparam, dpman, dpwrap->param_spec, dpwrap->unit_name);
return TRUE;
}
@ -586,8 +588,7 @@ gst_dpman_get_wrapper(GstDParamManager *dpman, gchar *dparam_name)
static GstDParamWrapper*
gst_dpman_new_wrapper(GstDParamManager *dpman,
GParamSpec *param_spec,
gboolean is_log,
gboolean is_rate,
gchar *unit_name,
GstDPMUpdateMethod update_method)
{
GstDParamWrapper* dpwrap;
@ -596,6 +597,7 @@ gst_dpman_new_wrapper(GstDParamManager *dpman,
g_return_val_if_fail (dpman != NULL, NULL);
g_return_val_if_fail (GST_IS_DPMAN (dpman), NULL);
g_return_val_if_fail (param_spec != NULL, NULL);
g_return_val_if_fail (gst_unitconv_unit_exists(unit_name), NULL);
dparam_name = g_strdup(g_param_spec_get_name(param_spec));
g_return_val_if_fail(gst_dpman_get_wrapper(dpman, dparam_name) == NULL, NULL);
@ -605,8 +607,7 @@ gst_dpman_new_wrapper(GstDParamManager *dpman,
dpwrap->value = g_new0(GValue,1);
g_value_init(dpwrap->value, G_PARAM_SPEC_VALUE_TYPE(param_spec));
dpwrap->param_spec = param_spec;
dpwrap->is_log = is_log;
dpwrap->is_rate = is_rate;
dpwrap->unit_name = unit_name;
g_hash_table_insert(GST_DPMAN_DPARAMS(dpman), dparam_name, dpwrap);
GST_DPMAN_DPARAMS_LIST(dpman) = g_slist_append(GST_DPMAN_DPARAMS_LIST(dpman), dpwrap);

View file

@ -26,6 +26,7 @@
#include <gst/gstprops.h>
#include <gst/control/dparamcommon.h>
#include <gst/control/dparam.h>
#include <gst/control/unitconvert.h>
#ifdef __cplusplus
extern "C" {
@ -62,7 +63,7 @@ typedef guint (*GstDPMModeProcessFunction) (GstDParamManager *dpman, guint frame
typedef void (*GstDPMModeSetupFunction) (GstDParamManager *dpman);
typedef void (*GstDPMModeTeardownFunction) (GstDParamManager *dpman);
typedef void (*GstDPMUpdateFunction) (GValue *value, gpointer data);
typedef void (*GstDPMUpdateFunction) (const GValue *value, gpointer data);
struct _GstDParamManager {
GstObject object;
@ -99,8 +100,7 @@ struct _GstDParamWrapper {
GstDPMUpdateMethod update_method;
gpointer update_data;
GstDPMUpdateFunction update_func;
gboolean is_log;
gboolean is_rate;
gchar *unit_name;
};
#define GST_DPMAN_PREPROCESSFUNC(dpman) (((dpman)->mode)->preprocessfunc)
@ -117,6 +117,10 @@ struct _GstDParamWrapper {
#define GST_DPMAN_PROCESS_COUNTDOWN(dpman, frame_countdown, frame_count) \
(frame_countdown-- || \
(frame_countdown = GST_DPMAN_PROCESS(dpman, frame_count)))
#define GST_DPMAN_PROCESS_CHUNK(dpman, frames_to_process, frame_count) \
(frames_to_process || \
(frames_to_process = GST_DPMAN_PROCESS(dpman, frame_count)))
#define GST_DPMAN_DO_UPDATE(dpwrap) ((dpwrap->update_func)(dpwrap->value, dpwrap->update_data))
@ -128,20 +132,17 @@ GstDParamManager* gst_dpman_get_manager (GstElement *parent);
gboolean gst_dpman_add_required_dparam_callback (GstDParamManager *dpman,
GParamSpec *param_spec,
gboolean is_log,
gboolean is_rate,
gchar *unit_name,
GstDPMUpdateFunction update_func,
gpointer update_data);
gboolean gst_dpman_add_required_dparam_direct (GstDParamManager *dpman,
GParamSpec *param_spec,
gboolean is_log,
gboolean is_rate,
gchar *unit_name,
gpointer update_data);
gboolean gst_dpman_add_required_dparam_array (GstDParamManager *dpman,
GParamSpec *param_spec,
gboolean is_log,
gboolean is_rate,
gchar *unit_name,
gpointer update_data);
void gst_dpman_remove_required_dparam (GstDParamManager *dpman, gchar *dparam_name);
@ -150,7 +151,7 @@ void gst_dpman_detach_dparam (GstDParamManager *dpman, gchar *dparam_name);
GstDParam* gst_dpman_get_dparam(GstDParamManager *dpman, gchar *name);
GType gst_dpman_get_dparam_type (GstDParamManager *dpman, gchar *name);
GParamSpec** gst_dpman_list_param_specs(GstDParamManager *dpman);
GParamSpec** gst_dpman_list_dparam_specs(GstDParamManager *dpman);
GParamSpec* gst_dpman_get_param_spec (GstDParamManager *dpman, gchar *dparam_name);
void gst_dpman_dparam_spec_has_changed (GstDParamManager *dpman, gchar *dparam_name);

View file

@ -0,0 +1,424 @@
/* GStreamer
* Copyright (C) 2001 Steve Baker <stevebaker_org@yahoo.co.uk>
*
* unitconvert.c: Conversion between units of measurement
*
* 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.
*/
#include <gst/control/unitconvert.h>
#include <gst/gstinfo.h>
static GHashTable *_gst_units;
static GHashTable *_gst_unit_domain_defaults;
static gboolean _gst_unitconv_init_done = FALSE;
typedef struct _GstUnit GstUnit;
struct _GstUnit {
GParamSpec *unit_spec;
const gchar *domain_name;
gboolean domain_default;
gboolean logarithmic;
GHashTable *convert_to_funcs;
GSList *convert_paramspecs;
};
static void gst_unitconv_add_core_converters(void);
static void gst_unitconv_class_init (GstUnitConvertClass *klass);
static void gst_unitconv_init (GstUnitConvert *unitconv);
static void gst_unitconv_dispose (GObject *object);
GType
gst_unitconv_get_type(void) {
static GType unitconv_type = 0;
if (!unitconv_type) {
static const GTypeInfo unitconv_info = {
sizeof(GstUnitConvertClass),
NULL,
NULL,
(GClassInitFunc)gst_unitconv_class_init,
NULL,
NULL,
sizeof(GstUnitConvert),
0,
(GInstanceInitFunc)gst_unitconv_init,
};
unitconv_type = g_type_register_static(GST_TYPE_OBJECT, "GstUnitConvert", &unitconv_info, 0);
}
return unitconv_type;
}
static void
gst_unitconv_class_init (GstUnitConvertClass *klass)
{
GObjectClass *gobject_class;
GstUnitConvertClass *unitconv_class;
GstObjectClass *gstobject_class;
gobject_class = (GObjectClass*)klass;
unitconv_class = (GstUnitConvertClass*)klass;
gstobject_class = (GstObjectClass*) klass;
gobject_class->dispose = gst_unitconv_dispose;
}
static void
gst_unitconv_init (GstUnitConvert *unitconv)
{
g_return_if_fail (unitconv != NULL);
unitconv->convert_func_chain = NULL;
unitconv->convert_params = g_hash_table_new(g_str_hash,g_str_equal);
}
GstUnitConvert*
gst_unitconv_new ()
{
GstUnitConvert *unitconv;
unitconv = g_object_new (gst_unitconv_get_type (), NULL);
return unitconv;
}
static void
gst_unitconv_init_for_change_state(GstUnitConvert *unitconv){
unitconv->convert_func_chain = NULL;
}
gboolean
gst_unitconv_set_convert_units(GstUnitConvert *unitconv, gchar *from_unit_named, gchar *to_unit_named)
{
GHashTable *convert_funcs;
GstUnit *from_unit, *to_unit;
GstUnitConvertFunc convert_func;
g_return_val_if_fail (unitconv != NULL, FALSE);
g_return_val_if_fail (from_unit_named != NULL, FALSE);
g_return_val_if_fail (to_unit_named != NULL, FALSE);
g_return_val_if_fail (GST_IS_UNIT_CONVERT(unitconv), FALSE);
from_unit = g_hash_table_lookup(_gst_units, from_unit_named);
to_unit = g_hash_table_lookup(_gst_units, to_unit_named);
g_return_val_if_fail (from_unit != NULL, FALSE);
g_return_val_if_fail (to_unit != NULL, FALSE);
convert_funcs = from_unit->convert_to_funcs;
convert_func = g_hash_table_lookup(convert_funcs, to_unit);
if (convert_func == NULL){
g_warning("cannot convert from %s to %s", from_unit_named, to_unit_named);
}
gst_unitconv_init_for_change_state(unitconv);
unitconv->convert_func_chain = g_slist_append(unitconv->convert_func_chain, convert_func);
return TRUE;
}
gboolean
gst_unitconv_convert_value(GstUnitConvert *unitconv, GValue *from_value, GValue *to_value)
{
GstUnitConvertFunc convert_func;
GSList *convert_func_chain;
g_return_val_if_fail (unitconv->convert_func_chain != NULL, FALSE);
/* only do this until we can chain convert funcs */
g_return_val_if_fail (g_slist_length(unitconv->convert_func_chain) == 1, FALSE);
convert_func_chain = unitconv->convert_func_chain;
convert_func = (GstUnitConvertFunc)(convert_func_chain);
convert_func(unitconv, from_value, to_value);
return TRUE;
}
gboolean
gst_unitconv_unit_exists(gchar *unit_name)
{
g_return_val_if_fail (unit_name != NULL, FALSE);
return (g_hash_table_lookup(_gst_units, unit_name) != NULL);
}
gboolean
gst_unitconv_unit_is_logarithmic(gchar *unit_name)
{
GstUnit *unit;
g_return_val_if_fail (unit_name != NULL, FALSE);
unit = g_hash_table_lookup(_gst_units, unit_name);
g_return_val_if_fail (unit != NULL, FALSE);
return unit->logarithmic;
}
GParamSpec*
gst_unitconv_unit_spec(gchar *unit_name)
{
GstUnit *unit;
g_return_val_if_fail (unit_name != NULL, FALSE);
unit = g_hash_table_lookup(_gst_units, unit_name);
g_return_val_if_fail (unit != NULL, FALSE);
return unit->unit_spec;
}
static void
gst_unitconv_dispose (GObject *object)
{
}
void
_gst_unitconv_initialize (void)
{
if (_gst_unitconv_init_done) return;
_gst_unitconv_init_done = TRUE;
_gst_units = g_hash_table_new(g_str_hash,g_str_equal);
_gst_unit_domain_defaults = g_hash_table_new(g_str_hash,g_str_equal);
/* frequency based units */
gst_unitconv_register_unit("frequency", TRUE, TRUE,
g_param_spec_float("hertz", "Hz", "Frequency in hertz",
0, G_MAXFLOAT, 0, 0));
gst_unitconv_register_unit("frequency", FALSE, TRUE,
g_param_spec_float("rate_proportion", "rate proportion", "Proportion of the sample rate",
0, 1, 0, 0));
gst_unitconv_register_unit("frequency", FALSE, FALSE,
g_param_spec_string("twelve_tone_scale", "note", "Name of the note from the western twelve tone scale",
"C", 0));
gst_unitconv_register_unit("frequency", FALSE, FALSE,
g_param_spec_int("midi_note", "midi note", "MIDI note value of the frequency",
1, 127, 1, 0));
/* time based units */
gst_unitconv_register_unit("time", TRUE, FALSE,
g_param_spec_float("seconds", "s", "Time in seconds",
-G_MAXFLOAT, G_MAXFLOAT, 0, 0));
gst_unitconv_register_unit("time", FALSE, FALSE,
g_param_spec_int64("nanoseconds", "ns", "Time in nanoseconds",
G_MININT64, G_MAXINT64, 0, 0));
gst_unitconv_register_unit("time", FALSE, FALSE,
g_param_spec_int64("samples", "samples", "Time in number of samples",
G_MININT64, G_MAXINT64, 0, 0));
gst_unitconv_register_convert_property("samples",
g_param_spec_int("samplerate","samplerate","samplerate",
0, G_MAXINT,0,G_PARAM_READWRITE));
/* magnitude based units */
gst_unitconv_register_unit("magnitude", TRUE, FALSE,
g_param_spec_float("scalar", "scalar", "Magnitude as a scalar",
-G_MAXFLOAT, G_MAXFLOAT, 0, 0));
gst_unitconv_register_unit("magnitude", FALSE, FALSE,
g_param_spec_int("scalar_int", "scalar int", "Magnitude as an integer scalar",
G_MININT, G_MAXINT, 0, 0));
gst_unitconv_register_unit("magnitude", FALSE, TRUE,
g_param_spec_float("decibel", "dB", "Magnitude in decibels",
-G_MAXFLOAT, G_MAXFLOAT, 0, 0));
gst_unitconv_register_unit("magnitude", FALSE, FALSE,
g_param_spec_float("percent", "%", "Magnitude in percent",
-G_MAXFLOAT, G_MAXFLOAT, 0, 0));
/* generic units */
gst_unitconv_register_unit("float_default", TRUE, FALSE,
g_param_spec_float("float", "float", "Float value",
-G_MAXFLOAT, G_MAXFLOAT, 0, 0));
gst_unitconv_register_unit("int_default", TRUE, FALSE,
g_param_spec_int("int", "int", "Integer value",
G_MININT, G_MAXINT, 0, 0));
gst_unitconv_register_unit("int64_default", TRUE, FALSE,
g_param_spec_int64("int64", "int64", "64 bit integer value",
G_MININT, G_MAXINT, 0, 0));
gst_unitconv_add_core_converters();
}
gboolean
gst_unitconv_register_unit(const gchar *domain_name,
gboolean is_domain_default,
gboolean is_logarithmic,
GParamSpec *unit_spec)
{
GstUnit* unit;
gchar *unit_name;
g_return_val_if_fail (unit_spec != NULL, FALSE);
g_return_val_if_fail (G_IS_PARAM_SPEC(unit_spec), FALSE);
g_return_val_if_fail (domain_name != NULL, FALSE);
unit_name = g_strdup(g_param_spec_get_name(unit_spec));
/* check if this unit name already exists */
g_return_val_if_fail (
g_hash_table_lookup(_gst_units, unit_name) == NULL, FALSE);
if (is_domain_default){
/* check if an default unit already exists for this domain */
g_return_val_if_fail (
g_hash_table_lookup(_gst_unit_domain_defaults, domain_name) == NULL, FALSE);
}
GST_DEBUG (GST_CAT_PARAMS,"creating unit: %s\n", unit_name);
unit = g_new0(GstUnit,1);
unit->unit_spec = unit_spec;
unit->domain_name = domain_name;
unit->domain_default = is_domain_default;
unit->logarithmic = is_logarithmic;
unit->convert_to_funcs = g_hash_table_new(NULL,NULL);
//unit->convert_properties = g_hash_table_new(g_str_hash,g_str_equal);
g_hash_table_insert(_gst_units, g_strdup(unit_name), unit);
if (is_domain_default){
g_hash_table_insert(_gst_unit_domain_defaults, g_strdup(domain_name), unit);
}
return TRUE;
}
gboolean
gst_unitconv_register_convert_func(gchar *from_unit_named, gchar *to_unit_named, GstUnitConvertFunc convert_func)
{
GHashTable *convert_funcs;
GstUnit *from_unit, *to_unit;
g_return_val_if_fail (from_unit_named != NULL, FALSE);
g_return_val_if_fail (to_unit_named != NULL, FALSE);
from_unit = g_hash_table_lookup(_gst_units, from_unit_named);
to_unit = g_hash_table_lookup(_gst_units, to_unit_named);
g_return_val_if_fail (from_unit != NULL, FALSE);
g_return_val_if_fail (to_unit != NULL, FALSE);
convert_funcs = from_unit->convert_to_funcs;
g_return_val_if_fail (
g_hash_table_lookup(convert_funcs, to_unit) == NULL, FALSE);
GST_DEBUG (GST_CAT_PARAMS,"adding unit converter from %s to %s\n",
g_param_spec_get_name(from_unit->unit_spec),
g_param_spec_get_name(to_unit->unit_spec));
g_hash_table_insert(convert_funcs, to_unit, convert_func);
return TRUE;
}
gboolean
gst_unitconv_register_convert_property(gchar *unit_name, GParamSpec *convert_prop_spec)
{
GstUnit *unit;
g_return_val_if_fail (unit_name != NULL, FALSE);
g_return_val_if_fail (convert_prop_spec != NULL, FALSE);
unit = g_hash_table_lookup(_gst_units, unit_name);
g_return_val_if_fail (unit != NULL, FALSE);
unit->convert_paramspecs = g_slist_append(unit->convert_paramspecs, convert_prop_spec);
return TRUE;
}
static void
gst_unitconv_time_seconds_to_nanoseconds(GstUnitConvert *unitconv, GValue *seconds_val, GValue *nanos_val)
{
g_value_set_int64(nanos_val,
(gint64)(g_value_get_float(seconds_val) * 1000000000.0));
}
static void
gst_unitconv_time_nanoseconds_to_seconds(GstUnitConvert *unitconv, GValue *nanos_val, GValue *seconds_val)
{
g_value_set_float(seconds_val,
((gfloat)g_value_get_int64(nanos_val)) / 1000000000.0);
}
static void
gst_unitconv_time_seconds_to_samples(GstUnitConvert *unitconv, GValue *seconds_val, GValue *samples_val)
{
GValue *samplerate;
//GValue *samplerate = g_hash_table_lookup(unitconv->currentToUnit->convert_properties, "samplerate");
g_value_set_int64(samples_val,
(gint64)(g_value_get_float(seconds_val) * (gfloat)g_value_get_int(samplerate)));
}
static void
gst_unitconv_time_samples_to_seconds(GstUnitConvert *unitconv, GValue *samples_val, GValue *seconds_val)
{
GValue *samplerate;
//GValue *samplerate = g_hash_table_lookup(unitconv->currentFromUnit->convert_properties, "samplerate");
g_value_set_float(seconds_val,
((gfloat)g_value_get_int64(samples_val)) / (gfloat)g_value_get_int(samplerate));
}
static void
gst_unitconv_magnitude_scalar_to_percent(GstUnitConvert *unitconv, GValue *scalar_val, GValue *percent_val)
{
g_value_set_float(percent_val,
g_value_get_float(scalar_val) * 100.0);
}
static void
gst_unitconv_magnitude_percent_to_scalar(GstUnitConvert *unitconv, GValue *percent_val, GValue *scalar_val)
{
g_value_set_float(scalar_val,
g_value_get_float(percent_val) / 100.0);
}
static void
gst_unitconv_add_core_converters(void){
gst_unitconv_register_convert_func("nanoseconds", "seconds", gst_unitconv_time_nanoseconds_to_seconds);
gst_unitconv_register_convert_func("seconds", "nanoseconds", gst_unitconv_time_seconds_to_nanoseconds);
gst_unitconv_register_convert_func("seconds", "samples", gst_unitconv_time_seconds_to_samples);
gst_unitconv_register_convert_func("samples", "seconds", gst_unitconv_time_samples_to_seconds);
gst_unitconv_register_convert_func("scalar", "percent", gst_unitconv_magnitude_scalar_to_percent);
gst_unitconv_register_convert_func("percent", "scalar", gst_unitconv_magnitude_percent_to_scalar);
}

View file

@ -0,0 +1,81 @@
/* GStreamer
* Copyright (C) 2001 Steve Baker <stevebaker_org@yahoo.co.uk>
*
* unitconvert.c: Conversion between units of measurement
*
* 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_UNITCONVERT_H__
#define __GST_UNITCONVERT_H__
#include <gst/gstobject.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define GST_TYPE_UNIT_CONVERT (gst_unitconv_get_type ())
#define GST_UNIT_CONVERT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_UNIT_CONVERT,GstUnitConvert))
#define GST_UNIT_CONVERT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_UNIT_CONVERT,GstUnitConvert))
#define GST_IS_UNIT_CONVERT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_UNIT_CONVERT))
#define GST_IS_UNIT_CONVERT_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_UNIT_CONVERT))
#define GST_UNIT_CONVERT_NAME(unitconv) (GST_OBJECT_NAME(unitconv))
#define GST_UNIT_CONVERT_PARENT(unitconv) (GST_OBJECT_PARENT(unitconv))
typedef struct _GstUnitConvertClass GstUnitConvertClass;
typedef struct _GstUnitConvert GstUnitConvert;
typedef void (*GstUnitConvertFunc) (GstUnitConvert *unitconv, GValue *from_val, GValue *to_val);
struct _GstUnitConvert {
GstObject object;
GHashTable *convert_params;
GSList *convert_func_chain;
GSList *temp_gvalues;
};
struct _GstUnitConvertClass {
GstObjectClass parent_class;
/* signal callbacks */
};
GstUnitConvert* gst_unitconv_new ();
void _gst_unitconv_initialize (void);
gboolean gst_unitconv_set_convert_units(GstUnitConvert *unitconv, gchar *from_unit_named, gchar *to_unit_named);
gboolean gst_unitconv_convert_value(GstUnitConvert *unitconv, GValue *from_value, GValue *to_value);
GParamSpec* gst_unitconv_unit_spec(gchar *unit_name);
gboolean gst_unitconv_unit_exists(gchar *unit_name);
gboolean gst_unitconv_unit_is_logarithmic(gchar *unit_name);
gboolean gst_unitconv_register_unit(const gchar *domain_name,
gboolean is_domain_default,
gboolean is_logarithmic,
GParamSpec *unit_spec);
gboolean gst_unitconv_register_convert_func(gchar *from_unit_named, gchar *to_unit_named, GstUnitConvertFunc convert_func);
gboolean gst_unitconv_register_convert_property(gchar *unit_name, GParamSpec *convert_prop_spec);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GST_UNITCONVERT_H__ */