From ea87e16f9c4824afdebfa57c6f84c1a07ff621db Mon Sep 17 00:00:00 2001 From: Jiwon Kim Date: Wed, 9 Nov 2016 23:08:05 +0900 Subject: [PATCH] ecore_audio: Add tizen ecore_audio module Modulation (phase 1) is completed. It opens %{libdir}/ecore_audio/modules/tizen/{version}/module.so , and use it than libpulse. Origin code (using libpulse) also work well. But that's volume is handled media volume. As using Tizen's audio module, volume control can be followed to platform poicy. Change-Id: Ic8068b87a10ee8cd2e4786d4ad7d4bf529a7d881 Signed-off-by: Jiwon Kim --- configure.ac | 18 ++ packaging/efl.spec | 1 + src/Makefile_Ecore_Audio.am | 15 +- src/lib/ecore_audio/Ecore_Audio.h | 4 + src/lib/ecore_audio/ecore_audio_obj_in_sndfile.c | 14 ++ src/lib/ecore_audio/ecore_audio_obj_out_tizen.c | 208 +++++++++++++++++++++++ src/lib/ecore_audio/ecore_audio_obj_out_tizen.h | 46 +++++ src/lib/ecore_audio/ecore_audio_out_tizen.eo | 10 ++ src/lib/edje/edje_multisense.c | 10 ++ 9 files changed, 325 insertions(+), 1 deletion(-) create mode 100644 src/lib/ecore_audio/ecore_audio_obj_out_tizen.c create mode 100644 src/lib/ecore_audio/ecore_audio_obj_out_tizen.h create mode 100644 src/lib/ecore_audio/ecore_audio_out_tizen.eo diff --git a/configure.ac b/configure.ac index 8aaba7b..584da9e 100755 --- a/configure.ac +++ b/configure.ac @@ -3311,6 +3311,22 @@ want_alsa="no" # TODO: and the EFL_OPTIONAL_DEPEND_PKG(), use EFL_DEPEND_PKG() want_sndfile="yes" +AC_ARG_ENABLE([tizenaudio], + [AS_HELP_STRING([--enable-tizenaudio],[enable tizen audio sound support. @<:@default=enabled@:>@])], + [ + if test "x${enableval}" = "xyes" ; then + want_tizenaudio="yes" + else + want_tizenaudio="no" + fi + ], + [want_tizenaudio="no"]) +if test "x${want_tizenaudio}" = "xyes"; then + AC_DEFINE([HAVE_TIZENAUDIO], [1], [Tizen Audio support enabled]) +else + AC_DEFINE([HAVE_TIZENAUDIO], [0], [Tizen Audio support disabled]) +fi + AC_ARG_ENABLE([pulseaudio], [AS_HELP_STRING([--disable-pulseaudio],[disable pulseaudio sound support. @<:@default=enabled@:>@])], [ @@ -3398,6 +3414,7 @@ EFL_ADD_FEATURE([ECORE_AUDIO], [alsa]) EFL_ADD_FEATURE([ECORE_AUDIO], [pulseaudio]) EFL_ADD_FEATURE([ECORE_AUDIO], [sndfile]) EFL_ADD_FEATURE([ECORE_AUDIO], [coreaudio]) +EFL_ADD_FEATURE([ECORE_AUDIO], [tizenaudio]) ### Checks for header files @@ -3415,6 +3432,7 @@ EFL_LIB_END_OPTIONAL([Ecore_Audio]) AM_CONDITIONAL([HAVE_ECORE_AUDIO_PULSE], [test "x${want_pulseaudio}" = "xyes"]) AM_CONDITIONAL([HAVE_ECORE_AUDIO_SNDFILE], [test "x${want_sndfile}" = "xyes"]) AM_CONDITIONAL([HAVE_ECORE_AUDIO_CORE_AUDIO], [test "x${want_coreaudio}" = "xyes"]) +AM_CONDITIONAL([HAVE_ECORE_AUDIO_TIZEN], [test "x${want_tizenaudio}" = "xyes"]) #### End of Ecore_Audio diff --git a/packaging/efl.spec b/packaging/efl.spec index a869eb5..5d71ca0 100755 --- a/packaging/efl.spec +++ b/packaging/efl.spec @@ -729,6 +729,7 @@ CFLAGS+=" -DEFL_FEATURE_EMULATOR " --enable-harfbuzz \ --enable-hyphen \ --with-dictionaries-hyphen-dir=/usr/share/hyphen/ \ + --enable-tizenaudio \ --enable-i-really-know-what-i-am-doing-and-that-this-will-probably-break-things-and-i-will-fix-them-myself-and-send-patches-aba diff --git a/src/Makefile_Ecore_Audio.am b/src/Makefile_Ecore_Audio.am index ccce8f7..5cd5d96 100644 --- a/src/Makefile_Ecore_Audio.am +++ b/src/Makefile_Ecore_Audio.am @@ -11,6 +11,10 @@ ecore_audio_eolian_files = \ lib/ecore_audio/ecore_audio_in_tone.eo +if HAVE_ECORE_AUDIO_TIZEN +ecore_audio_eolian_files += lib/ecore_audio/ecore_audio_out_tizen.eo +endif + if HAVE_ECORE_AUDIO_PULSE ecore_audio_eolian_files += lib/ecore_audio/ecore_audio_out_pulse.eo endif @@ -57,11 +61,20 @@ lib/ecore_audio/ecore_audio_obj_out.c \ lib/ecore_audio/ecore_audio_obj_in_tone.c \ 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@ -DPACKAGE_LIB_DIR=\"$(libdir)\" + lib_ecore_audio_libecore_audio_la_LIBADD = @ECORE_AUDIO_LIBS@ lib_ecore_audio_libecore_audio_la_DEPENDENCIES = @ECORE_AUDIO_INTERNAL_LIBS@ lib_ecore_audio_libecore_audio_la_LDFLAGS = @EFL_LTLIBRARY_FLAGS@ +if HAVE_ECORE_AUDIO_TIZEN +dist_installed_ecoreaudiomainheaders_DATA += \ +lib/ecore_audio/ecore_audio_obj_out_tizen.h + +lib_ecore_audio_libecore_audio_la_SOURCES += \ +lib/ecore_audio/ecore_audio_obj_out_tizen.c +endif + if HAVE_ECORE_AUDIO_PULSE dist_installed_ecoreaudiomainheaders_DATA += \ lib/ecore_audio/ecore_audio_obj_out_pulse.h diff --git a/src/lib/ecore_audio/Ecore_Audio.h b/src/lib/ecore_audio/Ecore_Audio.h index 116ab68..56fc383 100644 --- a/src/lib/ecore_audio/Ecore_Audio.h +++ b/src/lib/ecore_audio/Ecore_Audio.h @@ -226,6 +226,10 @@ EAPI int ecore_audio_shutdown(void); # include #endif +#if HAVE_TIZENAUDIO +# include +#endif + /** * @} */ diff --git a/src/lib/ecore_audio/ecore_audio_obj_in_sndfile.c b/src/lib/ecore_audio/ecore_audio_obj_in_sndfile.c index 599ae27..3237c5c 100644 --- a/src/lib/ecore_audio/ecore_audio_obj_in_sndfile.c +++ b/src/lib/ecore_audio/ecore_audio_obj_in_sndfile.c @@ -30,6 +30,13 @@ typedef struct _Ecore_Audio_In_Sndfile_Data Ecore_Audio_In_Sndfile_Data; 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) { + // TIZEN_ONLY(20161116): Add signed 16 read if write module only support S16 + char *pcm_fmt; + eo_do(eo_obj, pcm_fmt = (char *)eo_key_data_get("pcm_fmt")); + if (pcm_fmt && !strcmp(pcm_fmt, "S16")) + return sf_read_short(obj->handle, data, len/2)*2; + // + return sf_read_float(obj->handle, data, len/4)*4; } @@ -205,6 +212,13 @@ _ecore_audio_in_sndfile_eo_base_destructor(Eo *eo_obj, Ecore_Audio_In_Sndfile_Da if (ea_obj->vio) _free_vio(ea_obj); + // TIZEN_ONLY(20161116): Add signed 16 read if write module only support S16 + char *pcm_fmt; + eo_do(eo_obj, pcm_fmt = (char *)eo_key_data_get("pcm_fmt")); + eo_do(eo_obj, eo_key_data_set("pcm_fmt", NULL)); + free(pcm_fmt); + // + eo_do_super(eo_obj, MY_CLASS, eo_destructor()); } diff --git a/src/lib/ecore_audio/ecore_audio_obj_out_tizen.c b/src/lib/ecore_audio/ecore_audio_obj_out_tizen.c new file mode 100644 index 0000000..591f9a9 --- /dev/null +++ b/src/lib/ecore_audio/ecore_audio_obj_out_tizen.c @@ -0,0 +1,208 @@ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#if defined (__MacOSX__) || (defined (__MACH__) && defined (__APPLE__)) || defined (__FreeBSD__) +# include +#endif + +#ifdef HAVE_FEATURES_H +#include +#endif + +#include +#include "ecore_audio_private.h" + +#include +#include +#include + +#define MY_CLASS ECORE_AUDIO_OUT_TIZEN_CLASS +#define MY_CLASS_NAME "Ecore_Audio_Out_Tizen" + +#if defined(_WIN32) || defined(__CYGWIN__) +# define MODULE_EXT ".dll" +#else +# define MODULE_EXT ".so" +#endif + +#define AUDIO_MODULE_NAME "module"MODULE_EXT +#define MODULE_PATH PACKAGE_LIB_DIR"/ecore_audio/modules/tizen/"MODULE_ARCH + +struct _Ecore_Audio_Out_Tizen_Module_Func +{ + int (*init) (int sample_rate, int channel, void **handle); + int (*deinit) (void *handle); + int (*get_buffer_size) (void *handle, size_t *size); + int (*write) (void *handle, void *buf, unsigned int len); + int (*drain) (void *handle); + int (*set_write_cb) (void *handle, void (*out_cb)(void *handle, size_t nbytes, void *user_data), void *data); + int (*unset_write_cb) (void *handle); +}; + +typedef struct _Ecore_Audio_Out_Tizen_Module_Func Ecore_Audio_Out_Tizen_Module_Func; + +static Ecore_Audio_Out_Tizen_Module_Func module_func = { NULL, }; +static Eina_Module *module = NULL; + +struct _Ecore_Audio_Out_Tizen_Data +{ + Ecore_Audio_Out_Tizen_Module_Func *func; + Eo *attached_in; +}; + +typedef struct _Ecore_Audio_Out_Tizen_Data Ecore_Audio_Out_Tizen_Data; + +static Eina_Bool _module_load(Ecore_Audio_Out_Tizen_Data *td) +{ + if (td->func) + return EINA_TRUE; + + if (!module) + { + Eina_Module *em = NULL; + em = eina_module_new(MODULE_PATH "/" AUDIO_MODULE_NAME); + if (!eina_module_load(em)) + { + eina_module_free(em); + return EINA_FALSE; + } + + module_func.init = eina_module_symbol_get(em, "ecore_audio_init"); + module_func.deinit = eina_module_symbol_get(em, "ecore_audio_deinit"); + module_func.get_buffer_size = eina_module_symbol_get(em, "ecore_audio_get_buffer_size"); + module_func.write = eina_module_symbol_get(em, "ecore_audio_write"); + module_func.drain = eina_module_symbol_get(em, "ecore_audio_drain"); + module_func.set_write_cb = eina_module_symbol_get(em, "ecore_audio_set_write_cb"); + module_func.unset_write_cb = eina_module_symbol_get(em, "ecore_audio_unset_write_cb"); + + if ((!module_func.init) || (!module_func.deinit) || (!module_func.get_buffer_size) + || (!module_func.write) || (!module_func.drain) || (!module_func.set_write_cb)) + { + module_func.init = NULL; + module_func.deinit = NULL; + module_func.get_buffer_size = NULL; + module_func.write = NULL; + module_func.drain = NULL; + module_func.set_write_cb = NULL; + module_func.unset_write_cb = NULL; + + eina_module_free(em); + return EINA_FALSE; + } + module = em; + } + + td->func = &module_func; + + return EINA_TRUE; +} + +static void _stream_write_cb(void *handle, size_t len EINA_UNUSED, void *data) +{ + Eo *in = data; + Ecore_Audio_Out_Tizen_Data *_td; + eo_do(in, _td = eo_key_data_get("mod_data")); + + void *buf; + ssize_t bread = 0; + size_t wlen; + + _td->func->get_buffer_size(handle, &wlen); + buf = malloc(wlen); + eo_do(in, bread = ecore_audio_obj_in_read(buf, wlen)); + + if (bread > 0) + { + _td->func->write(handle, buf, (unsigned int)bread); + } + + free(buf); +} + +EOLIAN static Eina_Bool +_ecore_audio_out_tizen_ecore_audio_out_input_attach(Eo *eo_obj, Ecore_Audio_Out_Tizen_Data *_td, Eo *in) +{ + int ret; + Eina_Bool ret2; + void *handle; + int samplerate = 0; + int channels = 0; + + eo_do_super(eo_obj, MY_CLASS, ret2 = ecore_audio_obj_out_input_attach(in)); + if (!ret2) + return EINA_FALSE; + + eo_do(in, channels = ecore_audio_obj_in_channels_get()); + eo_do(in, samplerate = ecore_audio_obj_in_samplerate_get()); + + ret = _td->func->init(samplerate, channels, &handle); + if (ret) + { + eo_do_super(eo_obj, MY_CLASS, ecore_audio_obj_out_input_detach(in)); + ERR("init error : %d", ret); + return EINA_FALSE; + } + eo_do(in, eo_key_data_set("mod_handle", handle)); + eo_do(in, eo_key_data_set("mod_data", _td)); + eo_do(in, eo_key_data_set("pcm_fmt", strdup("S16"))); + _td->attached_in = in; + ret = _td->func->set_write_cb(handle, _stream_write_cb, in); + if (ret) + { + eo_do_super(eo_obj, MY_CLASS, ecore_audio_obj_out_input_detach(in)); + ERR("set_write_callback error : %d", ret); + _td->func->deinit(handle); + return EINA_FALSE; + } + + return EINA_TRUE; +} + +EOLIAN static Eina_Bool +_ecore_audio_out_tizen_ecore_audio_out_input_detach(Eo *eo_obj, Ecore_Audio_Out_Tizen_Data *_td, Eo *in) +{ + Eina_Bool ret2 = EINA_FALSE; + void *handle; + + eo_do_super(eo_obj, MY_CLASS, ret2 = ecore_audio_obj_out_input_detach(in)); + if (!ret2) + return EINA_FALSE; + + eo_do(in, handle = eo_key_data_get("mod_handle")); + _td->func->unset_write_cb(handle); + _td->func->drain(handle); + _td->func->deinit(handle); + + return EINA_TRUE; +} + +EOLIAN static Eo * +_ecore_audio_out_tizen_eo_base_constructor(Eo *eo_obj, Ecore_Audio_Out_Tizen_Data *_td) +{ + + Ecore_Audio_Output *out_obj = eo_data_scope_get(eo_obj, ECORE_AUDIO_OUT_CLASS); + + eo_obj = eo_do_super_ret(eo_obj, MY_CLASS, eo_obj, eo_constructor()); + + if (!_module_load(_td)) + { + // Need to destructing + ERR("Faild to load ecore audio module"); + return NULL; + } + + return eo_obj; +} + +EOLIAN static void +_ecore_audio_out_tizen_eo_base_destructor(Eo *eo_obj, Ecore_Audio_Out_Tizen_Data *_td EINA_UNUSED) +{ + eo_do_super(eo_obj, MY_CLASS, eo_destructor()); +} + +#include "ecore_audio_out_tizen.eo.c" diff --git a/src/lib/ecore_audio/ecore_audio_obj_out_tizen.h b/src/lib/ecore_audio/ecore_audio_obj_out_tizen.h new file mode 100644 index 0000000..60d9caf --- /dev/null +++ b/src/lib/ecore_audio/ecore_audio_obj_out_tizen.h @@ -0,0 +1,46 @@ +#ifndef ECORE_AUDIO_OUT_TIZEN_H +#define ECORE_AUDIO_OUT_TIZEN_H + +#include +#include + +#ifdef EAPI +#undef EAPI +#endif + +#ifdef __GNUC__ +#if __GNUC__ >= 4 +#define EAPI __attribute__ ((visibility("default"))) +#else +#define EAPI +#endif +#else +#define EAPI +#endif + +/** + * @file ecore_audio_obj_out_pulse.h + * @brief Ecore_Audio pulseaudio output + */ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @internal + * @defgroup ecore_audio_obj_out_tizen - Ecore_Audio tizen audio-io output + * @ingroup Ecore_Audio_Group + * @{ + */ +#include "ecore_audio_out_tizen.eo.h" +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/lib/ecore_audio/ecore_audio_out_tizen.eo b/src/lib/ecore_audio/ecore_audio_out_tizen.eo new file mode 100644 index 0000000..80b3063 --- /dev/null +++ b/src/lib/ecore_audio/ecore_audio_out_tizen.eo @@ -0,0 +1,10 @@ +class Ecore_Audio_Out_Tizen (Ecore_Audio_Out) +{ + eo_prefix: ecore_audio_obj_out_tizen; + implements { + Eo.Base.constructor; + Eo.Base.destructor; + Ecore_Audio_Out.input_attach; + Ecore_Audio_Out.input_detach; + } +} diff --git a/src/lib/edje/edje_multisense.c b/src/lib/edje/edje_multisense.c index 92e36d5..fec67df 100644 --- a/src/lib/edje/edje_multisense.c +++ b/src/lib/edje/edje_multisense.c @@ -209,12 +209,22 @@ _edje_multisense_internal_sound_sample_play(Edje *ed, const char *sample_name, c eo_event_callback_add(ECORE_AUDIO_IN_EVENT_IN_STOPPED, _play_finished, NULL)); if (!out) { +#if HAVE_TIZENAUDIO + if (!(out = eo_add(ECORE_AUDIO_OUT_TIZEN_CLASS, NULL))) + { + ERR("Could not create multisense audio out (Tizen Audio)"); +#endif + #if HAVE_COREAUDIO out = eo_add(ECORE_AUDIO_OUT_CORE_AUDIO_CLASS, NULL); #elif HAVE_PULSE out = eo_add(ECORE_AUDIO_OUT_PULSE_CLASS, NULL, eo_event_callback_add(ECORE_AUDIO_OUT_PULSE_EVENT_CONTEXT_FAIL, _out_fail, NULL)); #endif + +#if HAVE_TIZENAUDIO + } +#endif if (out) outs++; } if (!out) -- 2.7.4