forked from enlightenment/efl
ecore_audio - save 232k of real RAM by dlopening depednecies
so libpuls and libsndfile suck in dependencies. they suck in so much that by the time linking is done we've written to about 230kb of PRIVATE MEMORY as dirty pages in symbol tablesm global veriables etc. etc. - this is just horrible. especially if an app never makes any sound... it's just wasted memory. this stuff is invisible to normal memory debug tools. so this begins to address things. please see T4227. my numbers now put me at: 1780Kb total dirty writable mapped from library file pages. down from 2012Kb. This fixes some memory bloat reported in the above ticket, but there is more to fix for sure. @fix
This commit is contained in:
parent
e077e92372
commit
d27f5fcab7
19
configure.ac
19
configure.ac
|
@ -3932,9 +3932,22 @@ EFL_INTERNAL_DEPEND_PKG([ECORE_AUDIO], [emile])
|
||||||
|
|
||||||
EFL_ADD_LIBS([ECORE_AUDIO], [-lm])
|
EFL_ADD_LIBS([ECORE_AUDIO], [-lm])
|
||||||
|
|
||||||
EFL_OPTIONAL_DEPEND_PKG([ECORE_AUDIO], [${want_alsa}], [ALSA], [alsa])
|
if test "x${want_alsa}" = "xyes" ; then
|
||||||
EFL_OPTIONAL_DEPEND_PKG([ECORE_AUDIO], [${want_pulseaudio}], [PULSE], [libpulse])
|
PKG_CHECK_MODULES([ECORE_AUDIO_ALSA], [alsa])
|
||||||
EFL_OPTIONAL_DEPEND_PKG([ECORE_AUDIO], [${want_sndfile}], [SNDFILE], [sndfile])
|
AC_DEFINE([HAVE_ALSA], [1], [Alsa support])
|
||||||
|
fi
|
||||||
|
if test "x${want_pulseaudio}" = "xyes" ; then
|
||||||
|
PKG_CHECK_MODULES([ECORE_AUDIO_PULSE], [libpulse])
|
||||||
|
AC_DEFINE([HAVE_PULSE], [1], [Pulseaudio support])
|
||||||
|
fi
|
||||||
|
if test "x${want_sndfile}" = "xyes" ; then
|
||||||
|
PKG_CHECK_MODULES([ECORE_AUDIO_SNDFILE], [sndfile])
|
||||||
|
AC_DEFINE([HAVE_SNDFILE], [1], [Sndfile support])
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl EFL_OPTIONAL_DEPEND_PKG([ECORE_AUDIO_ALSA], [${want_alsa}], [ALSA], [alsa])
|
||||||
|
dnl EFL_OPTIONAL_DEPEND_PKG([ECORE_AUDIO_PULSE], [${want_pulseaudio}], [PULSE], [libpulse])
|
||||||
|
dnl EFL_OPTIONAL_DEPEND_PKG([ECORE_AUDIO_SNDFILE], [${want_sndfile}], [SNDFILE], [sndfile])
|
||||||
|
|
||||||
EFL_EVAL_PKGS([ECORE_AUDIO])
|
EFL_EVAL_PKGS([ECORE_AUDIO])
|
||||||
|
|
||||||
|
|
|
@ -53,8 +53,8 @@ lib/ecore_audio/ecore_audio_obj_out.c \
|
||||||
lib/ecore_audio/ecore_audio_obj_in_tone.c \
|
lib/ecore_audio/ecore_audio_obj_in_tone.c \
|
||||||
lib/ecore_audio/ecore_audio_private.h
|
lib/ecore_audio/ecore_audio_private.h
|
||||||
|
|
||||||
lib_ecore_audio_libecore_audio_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl @ECORE_AUDIO_CFLAGS@
|
lib_ecore_audio_libecore_audio_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl @ECORE_AUDIO_CFLAGS@ @ECORE_AUDIO_ALSA_CFLAGS@ @ECORE_AUDIO_PULSE_CFLAGS@ @ECORE_AUDIO_SNDFILE_CFLAGS@
|
||||||
lib_ecore_audio_libecore_audio_la_LIBADD = @ECORE_AUDIO_LIBS@
|
lib_ecore_audio_libecore_audio_la_LIBADD = @ECORE_AUDIO_LIBS@ @ECORE_AUDIO_ALSA_LIBS@
|
||||||
lib_ecore_audio_libecore_audio_la_DEPENDENCIES = @ECORE_AUDIO_INTERNAL_LIBS@
|
lib_ecore_audio_libecore_audio_la_DEPENDENCIES = @ECORE_AUDIO_INTERNAL_LIBS@
|
||||||
lib_ecore_audio_libecore_audio_la_LDFLAGS = @EFL_LTLIBRARY_FLAGS@
|
lib_ecore_audio_libecore_audio_la_LDFLAGS = @EFL_LTLIBRARY_FLAGS@
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,12 @@ int _ecore_audio_log_dom = -1;
|
||||||
static int _ecore_audio_init_count = 0;
|
static int _ecore_audio_init_count = 0;
|
||||||
Eina_List *ecore_audio_modules;
|
Eina_List *ecore_audio_modules;
|
||||||
|
|
||||||
|
#ifdef HAVE_PULSE
|
||||||
|
Ecore_Audio_Lib_Pulse *ecore_audio_pulse_lib = NULL;
|
||||||
|
#endif /* HAVE_PULSE */
|
||||||
|
#ifdef HAVE_SNDFILE
|
||||||
|
Ecore_Audio_Lib_Sndfile *ecore_audio_sndfile_lib = NULL;
|
||||||
|
#endif /* HAVE_SNDFILE */
|
||||||
|
|
||||||
/* externally accessible functions */
|
/* externally accessible functions */
|
||||||
|
|
||||||
|
@ -61,6 +67,13 @@ ecore_audio_shutdown(void)
|
||||||
if (--_ecore_audio_init_count != 0)
|
if (--_ecore_audio_init_count != 0)
|
||||||
return _ecore_audio_init_count;
|
return _ecore_audio_init_count;
|
||||||
|
|
||||||
|
#ifdef HAVE_SNDFILE
|
||||||
|
ecore_audio_sndfile_lib_unload();
|
||||||
|
#endif /* HAVE_SNDFILE */
|
||||||
|
#ifdef HAVE_PULSE
|
||||||
|
ecore_audio_pulse_lib_unload();
|
||||||
|
#endif /* HAVE_PULSE */
|
||||||
|
|
||||||
/* FIXME: Shutdown all the inputs and outputs first */
|
/* FIXME: Shutdown all the inputs and outputs first */
|
||||||
eina_log_timing(_ecore_audio_log_dom,
|
eina_log_timing(_ecore_audio_log_dom,
|
||||||
EINA_LOG_STATE_START,
|
EINA_LOG_STATE_START,
|
||||||
|
@ -78,6 +91,168 @@ ecore_audio_shutdown(void)
|
||||||
return _ecore_audio_init_count;
|
return _ecore_audio_init_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_PULSE
|
||||||
|
Eina_Bool
|
||||||
|
ecore_audio_pulse_lib_load(void)
|
||||||
|
{
|
||||||
|
if (ecore_audio_pulse_lib)
|
||||||
|
{
|
||||||
|
if (!ecore_audio_pulse_lib->mod)
|
||||||
|
{
|
||||||
|
ERR("Cannot find libpulse!");
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
return EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ecore_audio_pulse_lib = calloc(1, sizeof(Ecore_Audio_Lib_Pulse));
|
||||||
|
if (!ecore_audio_pulse_lib) return EINA_FALSE;
|
||||||
|
# define LOAD(x) \
|
||||||
|
if (!ecore_audio_pulse_lib->mod) { \
|
||||||
|
if ((ecore_audio_pulse_lib->mod = eina_module_new(x))) { \
|
||||||
|
if (!eina_module_load(ecore_audio_pulse_lib->mod)) { \
|
||||||
|
eina_module_free(ecore_audio_pulse_lib->mod); \
|
||||||
|
ecore_audio_pulse_lib->mod = NULL; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
# if defined(_WIN32) || defined(__CYGWIN__)
|
||||||
|
LOAD("libpulse-0.dll");
|
||||||
|
LOAD("libpulse.dll");
|
||||||
|
LOAD("pulse.dll");
|
||||||
|
# elif defined(__APPLE__) && defined(__MACH__)
|
||||||
|
LOAD("libpulse.0.dylib");
|
||||||
|
LOAD("libpulse.0.so");
|
||||||
|
LOAD("libpulse.so.0");
|
||||||
|
# else
|
||||||
|
LOAD("libpulse.so.0");
|
||||||
|
# endif
|
||||||
|
# undef LOAD
|
||||||
|
if (!ecore_audio_pulse_lib->mod) return EINA_FALSE;
|
||||||
|
|
||||||
|
#define SYM(x) \
|
||||||
|
if (!(ecore_audio_pulse_lib->x = eina_module_symbol_get(ecore_audio_pulse_lib->mod, #x))) { \
|
||||||
|
ERR("libpulse - cannot find %s", #x); \
|
||||||
|
goto err; \
|
||||||
|
}
|
||||||
|
SYM(pa_context_new);
|
||||||
|
SYM(pa_context_connect);
|
||||||
|
SYM(pa_context_set_sink_input_volume);
|
||||||
|
SYM(pa_context_get_state);
|
||||||
|
SYM(pa_context_set_state_callback);
|
||||||
|
SYM(pa_operation_unref);
|
||||||
|
SYM(pa_cvolume_set);
|
||||||
|
SYM(pa_stream_new);
|
||||||
|
SYM(pa_stream_unref);
|
||||||
|
SYM(pa_stream_connect_playback);
|
||||||
|
SYM(pa_stream_disconnect);
|
||||||
|
SYM(pa_stream_drain);
|
||||||
|
SYM(pa_stream_cork);
|
||||||
|
SYM(pa_stream_write);
|
||||||
|
SYM(pa_stream_begin_write);
|
||||||
|
SYM(pa_stream_set_write_callback);
|
||||||
|
SYM(pa_stream_trigger);
|
||||||
|
SYM(pa_stream_update_sample_rate);
|
||||||
|
SYM(pa_stream_get_index);
|
||||||
|
#undef SYM
|
||||||
|
return EINA_TRUE;
|
||||||
|
err:
|
||||||
|
if (ecore_audio_pulse_lib->mod)
|
||||||
|
{
|
||||||
|
eina_module_free(ecore_audio_pulse_lib->mod);
|
||||||
|
ecore_audio_pulse_lib->mod = NULL;
|
||||||
|
}
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ecore_audio_pulse_lib_unload(void)
|
||||||
|
{
|
||||||
|
if (ecore_audio_pulse_lib)
|
||||||
|
{
|
||||||
|
if (ecore_audio_pulse_lib->mod)
|
||||||
|
eina_module_free(ecore_audio_pulse_lib->mod);
|
||||||
|
free(ecore_audio_pulse_lib);
|
||||||
|
ecore_audio_pulse_lib = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* HAVE_PULSE */
|
||||||
|
|
||||||
|
#ifdef HAVE_SNDFILE
|
||||||
|
Eina_Bool
|
||||||
|
ecore_audio_sndfile_lib_load(void)
|
||||||
|
{
|
||||||
|
if (ecore_audio_sndfile_lib)
|
||||||
|
{
|
||||||
|
if (!ecore_audio_sndfile_lib->mod)
|
||||||
|
{
|
||||||
|
ERR("Cannot find libsndfile!");
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
return EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ecore_audio_sndfile_lib = calloc(1, sizeof(Ecore_Audio_Lib_Sndfile));
|
||||||
|
if (!ecore_audio_sndfile_lib) return EINA_FALSE;
|
||||||
|
# define LOAD(x) \
|
||||||
|
if (!ecore_audio_sndfile_lib->mod) { \
|
||||||
|
if ((ecore_audio_sndfile_lib->mod = eina_module_new(x))) { \
|
||||||
|
if (!eina_module_load(ecore_audio_sndfile_lib->mod)) { \
|
||||||
|
eina_module_free(ecore_audio_sndfile_lib->mod); \
|
||||||
|
ecore_audio_sndfile_lib->mod = NULL; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
# if defined(_WIN32) || defined(__CYGWIN__)
|
||||||
|
LOAD("libsndfile-1.dll");
|
||||||
|
LOAD("libsndfile.dll");
|
||||||
|
LOAD("sndfile.dll");
|
||||||
|
# elif defined(__APPLE__) && defined(__MACH__)
|
||||||
|
LOAD("libsndfile.1.dylib");
|
||||||
|
LOAD("libsndfile.1.so");
|
||||||
|
LOAD("libsndfile.so.1");
|
||||||
|
# else
|
||||||
|
LOAD("libsndfile.so.1");
|
||||||
|
# endif
|
||||||
|
# undef LOAD
|
||||||
|
if (!ecore_audio_sndfile_lib->mod) return EINA_FALSE;
|
||||||
|
|
||||||
|
#define SYM(x) \
|
||||||
|
if (!(ecore_audio_sndfile_lib->x = eina_module_symbol_get(ecore_audio_sndfile_lib->mod, #x))) { \
|
||||||
|
ERR("libsndfile - cannot find %s", #x); \
|
||||||
|
goto err; \
|
||||||
|
}
|
||||||
|
SYM(sf_open);
|
||||||
|
SYM(sf_open_virtual);
|
||||||
|
SYM(sf_close);
|
||||||
|
SYM(sf_read_float);
|
||||||
|
SYM(sf_write_float);
|
||||||
|
SYM(sf_write_sync);
|
||||||
|
SYM(sf_seek);
|
||||||
|
SYM(sf_strerror);
|
||||||
|
#undef SYM
|
||||||
|
return EINA_TRUE;
|
||||||
|
err:
|
||||||
|
if (ecore_audio_sndfile_lib->mod)
|
||||||
|
{
|
||||||
|
eina_module_free(ecore_audio_sndfile_lib->mod);
|
||||||
|
ecore_audio_sndfile_lib->mod = NULL;
|
||||||
|
}
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ecore_audio_sndfile_lib_unload(void)
|
||||||
|
{
|
||||||
|
if (ecore_audio_sndfile_lib)
|
||||||
|
{
|
||||||
|
if (ecore_audio_sndfile_lib->mod)
|
||||||
|
eina_module_free(ecore_audio_sndfile_lib->mod);
|
||||||
|
free(ecore_audio_sndfile_lib);
|
||||||
|
ecore_audio_sndfile_lib = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* HAVE_SNDFILE */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
|
|
|
@ -30,7 +30,8 @@ typedef struct _Ecore_Audio_In_Sndfile_Data Ecore_Audio_In_Sndfile_Data;
|
||||||
EOLIAN static ssize_t
|
EOLIAN static ssize_t
|
||||||
_ecore_audio_in_sndfile_ecore_audio_in_read_internal(Eo *eo_obj EINA_UNUSED, Ecore_Audio_In_Sndfile_Data *obj, void *data, size_t len)
|
_ecore_audio_in_sndfile_ecore_audio_in_read_internal(Eo *eo_obj EINA_UNUSED, Ecore_Audio_In_Sndfile_Data *obj, void *data, size_t len)
|
||||||
{
|
{
|
||||||
return sf_read_float(obj->handle, data, len/4)*4;
|
if (!ESF_LOAD()) return 0;
|
||||||
|
return ESF_CALL(sf_read_float)(obj->handle, data, len/4)*4;
|
||||||
}
|
}
|
||||||
|
|
||||||
EOLIAN static double
|
EOLIAN static double
|
||||||
|
@ -38,8 +39,9 @@ _ecore_audio_in_sndfile_ecore_audio_in_seek(Eo *eo_obj EINA_UNUSED, Ecore_Audio_
|
||||||
{
|
{
|
||||||
sf_count_t count, pos;
|
sf_count_t count, pos;
|
||||||
|
|
||||||
|
if (!ESF_LOAD()) return 0.0;
|
||||||
count = offs * obj->sfinfo.samplerate;
|
count = offs * obj->sfinfo.samplerate;
|
||||||
pos = sf_seek(obj->handle, count, mode);
|
pos = ESF_CALL(sf_seek)(obj->handle, count, mode);
|
||||||
|
|
||||||
return (double)pos / obj->sfinfo.samplerate;
|
return (double)pos / obj->sfinfo.samplerate;
|
||||||
}
|
}
|
||||||
|
@ -50,8 +52,9 @@ _ecore_audio_in_sndfile_ecore_audio_source_set(Eo *eo_obj, Ecore_Audio_In_Sndfil
|
||||||
Ecore_Audio_Object *ea_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_CLASS);
|
Ecore_Audio_Object *ea_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_CLASS);
|
||||||
Ecore_Audio_Input *in_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_IN_CLASS);
|
Ecore_Audio_Input *in_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_IN_CLASS);
|
||||||
|
|
||||||
|
if (!ESF_LOAD()) return EINA_FALSE;
|
||||||
if (obj->handle) {
|
if (obj->handle) {
|
||||||
sf_close(obj->handle);
|
ESF_CALL(sf_close)(obj->handle);
|
||||||
obj->handle = NULL;
|
obj->handle = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +63,7 @@ _ecore_audio_in_sndfile_ecore_audio_source_set(Eo *eo_obj, Ecore_Audio_In_Sndfil
|
||||||
if (!ea_obj->source)
|
if (!ea_obj->source)
|
||||||
return EINA_FALSE;
|
return EINA_FALSE;
|
||||||
|
|
||||||
obj->handle = sf_open(ea_obj->source, SFM_READ, &obj->sfinfo);
|
obj->handle = ESF_CALL(sf_open)(ea_obj->source, SFM_READ, &obj->sfinfo);
|
||||||
|
|
||||||
if (!obj->handle) {
|
if (!obj->handle) {
|
||||||
eina_stringshare_del(ea_obj->source);
|
eina_stringshare_del(ea_obj->source);
|
||||||
|
@ -147,8 +150,9 @@ _ecore_audio_in_sndfile_ecore_audio_vio_set(Eo *eo_obj, Ecore_Audio_In_Sndfile_D
|
||||||
Ecore_Audio_Object *ea_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_CLASS);
|
Ecore_Audio_Object *ea_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_CLASS);
|
||||||
Ecore_Audio_Input *in_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_IN_CLASS);
|
Ecore_Audio_Input *in_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_IN_CLASS);
|
||||||
|
|
||||||
|
if (!ESF_LOAD()) return;
|
||||||
if (obj->handle) {
|
if (obj->handle) {
|
||||||
sf_close(obj->handle);
|
ESF_CALL(sf_close)(obj->handle);
|
||||||
obj->handle = NULL;
|
obj->handle = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,7 +174,7 @@ _ecore_audio_in_sndfile_ecore_audio_vio_set(Eo *eo_obj, Ecore_Audio_In_Sndfile_D
|
||||||
ea_obj->vio->free_func = free_func;
|
ea_obj->vio->free_func = free_func;
|
||||||
in_obj->seekable = (vio->seek != NULL);
|
in_obj->seekable = (vio->seek != NULL);
|
||||||
|
|
||||||
obj->handle = sf_open_virtual(&vio_wrapper, SFM_READ, &obj->sfinfo, eo_obj);
|
obj->handle = ESF_CALL(sf_open_virtual)(&vio_wrapper, SFM_READ, &obj->sfinfo, eo_obj);
|
||||||
|
|
||||||
if (!obj->handle) {
|
if (!obj->handle) {
|
||||||
eina_stringshare_del(ea_obj->source);
|
eina_stringshare_del(ea_obj->source);
|
||||||
|
@ -199,8 +203,9 @@ _ecore_audio_in_sndfile_eo_base_destructor(Eo *eo_obj, Ecore_Audio_In_Sndfile_Da
|
||||||
{
|
{
|
||||||
Ecore_Audio_Object *ea_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_CLASS);
|
Ecore_Audio_Object *ea_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_CLASS);
|
||||||
|
|
||||||
|
if (!ESF_LOAD()) return;
|
||||||
if (obj->handle)
|
if (obj->handle)
|
||||||
sf_close(obj->handle);
|
ESF_CALL(sf_close)(obj->handle);
|
||||||
|
|
||||||
if (ea_obj->vio)
|
if (ea_obj->vio)
|
||||||
_free_vio(ea_obj);
|
_free_vio(ea_obj);
|
||||||
|
|
|
@ -54,19 +54,19 @@ _ecore_audio_out_pulse_ecore_audio_volume_set(Eo *eo_obj, Ecore_Audio_Out_Pulse_
|
||||||
pa_cvolume pa_volume;
|
pa_cvolume pa_volume;
|
||||||
Ecore_Audio_Output *out_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_OUT_CLASS);
|
Ecore_Audio_Output *out_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_OUT_CLASS);
|
||||||
|
|
||||||
|
if (!EPA_LOAD()) return;
|
||||||
if (volume < 0)
|
if (volume < 0)
|
||||||
volume = 0;
|
volume = 0;
|
||||||
|
|
||||||
pa_cvolume_set(&pa_volume, 2, volume * PA_VOLUME_NORM);
|
EPA_CALL(pa_cvolume_set)(&pa_volume, 2, volume * PA_VOLUME_NORM);
|
||||||
|
|
||||||
ecore_audio_obj_volume_set(eo_super(eo_obj, MY_CLASS), volume);
|
ecore_audio_obj_volume_set(eo_super(eo_obj, MY_CLASS), volume);
|
||||||
|
|
||||||
EINA_LIST_FOREACH(out_obj->inputs, input, in) {
|
EINA_LIST_FOREACH(out_obj->inputs, input, in) {
|
||||||
stream = eo_key_data_get(in, "pulse_data");
|
stream = eo_key_data_get(in, "pulse_data");
|
||||||
idx = pa_stream_get_index(stream);
|
idx = EPA_CALL(pa_stream_get_index)(stream);
|
||||||
pa_operation_unref(pa_context_set_sink_input_volume(class_vars.context, idx, &pa_volume, NULL, NULL));
|
EPA_CALL(pa_operation_unref)(EPA_CALL(pa_context_set_sink_input_volume)(class_vars.context, idx, &pa_volume, NULL, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _write_cb(pa_stream *stream, size_t len, void *data)
|
static void _write_cb(pa_stream *stream, size_t len, void *data)
|
||||||
|
@ -77,14 +77,15 @@ static void _write_cb(pa_stream *stream, size_t len, void *data)
|
||||||
ssize_t bread = 0;
|
ssize_t bread = 0;
|
||||||
size_t wlen = len;
|
size_t wlen = len;
|
||||||
|
|
||||||
pa_stream_begin_write(stream, &buf, &wlen);
|
if (!EPA_LOAD()) return;
|
||||||
|
EPA_CALL(pa_stream_begin_write)(stream, &buf, &wlen);
|
||||||
|
|
||||||
bread = ecore_audio_obj_in_read(in, buf, wlen);
|
bread = ecore_audio_obj_in_read(in, buf, wlen);
|
||||||
|
|
||||||
pa_stream_write(stream, buf, bread, NULL, 0, PA_SEEK_RELATIVE);
|
EPA_CALL(pa_stream_write)(stream, buf, bread, NULL, 0, PA_SEEK_RELATIVE);
|
||||||
if (bread < (int)len)
|
if (bread < (int)len)
|
||||||
{
|
{
|
||||||
pa_operation_unref(pa_stream_trigger(stream, NULL, NULL));
|
EPA_CALL(pa_operation_unref)(EPA_CALL(pa_stream_trigger)(stream, NULL, NULL));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +100,7 @@ static void _update_samplerate_cb(void *data EINA_UNUSED, const Eo_Event *event)
|
||||||
|
|
||||||
stream = eo_key_data_get(event->object, "pulse_data");
|
stream = eo_key_data_get(event->object, "pulse_data");
|
||||||
|
|
||||||
pa_operation_unref(pa_stream_update_sample_rate(stream, samplerate * speed, NULL, NULL));
|
EPA_CALL(pa_operation_unref)(EPA_CALL(pa_stream_update_sample_rate)(stream, samplerate * speed, NULL, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
static Eina_Bool _input_attach_internal(Eo *eo_obj, Eo *in)
|
static Eina_Bool _input_attach_internal(Eo *eo_obj, Eo *in)
|
||||||
|
@ -111,6 +112,7 @@ static Eina_Bool _input_attach_internal(Eo *eo_obj, Eo *in)
|
||||||
Eina_Bool ret = EINA_FALSE;
|
Eina_Bool ret = EINA_FALSE;
|
||||||
Ecore_Audio_Object *ea_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_CLASS);
|
Ecore_Audio_Object *ea_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_CLASS);
|
||||||
|
|
||||||
|
if (!EPA_LOAD()) return EINA_FALSE;
|
||||||
ret = ecore_audio_obj_out_input_attach(eo_super(eo_obj, MY_CLASS), in);
|
ret = ecore_audio_obj_out_input_attach(eo_super(eo_obj, MY_CLASS), in);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
return EINA_FALSE;
|
return EINA_FALSE;
|
||||||
|
@ -123,7 +125,7 @@ static Eina_Bool _input_attach_internal(Eo *eo_obj, Eo *in)
|
||||||
|
|
||||||
ss.rate = ss.rate * speed;
|
ss.rate = ss.rate * speed;
|
||||||
|
|
||||||
stream = pa_stream_new(class_vars.context, name, &ss, NULL);
|
stream = EPA_CALL(pa_stream_new)(class_vars.context, name, &ss, NULL);
|
||||||
if (!stream) {
|
if (!stream) {
|
||||||
ERR("Could not create stream");
|
ERR("Could not create stream");
|
||||||
ecore_audio_obj_out_input_detach(eo_super(eo_obj, MY_CLASS), in);
|
ecore_audio_obj_out_input_detach(eo_super(eo_obj, MY_CLASS), in);
|
||||||
|
@ -135,11 +137,11 @@ static Eina_Bool _input_attach_internal(Eo *eo_obj, Eo *in)
|
||||||
eo_key_data_set(in, "pulse_data", stream);
|
eo_key_data_set(in, "pulse_data", stream);
|
||||||
|
|
||||||
|
|
||||||
pa_stream_set_write_callback(stream, _write_cb, in);
|
EPA_CALL(pa_stream_set_write_callback)(stream, _write_cb, in);
|
||||||
pa_stream_connect_playback(stream, NULL, NULL, PA_STREAM_VARIABLE_RATE, NULL, NULL);
|
EPA_CALL(pa_stream_connect_playback)(stream, NULL, NULL, PA_STREAM_VARIABLE_RATE, NULL, NULL);
|
||||||
|
|
||||||
if (ea_obj->paused)
|
if (ea_obj->paused)
|
||||||
pa_operation_unref(pa_stream_cork(stream, 1, NULL, NULL));
|
EPA_CALL(pa_operation_unref)(EPA_CALL(pa_stream_cork)(stream, 1, NULL, NULL));
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -169,8 +171,9 @@ _ecore_audio_out_pulse_ecore_audio_out_input_attach(Eo *eo_obj, Ecore_Audio_Out_
|
||||||
|
|
||||||
static void _drain_cb(pa_stream *stream, int success EINA_UNUSED, void *data EINA_UNUSED)
|
static void _drain_cb(pa_stream *stream, int success EINA_UNUSED, void *data EINA_UNUSED)
|
||||||
{
|
{
|
||||||
pa_stream_disconnect(stream);
|
if (!EPA_LOAD()) return;
|
||||||
pa_stream_unref(stream);
|
EPA_CALL(pa_stream_disconnect)(stream);
|
||||||
|
EPA_CALL(pa_stream_unref)(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
EOLIAN static Eina_Bool
|
EOLIAN static Eina_Bool
|
||||||
|
@ -180,21 +183,22 @@ _ecore_audio_out_pulse_ecore_audio_out_input_detach(Eo *eo_obj, Ecore_Audio_Out_
|
||||||
Eina_Bool ret2 = EINA_FALSE;
|
Eina_Bool ret2 = EINA_FALSE;
|
||||||
pa_operation *op;
|
pa_operation *op;
|
||||||
|
|
||||||
|
if (!EPA_LOAD()) return EINA_FALSE;
|
||||||
ret2 = ecore_audio_obj_out_input_detach(eo_super(eo_obj, MY_CLASS), in);
|
ret2 = ecore_audio_obj_out_input_detach(eo_super(eo_obj, MY_CLASS), in);
|
||||||
if (!ret2)
|
if (!ret2)
|
||||||
return EINA_FALSE;
|
return EINA_FALSE;
|
||||||
|
|
||||||
stream = eo_key_data_get(in, "pulse_data");
|
stream = eo_key_data_get(in, "pulse_data");
|
||||||
|
|
||||||
pa_stream_set_write_callback(stream, NULL, NULL);
|
EPA_CALL(pa_stream_set_write_callback)(stream, NULL, NULL);
|
||||||
op = pa_stream_drain(stream, _drain_cb, NULL);
|
op = EPA_CALL(pa_stream_drain) (stream, _drain_cb, NULL);
|
||||||
if (!op)
|
if (!op)
|
||||||
{
|
{
|
||||||
ERR("Failed to drain PulseAudio stream.");
|
ERR("Failed to drain PulseAudio stream.");
|
||||||
return EINA_FALSE;
|
return EINA_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
pa_operation_unref(op);
|
EPA_CALL(pa_operation_unref)(op);
|
||||||
return EINA_TRUE;
|
return EINA_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,7 +208,8 @@ static void _state_cb(pa_context *context, void *data EINA_UNUSED)
|
||||||
Eo *eo_obj;
|
Eo *eo_obj;
|
||||||
pa_context_state_t state;
|
pa_context_state_t state;
|
||||||
|
|
||||||
state = pa_context_get_state(context);
|
if (!EPA_LOAD()) return;
|
||||||
|
state = EPA_CALL(pa_context_get_state)(context);
|
||||||
class_vars.state = state;
|
class_vars.state = state;
|
||||||
|
|
||||||
//ref everything in the list to be sure...
|
//ref everything in the list to be sure...
|
||||||
|
@ -263,6 +268,7 @@ _ecore_audio_out_pulse_eo_base_constructor(Eo *eo_obj, Ecore_Audio_Out_Pulse_Dat
|
||||||
char **argv;
|
char **argv;
|
||||||
Ecore_Audio_Output *out_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_OUT_CLASS);
|
Ecore_Audio_Output *out_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_OUT_CLASS);
|
||||||
|
|
||||||
|
if (!EPA_LOAD()) return NULL;
|
||||||
eo_obj = eo_constructor(eo_super(eo_obj, MY_CLASS));
|
eo_obj = eo_constructor(eo_super(eo_obj, MY_CLASS));
|
||||||
|
|
||||||
out_obj->need_writer = EINA_FALSE;
|
out_obj->need_writer = EINA_FALSE;
|
||||||
|
@ -271,12 +277,12 @@ _ecore_audio_out_pulse_eo_base_constructor(Eo *eo_obj, Ecore_Audio_Out_Pulse_Dat
|
||||||
ecore_app_args_get(&argc, &argv);
|
ecore_app_args_get(&argc, &argv);
|
||||||
if (!argc) {
|
if (!argc) {
|
||||||
DBG("Could not get program name, pulse outputs will be named ecore_audio");
|
DBG("Could not get program name, pulse outputs will be named ecore_audio");
|
||||||
class_vars.context = pa_context_new(class_vars.api, "ecore_audio");
|
class_vars.context = EPA_CALL(pa_context_new)(class_vars.api, "ecore_audio");
|
||||||
} else {
|
} else {
|
||||||
class_vars.context = pa_context_new(class_vars.api, basename(argv[0]));
|
class_vars.context = EPA_CALL(pa_context_new)(class_vars.api, basename(argv[0]));
|
||||||
}
|
}
|
||||||
pa_context_set_state_callback(class_vars.context, _state_cb, NULL);
|
EPA_CALL(pa_context_set_state_callback)(class_vars.context, _state_cb, NULL);
|
||||||
pa_context_connect(class_vars.context, NULL, PA_CONTEXT_NOFLAGS, NULL);
|
EPA_CALL(pa_context_connect)(class_vars.context, NULL, PA_CONTEXT_NOFLAGS, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
class_vars.outputs = eina_list_append(class_vars.outputs, eo_obj);
|
class_vars.outputs = eina_list_append(class_vars.outputs, eo_obj);
|
||||||
|
|
|
@ -40,21 +40,22 @@ static Eina_Bool _write_cb(void *data)
|
||||||
ssize_t written, bread = 0;
|
ssize_t written, bread = 0;
|
||||||
float buf[1024];
|
float buf[1024];
|
||||||
|
|
||||||
|
if (!ESF_LOAD()) return EINA_FALSE;
|
||||||
/* TODO: Support mixing of multiple inputs */
|
/* TODO: Support mixing of multiple inputs */
|
||||||
in = eina_list_data_get(out_obj->inputs);
|
in = eina_list_data_get(out_obj->inputs);
|
||||||
|
|
||||||
bread = ecore_audio_obj_in_read(in, buf, 4*1024);
|
bread = ecore_audio_obj_in_read(in, buf, 4*1024);
|
||||||
|
|
||||||
if (bread == 0) {
|
if (bread == 0) {
|
||||||
sf_write_sync(obj->handle);
|
ESF_CALL(sf_write_sync)(obj->handle);
|
||||||
ea_obj->paused = EINA_TRUE;
|
ea_obj->paused = EINA_TRUE;
|
||||||
out_obj->write_idler = NULL;
|
out_obj->write_idler = NULL;
|
||||||
return EINA_FALSE;
|
return EINA_FALSE;
|
||||||
}
|
}
|
||||||
written = sf_write_float(obj->handle, buf, bread/4)*4;
|
written = ESF_CALL(sf_write_float)(obj->handle, buf, bread/4)*4;
|
||||||
|
|
||||||
if (written != bread)
|
if (written != bread)
|
||||||
ERR("Short write! (%s)\n", sf_strerror(obj->handle));
|
ERR("Short write! (%s)\n", ESF_CALL(sf_strerror)(obj->handle));
|
||||||
|
|
||||||
return EINA_TRUE;
|
return EINA_TRUE;
|
||||||
}
|
}
|
||||||
|
@ -66,6 +67,7 @@ _ecore_audio_out_sndfile_ecore_audio_out_input_attach(Eo *eo_obj, Ecore_Audio_Ou
|
||||||
Ecore_Audio_Output *out_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_OUT_CLASS);
|
Ecore_Audio_Output *out_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_OUT_CLASS);
|
||||||
Eina_Bool ret2 = EINA_FALSE;
|
Eina_Bool ret2 = EINA_FALSE;
|
||||||
|
|
||||||
|
if (!ESF_LOAD()) return EINA_FALSE;
|
||||||
ret2 = ecore_audio_obj_out_input_attach(eo_super(eo_obj, MY_CLASS), in);
|
ret2 = ecore_audio_obj_out_input_attach(eo_super(eo_obj, MY_CLASS), in);
|
||||||
if (!ret2)
|
if (!ret2)
|
||||||
return EINA_FALSE;
|
return EINA_FALSE;
|
||||||
|
@ -73,7 +75,7 @@ _ecore_audio_out_sndfile_ecore_audio_out_input_attach(Eo *eo_obj, Ecore_Audio_Ou
|
||||||
obj->sfinfo.samplerate = ecore_audio_obj_in_samplerate_get(in);
|
obj->sfinfo.samplerate = ecore_audio_obj_in_samplerate_get(in);
|
||||||
obj->sfinfo.channels = ecore_audio_obj_in_channels_get(in);
|
obj->sfinfo.channels = ecore_audio_obj_in_channels_get(in);
|
||||||
|
|
||||||
obj->handle = sf_open(ea_obj->source, SFM_WRITE, &obj->sfinfo);
|
obj->handle = ESF_CALL(sf_open)(ea_obj->source, SFM_WRITE, &obj->sfinfo);
|
||||||
|
|
||||||
if (!obj->handle) {
|
if (!obj->handle) {
|
||||||
eina_stringshare_del(ea_obj->source);
|
eina_stringshare_del(ea_obj->source);
|
||||||
|
@ -97,8 +99,9 @@ _ecore_audio_out_sndfile_ecore_audio_source_set(Eo *eo_obj, Ecore_Audio_Out_Sndf
|
||||||
{
|
{
|
||||||
Ecore_Audio_Object *ea_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_CLASS);
|
Ecore_Audio_Object *ea_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_CLASS);
|
||||||
|
|
||||||
|
if (!ESF_LOAD()) return EINA_FALSE;
|
||||||
if (obj->handle) {
|
if (obj->handle) {
|
||||||
sf_close(obj->handle);
|
ESF_CALL(sf_close)(obj->handle);
|
||||||
obj->handle = NULL;
|
obj->handle = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,8 +180,9 @@ _ecore_audio_out_sndfile_eo_base_destructor(Eo *eo_obj, Ecore_Audio_Out_Sndfile_
|
||||||
{
|
{
|
||||||
Ecore_Audio_Output *out_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_OUT_CLASS);
|
Ecore_Audio_Output *out_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_OUT_CLASS);
|
||||||
|
|
||||||
|
if (!ESF_LOAD()) return;
|
||||||
if (obj->handle)
|
if (obj->handle)
|
||||||
sf_close(obj->handle);
|
ESF_CALL(sf_close)(obj->handle);
|
||||||
if (out_obj->write_idler)
|
if (out_obj->write_idler)
|
||||||
ecore_idler_del(out_obj->write_idler);
|
ecore_idler_del(out_obj->write_idler);
|
||||||
|
|
||||||
|
|
|
@ -144,6 +144,7 @@ struct _Ecore_Audio_Input
|
||||||
|
|
||||||
extern Eina_List *ecore_audio_modules;
|
extern Eina_List *ecore_audio_modules;
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
#ifdef HAVE_ALSA
|
#ifdef HAVE_ALSA
|
||||||
/* ecore_audio_alsa */
|
/* ecore_audio_alsa */
|
||||||
struct _Ecore_Audio_Alsa
|
struct _Ecore_Audio_Alsa
|
||||||
|
@ -158,26 +159,85 @@ Ecore_Audio_Module *ecore_audio_alsa_init(void);
|
||||||
void ecore_audio_alsa_shutdown(void);
|
void ecore_audio_alsa_shutdown(void);
|
||||||
#endif /* HAVE_ALSA */
|
#endif /* HAVE_ALSA */
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
#ifdef HAVE_PULSE
|
#ifdef HAVE_PULSE
|
||||||
|
typedef struct _Ecore_Audio_Lib_Pulse Ecore_Audio_Lib_Pulse;
|
||||||
|
|
||||||
|
struct _Ecore_Audio_Lib_Pulse
|
||||||
|
{
|
||||||
|
Eina_Module *mod;
|
||||||
|
|
||||||
|
pa_context *(*pa_context_new) (pa_mainloop_api *mainloop, const char *name);
|
||||||
|
int (*pa_context_connect) (pa_context *c, const char *server, pa_context_flags_t flags, const pa_spawn_api *api);
|
||||||
|
pa_operation *(*pa_context_set_sink_input_volume) (pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata);
|
||||||
|
pa_context_state_t (*pa_context_get_state) (pa_context *c);
|
||||||
|
void (*pa_context_set_state_callback) (pa_context *c, pa_context_notify_cb_t cb, void *userdata);
|
||||||
|
void (*pa_operation_unref) (pa_operation *o);
|
||||||
|
pa_cvolume *(*pa_cvolume_set) (pa_cvolume *a, unsigned channels, pa_volume_t v);
|
||||||
|
pa_stream *(*pa_stream_new) (pa_context *c, const char *name, const pa_sample_spec *ss, const pa_channel_map *map);
|
||||||
|
void (*pa_stream_unref) (pa_stream *s);
|
||||||
|
int (*pa_stream_connect_playback) (pa_stream *s, const char *dev, const pa_buffer_attr *attr, pa_stream_flags_t flags, const pa_cvolume *volume, pa_stream *sync_stream);
|
||||||
|
int (*pa_stream_disconnect) (pa_stream *s);
|
||||||
|
pa_operation *(*pa_stream_drain) (pa_stream *s, pa_stream_success_cb_t cb, void *userdata);
|
||||||
|
pa_operation *(*pa_stream_cork) (pa_stream *s, int b, pa_stream_success_cb_t cb, void *userdata);
|
||||||
|
int (*pa_stream_write) (pa_stream *p, const void *data, size_t nbytes, pa_free_cb_t free_cb, int64_t offset, pa_seek_mode_t seek);
|
||||||
|
int (*pa_stream_begin_write) (pa_stream *p, void **data, size_t *nbytes);
|
||||||
|
void (*pa_stream_set_write_callback) (pa_stream *p, pa_stream_request_cb_t cb, void *userdata);
|
||||||
|
pa_operation *(*pa_stream_trigger) (pa_stream *s, pa_stream_success_cb_t cb, void *userdata);
|
||||||
|
pa_operation *(*pa_stream_update_sample_rate) (pa_stream *s, uint32_t rate, pa_stream_success_cb_t cb, void *userdata);
|
||||||
|
uint32_t (*pa_stream_get_index) (pa_stream *s);
|
||||||
|
};
|
||||||
|
|
||||||
|
#define EPA_CALL(x) ecore_audio_pulse_lib->x
|
||||||
|
#define EPA_LOAD() ecore_audio_pulse_lib_load()
|
||||||
|
|
||||||
|
extern Ecore_Audio_Lib_Pulse *ecore_audio_pulse_lib;
|
||||||
|
|
||||||
|
Eina_Bool ecore_audio_pulse_lib_load(void);
|
||||||
|
void ecore_audio_pulse_lib_unload(void);
|
||||||
|
|
||||||
|
/* These are unused from ecore_audio_pulse.c which isn't used
|
||||||
Ecore_Audio_Module *ecore_audio_pulse_init(void);
|
Ecore_Audio_Module *ecore_audio_pulse_init(void);
|
||||||
void ecore_audio_pulse_shutdown(void);
|
void ecore_audio_pulse_shutdown(void);
|
||||||
|
*/
|
||||||
#endif /* HAVE_PULSE */
|
#endif /* HAVE_PULSE */
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
#ifdef HAVE_SNDFILE
|
#ifdef HAVE_SNDFILE
|
||||||
/* ecore_audio_sndfile */
|
/* ecore_audio_sndfile */
|
||||||
Ecore_Audio_Module *ecore_audio_sndfile_init(void);
|
typedef struct _Ecore_Audio_Lib_Sndfile Ecore_Audio_Lib_Sndfile;
|
||||||
void ecore_audio_sndfile_shutdown(void);
|
|
||||||
|
struct _Ecore_Audio_Lib_Sndfile
|
||||||
|
{
|
||||||
|
Eina_Module *mod;
|
||||||
|
|
||||||
|
SNDFILE *(*sf_open) (const char *path, int mode, SF_INFO *sfinfo);
|
||||||
|
SNDFILE *(*sf_open_virtual) (SF_VIRTUAL_IO *sfvirtual, int mode, SF_INFO *sfinfo, void *user_data);
|
||||||
|
int (*sf_close) (SNDFILE *sndfile);
|
||||||
|
sf_count_t (*sf_read_float) (SNDFILE *sndfile, float *ptr, sf_count_t items);
|
||||||
|
sf_count_t (*sf_write_float) (SNDFILE *sndfile, const float *ptr, sf_count_t items);
|
||||||
|
void (*sf_write_sync) (SNDFILE *sndfile);
|
||||||
|
sf_count_t (*sf_seek) (SNDFILE *sndfile, sf_count_t frames, int whence);
|
||||||
|
const char *(*sf_strerror) (SNDFILE *sndfile);
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ESF_CALL(x) ecore_audio_sndfile_lib->x
|
||||||
|
#define ESF_LOAD() ecore_audio_sndfile_lib_load()
|
||||||
|
|
||||||
|
extern Ecore_Audio_Lib_Sndfile *ecore_audio_sndfile_lib;
|
||||||
|
|
||||||
|
Eina_Bool ecore_audio_sndfile_lib_load(void);
|
||||||
|
void ecore_audio_sndfile_lib_unload(void);
|
||||||
#endif /* HAVE_SNDFILE */
|
#endif /* HAVE_SNDFILE */
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
#ifdef HAVE_COREAUDIO
|
#ifdef HAVE_COREAUDIO
|
||||||
/* ecore_audio_core_audio */
|
/* ecore_audio_core_audio */
|
||||||
Ecore_Audio_Module *ecore_audio_core_audio_init(void);
|
Ecore_Audio_Module *ecore_audio_core_audio_init(void);
|
||||||
void ecore_audio_core_audio_shutdown(void);
|
void ecore_audio_core_audio_shutdown(void);
|
||||||
#endif /* HAVE_COREAUDIO */
|
#endif /* HAVE_COREAUDIO */
|
||||||
|
|
||||||
Ecore_Audio_Module *ecore_audio_tone_init(void);
|
//////////////////////////////////////////////////////////////////////////
|
||||||
void ecore_audio_tone_shutdown(void);
|
|
||||||
|
|
||||||
Ecore_Audio_Module *ecore_audio_custom_init(void);
|
Ecore_Audio_Module *ecore_audio_custom_init(void);
|
||||||
void ecore_audio_custom_shutdown(void);
|
void ecore_audio_custom_shutdown(void);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue