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

Reply via email to