From 93baa70cd9facd16de7fbb556f92e91e2ce561e5 Mon Sep 17 00:00:00 2001 From: Ji-hoon Lee Date: Thu, 14 Feb 2019 14:26:31 +0900 Subject: [PATCH] Add wakeup manager for multiple wakeup engine management Change-Id: I3da8f8b77d333e1d14170f95c0b88a1a5e896cf3 --- CMakeLists.txt | 25 +- inc/multi_assistant_main.h | 62 +- inc/multi_assistant_service.h | 13 +- inc/multi_assistant_service_plugin.h | 104 ++- lib/aarch64/libmulti-wakeup-recognizer.so | Bin 12984 -> 0 bytes lib/armv7l/libmulti-wakeup-recognizer.so | Bin 9972 -> 0 bytes lib/i586/libmulti-wakeup-recognizer.so | Bin 13728 -> 0 bytes lib/x86_64/libmulti-wakeup-recognizer.so | Bin 14448 -> 0 bytes .../org.tizen.multi-assistant-service.spec | 4 +- plugins/CMakeLists.txt | 1 + plugins/wakeup-manager/CMakeLists.txt | 53 ++ plugins/wakeup-manager/inc/wakeup_manager.h | 208 +++++ .../wakeup-manager/inc/wakeup_manager_main.h | 46 + plugins/wakeup-manager/src/wakeup_manager.cpp | 879 ++++++++++++++++++ src/multi_assistant_dbus.c | 140 ++- src/multi_assistant_dbus.h | 4 +- src/multi_assistant_dbus_server.c | 124 +++ src/multi_assistant_dbus_server.h | 8 + src/multi_assistant_service.c | 183 ++-- src/multi_assistant_service_plugin.c | 471 +++++++--- 20 files changed, 2036 insertions(+), 289 deletions(-) delete mode 100644 lib/aarch64/libmulti-wakeup-recognizer.so delete mode 100644 lib/armv7l/libmulti-wakeup-recognizer.so delete mode 100644 lib/i586/libmulti-wakeup-recognizer.so delete mode 100644 lib/x86_64/libmulti-wakeup-recognizer.so create mode 100644 plugins/CMakeLists.txt create mode 100644 plugins/wakeup-manager/CMakeLists.txt create mode 100644 plugins/wakeup-manager/inc/wakeup_manager.h create mode 100644 plugins/wakeup-manager/inc/wakeup_manager_main.h create mode 100644 plugins/wakeup-manager/src/wakeup_manager.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index ddb18cf..276a0cb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,8 +25,8 @@ pkg_check_modules(pkgs REQUIRED ecore dbus-1 glib-2.0 - message-port libxml-2.0 + multi-assistant ) @@ -72,25 +72,6 @@ INSTALL(FILES ${CMAKE_SOURCE_DIR}/LICENSE.Flora DESTINATION /usr/share/license/) INSTALL(FILES ${CMAKE_SOURCE_DIR}/${PKGNAME}.xml DESTINATION /usr/share/packages) INSTALL(TARGETS ${BINNAME} DESTINATION ${BINDIR}) +TARGET_LINK_LIBRARIES(${BINNAME} -ldl ${pkgs_LDFLAGS} ${EXTRA_LDFLAGS}) -FIND_PROGRAM(UNAME NAMES uname) -EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH") - -# Install libraries -IF("${ARCH}" MATCHES "^arm.*") -TARGET_LINK_LIBRARIES(${BINNAME} -Llib/armv7l -ldl ${pkgs_LDFLAGS} ${EXTRA_LDFLAGS}) -INSTALL(FILES ${CMAKE_SOURCE_DIR}/lib/armv7l/libmulti-wakeup-recognizer.so DESTINATION ${TZ_SYS_RO_SHARE}/multiassistant/ma/1.0/engine/ COMPONENT RuntimeLibraries) -ELSEIF("${ARCH}" MATCHES "^i586.*") -TARGET_LINK_LIBRARIES(${BINNAME} -Llib/i586 -ldl ${pkgs_LDFLAGS} ${EXTRA_LDFLAGS}) -INSTALL(FILES ${CMAKE_SOURCE_DIR}/lib/i586/libmulti-wakeup-recognizer.so DESTINATION ${TZ_SYS_RO_SHARE}/multiassistant/ma/1.0/engine/ COMPONENT RuntimeLibraries) -ELSEIF("${ARCH}" MATCHES "^i686.*") -TARGET_LINK_LIBRARIES(${BINNAME} -Llib/i586 -ldl ${pkgs_LDFLAGS} ${EXTRA_LDFLAGS}) -INSTALL(FILES ${CMAKE_SOURCE_DIR}/lib/i586/libmulti-wakeup-recognizer.so DESTINATION ${TZ_SYS_RO_SHARE}/multiassistant/ma/1.0/engine/ COMPONENT RuntimeLibraries) -ELSEIF("${ARCH}" MATCHES "^aarch64.*") -TARGET_LINK_LIBRARIES(${BINNAME} -Llib/aarch64 -ldl ${pkgs_LDFLAGS} ${EXTRA_LDFLAGS}) -INSTALL(FILES ${CMAKE_SOURCE_DIR}/lib/aarch64/libmulti-wakeup-recognizer.so DESTINATION ${TZ_SYS_RO_SHARE}/multiassistant/ma/1.0/engine/ COMPONENT RuntimeLibraries) -ELSEIF("${ARCH}" MATCHES "^x86_64.*") -TARGET_LINK_LIBRARIES(${BINNAME} -Llib/x86_64 -ldl ${pkgs_LDFLAGS} ${EXTRA_LDFLAGS}) -INSTALL(FILES ${CMAKE_SOURCE_DIR}/lib/x86_64/libmulti-wakeup-recognizer.so DESTINATION ${TZ_SYS_RO_SHARE}/multiassistant/ma/1.0/engine/ COMPONENT RuntimeLibraries) -ENDIF() - +ADD_SUBDIRECTORY(plugins) diff --git a/inc/multi_assistant_main.h b/inc/multi_assistant_main.h index 7d3237b..cfe85b4 100644 --- a/inc/multi_assistant_main.h +++ b/inc/multi_assistant_main.h @@ -1,9 +1,9 @@ #ifndef __MULTI_ASSISTANT_SERVICE_H__ #define __MULTI_ASSISTANT_SERVICE_H__ -#include #include #include +#include "multi_wakeup_recognizer.h" #ifdef LOG_TAG #undef LOG_TAG @@ -38,9 +38,9 @@ #define MA_CLIENT_SERVICE_OBJECT_PATH "/org/tizen/multiassistant/maclient" #define MA_CLIENT_SERVICE_INTERFACE "org.tizen.multiassistant.maclient" -#define MA_UI_CLIENT_SERVICE_NAME "org.tizen.multiassistant.mauiclient" -#define MA_UI_CLIENT_SERVICE_OBJECT_PATH "/org/tizen/multiassistant/mauiclient" -#define MA_UI_CLIENT_SERVICE_INTERFACE "org.tizen.multiassistant.mauiclient" +#define MA_UI_CLIENT_SERVICE_NAME "org.tizen.multiassistant.mauiclient" +#define MA_UI_CLIENT_SERVICE_OBJECT_PATH"/org/tizen/multiassistant/mauiclient" +#define MA_UI_CLIENT_SERVICE_INTERFACE "org.tizen.multiassistant.mauiclient" #define MA_SERVER_SERVICE_NAME "org.tizen.multiassistant.maserver" #define MA_SERVER_SERVICE_OBJECT_PATH "/org/tizen/multiassistant/maserver" @@ -49,32 +49,32 @@ /************************************************************************************** *** Definitions for DBus methods *************************************************************************************/ -#define MA_METHOD_HELLO "ma_method_hello" - -#define MA_METHOD_INITIALIZE "ma_method_initialize" -#define MA_METHOD_DEINITIALIZE "ma_method_deinitialize" -#define MA_METHOD_REQUEST_SPEECH_DATA "ma_method_request_speech_data" -#define MA_METHOD_GET_RECORDING_AUDIO_FORMAT "ma_method_get_recording_audio_format" -#define MA_METHOD_SEND_ASR_RESULT "ma_method_send_asr_result" -#define MA_METHOD_SEND_RESULT "ma_method_send_result" - -#define MA_UI_METHOD_INITIALIZE "ma_ui_method_initialize" -#define MA_UI_METHOD_DEINITIALIZE "ma_ui_method_deinitialize" -#define MA_UI_METHOD_CHANGE_ASSISTANT "ma_ui_method_change_assistant" - -#define MAS_METHOD_HELLO "mas_method_hello" -#define MAS_METHOD_SEND_SPEECH_DATA "mas_method_send_speech_data" -#define MAS_METHOD_ERROR "mas_method_error" - -#define MAS_UI_METHOD_SEND_ASR_RESULT "mas_ui_method_send_asr_result" -#define MAS_UI_METHOD_SEND_RESULT "mas_ui_method_send_result" -#define MAS_UI_METHOD_CHANGE_ASSISTANT "mas_ui_method_change_assistant" -#define MAS_UI_METHOD_ERROR "mas_ui_method_error" - -/************************************************************************************** - *** Definitions for configuration - *************************************************************************************/ -#define MA_DEFAULT_ENGINE tzplatform_mkpath(tzplatform_getid("TZ_SYS_RO_SHARE"), "multiassistant/ma/1.0/engine") - +#define MA_METHOD_HELLO "ma_method_hello" + +#define MA_METHOD_INITIALIZE "ma_method_initialize" +#define MA_METHOD_DEINITIALIZE "ma_method_deinitialize" +#define MA_METHOD_GET_RECORDING_AUDIO_FORMAT "ma_method_get_recording_audio_format" +#define MA_METHOD_SEND_ASR_RESULT "ma_method_send_asr_result" +#define MA_METHOD_SEND_RESULT "ma_method_send_result" +#define MA_METHOD_SEND_RECOGNITION_RESULT "ma_method_send_recognition_result" +#define MA_METHOD_START_STREAMING_AUDIO_DATA "ma_method_start_streaming_audio_data" +#define MA_METHOD_STOP_STREAMING_AUDIO_DATA "ma_method_stop_streaming_audio_data" +#define MA_METHOD_UPDATE_VOICE_FEEDBACK_STATE "ma_method_update_voice_feedback_state" +#define MA_METHOD_ERROR "ma_method_error" + +#define MA_UI_METHOD_INITIALIZE "ma_ui_method_initialize" +#define MA_UI_METHOD_DEINITIALIZE "ma_ui_method_deinitialize" +#define MA_UI_METHOD_CHANGE_ASSISTANT "ma_ui_method_change_assistant" + +#define MAS_METHOD_HELLO "mas_method_hello" +#define MAS_METHOD_ACTIVE_STATE_CHANGE "mas_method_active_state_change" +#define MAS_METHOD_STREAMING_AUDIO_DATA "mas_method_streaming_audio_data" +#define MAS_METHOD_ERROR "mas_method_error" + +#define MAS_UI_METHOD_SEND_ASR_RESULT "mas_ui_method_send_asr_result" +#define MAS_UI_METHOD_SEND_RESULT "mas_ui_method_send_result" +#define MAS_UI_METHOD_CHANGE_ASSISTANT "mas_ui_method_change_assistant" +#define MAS_UI_METHOD_ERROR "mas_ui_method_error" +#define MAS_UI_METHOD_SEND_RECOGNITION_RESULT "mas_ui_method_send_recognition_result" #endif /* __MULTI_ASSISTANT_SERVICE_H__ */ diff --git a/inc/multi_assistant_service.h b/inc/multi_assistant_service.h index f530d11..ff4fe3f 100644 --- a/inc/multi_assistant_service.h +++ b/inc/multi_assistant_service.h @@ -39,6 +39,16 @@ int mas_client_send_asr_result(int pid, int event, char* asr_result); int mas_client_send_result(int pid, char* display_text, char* utterance_text, char* result_json); +int mas_client_send_recognition_result(int pid, int result); + +int mas_client_start_streaming_audio_data(int pid, int type); + +int mas_client_stop_streaming_audio_data(int pid, int type); + +int mas_client_update_voice_feedback_state(int pid, int state); + +int mas_client_update_result_state(int pid, int state); + int mas_ui_client_initialize(int pid); int mas_ui_client_deinitialize(int pid); @@ -61,9 +71,6 @@ int mas_launch_client_by_wakeup_word(const char *wakeup_word); int mas_launch_client_by_appid(const char *appid); -void ma_client_set_temp_speech_data_requested(int val); -int ma_client_get_temp_speech_data_requested(); - #ifdef __cplusplus } #endif diff --git a/inc/multi_assistant_service_plugin.h b/inc/multi_assistant_service_plugin.h index 6f8be89..0989be8 100644 --- a/inc/multi_assistant_service_plugin.h +++ b/inc/multi_assistant_service_plugin.h @@ -21,7 +21,7 @@ #include #include "multi_wakeup_recognizer.h" - +#include "multi_assistant_main.h" #ifdef __cplusplus extern "C" { @@ -36,13 +36,27 @@ int multi_assistant_service_plugin_set_language(const char* language); int multi_assistant_service_plugin_set_wakeup_word(const char* language, const char* wakeup_word); -int multi_assistant_service_plugin_start_recording(void); +int multi_assistant_service_plugin_activate(void); + +int multi_assistant_service_plugin_deactivate(void); + +int multi_assistant_service_plugin_update_voice_feedback_state(const char *appid, int state); + +int multi_assistant_service_plugin_update_result_state(const char *appid, int state); + +int multi_assistant_service_plugin_process_event(int event, void *data, int len); -int multi_assistant_service_plugin_stop_recording(void); +int multi_assistant_service_plugin_start_streaming_utterance_data(void); -int multi_assistant_service_plugin_cancel_recording(void); +int multi_assistant_service_plugin_stop_streaming_utterance_data(void); -int multi_assistant_service_plugin_request_speech_data(void); +int multi_assistant_service_plugin_start_streaming_previous_utterance_data(void); + +int multi_assistant_service_plugin_stop_streaming_previous_utterance_data(void); + +int multi_assistant_service_plugin_start_streaming_follow_up_data(void); + +int multi_assistant_service_plugin_stop_streaming_follow_up_data(void); int multi_assistant_service_plugin_get_recording_audio_format(int *rate, int *channel, int *audio_type); @@ -50,12 +64,90 @@ int multi_assistant_service_plugin_set_callbacks(void); int multi_assistant_service_plugin_set_wakeup_event_callback(wakeup_service_wakeup_event_cb callback, void* user_data); -int multi_assistant_service_plugin_set_speech_streaming_callback(wakeup_service_speech_streaming_cb callback, void* user_data); +int multi_assistant_service_plugin_set_utterance_streaming_callback(wakeup_service_speech_streaming_cb callback, void* user_data); + +int multi_assistant_service_plugin_set_previous_utterance_streaming_callback(wakeup_service_speech_streaming_cb callback, void* user_data); + +int multi_assistant_service_plugin_set_follow_up_streaming_callback(wakeup_service_speech_streaming_cb callback, void* user_data); int multi_assistant_service_plugin_set_speech_status_callback(wakeup_service_speech_status_cb callback, void* user_data); int multi_assistant_service_plugin_set_error_callback(wakeup_service_error_cb callback, void* user_data); +#define MA_WAKEUP_MANAGER_PATH tzplatform_mkpath(tzplatform_getid("TZ_SYS_RO_SHARE"), "multiassistant/") + +#define MA_DEFAULT_WAKEUP_MANAGER_FILENAME "libma-wakeup-manager.so" + + +#define MA_WAKEUP_MANAGER_FUNC_INITIALIZE "wakeup_manager_initialize" +typedef int (*wakeup_manager_initialize)(void); +#define MA_WAKEUP_MANAGER_FUNC_DEINITIALIZE "wakeup_manager_deinitialize" +typedef int (*wakeup_manager_deinitialize)(void); +#define MA_WAKEUP_MANAGER_FUNC_SET_WAKEUP_WORD "wakeup_manager_set_wakeup_word" +typedef int (*wakeup_manager_set_wakeup_word)(const char* language, const char* wakeup_word); +#define MA_WAKEUP_MANAGER_FUNC_SET_LANGUAGE "wakeup_manager_set_language" +typedef int (*wakeup_manager_set_language)(const char* language); +#define MA_WAKEUP_MANAGER_FUNC_ACTIVATE "wakeup_manager_activate" +typedef int (*wakeup_manager_activate)(void); +#define MA_WAKEUP_MANAGER_FUNC_DEACTIVATE "wakeup_manager_deactivate" +typedef int (*wakeup_manager_deactivate)(void); +#define MA_WAKEUP_MANAGER_FUNC_UPDATE_VOICE_FEEDBACK_STATE "wakeup_manager_update_voice_feedback_state" +typedef int (*wakeup_manager_update_voice_feedback_state)(const char *appid, int state); +#define MA_WAKEUP_MANAGER_FUNC_UPDATE_RESULT_STATE "wakeup_manager_update_result_state" +typedef int (*wakeup_manager_update_result_state)(const char *appid, int state); +#define MA_WAKEUP_MANAGER_FUNC_PROCESS_EVENT "wakeup_manager_process_event" +typedef int (*wakeup_manager_process_event)(int event, void* data, int len); +#define MA_WAKEUP_MANAGER_FUNC_START_STREAMING_UTTERANCE_DATA "wakeup_manager_start_streaming_utterance_data" +typedef int (*wakeup_manager_start_streaming_utterance_data)(void); +#define MA_WAKEUP_MANAGER_FUNC_STOP_STREAMING_UTTERANCE_DATA "wakeup_manager_stop_streaming_utterance_data" +typedef int (*wakeup_manager_stop_streaming_utterance_data)(void); +#define MA_WAKEUP_MANAGER_FUNC_START_STREAMING_PREVIOUS_UTTERANCE_DATA "wakeup_manager_start_streaming_previous_utterance_data" +typedef int (*wakeup_manager_start_streaming_previous_utterance_data)(void); +#define MA_WAKEUP_MANAGER_FUNC_STOP_STREAMING_PREVIOUS_UTTERANCE_DATA "wakeup_manager_stop_streaming_previous_utterance_data" +typedef int (*wakeup_manager_stop_streaming_previous_utterance_data)(void); +#define MA_WAKEUP_MANAGER_FUNC_START_STREAMING_FOLLOW_UP_DATA "wakeup_manager_start_streaming_follow_up_data" +typedef int (*wakeup_manager_start_streaming_follow_up_data)(void); +#define MA_WAKEUP_MANAGER_FUNC_STOP_STREAMING_FOLLOW_UP_DATA "wakeup_manager_stop_streaming_follow_up_data" +typedef int (*wakeup_manager_stop_streaming_follow_up_data)(void); +#define MA_WAKEUP_MANAGER_FUNC_GET_AUDIO_FORMAT "wakeup_manager_get_audio_format" +typedef int (*wakeup_manager_get_audio_format)(int* rate, int* channel, int* audio_type); +#define MA_WAKEUP_MANAGER_FUNC_SET_WAKEUP_EVENT_CALLBACK "wakeup_manager_set_wakeup_event_callback" +typedef int (*wakeup_manager_set_wakeup_event_callback)(wakeup_service_wakeup_event_cb callback, void* user_data); +#define MA_WAKEUP_MANAGER_FUNC_SET_UTTERANCE_STREAMING_CALLBACK "wakeup_manager_set_utterance_streaming_callback" +typedef int (*wakeup_manager_set_utterance_streaming_callback)(wakeup_service_speech_streaming_cb callback, void* user_data); +#define MA_WAKEUP_MANAGER_FUNC_SET_PREVIOUS_UTTERANCE_STREAMING_CALLBACK "wakeup_manager_set_previous_utterance_streaming_callback" +typedef int (*wakeup_manager_set_previous_utterance_streaming_callback)(wakeup_service_speech_streaming_cb callback, void* user_data); +#define MA_WAKEUP_MANAGER_FUNC_SET_FOLLOW_UP_STREAMING_CALLBACK "wakeup_manager_set_follow_up_streaming_callback" +typedef int (*wakeup_manager_set_follow_up_streaming_callback)(wakeup_service_speech_streaming_cb callback, void* user_data); +#define MA_WAKEUP_MANAGER_FUNC_SET_SPEECH_STATUS_CALLBACK "wakeup_manager_set_speech_status_callback" +typedef int (*wakeup_manager_set_speech_status_callback)(wakeup_service_speech_status_cb callback, void* user_data); +#define MA_WAKEUP_MANAGER_FUNC_SET_ERROR_CALLBACK "wakeup_manager_set_error_callback" +typedef int (*wakeup_manager_set_error_callback)(wakeup_service_error_cb callback, void* user_data); + +typedef struct { + wakeup_manager_initialize initialize; + wakeup_manager_deinitialize deinitialize; + wakeup_manager_set_wakeup_word set_wakeup_word; + wakeup_manager_set_language set_language; + wakeup_manager_activate activate; + wakeup_manager_deactivate deactivate; + wakeup_manager_update_voice_feedback_state update_voice_feedback_state; + wakeup_manager_update_result_state update_result_state; + wakeup_manager_process_event process_event; + wakeup_manager_start_streaming_utterance_data start_streaming_utterance_data; + wakeup_manager_stop_streaming_utterance_data stop_streaming_utterance_data; + wakeup_manager_start_streaming_previous_utterance_data start_streaming_previous_utterance_data; + wakeup_manager_stop_streaming_previous_utterance_data stop_streaming_previous_utterance_data; + wakeup_manager_start_streaming_follow_up_data start_streaming_follow_up_data; + wakeup_manager_stop_streaming_follow_up_data stop_streaming_follow_up_data; + wakeup_manager_get_audio_format get_audio_format; + wakeup_manager_set_wakeup_event_callback set_wakeup_event_callback; + wakeup_manager_set_utterance_streaming_callback set_utterance_streaming_callback; + wakeup_manager_set_previous_utterance_streaming_callback set_previous_utterance_streaming_callback; + wakeup_manager_set_follow_up_streaming_callback set_follow_up_streaming_callback; + wakeup_manager_set_speech_status_callback set_speech_status_callback; + wakeup_manager_set_error_callback set_error_callback; +} wakeup_manager_interface; #ifdef __cplusplus } diff --git a/lib/aarch64/libmulti-wakeup-recognizer.so b/lib/aarch64/libmulti-wakeup-recognizer.so deleted file mode 100644 index be06f4e35353a2e0ab553fa6549ad6a6a2fea1e2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12984 zcmb_j4|G)3nZGlWgb@Cign!Y1JSed-zz``~s2-h6G9nde3}IJAI+@J8BvU3cab|*G z+&WO`)?Is=DG_X|Hqt}aaCW!Z9^7JUYg$W>tEXLD1=+P=YQ?f$UBglgaf!3P@4oxZ zym^^~*!6O5zWd$#{lDM6@6ElBhdk?VwcBihi$nZK5LRDo^tjZ(#ignN;1a7v0sfYY zt0ZlHW@t<+uhQsZC?tpRw*W(hYP_)0uz}&A-Qd$4EYcXKZsOAvpQiX27Aro6g^E27 zkZQMb)e4s=I)+3`rT$DjK<(a7NpuW++~^hzneR^Uk)4w*D%{e>*vLs8qfs7 zHiqP1$~BsLj@J~^*gR94nmm^a(AKB}h303LYzZ+_!CZiRrg5UD7~WoVo2y`_tFW!Q z#8EfkD%KX;^QJGl^5Mebg(a1F_PdCdY@(P^jL8<73yL4bR70h>QJiTW$TsqW;!N?D z^Y?>QXCF=;jCSXjuKll9-=Eoh)5~vcYrLuF*{`3QS@dxH?7!c4*Zdo~CW7c`FkFy8*-)Sbx>e)b=KS^n1S*OyIMH26yCQ*RD^C;4XE@f&CDIna@~r?36X zpM^OS7KbPj2}&AEaUil~YCZB0`_4GSW}6W!#u+xCK{2wHY2(m8G)_Odg=Q53{9jOM zj;!Sy=*ZRYL%(Jv2EKZn{%=5WE;*k;A{C1=QMnWZrt%f+SEX24L$r`l67sJQ{|s0H zdQH*uI;J&NN-LEXps6%r;gFnT6mXP&1BfL`@7bzsy+*E%oyX5e`=^TzN@A3E4Is+K zk+Vwatyg*zivA$v)Wr8RSy=HY)Yw zk1X8=5ceoKE;a8g=QoPJThXhqiXvrCuZj=Te;@r6haok;oF^;CiSv6Zo^peNt^sAw zOG=Kg#GzB!lb{U|5WThOmdl|h3#5Q?;VJEFmG+)5PC$udRO z>h*UYoxWCGv_y5?$`g!vw?S?oLuJt%(@he*2tqW_*9C!{5*dNdk|UPfAOng`mvwHv%4tVRyn)`<7^hO8bv?A^4{=m`azW%4;= z5$AOR7_BZsstM^ZQZkMEsdaT;gF-sV`$*cGrvq}#MZNDLV%+XjTV_Rdf|xZKE~ z<&+YwVJ!bBgo?H6*STxGE1lP6z46!uwl);wFSTr+(7!2iPbP^%>`(5)E3RG09~Z#+ zcaH-!R9tGmEmrSS+&@%oj1Q`Pl=~T9t@>?{gDp2*T&8{{LXO>L>No$6t2g!YGl&@O zGWGMbhWeXK{q*~TOPi^mey4EhF!l5A3L4vP>R-XcfRCwuJN!~1lB2z*ezW~goBGYa zCHhVM=HCuSO#NoR22B0*8;8q_rhfVz#O0W&pMG<3Ice&r-&tHnyPoeGb%^9jA$mr; ze*W};!+V0q2o7PqTZm&NpZAOuyQ`9#ec_3Pn&UWEIko{~&BmC-8-VXJ;eP@AfC;|` z_%G6Uf5{htzh%Okf!mi#U69vb(gJ+33I7ssw+RmeZ#M7*y%H_+jJSk2{GX}RJgYxD zF}|pGX>!qgk(9L57UJbwR*Q3eLNv3F2p82{ON#chRNVy^Ai@{4MI< zpM!4~bhuZ0Mw-!fK?d=$oYAhI$#|ciCPwyxuIa$mH7=XDUdmhI838;j+Z~>fe@LbF zzlN%bL_^borEAVlbB&C4{X)(W+azh5w4_bAMtnj%a}qwM?Of#<*_lcm<~i2HEhlJ> z{}nVsmC>%B_UVO*2JANdP0&NR;CAID&u_H#;Wu%A&r6Qvg;`<*uT%Z819?fjmUlnn zUY-2CWA>rnIc6Pt+cD?RcVHty?yD%u$a4?oCHG<+Z?Fv)X1PYrZ>;GX?Rp{Y1L-H- zXTU>xNk7>^`g_n1z1;!myRg~bw>u${cn$A|4gD{`uBTwngOJ^`7;&?^Mw$@2IPmY< z#R%~*&CzLz2I6HO$)>QfiR`(s*`2XTh;vKITpvPKBgI`4Vh!1znZKX(9h_nK$M%w~ zWM>RIhs(uC%x+7{*ug#ox__8r2>ahgygqOU#BDZWHSZAlxgK^rRclKQI_4g_<Dm{F&Goyp&g@{~g$K27D~X?JAJ^ z=ZHip$(cv`RUVFZ{Y1{MUYwcVta$kyeX(7(Bz_k4m%Z#r$Bp7O?64g|ERbVlZ<(~0 z{7Ze5+W)*=oO}B!*N3hG(P+ePj*QJVrd`$Q(Fm9!KtXVO+q6OumlYU-Ws|{*s@2 z4gb1#!xm$Iv5(nb0+1cM*)!6l{H+5{?G1oF)Q8|N@$+7@r;PR*d)8jF5p=TYL_T2>8X8Yy?C;P4eT!TvXk)JWl2m3Hf(JTP0Ry1ZGJmv5Kx+upeH)tI!23;;6 zD4z;IlRsbWiA~e8_Hf=8=@}B+m091ETQvVPuf~2j=g?H>Fwe6`$z&UB%7$Fe5zg;a zt?iZk1$d5i+4@Fn1)gK}^xk}7GxnOr@);&|^Bz6y&+DUonf9BD4!g`l@||*$_IR?7 zZ1~-%%x}5xXK5g>d6t6;MN3M8zt}*eL^6P&u$+eV@*BQvB ze58CGKfekmjMqDmX^z*P%8X2k*J(rNn0H#vFVD3T#H)Ggq~diHIyhc?s!YC{;`N-e zBUii*!Up!ioL@gMc+&CmEY0{fZoKS86UOV?kjc6zzs{IsQoO#Y>>Qh4#_v!5?P)n` zGo5V;SuEpOr=LV%8K-ll^ik+IRy(hg43dH;$8;d*mj+bCKBra0 zDk}olYBy_}JsTQ54O?iyESGRAU7e&F)8EkWg@!Gf#rZME|5}SL7}7|oRj$FmArjYO zogE#KXj~6yyq>@iyOwOBVzI~ItM^5H?K-YVv|vmNhUJ~ZvNS)jFJs$i^<7rptz>3A zq6H$%mcA;n-e_noone1G7zrD0S?sIxxHqlclG73`+mbB5jO&Z^xxV%}jgEOEEqvHc zw+~u%u6W3KL=>13w;gFQdK$ z$U$k;c=NO_+|e1&XrbBKuxb5z;<1%GZlpU;x(*zCFO@n1*!172)LFnGz%m=|S>I2k zssUX?snmABV|Xzg037(ARB8yY2`@4l9?06CQmJ}+Fast4doO?vu>ONo>LTDVz)Bn% zCx%n0COSO6m`Zg6_5;2MSUmzdz(K%jbqI_1Gg)j8G>E+ISKG>`8>hd^&`amW8f=z# zhBY&*pD1`Tzi!3?_ujl7NA08b#?z;czxtYqo*eD~eK$$8(APa`-)FlE948DG(o1rW zfu8hmsY9a&^(6Y`9c<0a`X`E>oC>`)dkcG}+`2!n_R)fU`AtQqPra^$)lAz^^xCT@ zj=z5DG^}yUV``G~Thsx>Sl(e;NkNiyQi*aaQ72gz#bF8Npb&HOF4|_l z$R!z!`!aqJeIw{!1pVU{dWxHj!{%&yvTrrb`FQk!Z2H3_AN0FT^q$PTYyx$9UTy-- z+n}$cTr%kE-A@!gIi+U$0$0u6f}Z@kNAvbMJp1jB+5APPPNySLW1RM{0?!iU)=BX9 zoAk-~F!BKNiV&vff{2W7l^GooR(VCc~o1dlvOMMEX9gT+#EL%vB2Kdof=7Jg(G;Bg)VVAEhG1 zQl{+VJEF%F1K$nN_bpWT&L*O8zOz!FjR+-1B=|nZU=t@5qI2*b7wFV zSRM=rr{3mmp;s*-``di6HsO??st}G3C?Gu)3~!Y}VmsOmvTb@ah8HB^jOrmDiO=fx zMuqcBe*9tC-nIZRkij6~#Lc&G%5P!}_Kr{-?2)*W8^Rgax1*2D@cN=r-wuObwZ{qj zq`Mb`l5!bap)B1hAsH@F{S0_rGG2=YtwrYN^~&&GC6D=doiKh2c=5UtVSZlU3@<4~ zOwatPTYM1>TH9%UMacU=Lg8d1ttIB?b@^S@&-}cfFy#FMWU}yjWxNFqTFcDO>z84Z zB4qoSj^STnoc0FBd4FK2DSon_bhG`cTg1>H+06enwSO?={fPB5Kl}ef#qU-Ed4FTb z`yuhqMYZz(J^IKl-hcUfQii;bfn!}~?=jVL%t~*ypVki9&+#v2J_Wn^L8TOO{1hsZ7JlpZ>GIu?i2<$pueb2K zmKekge`$GuSoQxF0OJfF!2rdN z`T4u!vdi$ZJbKTd++%)zuJQjXC{`20)4+OpUXOy;tiM`4XR6hQ_4TYsLFQ-poQ0p? zClZRk=`#GJ+pM3TbAyVX^{^N#{&yIlKKB2tvj42&cQK=aR{k%bpY&S`^H*91todi2 SdoyYAQUg0{?nK+F>;C`*b6L#* diff --git a/lib/armv7l/libmulti-wakeup-recognizer.so b/lib/armv7l/libmulti-wakeup-recognizer.so deleted file mode 100644 index 402493319960085af0b330a0573b4f7dd397a2cf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9972 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

PO_;q=_*4Arl6ma!=h+WUvs)U^};pm1yR}b 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 Q={wof2;6(JfLzM>AN=DebN~PV diff --git a/lib/x86_64/libmulti-wakeup-recognizer.so b/lib/x86_64/libmulti-wakeup-recognizer.so deleted file mode 100644 index 68abf96270b0066e427ea13c96779002479e348f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14448 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 diff --git a/packaging/org.tizen.multi-assistant-service.spec b/packaging/org.tizen.multi-assistant-service.spec index 5832e1a..efa5231 100644 --- a/packaging/org.tizen.multi-assistant-service.spec +++ b/packaging/org.tizen.multi-assistant-service.spec @@ -20,8 +20,8 @@ BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(ecore) BuildRequires: pkgconfig(dbus-1) BuildRequires: pkgconfig(libtzplatform-config) -BuildRequires: pkgconfig(message-port) BuildRequires: pkgconfig(libxml-2.0) +BuildRequires: pkgconfig(multi-assistant) BuildRequires: boost-system BuildRequires: boost-thread @@ -87,7 +87,7 @@ exit 0 %defattr(-,root,root,-) /usr/share/license/* /usr/share/packages/org.tizen.multi-assistant-service.xml -%{TZ_SYS_RO_SHARE}/multiassistant/ma/1.0/engine/libmulti-wakeup-recognizer.so +%{TZ_SYS_RO_SHARE}/multiassistant/libma-wakeup-manager.so %{_appdir}/author-signature.xml %{_appdir}/signature1.xml #%{_appdir}/lib/* diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt new file mode 100644 index 0000000..2d6e382 --- /dev/null +++ b/plugins/CMakeLists.txt @@ -0,0 +1 @@ +ADD_SUBDIRECTORY(wakeup-manager) diff --git a/plugins/wakeup-manager/CMakeLists.txt b/plugins/wakeup-manager/CMakeLists.txt new file mode 100644 index 0000000..231e8b6 --- /dev/null +++ b/plugins/wakeup-manager/CMakeLists.txt @@ -0,0 +1,53 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(ma-wakeup-manager) + +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +SET(PACKAGE ${PROJECT_NAME}) + +SET(CMAKE_SKIP_BUILD_RPATH TRUE) + +INCLUDE_DIRECTORIES( + ${CMAKE_SOURCE_DIR}/inc + ./inc + ) + +INCLUDE(FindPkgConfig) +pkg_check_modules(pkgs REQUIRED + appcore-agent + ecore + dlog + capi-appfw-app-manager + capi-network-connection + capi-media-audio-io + capi-media-sound-manager + eina +) + +IF("${CMAKE_BUILD_TYPE}" STREQUAL "") + SET(CMAKE_BUILD_TYPE "Release") +ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "") +MESSAGE("Build type: ${CMAKE_BUILD_TYPE}") + +ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"") +ADD_DEFINITIONS("-DPACKAGE=\"${PACKAGE}\"") + +SET(SRCS + src/wakeup_manager.cpp +) + +FOREACH(flag ${pkgs_CFLAGS}) + SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} ${flag}") +ENDFOREACH(flag) + + +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXXFLAGS} -fPIC -std=c++11 -fvisibility=hidden") + +SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} -fPIC -Wall" ) +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXXFLAGS}") +SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g") + +ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS} ) + +# Install libraries +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} -ldl ${EXTRA_LDFLAGS}) +INSTALL(FILES ${CMAKE_SOURCE_DIR}/plugins/wakeup-manager/libma-wakeup-manager.so DESTINATION ${TZ_SYS_RO_SHARE}/multiassistant/) diff --git a/plugins/wakeup-manager/inc/wakeup_manager.h b/plugins/wakeup-manager/inc/wakeup_manager.h new file mode 100644 index 0000000..22619cc --- /dev/null +++ b/plugins/wakeup-manager/inc/wakeup_manager.h @@ -0,0 +1,208 @@ +/* + * Copyright 2018 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef _MULTI_WAKEUP_RECOGNIZER_H_ +#define _MULTI_WAKEUP_RECOGNIZER_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined _WIN32 || defined __CYGWIN__ + #ifdef BUILDING_DLL + #ifdef __GNUC__ + #define DLL_PUBLIC __attribute__ ((dllexport)) + #else + #define DLL_PUBLIC __declspec(dllexport) // Note: actually gcc seems to also supports this syntax. + #endif + #else + #ifdef __GNUC__ + #define DLL_PUBLIC __attribute__ ((dllimport)) + #else + #define DLL_PUBLIC __declspec(dllimport) // Note: actually gcc seems to also supports this syntax. + #endif + #endif + #define DLL_LOCAL +#else + #if __GNUC__ >= 4 + #define DLL_PUBLIC __attribute__ ((visibility ("default"))) + #define DLL_LOCAL __attribute__ ((visibility ("hidden"))) + #else + #define DLL_PUBLIC + #define DLL_LOCAL + #endif +#endif + +typedef enum { + WAKEUP_EVENT_ERROR = -1, /**< Event when the wakeup recognition has failed */ + WAKEUP_EVENT_SUCCESS = 1, /**< Event when the wakeup word is matched succesfully */ + WAKEUP_EVENT_REJECTED = 2 /**< Event when the wakeup word is not matched */ +} wakeup_service_wakeup_event_e; + +typedef enum { + WAKEUP_SPEECH_STREAMING_EVENT_FAIL = -1, /**< Failed */ + WAKEUP_SPEECH_STREAMING_EVENT_START = 1, /**< Start event */ + WAKEUP_SPEECH_STREAMING_EVENT_CONTINUE = 2, /**< Continue event */ + WAKEUP_SPEECH_STREAMING_EVENT_FINISH = 3 /**< Finish event */ +} wakeup_service_speech_streaming_event_e; + +typedef enum { + WAKEUP_SPEECH_STATUS_NONE = -1, /**< None */ + WAKEUP_SPEECH_STATUS_BEGINNING_POINT_DETECTED = 1, /**< Beginning point of speech is detected */ + WAKEUP_SPEECH_STATUS_END_POINT_DETECTED = 2 /**< End point of speech is detected */ +} wakeup_service_speech_status_e; + +typedef enum { + WAKEUP_MANAGER_STATE_INACTIVE = 0, + WAKEUP_MANAGER_STATE_LISTENING = 1, + WAKEUP_MANAGER_STATE_UTTERANCE = 2, + WAKEUP_MANAGER_STATE_PROCESSING = 3, + WAKEUP_MANAGER_STATE_VOICE_FEEDBACK = 4 +} wakeup_manager_state_e; + +typedef void (*wakeup_service_wakeup_event_cb)(wakeup_service_wakeup_event_e event, const char* wakeup_word, void* user_data); + +typedef void (*wakeup_service_speech_streaming_cb)(wakeup_service_speech_streaming_event_e event, void* buffer, int len, void *user_data); + +typedef void (*wakeup_service_speech_status_cb)(wakeup_service_speech_status_e status, void *user_data); + +typedef void (*wakeup_service_error_cb)(int error, const char* err_msg, void* user_data); + +typedef void (*wakeup_service_audio_data_require_status_cb)(bool require, void* user_data); + +DLL_PUBLIC int wakeup_manager_initialize(void); + +DLL_PUBLIC int wakeup_manager_deinitialize(void); + +DLL_PUBLIC int wakeup_manager_set_wakeup_word(const char* language, const char* wakeup_word); + +DLL_PUBLIC int wakeup_manager_set_language(const char* language); + +DLL_PUBLIC int wakeup_manager_activate(void); + +DLL_PUBLIC int wakeup_manager_deactivate(void); + +DLL_PUBLIC int wakeup_manager_update_voice_feedback_state(const char *appid, int state); + +DLL_PUBLIC int wakeup_manager_update_result_state(const char *appid, int state); + +DLL_PUBLIC int wakeup_manager_process_event(int event, void* data, int len); + +DLL_PUBLIC int wakeup_manager_start_streaming_utterance_data(void); + +DLL_PUBLIC int wakeup_manager_stop_streaming_utterance_data(void); + +DLL_PUBLIC int wakeup_manager_start_streaming_previous_utterance_data(void); + +DLL_PUBLIC int wakeup_manager_stop_streaming_previous_utterance_data(void); + +DLL_PUBLIC int wakeup_manager_start_streaming_follow_up_data(void); + +DLL_PUBLIC int wakeup_manager_stop_streaming_follow_up_data(void); + +DLL_PUBLIC int wakeup_manager_get_audio_format(int *rate, int *channel, int *audio_type); + +DLL_PUBLIC int wakeup_manager_set_wakeup_event_callback(wakeup_service_wakeup_event_cb callback, void* user_data); + +DLL_PUBLIC int wakeup_manager_set_utterance_streaming_callback(wakeup_service_speech_streaming_cb callback, void* user_data); + +DLL_PUBLIC int wakeup_manager_set_previous_utterance_streaming_callback(wakeup_service_speech_streaming_cb callback, void* user_data); + +DLL_PUBLIC int wakeup_manager_set_follow_up_streaming_callback(wakeup_service_speech_streaming_cb callback, void* user_data); + +DLL_PUBLIC int wakeup_manager_set_speech_status_callback(wakeup_service_speech_status_cb callback, void* user_data); + +DLL_PUBLIC int wakeup_manager_set_error_callback(wakeup_service_error_cb callback, void* user_data); + +/************************************************************************************** + *** Definitions for wakeup engine interface + *************************************************************************************/ +#define MA_WAKEUP_ENGINE_PATH tzplatform_mkpath(tzplatform_getid("TZ_SYS_RO_SHARE"), "multiassistant/engines") + +typedef struct { + wakeup_service_speech_streaming_event_e event; + void* buffer; + int len; +} wakeup_engine_speech_data; + +#define MA_WAKEUP_ENGINE_FUNC_INITIALIZE "wakeup_engine_initialize" +typedef int (*wakeup_engine_initialize)(void); +#define MA_WAKEUP_ENGINE_FUNC_DEINITIALIZE "wakeup_engine_deinitialize" +typedef int (*wakeup_engine_deinitialize)(void); +#define MA_WAKEUP_ENGINE_FUNC_ACTIVATE "wakeup_engine_activate" +typedef int (*wakeup_engine_activate)(void); +#define MA_WAKEUP_ENGINE_FUNC_DEACTIVATE "wakeup_engine_deactivate" +typedef int (*wakeup_engine_deactivate)(void); +#define MA_WAKEUP_ENGINE_FUNC_SET_WAKEUP_WORD "wakeup_engine_set_wakeup_word" +typedef int (*wakeup_engine_set_wakeup_word)(const char* language, const char* wakeup_word); +#define MA_WAKEUP_ENGINE_FUNC_SET_LANGUAGE "wakeup_engine_set_language" +typedef int (*wakeup_engine_set_language)(const char* language); +#define MA_WAKEUP_ENGINE_FUNC_UPDATE_MANAGER_STATE "wakeup_engine_update_manager_state" +typedef int (*wakeup_engine_update_manager_state)(wakeup_manager_state_e state); +#define MA_WAKEUP_ENGINE_FUNC_SET_AUDIO_FORMAT "wakeup_engine_set_audio_format" +typedef int (*wakeup_engine_set_audio_format)(int rate, int channel, int audio_type); +#define MA_WAKEUP_ENGINE_FUNC_GET_AUDIO_FORMAT "wakeup_engine_get_audio_format" +typedef int (*wakeup_engine_get_audio_format)(int* rate, int* channel, int* audio_type); +#define MA_WAKEUP_ENGINE_FUNC_FEED_AUDIO_DATA "wakeup_engine_feed_audio_data" +typedef int (*wakeup_engine_feed_audio_data)(void* data, int len); +#define MA_WAKEUP_ENGINE_FUNC_GET_UTTERANCE_DATA_COUNT "wakeup_engine_get_utterance_data_count" +typedef int (*wakeup_engine_get_utterance_data_count)(void); +#define MA_WAKEUP_ENGINE_FUNC_GET_UTTERANCE_DATA "wakeup_engine_get_utterance_data" +typedef int (*wakeup_engine_get_utterance_data)(int index, wakeup_engine_speech_data *data); +#define MA_WAKEUP_ENGINE_FUNC_GET_PREVIOUS_UTTERANCE_DATA_COUNT "wakeup_engine_get_previous_utterance_data_count" +typedef int (*wakeup_engine_get_previous_utterance_data_count)(void); +#define MA_WAKEUP_ENGINE_FUNC_GET_PREVIOUS_UTTERANCE_DATA "wakeup_engine_get_previous_utterance_data" +typedef int (*wakeup_engine_get_previous_utterance_data)(int index, wakeup_engine_speech_data *data); +#define MA_WAKEUP_ENGINE_FUNC_SET_WAKEUP_EVENT_CALLBACK "wakeup_engine_set_wakeup_event_callback" +typedef int (*wakeup_engine_set_wakeup_event_callback)(wakeup_service_wakeup_event_cb callback, void* user_data); +#define MA_WAKEUP_ENGINE_FUNC_SET_SPEECH_STATUS_CALLBACK "wakeup_engine_set_speech_status_callback" +typedef int (*wakeup_engine_set_speech_status_callback)(wakeup_service_speech_status_cb callback, void* user_data); +#define MA_WAKEUP_ENGINE_FUNC_SET_ERROR_CALLBACK "wakeup_engine_set_error_callback" +typedef int (*wakeup_engine_set_error_callback)(wakeup_service_error_cb callback, void* user_data); +#define MA_WAKEUP_ENGINE_FUNC_SET_AUDIO_DATA_REQUIRE_STATUS_CALLBACK "wakeup_engine_set_audio_data_require_status_callback" +typedef int (*wakeup_engine_set_audio_data_require_status_callback)(wakeup_service_audio_data_require_status_cb callback, void* user_data); + +typedef struct { + wakeup_engine_initialize initialize; + wakeup_engine_deinitialize deinitialize; + wakeup_engine_activate activate; + wakeup_engine_deactivate deactivate; + wakeup_engine_set_wakeup_word set_wakeup_word; + wakeup_engine_set_language set_language; + wakeup_engine_update_manager_state update_manager_state; + wakeup_engine_set_audio_format set_audio_format; + wakeup_engine_get_audio_format get_audio_format; + wakeup_engine_feed_audio_data feed_audio_data; + wakeup_engine_get_utterance_data_count get_utterance_data_count; + wakeup_engine_get_utterance_data get_utterance_data; + wakeup_engine_get_previous_utterance_data_count get_previous_utterance_data_count; + wakeup_engine_get_previous_utterance_data get_previous_utterance_data; + wakeup_engine_set_wakeup_event_callback set_wakeup_event_callback; + wakeup_engine_set_speech_status_callback set_speech_status_callback; + wakeup_engine_set_error_callback set_error_callback; + wakeup_engine_set_audio_data_require_status_callback set_audio_data_require_status_callback; +} wakeup_engine_interface; + +#ifdef __cplusplus +} +#endif + +#endif /* _MULTI_WAKEUP_RECOGNIZER_H_ */ diff --git a/plugins/wakeup-manager/inc/wakeup_manager_main.h b/plugins/wakeup-manager/inc/wakeup_manager_main.h new file mode 100644 index 0000000..80ce706 --- /dev/null +++ b/plugins/wakeup-manager/inc/wakeup_manager_main.h @@ -0,0 +1,46 @@ +#ifndef __MUTLI_WAKEUP_MAIN_H__ +#define __MUTLI_WAKEUP_MAIN_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "wakeup-manager" + +#ifdef __MODULE__ +#undef __MODULE__ +#endif +#define __MODULE__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) + +#define MWR_SECURE_LOG_(id, prio, tag, fmt, arg...) \ + ({ do { \ + __dlog_print(id, prio, tag, "%s: %s(%d) > [SECURE_LOG] " fmt, __MODULE__, __func__, __LINE__, ##arg); \ + } while (0); }) + +#define MWR_LOG_(prio, tag, fmt, arg...) \ + ({ do { \ + dlog_print(prio, tag, "%s: %s(%d) > " fmt, __MODULE__, __func__, __LINE__, ##arg); \ + } while (0); }) + +#define MWR_LOGD(fmt, args...) MWR_LOG_(DLOG_DEBUG, LOG_TAG, fmt, ##args) +#define MWR_LOGI(fmt, args...) MWR_LOG_(DLOG_INFO, LOG_TAG, fmt, ##args) +#define MWR_LOGW(fmt, args...) MWR_LOG_(DLOG_WARN, LOG_TAG, fmt, ##args) +#define MWR_LOGE(fmt, args...) MWR_LOG_(DLOG_ERROR, LOG_TAG, fmt, ##args) + +#define MWR_SLOGD(fmt, args...) MWR_SECURE_LOG_(DLOG_DEBUG, LOG_TAG, fmt, ##args) +#define MWR_SLOGI(fmt, args...) MWR_SECURE_LOG_(DLOG_INFO, LOG_TAG, fmt, ##args) +#define MWR_SLOGW(fmt, args...) MWR_SECURE_LOG_(DLOG_WARN, LOG_TAG, fmt, ##args) +#define MWR_SLOGE(fmt, args...) MWR_SECURE_LOG_(DLOG_ERROR, LOG_TAG, fmt, ##args) + +#ifdef __cplusplus +} +#endif + +#endif /* __MUTLI_WAKEUP_MAIN_H__ */ diff --git a/plugins/wakeup-manager/src/wakeup_manager.cpp b/plugins/wakeup-manager/src/wakeup_manager.cpp new file mode 100644 index 0000000..620379c --- /dev/null +++ b/plugins/wakeup-manager/src/wakeup_manager.cpp @@ -0,0 +1,879 @@ +/* + * Copyright 2018 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "ctype.h" + +#include "wakeup_manager_main.h" +#include "wakeup_manager.h" + +#define RECOGNITION_TYPE_FREE_PARTIAL "stt.recognition.type.FREE.PARTIAL" + +static wakeup_service_wakeup_event_cb g_wakeup_event_cb; +static void* g_wakeup_event_user_data; + +static wakeup_service_speech_streaming_cb g_utterance_streaming_cb; +static void* g_utterance_streaming_user_data; + +static wakeup_service_speech_streaming_cb g_previous_utterance_streaming_cb; +static void* g_previous_utterance_streaming_user_data; + +static wakeup_service_speech_streaming_cb g_follow_up_streaming_cb; +static void* g_follow_up_streaming_user_data; + +static wakeup_service_speech_status_cb g_speech_status_cb; +static void* g_speech_status_user_data; + +static wakeup_service_error_cb g_error_cb; +static void* g_error_user_data; + +#define MAX_WAKEUP_ENGINE_NUM 10 +static int g_engine_count = 0; + +typedef struct { + bool active; + bool enabled; + bool audio_data_require_status; + char engine_name[_POSIX_PATH_MAX]; + char engine_path[_POSIX_PATH_MAX]; + wakeup_engine_interface interface; +} wakeup_engine_info; + +//static int g_wakeup_engine_selected = -1; +static int g_wakeup_engine_selected = 0; +static wakeup_engine_info g_wakeup_engine_info[MAX_WAKEUP_ENGINE_NUM] = { NULL, }; + +static char* g_current_language = NULL; +static wakeup_manager_state_e g_wakeup_manager_state; + +static bool g_audio_data_required = false; +static audio_in_h g_audio_h = NULL; +static sound_stream_info_h g_stream_info_h = NULL; + +static std::thread g_recorder_thread; +static std::atomic_bool g_recorder_thread_should_stop; + +static std::thread g_speech_data_thread; +static std::atomic_bool g_speech_data_thread_should_stop; + +static int recorder_initialize() +{ + const int rate = 16000; + const audio_channel_e channel = AUDIO_CHANNEL_MONO; + const audio_sample_type_e type = AUDIO_SAMPLE_TYPE_S16_LE; + + int ret = audio_in_create(rate, channel, type, &g_audio_h); + if (AUDIO_IO_ERROR_NONE != ret) { + MWR_LOGD("[Recorder ERROR] Rate(%d) Channel(%d) Type(%d)", rate, channel, type); + MWR_LOGD("[Recorder ERROR] Fail to create audio handle : %d", ret); + return -1; + } + + if (0 != sound_manager_create_stream_information( + SOUND_STREAM_TYPE_VOICE_RECOGNITION, NULL, NULL, &g_stream_info_h)) { + MWR_LOGD("[Recorder ERROR] Fail to create stream info"); + audio_in_destroy(g_audio_h); + return -1; + } + + ret = audio_in_set_sound_stream_info(g_audio_h, g_stream_info_h); + if (AUDIO_IO_ERROR_NONE != ret) { + MWR_LOGD("[Recorder ERROR] Fail to set stream info : %d", ret); + sound_manager_destroy_stream_information(g_stream_info_h); + audio_in_destroy(g_audio_h); + return -1; + } + + ret = audio_in_prepare(g_audio_h); + if (AUDIO_IO_ERROR_NONE != ret) { + if (AUDIO_IO_ERROR_SOUND_POLICY == ret) + { + MWR_LOGD("[Recorder ERROR] Audio is busy."); + } else { + MWR_LOGD("[Recorder ERROR] Fail to start audio : %d", ret); + } + sound_manager_destroy_stream_information(g_stream_info_h); + audio_in_destroy(g_audio_h); + return -1; + } +} + +static int recorder_deinitialize(void) +{ + MWR_LOGD("[ENTER]"); + + int ret = 0; + ret = audio_in_unprepare(g_audio_h); + if (AUDIO_IO_ERROR_NONE != ret) { + MWR_LOGD("[Recorder ERROR] Fail to stop audio : %d", ret); + } + + if (0 != sound_manager_destroy_stream_information(g_stream_info_h)) { + MWR_LOGD("[Recorder ERROR] Fail to destroy stream info"); + } + + ret = audio_in_destroy(g_audio_h); + if (AUDIO_IO_ERROR_NONE != ret) { + MWR_LOGD("[Recorder ERROR] Fail to destroy audio : %d", ret); + } + + MWR_LOGD("[END]"); + return 0; +} + +#define FRAME_LENGTH 160 +#define BUFFER_LENGTH FRAME_LENGTH * 2 + +static void recorder_thread_func() +{ + static int buffer_count = 0; + + while (!(g_recorder_thread_should_stop.load())) { + char buffer[BUFFER_LENGTH + 10]; + int ret; + memset(buffer, '\0', BUFFER_LENGTH + 10); + int read_bytes = audio_in_read(g_audio_h, buffer, BUFFER_LENGTH); + if (0 > read_bytes) { + LOGE("[Recorder WARNING] Fail to read audio : %d", read_bytes); + break; + } + // LOCK REQUIRED + if (!g_audio_data_required) return; + for (int loop = 0;loop < g_engine_count;loop++) { + if (g_wakeup_engine_info[loop].audio_data_require_status && + g_wakeup_engine_info[loop].interface.feed_audio_data) { + ret = g_wakeup_engine_info[loop].interface.feed_audio_data(buffer, read_bytes); + if (0 == ret) { + LOGE("[ERROR] Fail to feed speech data, ret(%d)", ret); + } + } + } + // UNLOCK REQUIRED + /* Audio read log */ + if (0 == buffer_count % 100) { + LOGD("[Recorder][%d] Recording... : read_size(%d)", buffer_count, read_bytes); + } + + buffer_count++; + +#ifdef BUF_SAVE_MODE + /* write pcm buffer */ + if (g_pFile) + fwrite(buffer, 1, BUFFER_LENGTH, g_pFile); +#endif + } +} + +static void wakeup_engine_wakeup_event_cb(wakeup_service_wakeup_event_e event, const char* wakeup_word, void* user_data) +{ + MWR_LOGD("[ENTER]"); + if (NULL == user_data) return; + + for (int loop = 0;loop < g_engine_count;loop++) { + if (NULL != g_wakeup_engine_info[loop].engine_name && + strncmp(g_wakeup_engine_info[loop].engine_name, + (const char*)user_data, _POSIX_PATH_MAX) == 0) { + g_wakeup_event_cb(event, wakeup_word, g_wakeup_event_user_data); + } + } +} + +static void wakeup_engine_speech_status_cb(wakeup_service_speech_status_e status, void* user_data) +{ + MWR_LOGD("[ENTER]"); + if (NULL == user_data) return; + + for (int loop = 0;loop < g_engine_count;loop++) { + if (NULL != g_wakeup_engine_info[loop].engine_name && + strncmp(g_wakeup_engine_info[loop].engine_name, + (const char*)user_data, _POSIX_PATH_MAX) == 0) { + } + } +} + +static void wakeup_engine_error_cb(int error, const char* err_msg, void* user_data) +{ + MWR_LOGD("[ENTER]"); + if (NULL == user_data) return; + + for (int loop = 0;loop < g_engine_count;loop++) { + if (NULL != g_wakeup_engine_info[loop].engine_name && + strncmp(g_wakeup_engine_info[loop].engine_name, + (const char*)user_data, _POSIX_PATH_MAX) == 0) { + } + } +} + +static void join_recorder_thread() +{ + if (g_recorder_thread.joinable()) { + MWR_LOGD("g_recorder_thread is joinable, trying join()"); + g_recorder_thread_should_stop.store(true); + g_recorder_thread.join(); + } +} + +static void start_recorder_thread() +{ + join_recorder_thread(); + g_recorder_thread_should_stop.store(false); + g_recorder_thread = std::thread(recorder_thread_func); +} + +static void wakeup_engine_audio_data_require_status_cb(bool require, void* user_data) +{ + MWR_LOGD("[ENTER]"); + if (NULL == user_data) return; + + bool prev_audio_data_required = g_audio_data_required; + // LOCK REQUIRED + int audio_data_require_count = 0; + for (int loop = 0;loop < g_engine_count;loop++) { + if (NULL != g_wakeup_engine_info[loop].engine_name && + strncmp(g_wakeup_engine_info[loop].engine_name, + (const char*)user_data, _POSIX_PATH_MAX) == 0) { + g_wakeup_engine_info[loop].audio_data_require_status = require; + } + if (g_wakeup_engine_info[loop].enabled && + g_wakeup_engine_info[loop].audio_data_require_status) { + audio_data_require_count++; + } + } + if (audio_data_require_count > 0) { + g_audio_data_required = true; + if (g_audio_data_required != prev_audio_data_required) { + start_recorder_thread(); + } + } else { + g_audio_data_required = false; + if (g_audio_data_required != prev_audio_data_required) { + join_recorder_thread(); + } + } + // UNLOCK REQUIRED +} + +static void wakeup_engine_add_directory(const char* name, const char* path) +{ + if (NULL == path) return; + + DIR* dp = opendir(path); + if (NULL == dp) { + MWR_LOGD("Failed opening directory : %s", path); + } else { + struct dirent *dirp = NULL; + char filepath[_POSIX_PATH_MAX]; + do { + dirp = readdir(dp); + + if (NULL != dirp) { + if (g_engine_count >= MAX_WAKEUP_ENGINE_NUM) break; + + if (!strcmp(".", dirp->d_name) || !strcmp("..", dirp->d_name)) + continue; + + if (DT_REG != dirp->d_type) /* If not a regular file */ + continue; + + int filepath_len = strlen(MA_WAKEUP_ENGINE_PATH) + strlen(dirp->d_name) + 2; + if (filepath_len >= _POSIX_PATH_MAX) { + MWR_LOGD("File path is too long : %s", dirp->d_name); + closedir(dp); + return; + } + + memset(filepath, '\0', _POSIX_PATH_MAX); + snprintf(filepath, _POSIX_PATH_MAX, "%s/%s", path, dirp->d_name); + + MWR_LOGD("Name (%s), Filepath(%s)", name, filepath); + strncpy(g_wakeup_engine_info[g_engine_count].engine_path, filepath, _POSIX_PATH_MAX); + strncpy(g_wakeup_engine_info[g_engine_count].engine_name, name, _POSIX_PATH_MAX); + + char* error = NULL; + void* handle = dlopen(filepath, RTLD_LAZY); + if (NULL != (error = dlerror()) || NULL == handle) { + MWR_LOGD("[ERROR] Fail to dlopen(%s), error(%s)", filepath, error); + } else { + g_wakeup_engine_info[g_engine_count].interface.initialize = + (wakeup_engine_initialize)dlsym(handle, + MA_WAKEUP_ENGINE_FUNC_INITIALIZE); + g_wakeup_engine_info[g_engine_count].interface.deinitialize = + (wakeup_engine_deinitialize)dlsym(handle, + MA_WAKEUP_ENGINE_FUNC_DEINITIALIZE); + g_wakeup_engine_info[g_engine_count].interface.activate = + (wakeup_engine_activate)dlsym(handle, + MA_WAKEUP_ENGINE_FUNC_ACTIVATE); + g_wakeup_engine_info[g_engine_count].interface.deactivate = + (wakeup_engine_deactivate)dlsym(handle, + MA_WAKEUP_ENGINE_FUNC_DEACTIVATE); + g_wakeup_engine_info[g_engine_count].interface.set_wakeup_word = + (wakeup_engine_set_wakeup_word)dlsym(handle, + MA_WAKEUP_ENGINE_FUNC_SET_WAKEUP_WORD); + g_wakeup_engine_info[g_engine_count].interface.set_language = + (wakeup_engine_set_language)dlsym(handle, + MA_WAKEUP_ENGINE_FUNC_SET_LANGUAGE); + g_wakeup_engine_info[g_engine_count].interface.update_manager_state = + (wakeup_engine_update_manager_state)dlsym(handle, + MA_WAKEUP_ENGINE_FUNC_UPDATE_MANAGER_STATE); + g_wakeup_engine_info[g_engine_count].interface.set_audio_format = + (wakeup_engine_set_audio_format)dlsym(handle, + MA_WAKEUP_ENGINE_FUNC_SET_AUDIO_FORMAT); + g_wakeup_engine_info[g_engine_count].interface.get_audio_format = + (wakeup_engine_get_audio_format)dlsym(handle, + MA_WAKEUP_ENGINE_FUNC_GET_AUDIO_FORMAT); + g_wakeup_engine_info[g_engine_count].interface.feed_audio_data = + (wakeup_engine_feed_audio_data)dlsym(handle, + MA_WAKEUP_ENGINE_FUNC_FEED_AUDIO_DATA); + g_wakeup_engine_info[g_engine_count].interface.get_utterance_data_count = + (wakeup_engine_get_utterance_data_count)dlsym(handle, + MA_WAKEUP_ENGINE_FUNC_GET_UTTERANCE_DATA_COUNT); + g_wakeup_engine_info[g_engine_count].interface.get_utterance_data = + (wakeup_engine_get_utterance_data)dlsym(handle, + MA_WAKEUP_ENGINE_FUNC_GET_UTTERANCE_DATA); + g_wakeup_engine_info[g_engine_count].interface.set_wakeup_event_callback = + (wakeup_engine_set_wakeup_event_callback)dlsym(handle, + MA_WAKEUP_ENGINE_FUNC_SET_WAKEUP_EVENT_CALLBACK); + g_wakeup_engine_info[g_engine_count].interface.set_speech_status_callback = + (wakeup_engine_set_speech_status_callback)dlsym(handle, + MA_WAKEUP_ENGINE_FUNC_SET_SPEECH_STATUS_CALLBACK); + g_wakeup_engine_info[g_engine_count].interface.set_error_callback = + (wakeup_engine_set_error_callback)dlsym(handle, + MA_WAKEUP_ENGINE_FUNC_SET_ERROR_CALLBACK); + g_wakeup_engine_info[g_engine_count].interface.set_audio_data_require_status_callback = + (wakeup_engine_set_audio_data_require_status_callback)dlsym(handle, + MA_WAKEUP_ENGINE_FUNC_SET_AUDIO_DATA_REQUIRE_STATUS_CALLBACK); + } + ++g_engine_count; + } + } while (NULL != dirp && g_engine_count < MAX_WAKEUP_ENGINE_NUM); + + closedir(dp); + } +} + +static int wakeup_engine_info_initialize() +{ + DIR* dp = opendir(MA_WAKEUP_ENGINE_PATH); + if (NULL == dp) { + MWR_LOGD("Failed opening directory : %s", (const char*)MA_WAKEUP_ENGINE_PATH); + } else { + struct dirent *dirp = NULL; + char dirpath[_POSIX_PATH_MAX]; + do { + dirp = readdir(dp); + + if (NULL != dirp) { + if (!strcmp(".", dirp->d_name) || !strcmp("..", dirp->d_name)) + continue; + + if (DT_DIR != dirp->d_type) /* If not a directory */ + continue; + + int dirpath_len = strlen(MA_WAKEUP_ENGINE_PATH) + strlen(dirp->d_name) + 1; + if (dirpath_len >= _POSIX_PATH_MAX) { + MWR_LOGD("File path is too long : %s", dirp->d_name); + closedir(dp); + return -1; + } + + memset(dirpath, '\0', _POSIX_PATH_MAX); + snprintf(dirpath, _POSIX_PATH_MAX, "%s/%s", + (const char*)(MA_WAKEUP_ENGINE_PATH), dirp->d_name); + + wakeup_engine_add_directory(dirp->d_name, dirpath); + } + } while (NULL != dirp && g_engine_count < MAX_WAKEUP_ENGINE_NUM); + + closedir(dp); + } + + for (int loop = 0;loop < g_engine_count;loop++) { + g_wakeup_engine_info[loop].active = false; + /* We'll need to check vconf for enabled wakeup engines */ + g_wakeup_engine_info[loop].enabled = true; + g_wakeup_engine_info[loop].audio_data_require_status = false; + MWR_LOGD("Initializing wakeup engine : %s %p", g_wakeup_engine_info[loop].engine_path, g_wakeup_engine_info[loop].interface.initialize); + if (g_wakeup_engine_info[loop].interface.initialize) { + g_wakeup_engine_info[loop].interface.initialize(); + } + if (g_wakeup_engine_info[loop].interface.set_wakeup_event_callback) { + g_wakeup_engine_info[loop].interface.set_wakeup_event_callback( + wakeup_engine_wakeup_event_cb, g_wakeup_engine_info[loop].engine_name); + } + if (g_wakeup_engine_info[loop].interface.set_speech_status_callback) { + g_wakeup_engine_info[loop].interface.set_speech_status_callback( + wakeup_engine_speech_status_cb, g_wakeup_engine_info[loop].engine_name); + } + if (g_wakeup_engine_info[loop].interface.set_error_callback) { + g_wakeup_engine_info[loop].interface.set_error_callback( + wakeup_engine_error_cb, g_wakeup_engine_info[loop].engine_name); + } + if (g_wakeup_engine_info[loop].interface.set_audio_data_require_status_callback) { + g_wakeup_engine_info[loop].interface.set_audio_data_require_status_callback( + wakeup_engine_audio_data_require_status_cb, g_wakeup_engine_info[loop].engine_name); + } + } + return 0; +} + +int wakeup_manager_initialize(void) +{ + MWR_LOGD("[ENTER]"); + + g_wakeup_event_cb = NULL; + g_wakeup_event_user_data = NULL; + + g_utterance_streaming_cb = NULL; + g_utterance_streaming_user_data = NULL; + + g_follow_up_streaming_cb = NULL; + g_follow_up_streaming_user_data = NULL; + + g_speech_status_cb = NULL; + g_speech_status_user_data = NULL; + + g_error_cb = NULL; + g_error_user_data = NULL; + + g_engine_count = 0; + + recorder_initialize(); + wakeup_engine_info_initialize(); + + MWR_LOGD("[END]"); + return 0; +} + +int wakeup_manager_deinitialize(void) +{ + MWR_LOGD("[ENTER]"); + + recorder_deinitialize(); + + if (g_current_language) { + free(g_current_language); + g_current_language = NULL; + } + + for (int loop = 0;loop < g_engine_count;loop++) { + if (g_wakeup_engine_info[loop].interface.deinitialize) { + g_wakeup_engine_info[loop].interface.deinitialize(); + } + } + + MWR_LOGD("[END]"); + return 0; +} + +static int _is_valid_language(const char* language, bool* is_valid) +{ + if (language && is_valid) { + *is_valid = true; + } + return 0; +} + +int wakeup_manager_set_wakeup_word(const char* language, const char* wakeup_word) +{ + MWR_LOGD("[ENTER]"); + + if (NULL == language || NULL == wakeup_word) { + MWR_LOGD("[ERROR] Parameter is invalid, language(%s), wakeup_word(%s)", language, wakeup_word); + return -1; + } + + bool is_valid = false; + int ret = _is_valid_language(language, &is_valid); + if (0 != ret) { + MWR_LOGE("[ERROR] Fail to do wakeup_service_is_valid_language function (%d)", ret); + return ret; + } + if (is_valid == false) { + MWR_LOGE("[ERROR] Not supported language (%s)", language); + return -1; + } + + MWR_LOGD("[DEBUG] language(%s), wakeup word(%s)", language, wakeup_word); + + MWR_LOGD("[END]"); + return 0; +} + +int wakeup_manager_set_language(const char* language) +{ + MWR_LOGD("[ENTER]"); + + int ret = 0; + bool is_valid = false; + ret = _is_valid_language(language, &is_valid); + if (0 != ret) { + MWR_LOGE("[ERROR] wakeup_service_is_valid_language fail (%d)", ret); + return ret; + } + if (is_valid == false) { + MWR_LOGE("[ERROR] Not supported language (%s)", language); + return -1; + } + + g_current_language = strdup(language); + + MWR_LOGD("[END]"); + return 0; +} + +int wakeup_manager_change_state(wakeup_manager_state_e state) +{ + for (int loop = 0;loop < g_engine_count;loop++) { + if (g_wakeup_engine_info[loop].interface.update_manager_state) { + g_wakeup_engine_info[loop].interface.update_manager_state(state); + } + } +} + +int wakeup_manager_activate(void) +{ + MWR_LOGD("[ENTER]"); + + wakeup_manager_change_state(WAKEUP_MANAGER_STATE_LISTENING); + + for (int loop = 0;loop < g_engine_count;loop++) { + if (g_wakeup_engine_info[loop].interface.activate) { + g_wakeup_engine_info[loop].interface.activate(); + } + } + + MWR_LOGD("[END]"); + return 0; +} + +int wakeup_manager_deactivate(void) +{ + MWR_LOGD("[ENTER]"); + + for (int loop = 0;loop < g_engine_count;loop++) { + if (g_wakeup_engine_info[loop].interface.deactivate) { + g_wakeup_engine_info[loop].interface.deactivate(); + } + } + wakeup_manager_change_state(WAKEUP_MANAGER_STATE_INACTIVE); + + MWR_LOGD("[END]"); + return 0; +} + +int wakeup_manager_update_voice_feedback_state(const char* appid, int state) +{ + MWR_LOGD("[ENTER]"); + + if (state) { + if (g_wakeup_manager_state == WAKEUP_MANAGER_STATE_LISTENING || + g_wakeup_manager_state == WAKEUP_MANAGER_STATE_PROCESSING) { + wakeup_manager_change_state(WAKEUP_MANAGER_STATE_VOICE_FEEDBACK); + } + } else { + if (g_wakeup_manager_state == WAKEUP_MANAGER_STATE_VOICE_FEEDBACK) { + wakeup_manager_change_state(WAKEUP_MANAGER_STATE_LISTENING); + } + } + + MWR_LOGD("[END]"); + return 0; +} + +int wakeup_manager_update_result_state(const char* appid, int state) +{ + MWR_LOGD("[ENTER]"); + if (g_wakeup_manager_state == WAKEUP_MANAGER_STATE_PROCESSING) { + wakeup_manager_change_state(WAKEUP_MANAGER_STATE_LISTENING); + } + MWR_LOGD("[END]"); + return 0; +} + +int wakeup_manager_process_event(int event, void* data, int len) +{ + MWR_LOGD("[ENTER]"); + + MWR_LOGD("[END]"); + return 0; +} + +void __wakeup_service_streaming_cb(wakeup_service_speech_streaming_event_e event, void* buffer, unsigned int len) +{ + if (WAKEUP_SPEECH_STREAMING_EVENT_START == event) { + MWR_LOGD("streaming_cb START"); + } + if (WAKEUP_SPEECH_STREAMING_EVENT_FINISH == event) { + MWR_LOGD("streaming_cb FINISH"); + } + if (NULL != g_utterance_streaming_cb) { + g_utterance_streaming_cb(event, buffer, len, g_utterance_streaming_user_data); + } else { + MWR_LOGI("[INFO] No service streaming callback"); + } +} + +static void speech_data_thread_func(void) +{ + MWR_LOGD("[ENTER]"); + + if (g_wakeup_engine_selected < 0 || + g_wakeup_engine_selected >= MAX_WAKEUP_ENGINE_NUM) + return; + + wakeup_engine_interface *interface = + &(g_wakeup_engine_info[g_wakeup_engine_selected].interface); + + if (NULL == interface || + NULL == interface->get_utterance_data || + NULL == interface->get_utterance_data_count) + return; + + MWR_LOGD("data_count : %d", interface->get_utterance_data_count()); + + wakeup_engine_speech_data speech_data; + int index = 0; + + while (1) { + int ret = -1; + int cnt = 0; + + /* get feedback data */ + if (interface && interface->get_utterance_data) { + ret = interface->get_utterance_data(index, &speech_data); + if (0 != ret) { + /* empty queue */ + MWR_LOGD("[DEBUG] No feedback data. Waiting mode : %d", ret); + + /* waiting */ + while (1) { + usleep(10000); + if (index < interface->get_utterance_data_count()) { + MWR_LOGI("[INFO] Resume thread"); + break; + } + if (200 < cnt) { + MWR_LOGE("[ERROR] Wrong request, there's no pcm data"); + __wakeup_service_streaming_cb( + WAKEUP_SPEECH_STREAMING_EVENT_FAIL, NULL, 0); + return; + } + cnt++; + } + MWR_LOGI("[INFO] Finish to wait for new feedback data come"); + + /* resume feedback thread */ + continue; + } + + __wakeup_service_streaming_cb( + speech_data.event, speech_data.buffer, speech_data.len); + + if (WAKEUP_SPEECH_STREAMING_EVENT_FINISH == speech_data.event) { + MWR_LOGI("[INFO] Finish to get and send speech data"); + break; + } + + index++; + } + } +} + +int wakeup_manager_start_streaming_utterance_data(void) +{ + MWR_LOGD("[ENTER]"); + + if (g_speech_data_thread.joinable()) { + MWR_LOGD("g_speech_data_thread is joinable, trying join()"); + g_speech_data_thread_should_stop.store(true); + g_speech_data_thread.join(); + } + g_speech_data_thread_should_stop.store(false); + g_speech_data_thread = std::thread(speech_data_thread_func); + + MWR_LOGD("[END]"); + return 0; +} + +int wakeup_manager_stop_streaming_utterance_data(void) +{ + MWR_LOGD("[ENTER]"); + if (g_wakeup_manager_state == WAKEUP_MANAGER_STATE_UTTERANCE) { + wakeup_manager_change_state(WAKEUP_MANAGER_STATE_PROCESSING); + if (g_speech_data_thread.joinable()) { + MWR_LOGD("g_speech_data_thread is joinable, trying join()"); + g_speech_data_thread_should_stop.store(true); + g_speech_data_thread.join(); + } + } + MWR_LOGD("[END]"); + return 0; +} + +int wakeup_manager_start_streaming_follow_up_data(void) +{ + MWR_LOGD("[ENTER]"); + + MWR_LOGD("[END]"); + return 0; +} + +int wakeup_manager_stop_streaming_follow_up_data(void) +{ + MWR_LOGD("[ENTER]"); + + MWR_LOGD("[END]"); + return 0; +} + +int wakeup_manager_start_streaming_previous_utterance_data(void) +{ + MWR_LOGD("[ENTER]"); + + MWR_LOGD("[END]"); + return 0; +} + +int wakeup_manager_stop_streaming_previous_utterance_data(void) +{ + MWR_LOGD("[ENTER]"); + + MWR_LOGD("[END]"); + return 0; +} + +int wakeup_manager_get_audio_format(int* rate, int* channel, int* audio_type) +{ + MWR_LOGD("[ENTER]"); + + if (!audio_type || !rate || !channel) { + MWR_LOGE("[ERROR] Invalid parameter"); + return -1; + } + + *rate = 16000; + *channel = 0; + *audio_type = 0; + + MWR_LOGD("[END] rate(%d), channel(%d), audio_type(%d)", *rate, *channel, *audio_type); + return 0; +} + +int wakeup_manager_set_wakeup_event_callback(wakeup_service_wakeup_event_cb callback, void* user_data) +{ + MWR_LOGD("[ENTER]"); + + if (NULL == callback) { + MWR_LOGE("[ERROR] Input parameter is NULL"); + return -1; + } + + g_wakeup_event_cb = callback; + g_wakeup_event_user_data = user_data; + + MWR_LOGD("[END]"); + return 0; +} + +int wakeup_manager_set_utterance_streaming_callback(wakeup_service_speech_streaming_cb callback, void* user_data) +{ + MWR_LOGD("[ENTER]"); + + if (NULL == callback) { + MWR_LOGE("[ERROR] Input parameter is NULL"); + return -1; + } + + g_utterance_streaming_cb = callback; + g_utterance_streaming_user_data = user_data; + + MWR_LOGD("[END]"); + return 0; +} + +int wakeup_manager_set_previous_utterance_streaming_callback(wakeup_service_speech_streaming_cb callback, void* user_data) +{ + MWR_LOGD("[ENTER]"); + + if (NULL == callback) { + MWR_LOGE("[ERROR] Input parameter is NULL"); + return -1; + } + + g_previous_utterance_streaming_cb = callback; + g_previous_utterance_streaming_user_data = user_data; + + MWR_LOGD("[END]"); + return 0; +} + +int wakeup_manager_set_follow_up_streaming_callback(wakeup_service_speech_streaming_cb callback, void* user_data) +{ + MWR_LOGD("[ENTER]"); + + if (NULL == callback) { + MWR_LOGE("[ERROR] Input parameter is NULL"); + return -1; + } + + g_follow_up_streaming_cb = callback; + g_follow_up_streaming_user_data = user_data; + + MWR_LOGD("[END]"); + return 0; +} + +int wakeup_manager_set_speech_status_callback(wakeup_service_speech_status_cb callback, void* user_data) +{ + MWR_LOGD("[ENTER]"); + + if (NULL == callback) { + MWR_LOGE("[ERROR] Input parameter is NULL"); + return -1; + } + + g_speech_status_cb = callback; + g_speech_status_user_data = user_data; + + MWR_LOGD("[END]"); + return 0; +} + +int wakeup_manager_set_error_callback(wakeup_service_error_cb callback, void* user_data) +{ + MWR_LOGD("[ENTER]"); + + if (NULL == callback) { + MWR_LOGE("[ERROR] Input parameter is NULL"); + return -1; + } + + g_error_cb = callback; + g_error_user_data = user_data; + + MWR_LOGD("[END]"); + return 0; +} diff --git a/src/multi_assistant_dbus.c b/src/multi_assistant_dbus.c index a6ebc26..42ecaf1 100644 --- a/src/multi_assistant_dbus.c +++ b/src/multi_assistant_dbus.c @@ -173,7 +173,7 @@ int masc_dbus_send_error_message(int reason, const char* err_msg) return 0; } -int masc_dbus_send_speech_data(int pid, int event, unsigned char* data, unsigned int data_size) +int masc_dbus_send_streaming_audio_data(int pid, int event, unsigned char* data, unsigned int data_size) { if (0 != __dbus_check()) { return -1; //MAS_ERROR_OPERATION_FAILED; @@ -191,13 +191,14 @@ int masc_dbus_send_speech_data(int pid, int event, unsigned char* data, unsigned service_name, MA_CLIENT_SERVICE_OBJECT_PATH, MA_CLIENT_SERVICE_INTERFACE, - MAS_METHOD_SEND_SPEECH_DATA); + MAS_METHOD_STREAMING_AUDIO_DATA); + static int count = 0; if (NULL == msg) { - MAS_LOGE(">>>> Request mas send speech data : Fail to make message"); + MAS_LOGE(">>>> Request mas send utterance stream : Fail to make message"); return -1; // MAS_ERROR_OPERATION_FAILED; } else { - MAS_LOGD(">>>> Request mas send speech data : %s", service_name); + MAS_LOGD(">>>> Request mas send utterance stream : %s event(%d) %d", service_name, event, count++); } if (true != dbus_message_append_args(msg, @@ -210,54 +211,69 @@ int masc_dbus_send_speech_data(int pid, int event, unsigned char* data, unsigned return -1; } -#if 1 dbus_message_set_no_reply(msg, TRUE); if (1 != dbus_connection_send(g_conn_sender, msg, NULL)) { MAS_LOGE("[Dbus ERROR] Fail to Send"); return -1; // MAS_ERROR_OPERATION_FAILED; } else { - MAS_LOGD("[Dbus DEBUG] Success to Send speech data"); + MAS_LOGD("[Dbus DEBUG] Success to Send utterance stream"); dbus_connection_flush(g_conn_sender); } dbus_message_unref(msg); return 0; -#else - DBusMessage* result_msg; - int result = -1; +} - result_msg = dbus_connection_send_with_reply_and_block(g_conn_sender, msg, g_waiting_time, &err); - dbus_message_unref(msg); - if (dbus_error_is_set(&err)) { - MAS_LOGE("[ERROR] Send error (%s)", err.message); - dbus_error_free(&err); +int masc_dbus_active_state_change(int pid, int state) +{ + if (0 != __dbus_check()) { + return -1; //MAS_ERROR_OPERATION_FAILED; } - if (NULL != result_msg) { - dbus_message_get_args(result_msg, &err, - DBUS_TYPE_INT32, &result, - DBUS_TYPE_INVALID); - - if (dbus_error_is_set(&err)) { - MAS_LOGE("<<<< mas send speech data : Get arguments error (%s)", err.message); - dbus_error_free(&err); - result = -1; - } - dbus_message_unref(result_msg); + DBusMessage* msg; - if (0 == result) { - MAS_LOGD("<<<< mas send speech data : result(%d)", result); - } else { - MAS_LOGE("<<<< mas send speech data : result(%d)", result); - } + DBusError err; + dbus_error_init(&err); + + char service_name[64]; + memset(service_name, '\0', 64); + snprintf(service_name, 64, "%s_%d", MA_CLIENT_SERVICE_NAME, pid); + + msg = dbus_message_new_method_call( + service_name, + MA_CLIENT_SERVICE_OBJECT_PATH, + MA_CLIENT_SERVICE_INTERFACE, + MAS_METHOD_ACTIVE_STATE_CHANGE); + + static int count = 0; + if (NULL == msg) { + MAS_LOGE(">>>> Request mas send activate message : Fail to make message"); + return -1; // MAS_ERROR_OPERATION_FAILED; } else { - MAS_LOGE("<<<< Result message is NULL "); - mas_dbus_reconnect(); - result = -1; + MAS_LOGD(">>>> Request mas send activate message : %s", service_name); } - return result; -#endif + + if (true != dbus_message_append_args(msg, + DBUS_TYPE_INT32, &state, + DBUS_TYPE_INVALID)) { + dbus_message_unref(msg); + MAS_LOGE("[ERROR] Fail to append args"); + return -1; + } + + dbus_message_set_no_reply(msg, TRUE); + + if (1 != dbus_connection_send(g_conn_sender, msg, NULL)) { + MAS_LOGE("[Dbus ERROR] Fail to Send"); + return -1; // MAS_ERROR_OPERATION_FAILED; + } else { + MAS_LOGD("[Dbus DEBUG] Success to Send activate message : %d", state); + dbus_connection_flush(g_conn_sender); + } + + dbus_message_unref(msg); + return 0; } int masc_ui_dbus_send_hello(void) @@ -267,6 +283,7 @@ int masc_ui_dbus_send_hello(void) } DBusMessage* msg; + DBusError err; dbus_error_init(&err); @@ -537,6 +554,47 @@ int masc_ui_dbus_send_error_message(int reason, const char* err_msg) return 0; } +int masc_ui_dbus_send_recognition_result(int pid, int result) +{ + if (0 != __dbus_check()) { + return -1; //MAS_ERROR_OPERATION_FAILED; + } + + DBusMessage* msg; + + msg = dbus_message_new_method_call( + MA_UI_CLIENT_SERVICE_NAME, + MA_UI_CLIENT_SERVICE_OBJECT_PATH, + MA_UI_CLIENT_SERVICE_INTERFACE, + MAS_UI_METHOD_SEND_RECOGNITION_RESULT); + + if (NULL == msg) { + MAS_LOGE("@@ Request multi-assistant send recognition result : Fail to make message"); + return -1; //MA_ERROR_OPERATION_FAILED; + } else { + MAS_LOGD("[DEBUG] multi-assistant send recognition result(%d)", result); + } + + dbus_message_append_args(msg, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_INT32, &result, + DBUS_TYPE_INVALID); + + dbus_message_set_no_reply(msg, TRUE); + + if (1 != dbus_connection_send(g_conn_sender, msg, NULL)) { + MAS_LOGE("[Dbus ERROR] Fail to Send"); + return -1; // MAS_ERROR_OPERATION_FAILED; + } else { + MAS_LOGD("[Dbus DEBUG] Success to Send ASR result"); + dbus_connection_flush(g_conn_sender); + } + + dbus_message_unref(msg); + + return 0; +} + static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler *fd_handler) { if (NULL == g_conn_listener) return ECORE_CALLBACK_RENEW; @@ -576,6 +634,18 @@ static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler *fd_handle } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_SEND_RESULT)) { ma_service_dbus_send_result(g_conn_listener, msg); + } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_SEND_RECOGNITION_RESULT)) { + ma_service_dbus_send_recognition_result(g_conn_listener, msg); + + } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_START_STREAMING_AUDIO_DATA)) { + ma_service_dbus_start_streaming_audio_data(g_conn_listener, msg); + + } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_STOP_STREAMING_AUDIO_DATA)) { + ma_service_dbus_stop_streaming_audio_data(g_conn_listener, msg); + + } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_METHOD_UPDATE_VOICE_FEEDBACK_STATE)) { + ma_service_dbus_update_voice_feedback_state(g_conn_listener, msg); + } else if (dbus_message_is_method_call(msg, MA_SERVER_SERVICE_INTERFACE, MA_UI_METHOD_INITIALIZE)) { ma_service_ui_dbus_initialize(g_conn_listener, msg); diff --git a/src/multi_assistant_dbus.h b/src/multi_assistant_dbus.h index 76af068..8cadc79 100644 --- a/src/multi_assistant_dbus.h +++ b/src/multi_assistant_dbus.h @@ -29,7 +29,9 @@ int masc_dbus_send_hello(int pid); int masc_dbus_send_error_message(int reason, const char* err_msg); -int masc_dbus_send_speech_data(int pid, int event, unsigned char* data, unsigned int data_size); +int masc_dbus_send_streaming_audio_data(int pid, int event, unsigned char* data, unsigned int data_size); + +int masc_dbus_active_state_change(int pid, int state); int masc_ui_dbus_send_hello(void); diff --git a/src/multi_assistant_dbus_server.c b/src/multi_assistant_dbus_server.c index 46425b0..3e6fd55 100644 --- a/src/multi_assistant_dbus_server.c +++ b/src/multi_assistant_dbus_server.c @@ -314,6 +314,130 @@ int ma_service_dbus_send_result(DBusConnection* conn, DBusMessage* msg) return 0; } +int ma_service_dbus_send_recognition_result(DBusConnection* conn, DBusMessage* msg) +{ + DBusError err; + dbus_error_init(&err); + + int pid; + int result; + int ret = 0; + + dbus_message_get_args(msg, &err, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_INT32, &result, + DBUS_TYPE_INVALID); + + MAS_LOGD("[DEBUG] MAS SEND RECOGNITION RESULT"); + + if (dbus_error_is_set(&err)) { + MAS_LOGE("[IN ERROR] mas send error : Get arguments error (%s)", err.message); + dbus_error_free(&err); + ret = -1; //MAS_ERROR_OPERATION_FAILED; + } else { + MAS_LOGD("[IN] mas send error : pid(%d), result(%d)", pid, result); + ret = mas_client_send_recognition_result(pid, result); + } + + MAS_LOGD("<<<<<"); + MAS_LOGD(" "); + + return 0; +} + +int ma_service_dbus_start_streaming_audio_data(DBusConnection* conn, DBusMessage* msg) +{ + DBusError err; + dbus_error_init(&err); + + int pid; + int type; + int ret = 0; + + dbus_message_get_args(msg, &err, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_INT32, &type, + DBUS_TYPE_INVALID); + + MAS_LOGD("[DEBUG] MAS SEND START STREAMING"); + + if (dbus_error_is_set(&err)) { + MAS_LOGE("[IN ERROR] mas send start streaming : Get arguments error (%s)", err.message); + dbus_error_free(&err); + ret = -1; //MAS_ERROR_OPERATION_FAILED; + } else { + MAS_LOGD("[IN] mas send start streaming : pid(%d), result(%d)", pid, type); + ret = mas_client_start_streaming_audio_data(pid, type); + } + + MAS_LOGD("<<<<<"); + MAS_LOGD(" "); + + return 0; +} + +int ma_service_dbus_stop_streaming_audio_data(DBusConnection* conn, DBusMessage* msg) +{ + DBusError err; + dbus_error_init(&err); + + int pid; + int type; + int ret = 0; + + dbus_message_get_args(msg, &err, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_INT32, &type, + DBUS_TYPE_INVALID); + + MAS_LOGD("[DEBUG] MAS SEND STOP STREAMING"); + + if (dbus_error_is_set(&err)) { + MAS_LOGE("[IN ERROR] mas stop streaming : Get arguments error (%s)", err.message); + dbus_error_free(&err); + ret = -1; //MAS_ERROR_OPERATION_FAILED; + } else { + MAS_LOGD("[IN] mas stop streaming : pid(%d), result(%d)", pid, type); + ret = mas_client_stop_streaming_audio_data(pid, type); + } + + MAS_LOGD("<<<<<"); + MAS_LOGD(" "); + + return 0; +} + +int ma_service_dbus_update_voice_feedback_state(DBusConnection* conn, DBusMessage* msg) +{ + DBusError err; + dbus_error_init(&err); + + int pid; + int state; + int ret = 0; + + dbus_message_get_args(msg, &err, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_INT32, &state, + DBUS_TYPE_INVALID); + + MAS_LOGD("[DEBUG] MAS SEND UPDATE VOICE FEEDBACK"); + + if (dbus_error_is_set(&err)) { + MAS_LOGE("[IN ERROR] mas update voice feedback : Get arguments error (%s)", err.message); + dbus_error_free(&err); + ret = -1; //MAS_ERROR_OPERATION_FAILED; + } else { + MAS_LOGD("[IN] mas update voice feedback : pid(%d), result(%d)", pid, state); + ret = mas_client_update_voice_feedback_state(pid, state); + } + + MAS_LOGD("<<<<<"); + MAS_LOGD(" "); + + return 0; +} + int ma_service_ui_dbus_initialize(DBusConnection* conn, DBusMessage* msg) { DBusError err; diff --git a/src/multi_assistant_dbus_server.h b/src/multi_assistant_dbus_server.h index 1b75d8a..eff7f19 100644 --- a/src/multi_assistant_dbus_server.h +++ b/src/multi_assistant_dbus_server.h @@ -35,6 +35,14 @@ int ma_service_dbus_send_asr_result(DBusConnection* conn, DBusMessage* msg); int ma_service_dbus_send_result(DBusConnection* conn, DBusMessage* msg); +int ma_service_dbus_send_recognition_result(DBusConnection* conn, DBusMessage* msg); + +int ma_service_dbus_start_streaming_audio_data(DBusConnection* conn, DBusMessage* msg); + +int ma_service_dbus_stop_streaming_audio_data(DBusConnection* conn, DBusMessage* msg); + +int ma_service_dbus_update_voice_feedback_state(DBusConnection* conn, DBusMessage* msg); + int ma_service_ui_dbus_initialize(DBusConnection* conn, DBusMessage* msg); int ma_service_ui_dbus_deinitialize(DBusConnection* conn, DBusMessage* msg); diff --git a/src/multi_assistant_service.c b/src/multi_assistant_service.c index 77065de..7bc14ac 100644 --- a/src/multi_assistant_service.c +++ b/src/multi_assistant_service.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include @@ -33,9 +32,10 @@ #include "multi_assistant_service_plugin.h" #include "multi_assistant_dbus.h" #include "multi_assistant_config.h" +#include "multi_assistant_common.h" static const char *g_current_lang = "en_US"; -static int g_local_port_id = -1; + #define MAX_MACLIENT_INFO_NUM 16 #define MAX_WAKEUP_WORDS_NUM 4 @@ -59,16 +59,6 @@ static const char *g_wakeup_maclient_appid = NULL; /* client list */ static GSList* g_client_list = NULL; -static int g_temp_speech_data_requested = 0; -void ma_client_set_temp_speech_data_requested(int val) -{ - g_temp_speech_data_requested = val; -} -int ma_client_get_temp_speech_data_requested() -{ - return g_temp_speech_data_requested; -} - int ma_client_create(ma_client_s *info) { if (NULL == info) { @@ -196,7 +186,7 @@ int mas_client_initialize(int pid) if (g_wakeup_maclient_appid && strncmp(g_wakeup_maclient_appid, appid, MAX_APPID_LEN) == 0) { g_wakeup_maclient_appid = NULL; - mas_client_request_speech_data(pid); + mas_client_activate(pid); } else { MAS_LOGE("[ERROR] g_wakeup_maclient_appid and appid differ : %s %s", (g_wakeup_maclient_appid ? g_wakeup_maclient_appid : "NULL"), appid); @@ -234,7 +224,7 @@ int mas_client_get_audio_format(int pid, int* rate, int* channel, int* audio_typ return ret; } -int mas_client_request_speech_data(int pid) +int mas_client_activate(int pid) { int ret = -1; MAS_LOGD("[Enter] pid(%d)", pid); @@ -248,12 +238,14 @@ int mas_client_request_speech_data(int pid) } if (current_maclient_appid && 0 == strncmp(current_maclient_appid, appid, MAX_APPID_LEN)) { - MAS_LOGD("appid %s matches with current MA Client, requesting speech data", appid); - ma_client_set_temp_speech_data_requested(1); - ret = multi_assistant_service_plugin_request_speech_data(); + MAS_LOGD("appid %s matches with current MA Client, activating", appid); + /* + ret = multi_assistant_service_plugin_start_streaming_utterance_data(); if (0 != ret) { MAS_LOGE("[ERROR] Fail to request speech data(%d)", ret); } + */ + masc_dbus_active_state_change(pid, MA_ACTIVE_STATE_ACTIVE); } else { MAS_LOGE("appid %s does not match with current MA Client", appid); } @@ -275,18 +267,6 @@ int mas_client_send_asr_result(int pid, int event, char* asr_result) return ret; } -Eina_Bool __start_recording(void *data) -{ - (void)data; - - MAS_LOGD("[Enter] Start Recording again"); - int ret = multi_assistant_service_plugin_start_recording(); - if (0 != ret) { - MAS_LOGE("[ERROR] Fail to start recording, ret(%d)", ret); - } - return EINA_FALSE; -} - int mas_client_send_result(int pid, char* display_text, char* utterance_text, char* result_json) { MAS_LOGD("[Enter] pid(%d), display_text(%s), utterance_text(%s), result_json(%s)", pid, display_text, utterance_text, result_json); @@ -295,11 +275,77 @@ int mas_client_send_result(int pid, char* display_text, char* utterance_text, ch MAS_LOGE("[ERROR] Fail to send result, ret(%d)", ret); } - ecore_timer_add(0, __start_recording, NULL); + /* Should pass "RESULT_RECEIVED" event to wakeup manager */ + multi_assistant_service_plugin_update_result_state(NULL, 0); + + return ret; +} + +int mas_client_send_recognition_result(int pid, int result) +{ + MAS_LOGD("[Enter] pid(%d), result(%d)", pid, result); + int ret = masc_ui_dbus_send_recognition_result(pid, result); + if (0 != ret){ + MAS_LOGE("[ERROR] Fail to send recognition result, ret(%d)", ret); + } + + return ret; +} + +int mas_client_start_streaming_audio_data(int pid, int type) +{ + int ret = -1; + /* + switch(type) { + case MA_AUDIO_STREAMING_DATA_TYPE_CURRENT_UTTERANCE: + ret = multi_assistant_service_plugin_start_streaming_utterance_data(); + break; + case MA_AUDIO_STREAMING_DATA_TYPE_PREVIOUS_UTTERANCE: + ret = multi_assistant_service_plugin_start_streaming_previous_utterance_data(); + break; + case MA_AUDIO_STREAMING_DATA_TYPE_FOLLOW_UP_SPEECH: + ret = multi_assistant_service_plugin_start_streaming_follow_up_data(); + break; + } + */ + //if (pid is activated assistant) { + ret = multi_assistant_service_plugin_start_streaming_utterance_data(); + //} + return ret; +} +int mas_client_stop_streaming_audio_data(int pid, int type) +{ + int ret = -1; + /* + switch(type) { + case MA_AUDIO_STREAMING_DATA_TYPE_CURRENT_UTTERANCE: + ret = multi_assistant_service_plugin_stop_streaming_utterance_data(); + break; + case MA_AUDIO_STREAMING_DATA_TYPE_PREVIOUS_UTTERANCE: + ret = multi_assistant_service_plugin_stop_streaming_previous_utterance_data(); + break; + case MA_AUDIO_STREAMING_DATA_TYPE_FOLLOW_UP_SPEECH: + ret = multi_assistant_service_plugin_stop_streaming_follow_up_data(); + break; + } + */ + ret = multi_assistant_service_plugin_stop_streaming_utterance_data(); return ret; } +int mas_client_update_voice_feedback_state(int pid, int state) +{ + multi_assistant_service_plugin_update_voice_feedback_state(NULL, state); + return 0; +} + +int mas_client_update_result_state(int pid, int state) +{ + multi_assistant_service_plugin_update_result_state(NULL, state); + return 0; +} + int mas_ui_client_initialize(int pid) { MAS_LOGD("[Enter] pid(%d)", pid); @@ -324,15 +370,18 @@ int mas_ui_client_change_assistant(const char* appid) } mas_set_current_client_by_appid(appid); - if (mas_get_client_pid_by_appid(appid) != -1) { + int pid = mas_get_client_pid_by_appid(appid); + if (pid != -1) { + masc_dbus_active_state_change(pid, MA_ACTIVE_STATE_ACTIVE); /* Bring MA client to foreground - is there a better way instead of launching? */ mas_launch_client_by_appid(appid); MAS_LOGD("MA Client with appid %s exists, requesting speech data", (appid ? appid : "NULL")); - ma_client_set_temp_speech_data_requested(1); - int ret = multi_assistant_service_plugin_request_speech_data(); + /* + int ret = multi_assistant_service_plugin_start_streaming_utterance_data(); if (0 != ret) { - MAS_LOGE("[ERROR] Fail to request speech data(%d)", ret); + MAS_LOGE("[ERROR] Fail to start streaming utterance data(%d)", ret); } + */ } else { // Appropriate MA Client not available, trying to launch new one MAS_LOGD("MA Client with appid %s does not exist, launching client", (appid ? appid : "NULL")); @@ -352,39 +401,6 @@ int mas_ui_client_change_assistant(const char* appid) return 0; } -/* for message port - receiver */ -void __message_port_cb(int local_port_id, const char* remote_app_id, const char* remote_port, bool trusted_remote_port, bundle* message, void* user_data) -{ - char *command = NULL; - bundle_get_str(message, "command", &command); - - MAS_LOGD("Message from %s, command: %s", remote_app_id, command); - - if (!strncmp(command, "start", strlen(command))) { - multi_assistant_service_plugin_start_recording(); - } else if (!strncmp(command, "cancel", strlen(command))) { - multi_assistant_service_plugin_cancel_recording(); - } else { - MAS_LOGE("[ERROR] command is wrong, command(%s)", command); - } -} - -static void init_message_port(void) -{ - MAS_LOGD("[Enter] init_message_port"); - - g_local_port_id = message_port_register_local_port("multi_assistant_service_message_port", __message_port_cb, NULL); - if (g_local_port_id < 0) - MAS_LOGE("[ERROR] message port register error: %d", g_local_port_id); - else - MAS_LOGD("[DEBUG] port id: %d", g_local_port_id); -} - -static void deinit_message_port(void) -{ - message_port_unregister_local_port(g_local_port_id); -} - int __mas_assistant_info_cb(const char* appid, const char* name, const char* icon_path, const char* wakeup_list[], int cnt_wakeup, const char* supported_lang[], int cnt_lang, void* user_data) { @@ -427,7 +443,6 @@ int __mas_assistant_info_cb(const char* appid, const char* name, return 0; } - static int init_wakeup(void) { MAS_LOGD("[Enter] init_wakeup "); @@ -472,13 +487,11 @@ static int init_wakeup(void) return -1; } - if (0 != multi_assistant_service_plugin_start_recording()) { - MAS_LOGE("Fail to ws start recording"); + if (0 != multi_assistant_service_plugin_activate()) { + MAS_LOGE("Fail to ws activate"); return -1; } - init_message_port(); - return 0; } @@ -491,7 +504,11 @@ static void deinit_wakeup(void) g_current_lang = NULL; } */ - deinit_message_port(); + + if (0 != multi_assistant_service_plugin_deactivate()) { + MAS_LOGE("Fail to ws deactivate"); + return -1; + } int ret = mas_dbus_close_connection(); if (0 != ret) { @@ -595,6 +612,7 @@ int mas_set_current_client_by_wakeup_word(const char *wakeup_word) { int loop; int ret = -1; + int prev_selection = g_current_maclient_info; for (loop = 0; loop < MAX_MACLIENT_INFO_NUM && -1 == ret; loop++) { if (g_maclient_info[loop].used && @@ -633,12 +651,21 @@ int mas_set_current_client_by_wakeup_word(const char *wakeup_word) } } + if (g_current_maclient_info != prev_selection) { + if (prev_selection >= 0 && prev_selection < MAX_MACLIENT_INFO_NUM) { + masc_dbus_active_state_change( + mas_get_client_pid_by_appid(g_maclient_info[prev_selection].appid), + MA_ACTIVE_STATE_INACTIVE); + } + } + return ret; } int mas_set_current_client_by_appid(const char *appid) { int ret = -1; + int prev_selection = g_current_maclient_info; for (int loop = 0; loop < MAX_MACLIENT_INFO_NUM; loop++) { if (g_maclient_info[loop].used && @@ -646,9 +673,19 @@ int mas_set_current_client_by_appid(const char *appid) 0 < strlen(g_maclient_info[loop].wakeup_word[0])) { if (strncmp(appid, g_maclient_info[loop].appid, MAX_APPID_LEN) == 0) { g_current_maclient_info = loop; + ret = 0; } } } + + if (g_current_maclient_info != prev_selection) { + if (prev_selection >= 0 && prev_selection < MAX_MACLIENT_INFO_NUM) { + masc_dbus_active_state_change( + mas_get_client_pid_by_appid(g_maclient_info[prev_selection].appid), + MA_ACTIVE_STATE_INACTIVE); + } + } + return ret; } diff --git a/src/multi_assistant_service_plugin.c b/src/multi_assistant_service_plugin.c index 9c2de4b..c5fd251 100644 --- a/src/multi_assistant_service_plugin.c +++ b/src/multi_assistant_service_plugin.c @@ -32,6 +32,7 @@ #include "multi_assistant_service.h" #include "multi_assistant_service_plugin.h" #include "multi_assistant_dbus.h" +#include "multi_assistant_common.h" /* Sound buf save for test */ #if 1 @@ -48,6 +49,8 @@ static int g_count = 1; static void *g_handle = NULL; +static wakeup_manager_interface _wakeup_manager_interface = { NULL, }; + #if 0 /* + TEST_CODE */ Eina_Bool __send_asr_result(void *data) { @@ -79,7 +82,7 @@ Eina_Bool __send_result(void *data) } #endif /* -TEST_CODE */ -Eina_Bool __request_speech_data(void *data) +Eina_Bool __launch_assistant_by_wakeup_word(void *data) { MAS_LOGD("[ENTER]"); @@ -90,21 +93,27 @@ Eina_Bool __request_speech_data(void *data) mas_set_current_client_by_wakeup_word(wakeup_word); masc_ui_dbus_change_assistant(mas_get_client_appid_by_wakeup_word(wakeup_word)); if ((pid = mas_get_client_pid_by_wakeup_word(wakeup_word)) != -1) { + masc_dbus_active_state_change(pid, MA_ACTIVE_STATE_ACTIVE); /* Bring MA client to foreground - is there a better way instead of launching? */ mas_launch_client_by_wakeup_word(wakeup_word); + /* MAS_LOGD("MA Client with wakeup word %s exists, requesting speech data", (wakeup_word ? wakeup_word : "NULL")); - ma_client_set_temp_speech_data_requested(1); int ret = -1; if (NULL != g_handle) { - int (*ws_request_speech_data)(void); - ws_request_speech_data = (int (*)(void))dlsym(g_handle, "wakeup_service_request_speech_data"); - ret = ws_request_speech_data(); - if (0 != ret) { - MAS_LOGE("[ERROR] Fail to request speech data(%d)", ret); + wakeup_manager_start_streaming_utterance_data func = + _wakeup_manager_interface.start_streaming_utterance_data; + if (NULL == func) { + MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_START_STREAMING_UTTERANCE_DATA); + } else { + ret = func(); + if (0 != ret) { + MAS_LOGE("[ERROR] Fail to request speech data(%d)", ret); + } } } else { MAS_LOGE("[ERROR] g_handle is not valid"); } + */ } else { // Appropriate MA Client not available, trying to launch new one MAS_LOGD("MA Client with wakeup word %s does not exist, launching client", (wakeup_word ? wakeup_word : "NULL")); @@ -186,51 +195,28 @@ static void __wakeup_event_cb(wakeup_service_wakeup_event_e event, const char* w #endif /* - TEST_CODE */ if (WAKEUP_EVENT_SUCCESS == event && wakeup_word) { ecore_thread_main_loop_begin(); - ecore_timer_add(0.0f, __request_speech_data, (void*)strdup(wakeup_word)); + ecore_timer_add(0.0f, __launch_assistant_by_wakeup_word, (void*)strdup(wakeup_word)); ecore_thread_main_loop_end(); } } -static void __speech_streaming_cb(wakeup_service_speech_streaming_event_e event, unsigned char* buffer, int len, void *user_data) +static void __audio_streaming_cb(wakeup_service_speech_streaming_event_e event, unsigned char* buffer, int len, void *user_data) { - MAS_LOGD( "[SUCCESS] __speech_streaming_cb is called, event(%d), buffer(%p), len(%d)", event, buffer, len); + if (event == WAKEUP_SPEECH_STREAMING_EVENT_FAIL) { + mas_client_send_recognition_result(0, MA_RECOGNITION_RESULT_EVENT_ERROR); + return; + } + MAS_LOGD( "[SUCCESS] __audio_streaming_cb is called, event(%d), buffer(%p), len(%d)", event, buffer, len); int pid = mas_get_current_client_pid(); if (pid == -1) { MAS_LOGE("[ERROR] Fail to retrieve pid of current MA client"); } else { - if (g_pFile) { - int ret = masc_dbus_send_speech_data(pid, event, buffer, len); - if (0 != ret) { - MAS_LOGE("[ERROR] Fail to send speech data, ret(%d)", ret); - } - } else { - if (ma_client_get_temp_speech_data_requested()) { - /* read file and send dbus here */ - FILE *fp = fopen(g_temp_file_name, "rb"); - if (fp) { - unsigned char content[640]; - int first = 1; - size_t size; - while (size = fread(content, 1, 640, fp)) { - wakeup_service_speech_streaming_event_e new_event; - if (size == 640) { - new_event = (first ? WAKEUP_SPEECH_STREAMING_EVENT_START : WAKEUP_SPEECH_STREAMING_EVENT_CONTINUE); - } else { - new_event = WAKEUP_SPEECH_STREAMING_EVENT_FINISH; - } - int ret = masc_dbus_send_speech_data(pid, new_event, content, size); - if (0 != ret) { - MAS_LOGE("[ERROR] Fail to send speech data, ret(%d)", ret); - } - first = 0; - } - fclose(fp); - } - } + int ret = masc_dbus_send_streaming_audio_data(pid, event, buffer, len); + if (0 != ret) { + MAS_LOGE("[ERROR] Fail to send speech data, ret(%d)", ret); } } - ma_client_set_temp_speech_data_requested(0); #ifdef BUF_SAVE_MODE /* write pcm buffer */ @@ -266,9 +252,11 @@ static void __error_cb(int error, const char* err_msg, void* user_data) int multi_assistant_service_plugin_initialize(void) { + MAS_LOGD( "[Enter]"); + char filepath[512] = {'\0',}; - const char *default_engine_path = MA_DEFAULT_ENGINE; - snprintf(filepath, 512, "%s/%s", default_engine_path, "libmulti-wakeup-recognizer.so"); + const char *default_engine_path = MA_WAKEUP_MANAGER_PATH; + snprintf(filepath, 512, "%s/%s", default_engine_path, MA_DEFAULT_WAKEUP_MANAGER_FILENAME); char *error; g_handle = NULL; @@ -278,13 +266,84 @@ int multi_assistant_service_plugin_initialize(void) return -1; //MAS_ERROR_OPERATION_FAILED; } + _wakeup_manager_interface.initialize = + (wakeup_manager_initialize)dlsym(g_handle, + MA_WAKEUP_MANAGER_FUNC_INITIALIZE); + _wakeup_manager_interface.deinitialize = + (wakeup_manager_deinitialize)dlsym(g_handle, + MA_WAKEUP_MANAGER_FUNC_DEINITIALIZE); + _wakeup_manager_interface.set_wakeup_word = + (wakeup_manager_set_wakeup_word)dlsym(g_handle, + MA_WAKEUP_MANAGER_FUNC_SET_WAKEUP_WORD); + _wakeup_manager_interface.set_language = + (wakeup_manager_set_language)dlsym(g_handle, + MA_WAKEUP_MANAGER_FUNC_SET_LANGUAGE); + _wakeup_manager_interface.activate = + (wakeup_manager_activate)dlsym(g_handle, + MA_WAKEUP_MANAGER_FUNC_ACTIVATE); + _wakeup_manager_interface.deactivate = + (wakeup_manager_deactivate)dlsym(g_handle, + MA_WAKEUP_MANAGER_FUNC_DEACTIVATE); + _wakeup_manager_interface.update_voice_feedback_state = + (wakeup_manager_update_voice_feedback_state)dlsym(g_handle, + MA_WAKEUP_MANAGER_FUNC_UPDATE_VOICE_FEEDBACK_STATE); + _wakeup_manager_interface.update_result_state = + (wakeup_manager_update_result_state)dlsym(g_handle, + MA_WAKEUP_MANAGER_FUNC_UPDATE_RESULT_STATE); + _wakeup_manager_interface.process_event = + (wakeup_manager_process_event)dlsym(g_handle, + MA_WAKEUP_MANAGER_FUNC_PROCESS_EVENT); + _wakeup_manager_interface.start_streaming_utterance_data = + (wakeup_manager_start_streaming_utterance_data)dlsym(g_handle, + MA_WAKEUP_MANAGER_FUNC_START_STREAMING_UTTERANCE_DATA); + _wakeup_manager_interface.stop_streaming_utterance_data = + (wakeup_manager_stop_streaming_utterance_data)dlsym(g_handle, + MA_WAKEUP_MANAGER_FUNC_STOP_STREAMING_UTTERANCE_DATA); + _wakeup_manager_interface.start_streaming_previous_utterance_data = + (wakeup_manager_start_streaming_previous_utterance_data)dlsym(g_handle, + MA_WAKEUP_MANAGER_FUNC_START_STREAMING_PREVIOUS_UTTERANCE_DATA); + _wakeup_manager_interface.stop_streaming_previous_utterance_data = + (wakeup_manager_stop_streaming_previous_utterance_data)dlsym(g_handle, + MA_WAKEUP_MANAGER_FUNC_STOP_STREAMING_PREVIOUS_UTTERANCE_DATA); + _wakeup_manager_interface.start_streaming_follow_up_data = + (wakeup_manager_start_streaming_follow_up_data)dlsym(g_handle, + MA_WAKEUP_MANAGER_FUNC_START_STREAMING_FOLLOW_UP_DATA); + _wakeup_manager_interface.stop_streaming_follow_up_data = + (wakeup_manager_stop_streaming_follow_up_data)dlsym(g_handle, + MA_WAKEUP_MANAGER_FUNC_STOP_STREAMING_FOLLOW_UP_DATA); + _wakeup_manager_interface.get_audio_format = + (wakeup_manager_get_audio_format)dlsym(g_handle, + MA_WAKEUP_MANAGER_FUNC_GET_AUDIO_FORMAT); + _wakeup_manager_interface.set_wakeup_event_callback = + (wakeup_manager_set_wakeup_event_callback)dlsym(g_handle, + MA_WAKEUP_MANAGER_FUNC_SET_WAKEUP_EVENT_CALLBACK); + _wakeup_manager_interface.set_utterance_streaming_callback = + (wakeup_manager_set_utterance_streaming_callback)dlsym(g_handle, + MA_WAKEUP_MANAGER_FUNC_SET_UTTERANCE_STREAMING_CALLBACK); + _wakeup_manager_interface.set_previous_utterance_streaming_callback = + (wakeup_manager_set_previous_utterance_streaming_callback)dlsym(g_handle, + MA_WAKEUP_MANAGER_FUNC_SET_PREVIOUS_UTTERANCE_STREAMING_CALLBACK); + _wakeup_manager_interface.set_follow_up_streaming_callback = + (wakeup_manager_set_follow_up_streaming_callback)dlsym(g_handle, + MA_WAKEUP_MANAGER_FUNC_SET_FOLLOW_UP_STREAMING_CALLBACK); + _wakeup_manager_interface.set_speech_status_callback = + (wakeup_manager_set_speech_status_callback)dlsym(g_handle, + MA_WAKEUP_MANAGER_FUNC_SET_SPEECH_STATUS_CALLBACK); + _wakeup_manager_interface.set_error_callback = + (wakeup_manager_set_error_callback)dlsym(g_handle, + MA_WAKEUP_MANAGER_FUNC_SET_ERROR_CALLBACK); + int ret = -1; if (NULL != g_handle) { - int (*ws_initialize)(void); - ws_initialize = (int (*)(void))dlsym(g_handle, "wakeup_service_initialize"); - ret = ws_initialize(); - if (0 != ret) { - MAS_LOGE("[ERROR] Fail to initialize, ret(%d)", ret); + wakeup_manager_initialize func = _wakeup_manager_interface.initialize; + + if (NULL == func) { + MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_INITIALIZE); + } else { + ret = func(); + if (0 != ret) { + MAS_LOGE("[ERROR] Fail to initialize, ret(%d)", ret); + } } } else { MAS_LOGE("[ERROR] g_handle is not valid"); @@ -304,11 +363,14 @@ int multi_assistant_service_plugin_deinitialize(void) #endif int ret = -1; if (NULL != g_handle) { - int (*ws_deinitialize)(void); - ws_deinitialize = (int (*)(void))dlsym(g_handle, "wakeup_service_deinitialize"); - ret = ws_deinitialize(); - if (0 != ret) { - MAS_LOGE("[ERROR] Fail to deinitialize, ret(%d)", ret); + wakeup_manager_deinitialize func = _wakeup_manager_interface.deinitialize; + if (NULL == func) { + MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_DEINITIALIZE); + } else { + ret = func(); + if (0 != ret) { + MAS_LOGE("[ERROR] Fail to deinitialize, ret(%d)", ret); + } } dlclose(g_handle); @@ -324,11 +386,14 @@ int multi_assistant_service_plugin_set_language(const char* language) { int ret = -1; if (NULL != g_handle) { - int (*ws_set_language)(const char* language); - ws_set_language = (int (*)(const char* language))dlsym(g_handle, "wakeup_service_set_language"); - ret = ws_set_language(language); - if (0 != ret) { - MAS_LOGE("[ERROR] Fail to set langauge(%s), ret(%d)", language, ret); + wakeup_manager_set_language func = _wakeup_manager_interface.set_language; + if (NULL == func) { + MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_LANGUAGE); + } else { + ret = func(language); + if (0 != ret) { + MAS_LOGE("[ERROR] Fail to set langauge(%s), ret(%d)", language, ret); + } } } else { MAS_LOGE("[ERROR] g_handle is not valid"); @@ -340,11 +405,14 @@ int multi_assistant_service_plugin_set_wakeup_word(const char* language, const c { int ret = -1; if (NULL != g_handle) { - int (*ws_set_wakeup_word)(const char* language, const char* wakeup_word); - ws_set_wakeup_word = (int (*)(const char* language, const char* wakeup_word))dlsym(g_handle, "wakeup_service_set_wakeup_word"); - ret = ws_set_wakeup_word(language, wakeup_word); - if (0 != ret) { - MAS_LOGE("[ERROR] Fail to set wakeup word(%s)(%s), ret(%d)", language, wakeup_word, ret); + wakeup_manager_set_wakeup_word func = _wakeup_manager_interface.set_wakeup_word; + if (NULL == func) { + MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_WAKEUP_WORD); + } else { + ret = func(language, wakeup_word); + if (0 != ret) { + MAS_LOGE("[ERROR] Fail to set wakeup word(%s)(%s), ret(%d)", language, wakeup_word, ret); + } } } else { MAS_LOGE("[ERROR] g_handle is not valid"); @@ -352,15 +420,18 @@ int multi_assistant_service_plugin_set_wakeup_word(const char* language, const c return ret; } -int multi_assistant_service_plugin_start_recording(void) +int multi_assistant_service_plugin_activate(void) { int ret = -1; if (NULL != g_handle) { - int (*ws_start_recording)(void); - ws_start_recording = (int (*)(void))dlsym(g_handle, "wakeup_service_start_recording"); - ret = ws_start_recording(); - if (0 != ret) { - MAS_LOGE("[ERROR] Fail to start recording, ret(%d)", ret); + wakeup_manager_activate func = _wakeup_manager_interface.activate; + if (NULL == func) { + MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_ACTIVATE); + } else { + ret = func(); + if (0 != ret) { + MAS_LOGE("[ERROR] Fail to start recording, ret(%d)", ret); + } } } else { MAS_LOGE("[ERROR] g_handle is not valid"); @@ -368,15 +439,36 @@ int multi_assistant_service_plugin_start_recording(void) return ret; } -int multi_assistant_service_plugin_stop_recording(void) +int multi_assistant_service_plugin_deactivate(void) { int ret = -1; if (NULL != g_handle) { - int (*ws_stop_recording)(void); - ws_stop_recording = (int (*)(void))dlsym(g_handle, "wakeup_service_stop_recording"); - ret = ws_stop_recording(); - if (0 != ret) { - MAS_LOGE("[ERROR] Fail to stop recording, ret(%d)", ret); + wakeup_manager_deactivate func = _wakeup_manager_interface.deactivate; + if (NULL == func) { + MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_DEACTIVATE); + } else { + ret = func(); + if (0 != ret) { + MAS_LOGE("[ERROR] Fail to stop recording, ret(%d)", ret); + } + } + } else { + MAS_LOGE("[ERROR] g_handle is not valid"); + } + return ret; +} +int multi_assistant_service_plugin_update_voice_feedback_state(const char *appid, int state) +{ + int ret = -1; + if (NULL != g_handle) { + wakeup_manager_update_voice_feedback_state func = _wakeup_manager_interface.update_voice_feedback_state; + if (NULL == func) { + MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_UPDATE_VOICE_FEEDBACK_STATE); + } else { + ret = func(appid, state); + if (0 != ret) { + MAS_LOGE("[ERROR] Fail to stop recording, ret(%d)", ret); + } } } else { MAS_LOGE("[ERROR] g_handle is not valid"); @@ -384,15 +476,18 @@ int multi_assistant_service_plugin_stop_recording(void) return ret; } -int multi_assistant_service_plugin_cancel_recording(void) +int multi_assistant_service_plugin_update_result_state(const char *appid, int state) { int ret = -1; if (NULL != g_handle) { - int (*ws_cancel_recording)(void); - ws_cancel_recording = (int (*)(void))dlsym(g_handle, "wakeup_service_cancel_recording"); - ret = ws_cancel_recording(); - if (0 != ret) { - MAS_LOGE("[ERROR] Fail to cancel recording, ret(%d)", ret); + wakeup_manager_update_result_state func = _wakeup_manager_interface.update_result_state; + if (NULL == func) { + MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_UPDATE_RESULT_STATE); + } else { + ret = func(appid, state); + if (0 != ret) { + MAS_LOGE("[ERROR] Fail to stop recording, ret(%d)", ret); + } } } else { MAS_LOGE("[ERROR] g_handle is not valid"); @@ -400,15 +495,113 @@ int multi_assistant_service_plugin_cancel_recording(void) return ret; } -int multi_assistant_service_plugin_request_speech_data(void) +int multi_assistant_service_plugin_process_event(int event, void *data, int len) { int ret = -1; if (NULL != g_handle) { - int (*ws_request_speech_data)(void); - ws_request_speech_data = (int (*)(void))dlsym(g_handle, "wakeup_service_request_speech_data"); - ret = ws_request_speech_data(); - if (0 != ret) { - MAS_LOGE("[ERROR] Fail to request speech data, ret(%d)", ret); + wakeup_manager_process_event func = _wakeup_manager_interface.process_event; + if (NULL == func) { + MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_PROCESS_EVENT); + } else { + ret = func(event, data, len); + if (0 != ret) { + MAS_LOGE("[ERROR] Fail to stop recording, ret(%d)", ret); + } + } + } else { + MAS_LOGE("[ERROR] g_handle is not valid"); + } + return ret; +} + +int multi_assistant_service_plugin_start_streaming_utterance_data(void) +{ + int ret = -1; + if (NULL != g_handle) { + wakeup_manager_start_streaming_utterance_data func = _wakeup_manager_interface.start_streaming_utterance_data; + if (NULL == func) { + MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_START_STREAMING_UTTERANCE_DATA); + } else { + ret = func(); + if (0 != ret) { + MAS_LOGE("[ERROR] Fail to request speech data, ret(%d)", ret); + } + } + } else { + MAS_LOGE("[ERROR] g_handle is not valid"); + } + return ret; +} + +int multi_assistant_service_plugin_stop_streaming_utterance_data(void) +{ + int ret = -1; + if (NULL != g_handle) { + wakeup_manager_stop_streaming_utterance_data func = _wakeup_manager_interface.stop_streaming_utterance_data; + if (NULL == func) { + MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_STOP_STREAMING_UTTERANCE_DATA); + } else { + ret = func(); + if (0 != ret) { + MAS_LOGE("[ERROR] Fail to request speech data, ret(%d)", ret); + } + } + } else { + MAS_LOGE("[ERROR] g_handle is not valid"); + } + return ret; +} + +int multi_assistant_service_plugin_start_streaming_follow_up_data(void) +{ + int ret = -1; + if (NULL != g_handle) { + wakeup_manager_start_streaming_follow_up_data func = _wakeup_manager_interface.start_streaming_follow_up_data; + if (NULL == func) { + MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_START_STREAMING_FOLLOW_UP_DATA); + } else { + ret = func(); + if (0 != ret) { + MAS_LOGE("[ERROR] Fail to request speech data, ret(%d)", ret); + } + } + } else { + MAS_LOGE("[ERROR] g_handle is not valid"); + } + return ret; +} + +int multi_assistant_service_plugin_stop_streaming_follow_up_data(void) +{ + int ret = -1; + if (NULL != g_handle) { + wakeup_manager_stop_streaming_follow_up_data func = _wakeup_manager_interface.stop_streaming_follow_up_data; + if (NULL == func) { + MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_STOP_STREAMING_FOLLOW_UP_DATA); + } else { + ret = func(); + if (0 != ret) { + MAS_LOGE("[ERROR] Fail to request speech data, ret(%d)", ret); + } + } + } else { + MAS_LOGE("[ERROR] g_handle is not valid"); + } + return ret; +} + +int multi_assistant_service_plugin_get_recording_audio_format(int *rate, int *channel, int *audio_type) +{ + int ret = -1; + if (NULL != g_handle) { + wakeup_manager_get_audio_format func = _wakeup_manager_interface.get_audio_format; + if (NULL == func) { + MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_GET_AUDIO_FORMAT); + } else { + ret = func(rate, channel, audio_type); + if (0 != ret) { + MAS_LOGE("[ERROR] Fail to get recording audio format, ret(%d)", ret); + } } } else { MAS_LOGE("[ERROR] g_handle is not valid"); @@ -424,9 +617,21 @@ int multi_assistant_service_plugin_set_callbacks(void) return ret; } - ret = multi_assistant_service_plugin_set_speech_streaming_callback(__speech_streaming_cb, NULL); + ret = multi_assistant_service_plugin_set_utterance_streaming_callback(__audio_streaming_cb, NULL); + if (0 != ret) { + MAS_LOGE("Fail to set utterance streaming cb"); + return ret; + } + + ret = multi_assistant_service_plugin_set_previous_utterance_streaming_callback(__audio_streaming_cb, NULL); + if (0 != ret) { + MAS_LOGE("Fail to set previous utterance streaming cb"); + return ret; + } + + ret = multi_assistant_service_plugin_set_follow_up_streaming_callback(__audio_streaming_cb, NULL); if (0 != ret) { - MAS_LOGE("Fail to set speech data streaming cb"); + MAS_LOGE("Fail to set follow-up streaming cb"); return ret; } @@ -444,15 +649,18 @@ int multi_assistant_service_plugin_set_callbacks(void) return 0; } -int multi_assistant_service_plugin_get_recording_audio_format(int *rate, int *channel, int *audio_type) +int multi_assistant_service_plugin_set_wakeup_event_callback(wakeup_service_wakeup_event_cb callback, void* user_data) { int ret = -1; if (NULL != g_handle) { - int (*ws_get_recording_audio_format)(int *rate, int *channel, int *audio_type); - ws_get_recording_audio_format = (int (*)(int *rate, int *channel, int *audio_type))dlsym(g_handle, "wakeup_service_get_recording_audio_format"); - ret = ws_get_recording_audio_format(rate, channel, audio_type); - if (0 != ret) { - MAS_LOGE("[ERROR] Fail to get recording audio format, ret(%d)", ret); + wakeup_manager_set_wakeup_event_callback func = _wakeup_manager_interface.set_wakeup_event_callback; + if (NULL == func) { + MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_WAKEUP_EVENT_CALLBACK); + } else { + ret = func(callback, user_data); + if (0 != ret) { + MAS_LOGE("[ERROR] Fail to set wakeup event callback, ret(%d)", ret); + } } } else { MAS_LOGE("[ERROR] g_handle is not valid"); @@ -460,15 +668,18 @@ int multi_assistant_service_plugin_get_recording_audio_format(int *rate, int *ch return ret; } -int multi_assistant_service_plugin_set_wakeup_event_callback(wakeup_service_wakeup_event_cb callback, void* user_data) +int multi_assistant_service_plugin_set_utterance_streaming_callback(wakeup_service_speech_streaming_cb callback, void* user_data) { int ret = -1; if (NULL != g_handle) { - int (*ws_set_wakeup_event_callback)(wakeup_service_wakeup_event_cb callback, void* user_data); - ws_set_wakeup_event_callback = (int (*)(wakeup_service_wakeup_event_cb callback, void* user_data))dlsym(g_handle, "wakeup_service_set_wakeup_event_callback"); - ret = ws_set_wakeup_event_callback(callback, user_data); - if (0 != ret) { - MAS_LOGE("[ERROR] Fail to set wakeup event callback, ret(%d)", ret); + wakeup_manager_set_utterance_streaming_callback func = _wakeup_manager_interface.set_utterance_streaming_callback; + if (NULL == func) { + MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_UTTERANCE_STREAMING_CALLBACK); + } else { + ret = func(callback, user_data); + if (0 != ret) { + MAS_LOGE("[ERROR] Fail to set utterance streaming callback, ret(%d)", ret); + } } } else { MAS_LOGE("[ERROR] g_handle is not valid"); @@ -476,15 +687,37 @@ int multi_assistant_service_plugin_set_wakeup_event_callback(wakeup_service_wake return ret; } -int multi_assistant_service_plugin_set_speech_streaming_callback(wakeup_service_speech_streaming_cb callback, void* user_data) +int multi_assistant_service_plugin_set_previous_utterance_streaming_callback(wakeup_service_speech_streaming_cb callback, void* user_data) { int ret = -1; if (NULL != g_handle) { - int (*ws_set_speech_streaming_callback)(wakeup_service_speech_streaming_cb callback, void* user_data); - ws_set_speech_streaming_callback = (int (*)(wakeup_service_speech_streaming_cb callback, void* user_data))dlsym(g_handle, "wakeup_service_set_speech_streaming_callback"); - ret = ws_set_speech_streaming_callback(callback, user_data); - if (0 != ret) { - MAS_LOGE("[ERROR] Fail to speech streaming callback, ret(%d)", ret); + wakeup_manager_set_previous_utterance_streaming_callback func = _wakeup_manager_interface.set_previous_utterance_streaming_callback; + if (NULL == func) { + MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_PREVIOUS_UTTERANCE_STREAMING_CALLBACK); + } else { + ret = func(callback, user_data); + if (0 != ret) { + MAS_LOGE("[ERROR] Fail to set utterance streaming callback, ret(%d)", ret); + } + } + } else { + MAS_LOGE("[ERROR] g_handle is not valid"); + } + return ret; +} + +int multi_assistant_service_plugin_set_follow_up_streaming_callback(wakeup_service_speech_streaming_cb callback, void* user_data) +{ + int ret = -1; + if (NULL != g_handle) { + wakeup_manager_set_follow_up_streaming_callback func = _wakeup_manager_interface.set_follow_up_streaming_callback; + if (NULL == func) { + MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_FOLLOW_UP_STREAMING_CALLBACK); + } else { + ret = func(callback, user_data); + if (0 != ret) { + MAS_LOGE("[ERROR] Fail to set follow-up streaming callback, ret(%d)", ret); + } } } else { MAS_LOGE("[ERROR] g_handle is not valid"); @@ -496,11 +729,14 @@ int multi_assistant_service_plugin_set_speech_status_callback(wakeup_service_spe { int ret = -1; if (NULL != g_handle) { - int (*ws_set_speech_status_callback)(wakeup_service_speech_status_cb callback, void* user_data); - ws_set_speech_status_callback = (int (*)(wakeup_service_speech_status_cb callback, void* user_data))dlsym(g_handle, "wakeup_service_set_speech_status_callback"); - ret = ws_set_speech_status_callback(callback, user_data); - if (0 != ret) { - MAS_LOGE("[ERROR] Fail to set speech status callback, ret(%d)", ret); + wakeup_manager_set_speech_status_callback func = _wakeup_manager_interface.set_speech_status_callback; + if (NULL == func) { + MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_SPEECH_STATUS_CALLBACK); + } else { + ret = func(callback, user_data); + if (0 != ret) { + MAS_LOGE("[ERROR] Fail to set speech status callback, ret(%d)", ret); + } } } return ret; @@ -510,11 +746,14 @@ int multi_assistant_service_plugin_set_error_callback(wakeup_service_error_cb ca { int ret = -1; if (NULL != g_handle) { - int (*ws_set_error_callback)(wakeup_service_error_cb callback, void* user_data); - ws_set_error_callback = (int (*)(wakeup_service_error_cb callback, void* user_data))dlsym(g_handle, "wakeup_service_set_error_callback"); - ret = ws_set_error_callback(callback, user_data); - if (0 != ret) { - MAS_LOGE("[ERROR] Fail to set error callback, ret(%d)", ret); + wakeup_manager_set_error_callback func = _wakeup_manager_interface.set_error_callback; + if (NULL == func) { + MAS_LOGE("[ERROR] symbol lookup failed : %s", MA_WAKEUP_MANAGER_FUNC_SET_ERROR_CALLBACK); + } else { + ret = func(callback, user_data); + if (0 != ret) { + MAS_LOGE("[ERROR] Fail to set error callback, ret(%d)", ret); + } } } return ret; -- 2.34.1