From e89153a21dabae4ce2c3aac870a58c2d20f3b95a Mon Sep 17 00:00:00 2001 From: Daniel Willmann Date: Wed, 17 Apr 2013 19:06:21 +0100 Subject: [PATCH] ecore_audio: Implement virtual IO for generic input Signed-off-by: Daniel Willmann --- 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; }; /** -- 2.7.4