asdfuser pushed a commit to branch master.
commit e89153a21dabae4ce2c3aac870a58c2d20f3b95a
Author: Daniel Willmann <[email protected]>
Date: Wed Apr 17 19:06:21 2013 +0100
ecore_audio: Implement virtual IO for generic input
Signed-off-by: Daniel Willmann <[email protected]>
---
src/lib/ecore_audio/Ecore_Audio.h | 10 +++---
src/lib/ecore_audio/ecore_audio_obj.c | 1 +
src/lib/ecore_audio/ecore_audio_obj.h | 3 ++
src/lib/ecore_audio/ecore_audio_obj_in.c | 58 +++++++++++++++++++++++++++++--
src/lib/ecore_audio/ecore_audio_private.h | 10 +++++-
5 files changed, 74 insertions(+), 8 deletions(-)
diff --git a/src/lib/ecore_audio/Ecore_Audio.h
b/src/lib/ecore_audio/Ecore_Audio.h
index b87f647..c405140 100644
--- a/src/lib/ecore_audio/Ecore_Audio.h
+++ b/src/lib/ecore_audio/Ecore_Audio.h
@@ -76,11 +76,11 @@ typedef struct _Ecore_Audio_Object Ecore_Audio_Object;
/**< The audio object */
typedef int (*Ecore_Audio_Read_Callback)(void *user_data, void *data, int len);
struct _Ecore_Audio_Vio {
- int (*get_length)(Ecore_Audio_Object *in);
- int (*seek)(Ecore_Audio_Object *in, int offset, int whence);
- int (*tell)(Ecore_Audio_Object *in);
- int (*read)(Ecore_Audio_Object *in, void *buffer, int length);
- int (*write)(Ecore_Audio_Object *out, const void *buffer, int length);
+ int (*get_length)(void *data, Eo *eo_obj);
+ int (*seek)(void *data, Eo *eo_obj, int offset, int whence);
+ int (*tell)(void *data, Eo *eo_obj);
+ int (*read)(void *data, Eo *eo_obj, void *buffer, int length);
+ int (*write)(void *data, Eo *eo_obj, const void *buffer, int length);
};
typedef struct _Ecore_Audio_Vio Ecore_Audio_Vio; /**< Functions to implement
IO virtually */
diff --git a/src/lib/ecore_audio/ecore_audio_obj.c
b/src/lib/ecore_audio/ecore_audio_obj.c
index aa78c9c..62a784e 100644
--- a/src/lib/ecore_audio/ecore_audio_obj.c
+++ b/src/lib/ecore_audio/ecore_audio_obj.c
@@ -137,6 +137,7 @@ static const Eo_Op_Description op_desc[] = {
EO_OP_DESCRIPTION(ECORE_AUDIO_OBJ_SUB_ID_SOURCE_GET, "Gets the source of
the object."),
EO_OP_DESCRIPTION(ECORE_AUDIO_OBJ_SUB_ID_FORMAT_SET, "Sets the format of
the object."),
EO_OP_DESCRIPTION(ECORE_AUDIO_OBJ_SUB_ID_FORMAT_GET, "Gets the format of
the object."),
+ EO_OP_DESCRIPTION(ECORE_AUDIO_OBJ_SUB_ID_VIO_SET, "Sets virtual IO
callbacks for this object."),
EO_OP_DESCRIPTION_SENTINEL
};
diff --git a/src/lib/ecore_audio/ecore_audio_obj.h
b/src/lib/ecore_audio/ecore_audio_obj.h
index e806e8a..87c08b8 100644
--- a/src/lib/ecore_audio/ecore_audio_obj.h
+++ b/src/lib/ecore_audio/ecore_audio_obj.h
@@ -51,6 +51,7 @@ enum Ecore_Audio_Obj_Sub_Ids
ECORE_AUDIO_OBJ_SUB_ID_SOURCE_GET,
ECORE_AUDIO_OBJ_SUB_ID_FORMAT_SET,
ECORE_AUDIO_OBJ_SUB_ID_FORMAT_GET,
+ ECORE_AUDIO_OBJ_SUB_ID_VIO_SET,
ECORE_AUDIO_OBJ_SUB_ID_LAST
};
@@ -92,6 +93,8 @@ enum Ecore_Audio_Obj_Sub_Ids
#define ecore_audio_obj_format_get(ret)
ECORE_AUDIO_OBJ_ID(ECORE_AUDIO_OBJ_SUB_ID_FORMAT_GET),
EO_TYPECHECK(Ecore_Audio_Format *, ret)
+#define ecore_audio_obj_vio_set(vio, data, free_func)
ECORE_AUDIO_OBJ_ID(ECORE_AUDIO_OBJ_SUB_ID_VIO_SET),
EO_TYPECHECK(Ecore_Audio_Vio *, vio), EO_TYPECHECK(void *, data),
EO_TYPECHECK(eo_base_data_free_func, free_func)
+
/**
* @}
*/
diff --git a/src/lib/ecore_audio/ecore_audio_obj_in.c
b/src/lib/ecore_audio/ecore_audio_obj_in.c
index 983b310..1528a04 100644
--- a/src/lib/ecore_audio/ecore_audio_obj_in.c
+++ b/src/lib/ecore_audio/ecore_audio_obj_in.c
@@ -132,7 +132,9 @@ static void _remaining_get(Eo *eo_obj, void *_pd, va_list
*list)
double *ret = va_arg(*list, double *);
- if (ret) {
+ if (!ea_obj->seekable && ret) {
+ *ret = -1;
+ } else if (ret) {
eo_do(eo_obj, ecore_audio_obj_in_seek(0, SEEK_CUR, ret));
*ret = obj->length - *ret;
}
@@ -154,7 +156,7 @@ static void _read(Eo *eo_obj, void *_pd, va_list *list)
} else {
eo_do(eo_obj, ecore_audio_obj_in_read_internal(buf, len, &len_read));
if (len_read == 0) {
- if (!obj->looped) {
+ if (!obj->looped || !ea_obj->seekable) {
eo_do(eo_obj, eo_event_callback_call(ECORE_AUDIO_EV_IN_STOPPED,
NULL, NULL));
} else {
eo_do(eo_obj, ecore_audio_obj_in_seek(0, SEEK_SET, NULL));
@@ -169,6 +171,24 @@ static void _read(Eo *eo_obj, void *_pd, va_list *list)
*ret = len_read;
}
+static void _read_internal(Eo *eo_obj, void *_pd, va_list *list)
+{
+ const Ecore_Audio_Input *obj = _pd;
+ ssize_t len_read = 0;
+ const Ecore_Audio_Object *ea_obj = eo_data_get(eo_obj,
ECORE_AUDIO_OBJ_CLASS);
+
+ char *buf = va_arg(*list, char *);
+ size_t len = va_arg(*list, size_t);
+ ssize_t *ret = va_arg(*list, ssize_t *);
+
+ if (ea_obj->vio && ea_obj->vio->vio->read) {
+ len_read = ea_obj->vio->vio->read(ea_obj->vio->data, eo_obj, buf, len);
+ }
+
+ if (ret)
+ *ret = len_read;
+}
+
static void _output_get(Eo *eo_obj, void *_pd, va_list *list)
{
const Ecore_Audio_Input *obj = _pd;
@@ -179,6 +199,37 @@ static void _output_get(Eo *eo_obj, void *_pd, va_list
*list)
*ret = obj->output;
}
+static void _free_vio(Ecore_Audio_Object *ea_obj)
+{
+ if (ea_obj->vio->free_func)
+ ea_obj->vio->free_func(ea_obj->vio->data);
+
+ free(ea_obj->vio);
+ ea_obj->vio = NULL;
+}
+
+static void _vio_set(Eo *eo_obj, void *_pd EINA_UNUSED, va_list *list)
+{
+ Ecore_Audio_Object *ea_obj = eo_data_get(eo_obj, ECORE_AUDIO_OBJ_CLASS);
+
+ Ecore_Audio_Vio *vio = va_arg(*list, Ecore_Audio_Vio *);
+ void *data = va_arg(*list, Ecore_Audio_Vio *);
+ eo_base_data_free_func free_func = va_arg(*list, eo_base_data_free_func);
+
+ if (ea_obj->vio)
+ _free_vio(ea_obj);
+
+ if (!vio)
+ return;
+
+ ea_obj->vio = calloc(1, sizeof(Ecore_Audio_Vio_Internal));
+ ea_obj->vio->vio = vio;
+ ea_obj->vio->data = data;
+ ea_obj->vio->free_func = free_func;
+ //FIXME: Save previous value
+ ea_obj->seekable = (vio->seek != NULL);
+}
+
static void _constructor(Eo *eo_obj, void *_pd, va_list *list EINA_UNUSED)
{
Ecore_Audio_Input *obj = _pd;
@@ -205,6 +256,8 @@ static void _class_constructor(Eo_Class *klass)
EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_CONSTRUCTOR), _constructor),
EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DESTRUCTOR), _destructor),
+ EO_OP_FUNC(ECORE_AUDIO_OBJ_ID(ECORE_AUDIO_OBJ_SUB_ID_VIO_SET), _vio_set),
+
/* Specific functions to this class */
EO_OP_FUNC(ECORE_AUDIO_OBJ_IN_ID(ECORE_AUDIO_OBJ_IN_SUB_ID_SPEED_SET),
_speed_set),
EO_OP_FUNC(ECORE_AUDIO_OBJ_IN_ID(ECORE_AUDIO_OBJ_IN_SUB_ID_SPEED_GET),
_speed_get),
@@ -217,6 +270,7 @@ static void _class_constructor(Eo_Class *klass)
EO_OP_FUNC(ECORE_AUDIO_OBJ_IN_ID(ECORE_AUDIO_OBJ_IN_SUB_ID_LENGTH_GET),
_length_get),
EO_OP_FUNC(ECORE_AUDIO_OBJ_IN_ID(ECORE_AUDIO_OBJ_IN_SUB_ID_REMAINING_GET),
_remaining_get),
EO_OP_FUNC(ECORE_AUDIO_OBJ_IN_ID(ECORE_AUDIO_OBJ_IN_SUB_ID_READ), _read),
+
EO_OP_FUNC(ECORE_AUDIO_OBJ_IN_ID(ECORE_AUDIO_OBJ_IN_SUB_ID_READ_INTERNAL),
_read_internal),
EO_OP_FUNC(ECORE_AUDIO_OBJ_IN_ID(ECORE_AUDIO_OBJ_IN_SUB_ID_OUTPUT_GET),
_output_get),
EO_OP_FUNC_SENTINEL
diff --git a/src/lib/ecore_audio/ecore_audio_private.h
b/src/lib/ecore_audio/ecore_audio_private.h
index 7868b08..e899a04 100644
--- a/src/lib/ecore_audio/ecore_audio_private.h
+++ b/src/lib/ecore_audio/ecore_audio_private.h
@@ -91,6 +91,13 @@ struct _Ecore_Audio_Module
struct output_api *out_ops;
};
+struct _Ecore_Audio_Vio_Internal {
+ Ecore_Audio_Vio *vio;
+ void *data;
+ eo_base_data_free_func free_func;
+};
+typedef struct _Ecore_Audio_Vio_Internal Ecore_Audio_Vio_Internal;
+
/**
* @brief A common structure, could be input or output
*/
@@ -99,10 +106,11 @@ struct _Ecore_Audio_Object
const char *name;
const char *source;
+ Eina_Bool seekable;
Eina_Bool paused;
double volume;
Ecore_Audio_Format format;
-
+ Ecore_Audio_Vio_Internal *vio;
};
/**
--
------------------------------------------------------------------------------
Precog is a next-generation analytics platform capable of advanced
analytics on semi-structured data. The platform includes APIs for building
apps and a phenomenal toolset for data science. Developers can use
our toolset for easy data analysis & visualization. Get a free account!
http://www2.precog.com/precogplatform/slashdotnewsletter