forked from enlightenment/efl
ecore_audio: Implement virtual IO for generic input
Signed-off-by: Daniel Willmann <d.willmann@samsung.com>
This commit is contained in:
parent
f96ba47976
commit
e89153a21d
|
@ -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);
|
typedef int (*Ecore_Audio_Read_Callback)(void *user_data, void *data, int len);
|
||||||
|
|
||||||
struct _Ecore_Audio_Vio {
|
struct _Ecore_Audio_Vio {
|
||||||
int (*get_length)(Ecore_Audio_Object *in);
|
int (*get_length)(void *data, Eo *eo_obj);
|
||||||
int (*seek)(Ecore_Audio_Object *in, int offset, int whence);
|
int (*seek)(void *data, Eo *eo_obj, int offset, int whence);
|
||||||
int (*tell)(Ecore_Audio_Object *in);
|
int (*tell)(void *data, Eo *eo_obj);
|
||||||
int (*read)(Ecore_Audio_Object *in, void *buffer, int length);
|
int (*read)(void *data, Eo *eo_obj, void *buffer, int length);
|
||||||
int (*write)(Ecore_Audio_Object *out, const 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 */
|
typedef struct _Ecore_Audio_Vio Ecore_Audio_Vio; /**< Functions to implement IO virtually */
|
||||||
|
|
|
@ -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_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_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_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
|
EO_OP_DESCRIPTION_SENTINEL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,7 @@ enum Ecore_Audio_Obj_Sub_Ids
|
||||||
ECORE_AUDIO_OBJ_SUB_ID_SOURCE_GET,
|
ECORE_AUDIO_OBJ_SUB_ID_SOURCE_GET,
|
||||||
ECORE_AUDIO_OBJ_SUB_ID_FORMAT_SET,
|
ECORE_AUDIO_OBJ_SUB_ID_FORMAT_SET,
|
||||||
ECORE_AUDIO_OBJ_SUB_ID_FORMAT_GET,
|
ECORE_AUDIO_OBJ_SUB_ID_FORMAT_GET,
|
||||||
|
ECORE_AUDIO_OBJ_SUB_ID_VIO_SET,
|
||||||
ECORE_AUDIO_OBJ_SUB_ID_LAST
|
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_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)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -132,7 +132,9 @@ static void _remaining_get(Eo *eo_obj, void *_pd, va_list *list)
|
||||||
|
|
||||||
double *ret = va_arg(*list, double *);
|
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));
|
eo_do(eo_obj, ecore_audio_obj_in_seek(0, SEEK_CUR, ret));
|
||||||
*ret = obj->length - *ret;
|
*ret = obj->length - *ret;
|
||||||
}
|
}
|
||||||
|
@ -154,7 +156,7 @@ static void _read(Eo *eo_obj, void *_pd, va_list *list)
|
||||||
} else {
|
} else {
|
||||||
eo_do(eo_obj, ecore_audio_obj_in_read_internal(buf, len, &len_read));
|
eo_do(eo_obj, ecore_audio_obj_in_read_internal(buf, len, &len_read));
|
||||||
if (len_read == 0) {
|
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));
|
eo_do(eo_obj, eo_event_callback_call(ECORE_AUDIO_EV_IN_STOPPED, NULL, NULL));
|
||||||
} else {
|
} else {
|
||||||
eo_do(eo_obj, ecore_audio_obj_in_seek(0, SEEK_SET, NULL));
|
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;
|
*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)
|
static void _output_get(Eo *eo_obj, void *_pd, va_list *list)
|
||||||
{
|
{
|
||||||
const Ecore_Audio_Input *obj = _pd;
|
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;
|
*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)
|
static void _constructor(Eo *eo_obj, void *_pd, va_list *list EINA_UNUSED)
|
||||||
{
|
{
|
||||||
Ecore_Audio_Input *obj = _pd;
|
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_CONSTRUCTOR), _constructor),
|
||||||
EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DESTRUCTOR), _destructor),
|
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 */
|
/* 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_SET), _speed_set),
|
||||||
EO_OP_FUNC(ECORE_AUDIO_OBJ_IN_ID(ECORE_AUDIO_OBJ_IN_SUB_ID_SPEED_GET), _speed_get),
|
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_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_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), _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(ECORE_AUDIO_OBJ_IN_ID(ECORE_AUDIO_OBJ_IN_SUB_ID_OUTPUT_GET), _output_get),
|
||||||
|
|
||||||
EO_OP_FUNC_SENTINEL
|
EO_OP_FUNC_SENTINEL
|
||||||
|
|
|
@ -91,6 +91,13 @@ struct _Ecore_Audio_Module
|
||||||
struct output_api *out_ops;
|
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
|
* @brief A common structure, could be input or output
|
||||||
*/
|
*/
|
||||||
|
@ -99,10 +106,11 @@ struct _Ecore_Audio_Object
|
||||||
const char *name;
|
const char *name;
|
||||||
const char *source;
|
const char *source;
|
||||||
|
|
||||||
|
Eina_Bool seekable;
|
||||||
Eina_Bool paused;
|
Eina_Bool paused;
|
||||||
double volume;
|
double volume;
|
||||||
Ecore_Audio_Format format;
|
Ecore_Audio_Format format;
|
||||||
|
Ecore_Audio_Vio_Internal *vio;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue