From 2e716bcc29f548c0ef8e550928a1194a69b2fc45 Mon Sep 17 00:00:00 2001 From: Suyeon Hwang Date: Thu, 20 May 2021 14:24:25 +0900 Subject: [PATCH 01/16] Fix order of callbacks when error occurs on server Change-Id: Ica7d7246be36574221ea9b5fc041785b54f52570 Signed-off-by: Suyeon Hwang --- server/vcd_server.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/vcd_server.c b/server/vcd_server.c index 4355e2d..8c290cf 100644 --- a/server/vcd_server.c +++ b/server/vcd_server.c @@ -1104,7 +1104,6 @@ static void __vcd_server_nlu_result_cb(vce_result_event_e event, const char* nlu int vcd_send_error(vce_error_e error, const char* msg, void *user_data) { SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Engine Error cb - reason(%d), msg(%s)", error, msg); - ecore_main_loop_thread_safe_call_async(__cancel_by_error, NULL); char* error_msg = NULL; if (NULL != msg) { @@ -1125,6 +1124,8 @@ int vcd_send_error(vce_error_e error, const char* msg, void *user_data) error_msg = NULL; } + ecore_main_loop_thread_safe_call_async(__cancel_by_error, NULL); + return ret; } -- 2.7.4 From 153bf4899025a892153d79a9e27bef6f59e2ca6a Mon Sep 17 00:00:00 2001 From: "wn.jang" Date: Fri, 21 May 2021 10:51:56 +0900 Subject: [PATCH 02/16] Fix bug detected from static analysis tool Change-Id: I340a8f7a74cafb64ecb741a3a7c46ed56849d5f2 --- server/vcd_recorder.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/server/vcd_recorder.c b/server/vcd_recorder.c index 956bdbe..f532aca 100644 --- a/server/vcd_recorder.c +++ b/server/vcd_recorder.c @@ -542,6 +542,7 @@ int vcd_recorder_create(vcd_recoder_audio_cb audio_cb, vcd_recorder_interrupt_cb int vcd_recorder_destroy() { ma_ap_deinitialize(); + int ret = -1; if (VCD_RECORDER_STATE_RECORDING == g_recorder_state) { if (0 == strncmp(VCE_AUDIO_ID_BLUETOOTH, g_current_audio_type, strlen(VCE_AUDIO_ID_BLUETOOTH))) { #ifdef TV_BT_MODE @@ -552,12 +553,15 @@ int vcd_recorder_destroy() UnRegisterMSFAudioCallback(); #endif } else { - audio_in_unprepare(g_audio_h); + ret = audio_in_unprepare(g_audio_h); + if (AUDIO_IO_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to unprepare audio : %d", ret); + } } g_recorder_state = VCD_RECORDER_STATE_READY; } - int ret = sound_manager_remove_device_connection_changed_cb(g_device_id); + ret = sound_manager_remove_device_connection_changed_cb(g_device_id); if (0 != ret) SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to remove device connection changed callback, ret(%d)", ret); g_device_id = -1; -- 2.7.4 From e8f29e81d049e207320a5e451cd000b036208ba6 Mon Sep 17 00:00:00 2001 From: Suyeon Hwang Date: Fri, 21 May 2021 20:11:31 +0900 Subject: [PATCH 03/16] Remove memory leakage to avoid dangling Change-Id: I3ed4e6772cb6042076b0b78addcd384051d9232c Signed-off-by: Suyeon Hwang --- engine-parser/src/vc-engine-parser.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/engine-parser/src/vc-engine-parser.c b/engine-parser/src/vc-engine-parser.c index 8af3cd4..16aabc1 100644 --- a/engine-parser/src/vc-engine-parser.c +++ b/engine-parser/src/vc-engine-parser.c @@ -549,6 +549,10 @@ int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList * if (NULL != home_dir) { LOGD("[DEBUG] uid(%d), gid(%d), user_type(%s), home_dir(%s)", uid, gid, user_type, home_dir); + FREE(g_dir_config_base) + FREE(g_dir_home) + FREE(g_dir_engine_base) + FREE(g_dir_engine_info) g_dir_config_base = (char*)calloc(strlen(home_dir) + 14, sizeof(char)); g_dir_home = (char*)calloc(strlen(home_dir) + 17, sizeof(char)); g_dir_engine_base = (char*)calloc(strlen(home_dir) + 21, sizeof(char)); @@ -578,11 +582,6 @@ int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList * LOGE("[ERROR] Fail to make engine info file"); } - FREE(g_dir_config_base) - FREE(g_dir_home) - FREE(g_dir_engine_base) - FREE(g_dir_engine_info) - G_FREE(home_dir) } @@ -790,6 +789,7 @@ int PKGMGR_MDPARSER_PLUGIN_UNINSTALL(const char *pkgid, const char *appid, GList } if (NULL != home_dir) { + G_FREE(g_dir_engine_info) g_dir_engine_info = (char*)calloc(strlen(home_dir) + 33, sizeof(char)); if (NULL == g_dir_engine_info) { gum_user_service_list_free(users); @@ -814,7 +814,6 @@ int PKGMGR_MDPARSER_PLUGIN_UNINSTALL(const char *pkgid, const char *appid, GList } G_FREE(home_dir) - G_FREE(g_dir_engine_info) } G_FREE(user_type) -- 2.7.4 From bdf1a1c5bf5e64750b9b929cda241b33e4ba0284 Mon Sep 17 00:00:00 2001 From: Suyeon Hwang Date: Fri, 21 May 2021 20:14:29 +0900 Subject: [PATCH 04/16] Remove access to avoid toctou problem Change-Id: Ife99dd9f58a3f4fd8aee73a276bbd5703c39afec Signed-off-by: Suyeon Hwang --- engine-parser/src/vc-engine-parser.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/engine-parser/src/vc-engine-parser.c b/engine-parser/src/vc-engine-parser.c index 16aabc1..6663375 100644 --- a/engine-parser/src/vc-engine-parser.c +++ b/engine-parser/src/vc-engine-parser.c @@ -301,11 +301,9 @@ static int __remove_engine_info_xml(const char *pkgid, gchar *ut, uid_t uid) char path[256] = {'\0',}; snprintf(path, 256, "%s/%s.xml", dir_engine_info, pkgid); - if (0 == access(path, F_OK)) { - LOGD("Remove engine info xml(%s)", path); - if (0 != remove(path)) { - LOGE("[ERROR] Fail to remove engine info xml(%s)", path); - } + LOGD("Remove engine info xml(%s)", path); + if (0 != remove(path)) { + LOGE("[ERROR] Fail to remove engine info xml(%s)", path); } FREE(dir_engine_info) -- 2.7.4 From c32a3ec54cf5675b6a8a1b29f3921ed0cea53fa7 Mon Sep 17 00:00:00 2001 From: Suyeon Hwang Date: Wed, 26 May 2021 16:37:07 +0900 Subject: [PATCH 05/16] Update version (1.65.0) Change-Id: I3ca53fc771a79f89ab346721a459889e1451a044 Signed-off-by: Suyeon Hwang --- CMakeLists.txt | 2 +- packaging/voice-control.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 88b976f..837437a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,7 +26,7 @@ PROJECT(vc) SET(PREFIX ${CMAKE_INSTALL_PREFIX}) SET(EXEC_PREFIX "${PREFIX}") -SET(VERSION 1.60.13) +SET(VERSION 1.65.0) FIND_PROGRAM(UNAME NAMES uname) EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH") diff --git a/packaging/voice-control.spec b/packaging/voice-control.spec index 689b277..0e0f10e 100644 --- a/packaging/voice-control.spec +++ b/packaging/voice-control.spec @@ -1,6 +1,6 @@ Name: voice-control Summary: Voice control client library and daemon -Version: 1.60.13 +Version: 1.65.0 Release: 1 Group: Graphics & UI Framework/Voice Framework License: Apache-2.0 -- 2.7.4 From 676722705c7fcb30557bb720c5782ec858f108b2 Mon Sep 17 00:00:00 2001 From: Suyeon Hwang Date: Fri, 17 Jul 2020 15:19:50 +0900 Subject: [PATCH 06/16] Set and unset all audio feed callbacks on create/destroy Change-Id: Ia79cd65c242fe5392c615d81596f5b13217c7192 Signed-off-by: Suyeon Hwang --- server/vcd_recorder.c | 185 ++++++++++---------------------------------------- 1 file changed, 36 insertions(+), 149 deletions(-) diff --git a/server/vcd_recorder.c b/server/vcd_recorder.c index f532aca..f122ef6 100644 --- a/server/vcd_recorder.c +++ b/server/vcd_recorder.c @@ -536,6 +536,24 @@ int vcd_recorder_create(vcd_recoder_audio_cb audio_cb, vcd_recorder_interrupt_cb ma_ap_initialize(); ma_ap_set_audio_streaming_cb(audio_streaming_cb, NULL); + /* Set audio feed callback */ +#ifdef TV_BT_MODE + if (BT_ERROR_NONE != bt_hid_set_audio_data_receive_cb(_bt_hid_audio_data_receive_cb, NULL)) { + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail bt_hid_set_audio_data_receive_cb()"); + } +#endif +#ifdef TV_FFV_MODE + if (g_farfieldvoice_h) { + SLOG(LOG_INFO, TAG_VCD, "[Recorder INFO] Register farfield voice audio callback"); + farfield_voice_register_audio_cb(g_farfieldvoice_h, _ffv_audio_function_cb, NULL); + } +#endif +#ifdef TV_MSF_WIFI_MODE + if (MSFResult_OK != RegisterMSFAudioCallback(__msf_wifi_audio_data_receive_cb, NULL)) { + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to start Wi-Fi audio"); + } +#endif + return 0; } @@ -544,21 +562,7 @@ int vcd_recorder_destroy() ma_ap_deinitialize(); int ret = -1; if (VCD_RECORDER_STATE_RECORDING == g_recorder_state) { - if (0 == strncmp(VCE_AUDIO_ID_BLUETOOTH, g_current_audio_type, strlen(VCE_AUDIO_ID_BLUETOOTH))) { -#ifdef TV_BT_MODE - bt_hid_unset_audio_data_receive_cb(); -#endif - } else if (0 == strncmp(VCE_AUDIO_ID_WIFI, g_current_audio_type, strlen(VCE_AUDIO_ID_WIFI))) { -#ifdef TV_MSF_WIFI_MODE - UnRegisterMSFAudioCallback(); -#endif - } else { - ret = audio_in_unprepare(g_audio_h); - if (AUDIO_IO_ERROR_NONE != ret) { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to unprepare audio : %d", ret); - } - } - g_recorder_state = VCD_RECORDER_STATE_READY; + vcd_recorder_stop(); } ret = sound_manager_remove_device_connection_changed_cb(g_device_id); @@ -576,6 +580,11 @@ int vcd_recorder_destroy() SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to audio in destroy, ret(%d)", ret); g_audio_h = NULL; + +#ifdef TV_MSF_WIFI_MODE + UnRegisterMSFAudioCallback(); +#endif + #ifdef TV_FFV_MODE if (NULL != g_farfieldvoice_h) { SLOG(LOG_INFO, TAG_VCD, "[Recorder INFO] Unregister farfield voice"); @@ -586,9 +595,7 @@ int vcd_recorder_destroy() #ifdef TV_BT_MODE bt_hid_unset_audio_data_receive_cb(); - bt_hid_host_deinitialize(); - bt_product_deinit(); #endif @@ -607,7 +614,7 @@ int vcd_recorder_destroy() fclose(g_pcm_fp); g_pcm_fp = NULL; - return 0; + return VCD_ERROR_NONE; } int vcd_recorder_set(const char* audio_type, vce_audio_type_e type, int rate, int channel) @@ -1120,64 +1127,18 @@ int vcd_recorder_start() } g_buffer_count = 0; - - SLOG(LOG_INFO, TAG_VCD, "[Recorder] Enter, recorder state(%d)", g_recorder_state); - - if (VCD_RECORDER_STATE_RECORDING == g_recorder_state) return 0; - - bool started = false; - SLOG(LOG_INFO, TAG_VCD, "[Recorder] audio type : %s", g_current_audio_type); - - if (NULL != g_current_audio_type) { - if (0 == strncmp(VCE_AUDIO_ID_BLUETOOTH, g_current_audio_type, strlen(VCE_AUDIO_ID_BLUETOOTH))) { #ifdef TV_BT_MODE - if (BT_ERROR_NONE != bt_hid_set_audio_data_receive_cb(_bt_hid_audio_data_receive_cb, NULL)) { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail bt_hid_set_audio_data_receive_cb()"); - } - SLOG(LOG_INFO, TAG_VCD, "[Recorder] Start bt audio"); - g_bt_extend_count = 0; - started = true; + g_bt_extend_count = 0; #endif - } else if (0 == strncmp(VCE_AUDIO_ID_FFV, g_current_audio_type, strlen(VCE_AUDIO_ID_FFV))) { - SLOG(LOG_INFO, TAG_VCD, "[Recorder] call farfield_voice_register_audio_cb() function"); -#ifdef TV_FFV_MODE - if (g_farfieldvoice_h) { - SLOG(LOG_INFO, TAG_VCD, "[Recorder INFO] Register farfield voice audio callback"); - farfield_voice_register_audio_cb(g_farfieldvoice_h, _ffv_audio_function_cb, NULL); - } -#endif - started = true; - } else if (0 == strncmp(VCE_AUDIO_ID_WIFI, g_current_audio_type, strlen(VCE_AUDIO_ID_WIFI))) { - SLOG(LOG_INFO, TAG_VCD, "[Recorder] call RegisterMSFAudioCallback() function"); -#ifdef TV_MSF_WIFI_MODE - ret = RegisterMSFAudioCallback(__msf_wifi_audio_data_receive_cb, NULL); - SLOG(LOG_ERROR, TAG_VCD, "[Recorder] ret = %d", ret); - if (MSFResult_OK == ret) { - started = true; - } else { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to start Wi-Fi audio"); - return VCD_ERROR_OPERATION_FAILED; - } -#endif - } + SLOG(LOG_INFO, TAG_VCD, "[Recorder] Enter, recorder state(%d)", g_recorder_state); + if (VCD_RECORDER_STATE_RECORDING == g_recorder_state) { + return VCD_ERROR_NONE; } - SLOG(LOG_INFO, TAG_VCD, "[Recorder] started = %d", started); - if (false == started) { + if (NULL != g_current_audio_type && 0 == strncmp(VCE_AUDIO_ID_NONE, g_current_audio_type, strlen(VCE_AUDIO_ID_NONE))) { /* check audio format */ __check_audio_format(); -#if 0 - ret = sound_manager_acquire_focus(g_stream_info_h, SOUND_STREAM_FOCUS_FOR_RECORDING, NULL); - if (SOUND_MANAGER_ERROR_NONE != ret) { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to acquire focus : %d", ret); - } else { - ret = audio_in_set_sound_stream_info(g_audio_h, g_stream_info_h); - if (AUDIO_IO_ERROR_NONE != ret) { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to set stream info : %d", ret); - } - } -#endif ret = audio_in_prepare(g_audio_h); if (AUDIO_IO_ERROR_NONE != ret) { @@ -1226,7 +1187,7 @@ int vcd_recorder_start() SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] File not found!"); } #endif - return 0; + return VCD_ERROR_NONE; } int vcd_recorder_stop() @@ -1240,7 +1201,7 @@ int vcd_recorder_stop() } if (VCD_RECORDER_STATE_READY == g_recorder_state) - return 0; + return VCD_ERROR_NONE; g_recorder_state = VCD_RECORDER_STATE_READY; @@ -1256,91 +1217,17 @@ int vcd_recorder_stop() fclose(g_pcm_fp); g_pcm_fp = NULL; - bool stoped = false; - - if (NULL != g_current_audio_type) { - if (0 == strncmp(VCE_AUDIO_ID_BLUETOOTH, g_current_audio_type, strlen(VCE_AUDIO_ID_BLUETOOTH))) { -#ifdef TV_BT_MODE - // Unregister callback for bluetooth audio - bt_hid_unset_audio_data_receive_cb(); - - int bt_retry = 0; - while (5 > bt_retry) { - ret = bt_hid_rc_stop_sending_voice(NULL); - if (BT_ERROR_NONE == ret) { - SLOG(LOG_INFO, TAG_VCD, "[Recorder] Stop bt audio recorder"); - stoped = true; - break; - } else if (BT_ERROR_NOW_IN_PROGRESS == ret) { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail bt_hid_rc_stop_sending_voice()"); - usleep(50000); - bt_retry++; - } else { - break; - } - } - if (NULL != g_current_audio_type && - (!strncmp(g_current_audio_type, VCE_AUDIO_ID_BLUETOOTH, sizeof(VCE_AUDIO_ID_BLUETOOTH)) || - !strncmp(g_current_audio_type, VCE_AUDIO_ID_FFV, sizeof(VCE_AUDIO_ID_FFV)) || - !strncmp(g_current_audio_type, VCE_AUDIO_ID_WIFI, sizeof(VCE_AUDIO_ID_WIFI)))) { - SLOG(LOG_INFO, TAG_VCD, "[DEBUG] Recorder reset to NONE"); - vcd_recorder_set(VCE_AUDIO_ID_NONE, g_audio_type, g_audio_rate, g_audio_channel); - } - - if (false == stoped) { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to stop bt audio"); - return VCD_ERROR_OPERATION_FAILED; - } -#endif - } else if (0 == strncmp(VCE_AUDIO_ID_FFV, g_current_audio_type, strlen(VCE_AUDIO_ID_FFV))) { - SLOG(LOG_INFO, TAG_VCD, "[DEBUG] FFV"); -#ifdef TV_FFV_MODE - // Unregister callback for far field audio - if (g_farfieldvoice_h) - farfield_voice_unregister_audio_cb(g_farfieldvoice_h); -#endif - if (NULL != g_current_audio_type && - (!strncmp(g_current_audio_type, VCE_AUDIO_ID_BLUETOOTH, sizeof(VCE_AUDIO_ID_BLUETOOTH)) || - !strncmp(g_current_audio_type, VCE_AUDIO_ID_FFV, sizeof(VCE_AUDIO_ID_FFV)) || - !strncmp(g_current_audio_type, VCE_AUDIO_ID_WIFI, sizeof(VCE_AUDIO_ID_WIFI)))) { - SLOG(LOG_INFO, TAG_VCD, "[DEBUG] Recorder reset to NONE"); - vcd_recorder_set(VCE_AUDIO_ID_NONE, g_audio_type, g_audio_rate, g_audio_channel); - } - stoped = true; - } else if (0 == strncmp(VCE_AUDIO_ID_WIFI, g_current_audio_type, strlen(VCE_AUDIO_ID_WIFI))) { -#ifdef TV_MSF_WIFI_MODE - // Unregister callback for wifi audio - UnRegisterMSFAudioCallback(); - - if (NULL != g_current_audio_type && - (!strncmp(g_current_audio_type, VCE_AUDIO_ID_BLUETOOTH, sizeof(VCE_AUDIO_ID_BLUETOOTH)) || - !strncmp(g_current_audio_type, VCE_AUDIO_ID_WIFI, sizeof(VCE_AUDIO_ID_WIFI)))) { - SLOG(LOG_INFO, TAG_VCD, "[DEBUG] Recorder reset to NONE"); - vcd_recorder_set(VCE_AUDIO_ID_NONE, g_audio_type, g_audio_rate, g_audio_channel); - } - stoped = true; -#endif - } else { - SLOG(LOG_INFO, TAG_VCD, "[Recorder] current audio type is NONE"); - } - } - - if (false == stoped) { + if (NULL != g_current_audio_type && 0 == strncmp(VCE_AUDIO_ID_NONE, g_current_audio_type, strlen(VCE_AUDIO_ID_NONE))) { ret = audio_in_unprepare(g_audio_h); if (AUDIO_IO_ERROR_NONE != ret) { SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to stop audio : %d", ret); return VCD_ERROR_OPERATION_FAILED; } - -#if 0 - ret = sound_manager_release_focus(g_stream_info_h, SOUND_STREAM_FOCUS_FOR_RECORDING, NULL); - if (SOUND_MANAGER_ERROR_NONE != ret) { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to release focus : %d", ret); - } -#endif } - return 0; + vcd_recorder_set(VCE_AUDIO_ID_NONE, g_audio_type, g_audio_rate, g_audio_channel); + + return VCD_ERROR_NONE; } int vcd_recorder_get_state() -- 2.7.4 From c6c8b07de7bb0e323a156cb68c3fb29578052c82 Mon Sep 17 00:00:00 2001 From: Suyeon Hwang Date: Mon, 25 May 2020 11:39:44 +0900 Subject: [PATCH 07/16] Introduce dependency audio manager In some cases, developer may need to change the audio source by device. Dependency audio manager can allow developer to change the audio source. This patch introduces dependency audio manager and default audio manager module. Default audio manager uses tizen audio IO interface as audio source. Change-Id: Ia757539f8a4b37be18796114b582f30813c05ebd Signed-off-by: Suyeon Hwang --- CMakeLists.txt | 7 +- audio-manager/CMakeLists.txt | 22 ++ audio-manager/inc/vc_audio_manager.h | 44 ++++ audio-manager/src/vc_audio_manager.cpp | 278 +++++++++++++++++++++ packaging/voice-control.spec | 2 +- server/CMakeLists.txt | 1 + server/dependency_audio_manager.cpp | 217 ++++++++++++++++ server/dependency_audio_manager.h | 72 ++++++ server/vcd_recorder.c | 440 ++++++++++----------------------- 9 files changed, 766 insertions(+), 317 deletions(-) create mode 100644 audio-manager/CMakeLists.txt create mode 100644 audio-manager/inc/vc_audio_manager.h create mode 100644 audio-manager/src/vc_audio_manager.cpp create mode 100644 server/dependency_audio_manager.cpp create mode 100644 server/dependency_audio_manager.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 837437a..091ba64 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,12 +48,12 @@ INCLUDE(FindPkgConfig) IF("${_TV_PRODUCT}" STREQUAL "TRUE") pkg_check_modules(pkgs REQUIRED aul buxton2 capi-appfw-app-control capi-appfw-app-manager capi-base-common capi-media-audio-io capi-media-sound-manager ecore-wl2 - capi-network-bluetooth capi-network-bluetooth-tv capi-system-info cynara-client cynara-session dbus-1 db-util dlog ecore glib-2.0 json-glib-1.0 libgum libtzplatform-config libxml-2.0 sqlite3 vconf msfapi farfield-voice-api multi-assistant gmock + capi-network-bluetooth capi-network-bluetooth-tv capi-system-info cynara-client cynara-session dbus-1 db-util dlog ecore glib-2.0 json-glib-1.0 libgum libtzplatform-config libxml-2.0 sqlite3 vconf msfapi farfield-voice-api gmock ) ELSE() pkg_check_modules(pkgs REQUIRED aul buxton2 capi-appfw-app-control capi-appfw-app-manager capi-base-common capi-media-audio-io capi-media-sound-manager ecore-wl2 - capi-system-info cynara-client cynara-session dbus-1 db-util dlog ecore glib-2.0 json-glib-1.0 libgum libtzplatform-config libxml-2.0 sqlite3 vconf multi-assistant gmock + capi-system-info cynara-client cynara-session dbus-1 db-util dlog ecore glib-2.0 json-glib-1.0 libgum libtzplatform-config libxml-2.0 sqlite3 vconf gmock ) ENDIF() @@ -70,6 +70,9 @@ ADD_SUBDIRECTORY(server) ## Engine Parser ## ADD_SUBDIRECTORY(engine-parser) +## Dependency audio manager ## +ADD_SUBDIRECTORY(audio-manager) + INSTALL(FILES ${CMAKE_SOURCE_DIR}/voice-control.info DESTINATION ${TZ_SYS_RO_SHARE}/parser-plugins) ## config ## diff --git a/audio-manager/CMakeLists.txt b/audio-manager/CMakeLists.txt new file mode 100644 index 0000000..5ac8b25 --- /dev/null +++ b/audio-manager/CMakeLists.txt @@ -0,0 +1,22 @@ +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}) +INCLUDE_DIRECTORIES(./inc) + +FOREACH(flag ${pkgs_CFLAGS}) +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") +SET(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") +## for LCOV +#SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall -Werror -fprofile-arcs -ftest-coverage") +#SET(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall -Werror -fprofile-arcs -ftest-coverage") + +SET(SRCS + src/vc_audio_manager.cpp +) + +## Executable ## +ADD_LIBRARY("${PROJECT_NAME}-audio-manager" SHARED ${SRCS}) +TARGET_LINK_LIBRARIES("${PROJECT_NAME}-audio-manager" -ldl ${pkgs_LDFLAGS}) + +## Install +INSTALL(TARGETS "${PROJECT_NAME}-audio-manager" DESTINATION ${TZ_SYS_RO_SHARE}/voice/vc/1.0/dependency-audio-manager/) diff --git a/audio-manager/inc/vc_audio_manager.h b/audio-manager/inc/vc_audio_manager.h new file mode 100644 index 0000000..6b7cdfd --- /dev/null +++ b/audio-manager/inc/vc_audio_manager.h @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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 __VC_AUDIO_MANAGER_H__ +#define __VC_AUDIO_MANAGER_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "vc_audio_manager" + +typedef int (*dependency_audio_manager_feed_audio_data)(const void* data, const unsigned int length); + +int vcd_dependency_initialize(sound_stream_info_h stream_info_h, dependency_audio_manager_feed_audio_data callback); +int vcd_dependency_deinitialize(void); +int vcd_dependency_set_audio_info(sound_stream_info_h stream_info_h, const char* audio_source_type, vce_audio_type_e type, int rate, int channel); +int vcd_dependency_start_recording(void); +int vcd_dependency_stop_recording(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __VC_AUDIO_MANAGER_H__ */ diff --git a/audio-manager/src/vc_audio_manager.cpp b/audio-manager/src/vc_audio_manager.cpp new file mode 100644 index 0000000..89a1788 --- /dev/null +++ b/audio-manager/src/vc_audio_manager.cpp @@ -0,0 +1,278 @@ +/** + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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 "vce.h" +#include "vc_audio_manager.h" + + +#define FOCUS_SERVER_READY "/tmp/.focus_server_ready" +#define VCE_AUDIO_ID_NONE "VC_AUDIO_ID_NONE" /**< None audio id */ + +using namespace std; + +static dependency_audio_manager_feed_audio_data g_feed_audio_data = nullptr; + +static audio_in_h g_audio_h = nullptr; +static vce_audio_type_e g_audio_type = VCE_AUDIO_TYPE_PCM_S16_LE; +static int g_audio_rate = 0; +static int g_audio_channel = 0; +static char* g_audio_source_type = nullptr; + +volatile static bool g_is_recording = false; + + +static bool __convert_audio_channel(int channel, audio_channel_e* output) +{ + audio_channel_e audio_ch = AUDIO_CHANNEL_MONO; + + switch (channel) { + case 1: audio_ch = AUDIO_CHANNEL_MONO; break; + case 2: audio_ch = AUDIO_CHANNEL_STEREO; break; + case 3: audio_ch = AUDIO_CHANNEL_MULTI_3; break; + case 4: audio_ch = AUDIO_CHANNEL_MULTI_4; break; + case 5: audio_ch = AUDIO_CHANNEL_MULTI_5; break; + case 6: audio_ch = AUDIO_CHANNEL_MULTI_6; break; + case 7: audio_ch = AUDIO_CHANNEL_MULTI_7; break; + case 8: audio_ch = AUDIO_CHANNEL_MULTI_8; break; + default: + SLOG(LOG_ERROR, LOG_TAG, "[ERROR] Input channel is not supported. [channel(%d)]", channel); + return false; + } + + *output = audio_ch; + return true; +} + +static bool __convert_audio_sample_type(vce_audio_type_e audio_type, audio_sample_type_e* output) +{ + audio_sample_type_e audio_sample_type = AUDIO_SAMPLE_TYPE_S16_LE; + + switch (audio_type) { + case VCE_AUDIO_TYPE_PCM_S16_LE: + audio_sample_type = AUDIO_SAMPLE_TYPE_S16_LE; + break; + case VCE_AUDIO_TYPE_PCM_U8: + audio_sample_type = AUDIO_SAMPLE_TYPE_U8; + break; + default: + SLOG(LOG_ERROR, LOG_TAG, "[ERROR] Invalid Audio Type. [type(%d)]", audio_type); + return false; + } + + *output = audio_sample_type; + return true; +} + +static Eina_Bool __recorder_timer_func(void *data) +{ + const int FRAME_LENGTH = 160; + const int BUFFER_LENGTH = FRAME_LENGTH * 2; + + if (g_is_recording && nullptr != g_feed_audio_data) { + unsigned char buffer[BUFFER_LENGTH]; + memset(buffer, '\0', BUFFER_LENGTH); + + int read_bytes = audio_in_read(g_audio_h, buffer, BUFFER_LENGTH); + if (0 > read_bytes) { + SLOG(LOG_WARN, LOG_TAG, "[WARNING] Fail to read audio : %d", read_bytes); + return ECORE_CALLBACK_DONE; + } + + // TODO: check return value? + g_feed_audio_data(buffer, read_bytes); + } else { + SLOG(LOG_DEBUG, LOG_TAG, "[DEBUG] Recording is finished"); + return ECORE_CALLBACK_DONE; + } + + return ECORE_CALLBACK_RENEW; +} + +int vcd_dependency_initialize(sound_stream_info_h stream_info_h, dependency_audio_manager_feed_audio_data callback) +{ + int ret = 0; + + g_audio_type = VCE_AUDIO_TYPE_PCM_S16_LE; + g_audio_rate = 16000; + g_audio_channel = 1; + + audio_channel_e audio_ch = AUDIO_CHANNEL_MONO; + audio_sample_type_e audio_sample_type = AUDIO_SAMPLE_TYPE_U8; + + SLOG(LOG_INFO, LOG_TAG, "[Recorder] Audio type(%d) rate(%d) channel(%d)", g_audio_type, g_audio_rate, g_audio_channel); + + if (false == __convert_audio_channel(g_audio_channel, &audio_ch)) { + return VCE_ERROR_INVALID_PARAMETER; + } + + if (false == __convert_audio_sample_type(g_audio_type, &audio_sample_type)) { + return VCE_ERROR_INVALID_PARAMETER; + } + + ret = audio_in_create(g_audio_rate, audio_ch, audio_sample_type, &g_audio_h); + if (AUDIO_IO_ERROR_NONE != ret) { + SLOG(LOG_ERROR, LOG_TAG, "[Recorder ERROR] Rate(%d) Channel(%d) Type(%d)", g_audio_rate, audio_ch, audio_sample_type); + SLOG(LOG_ERROR, LOG_TAG, "[Recorder ERROR] Fail to create audio handle : %d", ret); + } + + if (0 != audio_in_set_sound_stream_info(g_audio_h, stream_info_h)) { + SLOG(LOG_ERROR, LOG_TAG, "[Recorder ERROR] Fail to set stream info"); + } + + g_audio_source_type = strdup(VCE_AUDIO_ID_NONE); + g_feed_audio_data = callback; + g_is_recording = false; + + return ret; +} + +int vcd_dependency_deinitialize(void) +{ + int ret = 0; + if (g_is_recording) { + ret = audio_in_unprepare(g_audio_h); + if (0 != ret) { + SLOG(LOG_ERROR, LOG_TAG, "[Recorder ERROR] Fail to stop audio : %d", ret); + } + g_is_recording = false; + } + + ret = audio_in_destroy(g_audio_h); + if (0 != ret) { + SLOG(LOG_ERROR, LOG_TAG, "[Recorder ERROR] Fail to audio in destroy, ret(%d)", ret); + } + + g_audio_h = nullptr; + g_feed_audio_data = nullptr; + + g_audio_type = VCE_AUDIO_TYPE_PCM_S16_LE; + g_audio_rate = 0; + g_audio_channel = 0; + + return ret; +} + +int vcd_dependency_set_audio_info(sound_stream_info_h stream_info_h, const char* audio_source_type, vce_audio_type_e type, int rate, int channel) +{ + if (nullptr == audio_source_type) { + SLOG(LOG_ERROR, LOG_TAG, "[ERROR] Invalid audio source type."); + return VCE_ERROR_INVALID_PARAMETER; + } + + if (nullptr == g_audio_h || nullptr == g_audio_source_type) { + SLOG(LOG_ERROR, LOG_TAG, "[ERROR] Audio in handle is not valid."); + return VCE_ERROR_INVALID_STATE; + } + + if (0 == strncmp(g_audio_source_type, audio_source_type, strlen(g_audio_source_type)) || + (g_audio_type == type && g_audio_rate == rate && g_audio_channel == channel)) { + SLOG(LOG_INFO, LOG_TAG, "[DEBUG] No changed information"); + return VCE_ERROR_NONE; + } + + SLOG(LOG_INFO, LOG_TAG, "[Recorder] New audio type(%d) rate(%d) channel(%d)", type, rate, channel); + audio_in_destroy(g_audio_h); + + audio_channel_e audio_ch = AUDIO_CHANNEL_MONO; + audio_sample_type_e audio_sample_type = AUDIO_SAMPLE_TYPE_U8; + + if (false == __convert_audio_channel(channel, &audio_ch)) { + return VCE_ERROR_INVALID_PARAMETER; + } + + if (false == __convert_audio_sample_type(type, &audio_sample_type)) { + return VCE_ERROR_INVALID_PARAMETER; + } + + int ret = 0; + ret = audio_in_create(rate, audio_ch, audio_sample_type, &g_audio_h); + if (AUDIO_IO_ERROR_NONE != ret) { + SLOG(LOG_ERROR, LOG_TAG, "[ERROR] Fail to create audio handle. [ret(%d)]", ret); + return ret; + } + + if (0 != audio_in_set_sound_stream_info(g_audio_h, stream_info_h)) { + SLOG(LOG_ERROR, LOG_TAG, "[ERROR] Fail to set stream info"); + } + + g_audio_type = type; + g_audio_rate = rate; + g_audio_channel = channel; + + return ret; +} + +int vcd_dependency_start_recording(void) +{ + int ret = 0; + + if (nullptr == g_audio_h) { + SLOG(LOG_ERROR, LOG_TAG, "[ERROR] Audio in handle is not valid."); + + return VCE_ERROR_INVALID_STATE; + } + + ret = audio_in_prepare(g_audio_h); + if (AUDIO_IO_ERROR_NONE != ret) { + if (AUDIO_IO_ERROR_SOUND_POLICY == ret) { + SLOG(LOG_ERROR, LOG_TAG, "[Recorder ERROR] Audio is busy."); + } else { + SLOG(LOG_ERROR, LOG_TAG, "[Recorder ERROR] Fail to start audio : %d", ret); + } + + return ret; + } + + g_is_recording = true; + + /* Add ecore timer to read audio data */ + ecore_main_loop_thread_safe_call_async([](void* data)->void + { + ecore_timer_add(0, __recorder_timer_func, NULL); + }, NULL); + + return ret; +} + +int vcd_dependency_stop_recording(void) +{ + int ret = 0; + + if (nullptr == g_audio_h) { + SLOG(LOG_ERROR, LOG_TAG, "[ERROR] Audio in handle is not valid."); + + return VCE_ERROR_INVALID_STATE; + } + + g_is_recording = false; + + ret = audio_in_unprepare(g_audio_h); + if (AUDIO_IO_ERROR_NONE != ret) { + SLOG(LOG_ERROR, LOG_TAG, "[Recorder ERROR] Fail to stop audio : %d", ret); + } + + return ret; +} \ No newline at end of file diff --git a/packaging/voice-control.spec b/packaging/voice-control.spec index 0e0f10e..8c36205 100644 --- a/packaging/voice-control.spec +++ b/packaging/voice-control.spec @@ -40,7 +40,6 @@ BuildRequires: pkgconfig(msfapi) BuildRequires: pkgconfig(farfield-voice-api) %endif BuildRequires: pkgconfig(vconf) -BuildRequires: pkgconfig(multi-assistant) BuildRequires: cmake BuildRequires: pkgconfig(gmock) @@ -187,6 +186,7 @@ mkdir -p %{_libdir}/voice/vc %{_libdir}/libvc_engine.so %{_bindir}/vc_getengine %{TZ_SYS_RO_SHARE}/voice/vc/1.0/vc-config.xml +%{TZ_SYS_RO_SHARE}/voice/vc/1.0/dependency-audio-manager/libvc-audio-manager.so %{TZ_SYS_RO_SHARE}/dbus-1/services/org.tizen.voice* %{TZ_SYS_RO_SHARE}/parser-plugins/voice-control.info %{TZ_SYS_RO_ETC}/package-manager/parserlib/metadata/libvc-engine-parser.so* diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index 778f56d..b5e14ce 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -16,6 +16,7 @@ SET(SRCS vcd_recorder.c vcd_server.c vce.c + dependency_audio_manager.cpp ) INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}) diff --git a/server/dependency_audio_manager.cpp b/server/dependency_audio_manager.cpp new file mode 100644 index 0000000..b604995 --- /dev/null +++ b/server/dependency_audio_manager.cpp @@ -0,0 +1,217 @@ +/** + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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 "dependency_audio_manager.h" + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "dependency_am" + + +static void *g_lib_handle = NULL; +static vcd_dependency_module_interface g_interface = { NULL, }; + + +int dependency_audio_manager_initialize(sound_stream_info_h stream_info_h, dependency_audio_manager_feed_audio_data callback) +{ + SLOG(LOG_DEBUG, LOG_TAG, "@@@ initialize"); + + const int FILEPATH_LEN = 512; + char filepath[FILEPATH_LEN] = {'\0', }; + char *vconf_str = vconf_get_str(VCD_DEPENDENCY_MODULE_PATH); + if (vconf_str) { + snprintf(filepath, FILEPATH_LEN - 1, "%s", vconf_str); + free(vconf_str); + } else { + const char *default_path = VCD_DEPENDENCY_DEFAULT_PATH; + snprintf(filepath, FILEPATH_LEN - 1, "%s/%s", default_path, VCD_DEPENDENCY_DEFAULT_FILENAME); + } + filepath[FILEPATH_LEN - 1] = '\0'; + + char *error; + g_lib_handle = NULL; + g_lib_handle = dlopen(filepath, RTLD_LAZY); + if (NULL != (error = dlerror())) { + SLOG(LOG_ERROR, LOG_TAG, "[ERROR] Fail to dlopen(%s), error(%s)", filepath, error); + return -1; //MAS_ERROR_OPERATION_FAILED; + } + + g_interface.initialize = + (vcd_dependency_initialize)dlsym(g_lib_handle, VCD_DEPENDENCY_FUNC_INITIALIZE); + g_interface.deinitialize = + (vcd_dependency_deinitialize)dlsym(g_lib_handle, VCD_DEPENDENCY_FUNC_DEINITIALIZE); + g_interface.set_audio_info = + (vcd_dependency_set_audio_info)dlsym(g_lib_handle, VCD_DEPENDENCY_FUNC_SET_AUDIO_INFO); + g_interface.start_recording = + (vcd_dependency_start_recording)dlsym(g_lib_handle, VCD_DEPENDENCY_FUNC_START_RECORDING); + g_interface.stop_recording = + (vcd_dependency_stop_recording)dlsym(g_lib_handle, VCD_DEPENDENCY_FUNC_STOP_RECORDING); + + int ret = 0; + if (NULL != g_lib_handle) { + vcd_dependency_initialize func = g_interface.initialize; + + if (NULL == func) { + SLOG(LOG_ERROR, LOG_TAG, "[ERROR] symbol lookup failed : %s", VCD_DEPENDENCY_FUNC_INITIALIZE); + } else { + try { + ret = func(stream_info_h, callback); + } catch (const std::exception& e) { + SLOG(LOG_ERROR, LOG_TAG, "[ERROR] %s of dependency module threw exception : %s", + VCD_DEPENDENCY_FUNC_INITIALIZE, e.what()); + } + + if (0 != ret) { + SLOG(LOG_ERROR, LOG_TAG, "[ERROR] Fail to initialize, ret(%d)", ret); + } + } + } else { + SLOG(LOG_ERROR, LOG_TAG, "[ERROR] g_lib_handle is not valid"); + } + + SLOG(LOG_DEBUG, LOG_TAG, "@@@"); + return ret; +} + +int dependency_audio_manager_deinitialize(void) +{ + SLOG(LOG_DEBUG, LOG_TAG, "@@@ Deinitialize"); + int ret = 0; + if (NULL != g_lib_handle) { + vcd_dependency_deinitialize func = g_interface.deinitialize; + + if (NULL == func) { + SLOG(LOG_ERROR, LOG_TAG, "[ERROR] symbol lookup failed : %s", VCD_DEPENDENCY_FUNC_DEINITIALIZE); + } else { + try { + ret = func(); + } catch (const std::exception& e) { + SLOG(LOG_ERROR, LOG_TAG, "[ERROR] %s of dependency module threw exception : %s", + VCD_DEPENDENCY_FUNC_DEINITIALIZE, e.what()); + } + + if (0 != ret) { + SLOG(LOG_ERROR, LOG_TAG, "[ERROR] Fail to initialize, ret(%d)", ret); + } + } + + dlclose(g_lib_handle); + g_lib_handle = NULL; + } else { + SLOG(LOG_ERROR, LOG_TAG, "[ERROR] g_lib_handle is not valid"); + } + + SLOG(LOG_DEBUG, LOG_TAG, "@@@"); + return ret; +} + +int dependency_audio_manager_set_audio_info(sound_stream_info_h stream_info_h, const char* audio_source_type, vce_audio_type_e type, int rate, int channel) +{ + SLOG(LOG_DEBUG, LOG_TAG, "@@@ Set audio information"); + int ret = 0; + if (NULL != g_lib_handle) { + vcd_dependency_set_audio_info func = g_interface.set_audio_info; + + if (NULL == func) { + SLOG(LOG_ERROR, LOG_TAG, "[ERROR] symbol lookup failed : %s", VCD_DEPENDENCY_FUNC_SET_AUDIO_INFO); + } else { + try { + ret = func(stream_info_h, audio_source_type, type, rate, channel); + } catch (const std::exception& e) { + SLOG(LOG_ERROR, LOG_TAG, "[ERROR] %s of dependency module threw exception : %s", + VCD_DEPENDENCY_FUNC_SET_AUDIO_INFO, e.what()); + } + + if (0 != ret) { + SLOG(LOG_ERROR, LOG_TAG, "[ERROR] Fail to initialize, ret(%d)", ret); + } + } + } else { + SLOG(LOG_ERROR, LOG_TAG, "[ERROR] g_lib_handle is not valid"); + } + + SLOG(LOG_DEBUG, LOG_TAG, "@@@"); + return ret; +} + +int dependency_audio_manager_start_recording() +{ + SLOG(LOG_DEBUG, LOG_TAG, "@@@ Start recording"); + int ret = 0; + if (NULL != g_lib_handle) { + vcd_dependency_start_recording func = g_interface.start_recording; + + if (NULL == func) { + SLOG(LOG_ERROR, LOG_TAG, "[ERROR] symbol lookup failed : %s", VCD_DEPENDENCY_FUNC_START_RECORDING); + } else { + try { + ret = func(); + } catch (const std::exception& e) { + SLOG(LOG_ERROR, LOG_TAG, "[ERROR] %s of dependency module threw exception : %s", + VCD_DEPENDENCY_FUNC_START_RECORDING, e.what()); + } + + if (0 != ret) { + SLOG(LOG_ERROR, LOG_TAG, "[ERROR] Fail to initialize, ret(%d)", ret); + } + } + } else { + SLOG(LOG_ERROR, LOG_TAG, "[ERROR] g_lib_handle is not valid"); + } + + SLOG(LOG_DEBUG, LOG_TAG, "@@@"); + return ret; + +} + +int dependency_audio_manager_stop_recording(void) +{ + SLOG(LOG_DEBUG, LOG_TAG, "@@@ Stop recording"); + int ret = 0; + if (NULL != g_lib_handle) { + vcd_dependency_stop_recording func = g_interface.stop_recording; + + if (NULL == func) { + SLOG(LOG_ERROR, LOG_TAG, "[ERROR] symbol lookup failed : %s", VCD_DEPENDENCY_FUNC_STOP_RECORDING); + } else { + try { + ret = func(); + } catch (const std::exception& e) { + SLOG(LOG_ERROR, LOG_TAG, "[ERROR] %s of dependency module threw exception : %s", + VCD_DEPENDENCY_FUNC_STOP_RECORDING, e.what()); + } + + if (0 != ret) { + SLOG(LOG_ERROR, LOG_TAG, "[ERROR] Fail to initialize, ret(%d)", ret); + } + } + } else { + SLOG(LOG_ERROR, LOG_TAG, "[ERROR] g_lib_handle is not valid"); + } + + SLOG(LOG_DEBUG, LOG_TAG, "@@@"); + return ret; +} \ No newline at end of file diff --git a/server/dependency_audio_manager.h b/server/dependency_audio_manager.h new file mode 100644 index 0000000..caa0445 --- /dev/null +++ b/server/dependency_audio_manager.h @@ -0,0 +1,72 @@ +/** + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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 __DEPENDENCY_AUDIO_MANAGER_H__ +#define __DEPENDENCY_AUDIO_MANAGER_H__ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/************************************************************************************** + *** Definitions for dependencies + *************************************************************************************/ +#define VCD_DEPENDENCY_DEFAULT_PATH tzplatform_mkpath(tzplatform_getid("TZ_SYS_RO_SHARE"), "voice/vc/1.0/dependency-audio-manager") +#define VCD_DEPENDENCY_DEFAULT_FILENAME "libvc-audio-manager.so" +#define VCD_DEPENDENCY_MODULE_PATH "db/voice/vc/dependency_module_path" + + +typedef int (*dependency_audio_manager_feed_audio_data)(const void* data, const unsigned int length); + + +#define VCD_DEPENDENCY_FUNC_INITIALIZE "vcd_dependency_initialize" +typedef int (*vcd_dependency_initialize)(sound_stream_info_h stream_info_h, dependency_audio_manager_feed_audio_data callback); +#define VCD_DEPENDENCY_FUNC_DEINITIALIZE "vcd_dependency_deinitialize" +typedef int (*vcd_dependency_deinitialize)(void); +#define VCD_DEPENDENCY_FUNC_SET_AUDIO_INFO "vcd_dependency_set_audio_info" +typedef int (*vcd_dependency_set_audio_info)(sound_stream_info_h stream_info_h, const char* audio_source_type, vce_audio_type_e type, int rate, int channel); +#define VCD_DEPENDENCY_FUNC_START_RECORDING "vcd_dependency_start_recording" +typedef int (*vcd_dependency_start_recording)(void); +#define VCD_DEPENDENCY_FUNC_STOP_RECORDING "vcd_dependency_stop_recording" +typedef int (*vcd_dependency_stop_recording)(void); + + +typedef struct { + vcd_dependency_initialize initialize; + vcd_dependency_deinitialize deinitialize; + vcd_dependency_set_audio_info set_audio_info; + vcd_dependency_start_recording start_recording; + vcd_dependency_stop_recording stop_recording; +} vcd_dependency_module_interface; + + +int dependency_audio_manager_initialize(sound_stream_info_h stream_info_h, dependency_audio_manager_feed_audio_data callback); +int dependency_audio_manager_deinitialize(void); +int dependency_audio_manager_set_audio_info(sound_stream_info_h stream_info_h, const char* audio_source_type, vce_audio_type_e type, int rate, int channel); +int dependency_audio_manager_start_recording(void); +int dependency_audio_manager_stop_recording(void); + + +#ifdef __cplusplus +} +#endif + +#endif /* __DEPENDENCY_AUDIO_MANAGER_H__ */ diff --git a/server/vcd_recorder.c b/server/vcd_recorder.c index f122ef6..969d5b4 100644 --- a/server/vcd_recorder.c +++ b/server/vcd_recorder.c @@ -41,55 +41,41 @@ #include "vcd_dbus.h" #include "vcd_engine_agent.h" #include "vcd_recorder.h" +#include "dependency_audio_manager.h" #include "vcd_main.h" -#include - #define FRAME_LENGTH 320 #define BUFFER_LENGTH FRAME_LENGTH * 2 -#define FOCUS_SERVER_READY "/tmp/.focus_server_ready" - -#define VCE_AUDIO_ID_NONE "VC_AUDIO_ID_NONE" /**< None audio id */ -#define VCE_AUDIO_ID_FFV "VC_FARFIELD_VOICE_VD" - -static vcd_recorder_state_e g_recorder_state = VCD_RECORDER_STATE_READY; - -static vcd_recoder_audio_cb g_audio_cb = NULL; - -static vcd_recorder_interrupt_cb g_interrupt_cb = NULL; - -static audio_in_h g_audio_h; - -static sound_stream_info_h g_stream_info_h; +#define FOCUS_SERVER_READY "/tmp/.focus_server_ready" -static vce_audio_type_e g_audio_type; +#define VCE_AUDIO_ID_NONE "VC_AUDIO_ID_NONE" /**< None audio id */ +#define VCE_AUDIO_ID_FFV "VC_FARFIELD_VOICE_VD" -static int g_audio_rate; -static int g_audio_channel; +static vcd_recorder_state_e g_recorder_state = VCD_RECORDER_STATE_READY; -static char g_normal_buffer[BUFFER_LENGTH + 10]; +static vcd_recoder_audio_cb g_audio_cb = NULL; +static vcd_recorder_interrupt_cb g_interrupt_cb = NULL; -static bool g_is_valid_audio_in = false; +static sound_stream_info_h g_stream_info_h = NULL; +static sound_stream_info_h g_stream_for_volume_h = NULL; +static virtual_sound_stream_h g_virtual_sound_stream_h = NULL; -static bool g_is_valid_bt_in = false; +static bool g_is_valid_audio_in = false; +static bool g_is_valid_bt_in = false; -static char* g_current_audio_type = NULL; +static char* g_current_audio_type = NULL; +static int g_buffer_count = 0; +static int g_device_id = -1; static char* g_pcm_path = NULL; static FILE* g_pcm_fp = NULL; -static int g_buffer_count; - -static int g_device_id = -1; - #ifdef TV_FFV_MODE farfield_voice_h g_farfieldvoice_h = NULL; #endif -static sound_stream_info_h g_stream_for_volume_h = NULL; -static virtual_sound_stream_h g_virtual_sound_stream_h = NULL; /* Sound buf save */ #if 0 @@ -97,12 +83,11 @@ static virtual_sound_stream_h g_virtual_sound_stream_h = NULL; #endif #ifdef BUF_SAVE_MODE -static FILE* g_normal_file; - +static FILE* g_normal_file = NULL; static int g_count = 1; #endif -static float get_volume_decibel(char* data, int size); +static float get_volume_decibel(const char* data, const unsigned int size); #ifdef TV_MSF_WIFI_MODE static void __msf_wifi_audio_data_receive_cb(msf_wifi_voice_data_s *voice_data, void* user_data) @@ -260,33 +245,6 @@ static void _ffv_audio_function_cb(void* data, unsigned int length, void* user_d } #endif -void audio_streaming_cb(ma_audio_streaming_event_e event, char* buffer, int len, void* user_data) -{ - if (0 == g_buffer_count || 0 == g_buffer_count % 50) { - SLOG(LOG_INFO, TAG_VCD, "[Recorder INFO] MA_ap audio function callback is invoked"); - - if (100000 == g_buffer_count) { - g_buffer_count = 0; - } - } - - g_buffer_count++; - - if (NULL != g_audio_cb) { - if (0 != g_audio_cb(buffer, len)) { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to read audio"); - } - } - - /* Set volume */ - if (0 == g_buffer_count % 15) { - float vol_db = get_volume_decibel(buffer, len); - if (0 != vcdc_send_set_volume(vcd_client_manager_get_pid(), vol_db)) { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder] Fail to send recording volume(%f)", vol_db); - } - } -} - #if 1 static const char* __get_focus_changed_reason_code(sound_stream_focus_change_reason_e reason) { @@ -410,6 +368,41 @@ static void __device_connection_changed_cb(sound_device_h device, bool is_connec return; } +static int __feed_audio_data_cb(const void* data, const unsigned int length) +{ + if (NULL != g_audio_cb) { + if (0 != g_audio_cb(data, length)) { + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to read audio"); + vcd_recorder_stop(); + } + } + + if (0 == g_buffer_count % 15) { + float vol_db = get_volume_decibel((char*)data, length); + if (0 != vcdc_send_set_volume(vcd_client_manager_get_pid(), vol_db)) { + SLOG(LOG_ERROR, TAG_VCD, "[Recorder] Fail to send recording volume(%f)", vol_db); + } + } + + if (0 == g_buffer_count % 50) { + SLOG(LOG_WARN, TAG_VCD, "[Recorder][%d] Recording... : read_size(%d)", g_buffer_count, length); + + if (100000 == g_buffer_count) { + g_buffer_count = 0; + } + } + + g_buffer_count++; + +#ifdef BUF_SAVE_MODE + /* write pcm buffer */ + fwrite(data, 1, BUFFER_LENGTH, g_normal_file); +#endif + + return 0; +} + + int vcd_recorder_create(vcd_recoder_audio_cb audio_cb, vcd_recorder_interrupt_cb interrupt_cb) { if (NULL == audio_cb || NULL == interrupt_cb) { @@ -440,42 +433,6 @@ int vcd_recorder_create(vcd_recoder_audio_cb audio_cb, vcd_recorder_interrupt_cb g_pcm_fp = NULL; g_pcm_path = NULL; - g_audio_type = VCE_AUDIO_TYPE_PCM_S16_LE; - g_audio_rate = 16000; - g_audio_channel = 1; - - audio_channel_e audio_ch; - audio_sample_type_e audio_type; - - SLOG(LOG_INFO, TAG_VCD, "[Recorder] Audio type(%d) rate(%d) channel(%d)", g_audio_type, g_audio_rate, g_audio_channel); - - switch (g_audio_channel) { - case 1: audio_ch = AUDIO_CHANNEL_MONO; break; - case 2: audio_ch = AUDIO_CHANNEL_STEREO; break; - default: - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Input channel is not supported"); - return VCD_ERROR_OPERATION_FAILED; - break; - } - - switch (g_audio_type) { - case VCE_AUDIO_TYPE_PCM_S16_LE: audio_type = AUDIO_SAMPLE_TYPE_S16_LE; break; - case VCE_AUDIO_TYPE_PCM_U8: audio_type = AUDIO_SAMPLE_TYPE_U8; break; - default: - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Invalid Audio Type"); - return VCD_ERROR_OPERATION_FAILED; - break; - } - - ret = audio_in_create(g_audio_rate, audio_ch, audio_type, &g_audio_h); - if (AUDIO_IO_ERROR_NONE == ret) { - g_is_valid_audio_in = true; - } else { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Rate(%d) Channel(%d) Type(%d)", g_audio_rate, audio_ch, audio_type); - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to create audio handle : %d", ret); - g_is_valid_audio_in = false; - } - ret = sound_manager_add_device_connection_changed_cb(SOUND_DEVICE_IO_DIRECTION_IN_MASK, __device_connection_changed_cb, NULL, &g_device_id); if (0 != ret) SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to add device connection changed callback"); @@ -486,8 +443,11 @@ int vcd_recorder_create(vcd_recoder_audio_cb audio_cb, vcd_recorder_interrupt_cb __apply_device_for_stream_routing(); } - if (0 != audio_in_set_sound_stream_info(g_audio_h, g_stream_info_h)) { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to set stream info"); + if (0 != dependency_audio_manager_initialize(g_stream_info_h, __feed_audio_data_cb)) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to initialize dependency audio manager"); + g_is_valid_audio_in = false; + } else { + g_is_valid_audio_in = true; } g_audio_cb = audio_cb; @@ -533,9 +493,6 @@ int vcd_recorder_create(vcd_recoder_audio_cb audio_cb, vcd_recorder_interrupt_cb SLOG(LOG_INFO, TAG_VCD, "[Recorder] Audio type : %s", g_current_audio_type); - ma_ap_initialize(); - ma_ap_set_audio_streaming_cb(audio_streaming_cb, NULL); - /* Set audio feed callback */ #ifdef TV_BT_MODE if (BT_ERROR_NONE != bt_hid_set_audio_data_receive_cb(_bt_hid_audio_data_receive_cb, NULL)) { @@ -559,26 +516,26 @@ int vcd_recorder_create(vcd_recoder_audio_cb audio_cb, vcd_recorder_interrupt_cb int vcd_recorder_destroy() { - ma_ap_deinitialize(); - int ret = -1; if (VCD_RECORDER_STATE_RECORDING == g_recorder_state) { vcd_recorder_stop(); } - ret = sound_manager_remove_device_connection_changed_cb(g_device_id); - if (0 != ret) + int ret = sound_manager_remove_device_connection_changed_cb(g_device_id); + if (0 != ret) { SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to remove device connection changed callback, ret(%d)", ret); + } g_device_id = -1; ret = sound_manager_destroy_stream_information(g_stream_info_h); - if (0 != ret) + if (0 != ret) { SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to destroy stream info, ret(%d)", ret); + } g_stream_info_h = NULL; - ret = audio_in_destroy(g_audio_h); - if (0 != ret) + ret = dependency_audio_manager_deinitialize(); + if (0 != ret) { SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to audio in destroy, ret(%d)", ret); - g_audio_h = NULL; + } #ifdef TV_MSF_WIFI_MODE @@ -606,18 +563,20 @@ int vcd_recorder_destroy() g_current_audio_type = NULL; } - if (g_pcm_path) + if (NULL != g_pcm_path) { free(g_pcm_path); - g_pcm_path = NULL; + g_pcm_path = NULL; + } - if (g_pcm_fp) + if (NULL != g_pcm_fp) { fclose(g_pcm_fp); - g_pcm_fp = NULL; + g_pcm_fp = NULL; + } return VCD_ERROR_NONE; } -int vcd_recorder_set(const char* audio_type, vce_audio_type_e type, int rate, int channel) +static int __set_audio_source_type(const char* audio_type) { if (NULL == audio_type) { SLOG(LOG_INFO, TAG_VCD, "[Recorder] Audio type is NULL"); @@ -627,7 +586,7 @@ int vcd_recorder_set(const char* audio_type, vce_audio_type_e type, int rate, in if (NULL != g_current_audio_type) { if (0 == strncmp(g_current_audio_type, audio_type, strlen(g_current_audio_type))) { SLOG(LOG_INFO, TAG_VCD, "[Recorder] Current audio type is already set : %s", audio_type); - return 0; + return VCD_ERROR_NONE; } } else { SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Recorder is NOT created"); @@ -657,96 +616,43 @@ int vcd_recorder_set(const char* audio_type, vce_audio_type_e type, int rate, in } } + if (NULL != g_current_audio_type) { + free(g_current_audio_type); + g_current_audio_type = NULL; + } + + g_current_audio_type = strdup(audio_type); + + return VCD_ERROR_NONE; +} + +int vcd_recorder_set(const char* audio_type, vce_audio_type_e type, int rate, int channel) +{ int ret = -1; + ret = __set_audio_source_type(audio_type); + if (0 != ret) { + return ret; + } + /* Check BT audio */ if (0 == strncmp(VCE_AUDIO_ID_BLUETOOTH, audio_type, strlen(VCE_AUDIO_ID_BLUETOOTH))) { if (false == g_is_valid_bt_in) { SLOG(LOG_ERROR, TAG_VCD, "[Recorder] BT audio is NOT valid"); return VCD_ERROR_OPERATION_REJECTED; } - - if (NULL != g_current_audio_type) { - free(g_current_audio_type); - g_current_audio_type = NULL; - } - - g_current_audio_type = strdup(audio_type); } else if (0 == strncmp(VCE_AUDIO_ID_WIFI, audio_type, strlen(VCE_AUDIO_ID_WIFI))) { - if (NULL != g_current_audio_type) { - free(g_current_audio_type); - g_current_audio_type = NULL; - } - - g_current_audio_type = strdup(audio_type); } else if (0 == strncmp(VCE_AUDIO_ID_FFV, audio_type, strlen(VCE_AUDIO_ID_FFV))) { - if (NULL != g_current_audio_type) { - free(g_current_audio_type); - g_current_audio_type = NULL; - } - - g_current_audio_type = strdup(audio_type); } else { if (false == g_is_valid_audio_in) { SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Audio-in is NOT valid"); return VCD_ERROR_OPERATION_REJECTED; } - if (g_audio_type != type || g_audio_rate != rate || g_audio_channel != channel) { - SLOG(LOG_INFO, TAG_VCD, "[Recorder] New audio type(%d) rate(%d) channel(%d)", type, rate, channel); - audio_in_destroy(g_audio_h); - g_audio_h = NULL; - - audio_channel_e audio_ch = AUDIO_CHANNEL_MONO; - audio_sample_type_e audio_sample_type; - - switch (channel) { - case 1: audio_ch = AUDIO_CHANNEL_MONO; break; - case 2: audio_ch = AUDIO_CHANNEL_STEREO; break; - case 3: audio_ch = AUDIO_CHANNEL_MULTI_3; break; - case 4: audio_ch = AUDIO_CHANNEL_MULTI_4; break; - case 5: audio_ch = AUDIO_CHANNEL_MULTI_5; break; - case 6: audio_ch = AUDIO_CHANNEL_MULTI_6; break; - case 7: audio_ch = AUDIO_CHANNEL_MULTI_7; break; - case 8: audio_ch = AUDIO_CHANNEL_MULTI_8; break; - default: - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Input channel is not supported, audio_ch(%d)", audio_ch); - return VCD_ERROR_OPERATION_FAILED; - break; - } - - switch (type) { - case VCE_AUDIO_TYPE_PCM_S16_LE: audio_sample_type = AUDIO_SAMPLE_TYPE_S16_LE; break; - case VCE_AUDIO_TYPE_PCM_U8: audio_sample_type = AUDIO_SAMPLE_TYPE_U8; break; - default: - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Invalid Audio Type"); - return VCD_ERROR_OPERATION_FAILED; - break; - } - - ret = audio_in_create(rate, audio_ch, audio_sample_type, &g_audio_h); - if (AUDIO_IO_ERROR_NONE != ret) { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to create audio handle : %d", ret); - g_is_valid_audio_in = false; - return VCD_ERROR_OPERATION_FAILED; - } - - if (0 != audio_in_set_sound_stream_info(g_audio_h, g_stream_info_h)) { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to set stream info"); - } - - g_audio_type = type; - g_audio_rate = rate; - g_audio_channel = channel; - } - -#ifdef TV_BT_MODE - if (NULL != g_current_audio_type) { - free(g_current_audio_type); - g_current_audio_type = NULL; + ret = dependency_audio_manager_set_audio_info(g_stream_info_h, audio_type, type, rate, channel); + if (0 != ret) { + g_is_valid_audio_in = false; + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to set audio information"); } - - g_current_audio_type = strdup(audio_type); -#endif } SLOG(LOG_INFO, TAG_VCD, "[Recorder] Current audio type is changed : %s", g_current_audio_type); @@ -770,9 +676,10 @@ int vcd_recorder_get(char** audio_type) return 0; } -static float get_volume_decibel(char* data, int size) +// TODO: make common function? +static float get_volume_decibel(const char* data, const unsigned int size) { -#define MAX_AMPLITUDE_MEAN_16 32768 + const int MAX_AMPLITUDE_MEAN_16 = 32768; int i, depthByte; int count = 0; @@ -827,6 +734,7 @@ Eina_Bool __read_test_func(void *data) buffer_size = MIN(buffer_size, BUFFER_LENGTH); + // TODO: change to __feed_audio_data_cb if (NULL != g_audio_cb && buffer_size != 0) g_audio_cb(buffer, buffer_size); @@ -842,65 +750,9 @@ Eina_Bool __read_test_func(void *data) return EINA_TRUE; } -Eina_Bool __read_normal_func(void *data) -{ - int ret = -1; - - if (VCD_RECORDER_STATE_RECORDING != g_recorder_state) { - SLOG(LOG_INFO, TAG_VCD, "[Recorder] Exit audio reading normal func"); - return EINA_FALSE; - } - - memset(g_normal_buffer, '\0', BUFFER_LENGTH + 10); - - ret = audio_in_read(g_audio_h, g_normal_buffer, BUFFER_LENGTH); - if (0 > ret) { - SLOG(LOG_WARN, TAG_VCD, "[Recorder WARNING] Fail to read audio : %d", ret); - g_recorder_state = VCD_RECORDER_STATE_READY; - return EINA_FALSE; - } - - if (NULL != g_audio_cb) { - if (0 != g_audio_cb(g_normal_buffer, BUFFER_LENGTH)) { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to read audio : %d", ret); - vcd_recorder_stop(); - return EINA_FALSE; - } - } - - /* Set volume */ - if (0 == g_buffer_count % 30) { - float vol_db = get_volume_decibel(g_normal_buffer, BUFFER_LENGTH); - if (0 != vcdc_send_set_volume(vcd_client_manager_get_pid(), vol_db)) { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder] Fail to send recording volume(%f)", vol_db); - } - } - - if (0 == g_buffer_count || 0 == g_buffer_count % 50) { - SLOG(LOG_WARN, TAG_VCD, "[Recorder][%d] Recording... : read_size(%d)", g_buffer_count, ret); - - if (100000 == g_buffer_count) { - g_buffer_count = 0; - } - } - - g_buffer_count++; - -#ifdef BUF_SAVE_MODE - /* write pcm buffer */ - fwrite(g_normal_buffer, 1, BUFFER_LENGTH, g_normal_file); -#endif - - return EINA_TRUE; -} - -static void __timer_read_normal_func(void *data) +static void __timer_read_test_func(void *data) { - SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] before __read_normal_func"); - if (g_pcm_path) - ecore_timer_add(0, __read_test_func, NULL); - else - ecore_timer_add(0, __read_normal_func, NULL); + ecore_timer_add(0, __read_test_func, NULL); return; } @@ -921,48 +773,11 @@ static void __check_audio_format() return; } - if (g_audio_type != type || g_audio_rate != rate || g_audio_channel != channel) { - SLOG(LOG_INFO, TAG_VCD, "[Recorder] New audio type(%d) rate(%d) channel(%d)", type, rate, channel); - audio_in_destroy(g_audio_h); - g_audio_h = NULL; - - audio_channel_e audio_ch; - audio_sample_type_e audio_type; - - switch (channel) { - case 1: audio_ch = AUDIO_CHANNEL_MONO; break; - case 2: audio_ch = AUDIO_CHANNEL_STEREO; break; - default: - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Input channel is not supported"); - return; - break; - } - - switch (type) { - case VCE_AUDIO_TYPE_PCM_S16_LE: audio_type = AUDIO_SAMPLE_TYPE_S16_LE; break; - case VCE_AUDIO_TYPE_PCM_U8: audio_type = AUDIO_SAMPLE_TYPE_U8; break; - default: - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Invalid Audio Type"); - return; - break; - } - - ret = audio_in_create(rate, audio_ch, audio_type, &g_audio_h); - if (AUDIO_IO_ERROR_NONE != ret) { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to create audio handle : %d", ret); - g_is_valid_audio_in = false; - return; - } - - if (0 != audio_in_set_sound_stream_info(g_audio_h, g_stream_info_h)) { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to set stream info"); - } - - g_audio_type = type; - g_audio_rate = rate; - g_audio_channel = channel; - } else { - SLOG(LOG_INFO, TAG_VCD, "[Recorder] audio type(%d) rate(%d) channel(%d)", g_audio_type, g_audio_rate, g_audio_channel); + ret = dependency_audio_manager_set_audio_info(g_stream_info_h, VCE_AUDIO_ID_NONE, type, rate, channel); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to set audio information"); + g_is_valid_audio_in = false; + return; } } @@ -1136,24 +951,21 @@ int vcd_recorder_start() return VCD_ERROR_NONE; } - if (NULL != g_current_audio_type && 0 == strncmp(VCE_AUDIO_ID_NONE, g_current_audio_type, strlen(VCE_AUDIO_ID_NONE))) { - /* check audio format */ - __check_audio_format(); - - ret = audio_in_prepare(g_audio_h); - if (AUDIO_IO_ERROR_NONE != ret) { - if (AUDIO_IO_ERROR_SOUND_POLICY == ret) { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Audio is busy."); - return VCD_ERROR_RECORDER_BUSY; - } else { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to start audio : %d", ret); - } - return VCD_ERROR_OPERATION_FAILED; + if (NULL != g_pcm_path) { + // For testing + ecore_main_loop_thread_safe_call_async(__timer_read_test_func, NULL); + } else { + if (NULL != g_current_audio_type && 0 == strncmp(VCE_AUDIO_ID_NONE, g_current_audio_type, strlen(VCE_AUDIO_ID_NONE))) { + /* check audio format */ + __check_audio_format(); } + } - /* Add ecore timer to read audio data */ - ecore_main_loop_thread_safe_call_async(__timer_read_normal_func, NULL); - SLOG(LOG_INFO, TAG_VCD, "[Recorder] Start audio in recorder"); + ret = dependency_audio_manager_start_recording(); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to start recording, [ret(%d)]", ret); + + return ret; } g_recorder_state = VCD_RECORDER_STATE_RECORDING; @@ -1200,8 +1012,10 @@ int vcd_recorder_stop() return VCD_ERROR_NONE; } - if (VCD_RECORDER_STATE_READY == g_recorder_state) + if (VCD_RECORDER_STATE_READY == g_recorder_state) { + SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Recorder is already stopped"); return VCD_ERROR_NONE; + } g_recorder_state = VCD_RECORDER_STATE_READY; @@ -1217,15 +1031,13 @@ int vcd_recorder_stop() fclose(g_pcm_fp); g_pcm_fp = NULL; - if (NULL != g_current_audio_type && 0 == strncmp(VCE_AUDIO_ID_NONE, g_current_audio_type, strlen(VCE_AUDIO_ID_NONE))) { - ret = audio_in_unprepare(g_audio_h); - if (AUDIO_IO_ERROR_NONE != ret) { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to stop audio : %d", ret); - return VCD_ERROR_OPERATION_FAILED; - } + ret = dependency_audio_manager_stop_recording(); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to stop audio : %d", ret); + return ret; } - vcd_recorder_set(VCE_AUDIO_ID_NONE, g_audio_type, g_audio_rate, g_audio_channel); + __set_audio_source_type(VCE_AUDIO_ID_NONE); return VCD_ERROR_NONE; } -- 2.7.4 From a7f2859094da725d7f0437c42bfd03cbbb312759 Mon Sep 17 00:00:00 2001 From: Suyeon Hwang Date: Thu, 18 Jun 2020 11:04:38 +0900 Subject: [PATCH 08/16] Improve log of default dependency module Change-Id: Id1d6166c87fbc62980c2143f1bdd28e4e9424624 Signed-off-by: Suyeon Hwang --- audio-manager/inc/vc_audio_manager.h | 5 --- audio-manager/src/vc_audio_manager.cpp | 63 ++++++++++++++++++------------- audio-manager/src/vc_audio_manager_dlog.h | 28 ++++++++++++++ 3 files changed, 64 insertions(+), 32 deletions(-) create mode 100644 audio-manager/src/vc_audio_manager_dlog.h diff --git a/audio-manager/inc/vc_audio_manager.h b/audio-manager/inc/vc_audio_manager.h index 6b7cdfd..16230dd 100644 --- a/audio-manager/inc/vc_audio_manager.h +++ b/audio-manager/inc/vc_audio_manager.h @@ -24,11 +24,6 @@ extern "C" { #endif -#ifdef LOG_TAG -#undef LOG_TAG -#endif -#define LOG_TAG "vc_audio_manager" - typedef int (*dependency_audio_manager_feed_audio_data)(const void* data, const unsigned int length); int vcd_dependency_initialize(sound_stream_info_h stream_info_h, dependency_audio_manager_feed_audio_data callback); diff --git a/audio-manager/src/vc_audio_manager.cpp b/audio-manager/src/vc_audio_manager.cpp index 89a1788..e676d2b 100644 --- a/audio-manager/src/vc_audio_manager.cpp +++ b/audio-manager/src/vc_audio_manager.cpp @@ -25,6 +25,7 @@ #include #include "vce.h" +#include "vc_audio_manager_dlog.h" #include "vc_audio_manager.h" @@ -58,7 +59,7 @@ static bool __convert_audio_channel(int channel, audio_channel_e* output) case 7: audio_ch = AUDIO_CHANNEL_MULTI_7; break; case 8: audio_ch = AUDIO_CHANNEL_MULTI_8; break; default: - SLOG(LOG_ERROR, LOG_TAG, "[ERROR] Input channel is not supported. [channel(%d)]", channel); + VCAM_LOGE("[ERROR] Input channel is not supported. [channel(%d)]", channel); return false; } @@ -78,7 +79,7 @@ static bool __convert_audio_sample_type(vce_audio_type_e audio_type, audio_sampl audio_sample_type = AUDIO_SAMPLE_TYPE_U8; break; default: - SLOG(LOG_ERROR, LOG_TAG, "[ERROR] Invalid Audio Type. [type(%d)]", audio_type); + VCAM_LOGE("[ERROR] Invalid Audio Type. [type(%d)]", audio_type); return false; } @@ -91,20 +92,22 @@ static Eina_Bool __recorder_timer_func(void *data) const int FRAME_LENGTH = 160; const int BUFFER_LENGTH = FRAME_LENGTH * 2; - if (g_is_recording && nullptr != g_feed_audio_data) { + if (g_is_recording) { unsigned char buffer[BUFFER_LENGTH]; memset(buffer, '\0', BUFFER_LENGTH); int read_bytes = audio_in_read(g_audio_h, buffer, BUFFER_LENGTH); if (0 > read_bytes) { - SLOG(LOG_WARN, LOG_TAG, "[WARNING] Fail to read audio : %d", read_bytes); + VCAM_LOGW("[WARNING] Fail to read audio : %d", read_bytes); return ECORE_CALLBACK_DONE; } // TODO: check return value? - g_feed_audio_data(buffer, read_bytes); + if (nullptr != g_feed_audio_data) { + g_feed_audio_data(buffer, read_bytes); + } } else { - SLOG(LOG_DEBUG, LOG_TAG, "[DEBUG] Recording is finished"); + VCAM_LOGD("[DEBUG] Recording is finished"); return ECORE_CALLBACK_DONE; } @@ -122,8 +125,6 @@ int vcd_dependency_initialize(sound_stream_info_h stream_info_h, dependency_audi audio_channel_e audio_ch = AUDIO_CHANNEL_MONO; audio_sample_type_e audio_sample_type = AUDIO_SAMPLE_TYPE_U8; - SLOG(LOG_INFO, LOG_TAG, "[Recorder] Audio type(%d) rate(%d) channel(%d)", g_audio_type, g_audio_rate, g_audio_channel); - if (false == __convert_audio_channel(g_audio_channel, &audio_ch)) { return VCE_ERROR_INVALID_PARAMETER; } @@ -132,37 +133,43 @@ int vcd_dependency_initialize(sound_stream_info_h stream_info_h, dependency_audi return VCE_ERROR_INVALID_PARAMETER; } + VCAM_LOGI("Audio type(%d), rate(%d), channel(%d)", g_audio_type, g_audio_rate, g_audio_channel); + ret = audio_in_create(g_audio_rate, audio_ch, audio_sample_type, &g_audio_h); if (AUDIO_IO_ERROR_NONE != ret) { - SLOG(LOG_ERROR, LOG_TAG, "[Recorder ERROR] Rate(%d) Channel(%d) Type(%d)", g_audio_rate, audio_ch, audio_sample_type); - SLOG(LOG_ERROR, LOG_TAG, "[Recorder ERROR] Fail to create audio handle : %d", ret); + VCAM_LOGE("[ERROR] Fail to create audio handle : %d", ret); + return VCE_ERROR_OPERATION_FAILED; } - if (0 != audio_in_set_sound_stream_info(g_audio_h, stream_info_h)) { - SLOG(LOG_ERROR, LOG_TAG, "[Recorder ERROR] Fail to set stream info"); + ret = audio_in_set_sound_stream_info(g_audio_h, stream_info_h); + if (AUDIO_IO_ERROR_NONE != ret) { + VCAM_LOGE("[ERROR] Fail to set stream info : %d", ret); + audio_in_destroy(g_audio_h); + return VCE_ERROR_OPERATION_FAILED; } g_audio_source_type = strdup(VCE_AUDIO_ID_NONE); g_feed_audio_data = callback; g_is_recording = false; - return ret; + return VCE_ERROR_NONE; } int vcd_dependency_deinitialize(void) { + VCAM_LOGI(""); int ret = 0; if (g_is_recording) { ret = audio_in_unprepare(g_audio_h); if (0 != ret) { - SLOG(LOG_ERROR, LOG_TAG, "[Recorder ERROR] Fail to stop audio : %d", ret); + VCAM_LOGE("[ERROR] Fail to stop audio : %d", ret); } g_is_recording = false; } ret = audio_in_destroy(g_audio_h); if (0 != ret) { - SLOG(LOG_ERROR, LOG_TAG, "[Recorder ERROR] Fail to audio in destroy, ret(%d)", ret); + VCAM_LOGE("[ERROR] Fail to audio in destroy, ret(%d)", ret); } g_audio_h = nullptr; @@ -178,22 +185,22 @@ int vcd_dependency_deinitialize(void) int vcd_dependency_set_audio_info(sound_stream_info_h stream_info_h, const char* audio_source_type, vce_audio_type_e type, int rate, int channel) { if (nullptr == audio_source_type) { - SLOG(LOG_ERROR, LOG_TAG, "[ERROR] Invalid audio source type."); + VCAM_LOGE("[ERROR] Invalid audio source type."); return VCE_ERROR_INVALID_PARAMETER; } if (nullptr == g_audio_h || nullptr == g_audio_source_type) { - SLOG(LOG_ERROR, LOG_TAG, "[ERROR] Audio in handle is not valid."); + VCAM_LOGE("[ERROR] Audio in handle is not valid."); return VCE_ERROR_INVALID_STATE; } if (0 == strncmp(g_audio_source_type, audio_source_type, strlen(g_audio_source_type)) || (g_audio_type == type && g_audio_rate == rate && g_audio_channel == channel)) { - SLOG(LOG_INFO, LOG_TAG, "[DEBUG] No changed information"); + VCAM_LOGI("No changed information"); return VCE_ERROR_NONE; } - SLOG(LOG_INFO, LOG_TAG, "[Recorder] New audio type(%d) rate(%d) channel(%d)", type, rate, channel); + VCAM_LOGI("New audio type(%d) rate(%d) channel(%d)", type, rate, channel); audio_in_destroy(g_audio_h); audio_channel_e audio_ch = AUDIO_CHANNEL_MONO; @@ -210,37 +217,38 @@ int vcd_dependency_set_audio_info(sound_stream_info_h stream_info_h, const char* int ret = 0; ret = audio_in_create(rate, audio_ch, audio_sample_type, &g_audio_h); if (AUDIO_IO_ERROR_NONE != ret) { - SLOG(LOG_ERROR, LOG_TAG, "[ERROR] Fail to create audio handle. [ret(%d)]", ret); + VCAM_LOGE("[ERROR] Fail to create audio handle. [ret(%d)]", ret); return ret; } if (0 != audio_in_set_sound_stream_info(g_audio_h, stream_info_h)) { - SLOG(LOG_ERROR, LOG_TAG, "[ERROR] Fail to set stream info"); + VCAM_LOGE("[ERROR] Fail to set stream info"); } g_audio_type = type; g_audio_rate = rate; g_audio_channel = channel; + VCAM_LOGI(""); return ret; } int vcd_dependency_start_recording(void) { + VCAM_LOGI(""); int ret = 0; if (nullptr == g_audio_h) { - SLOG(LOG_ERROR, LOG_TAG, "[ERROR] Audio in handle is not valid."); - + VCAM_LOGE("[ERROR] Audio in handle is not valid."); return VCE_ERROR_INVALID_STATE; } ret = audio_in_prepare(g_audio_h); if (AUDIO_IO_ERROR_NONE != ret) { if (AUDIO_IO_ERROR_SOUND_POLICY == ret) { - SLOG(LOG_ERROR, LOG_TAG, "[Recorder ERROR] Audio is busy."); + VCAM_LOGE("[ERROR] Audio is busy."); } else { - SLOG(LOG_ERROR, LOG_TAG, "[Recorder ERROR] Fail to start audio : %d", ret); + VCAM_LOGE("[ERROR] Fail to start audio : %d", ret); } return ret; @@ -259,10 +267,11 @@ int vcd_dependency_start_recording(void) int vcd_dependency_stop_recording(void) { + VCAM_LOGI(""); int ret = 0; if (nullptr == g_audio_h) { - SLOG(LOG_ERROR, LOG_TAG, "[ERROR] Audio in handle is not valid."); + VCAM_LOGE("[ERROR] Audio in handle is not valid."); return VCE_ERROR_INVALID_STATE; } @@ -271,7 +280,7 @@ int vcd_dependency_stop_recording(void) ret = audio_in_unprepare(g_audio_h); if (AUDIO_IO_ERROR_NONE != ret) { - SLOG(LOG_ERROR, LOG_TAG, "[Recorder ERROR] Fail to stop audio : %d", ret); + VCAM_LOGE("[ERROR] Fail to stop audio : %d", ret); } return ret; diff --git a/audio-manager/src/vc_audio_manager_dlog.h b/audio-manager/src/vc_audio_manager_dlog.h new file mode 100644 index 0000000..61c53c5 --- /dev/null +++ b/audio-manager/src/vc_audio_manager_dlog.h @@ -0,0 +1,28 @@ +#ifndef __VC_AUDIO_MANAGER_DLOG__ +#define __VC_AUDIO_MANAGER_DLOG__ + +#include +#include + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "vc_audio_manager" + +#ifdef __MODULE__ +#undef __MODULE__ +#endif +#define __MODULE__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) + +#define VCAM_LOG_(prio, tag, fmt, arg...) \ + ({ do { \ + dlog_print(prio, tag, "%s: %s(%d) > " fmt, __MODULE__, __func__, __LINE__, ##arg); \ + } while (0); }) + +#define VCAM_LOGD(fmt, args...) VCAM_LOG_(DLOG_DEBUG, LOG_TAG, fmt, ##args) +#define VCAM_LOGI(fmt, args...) VCAM_LOG_(DLOG_INFO, LOG_TAG, fmt, ##args) +#define VCAM_LOGW(fmt, args...) VCAM_LOG_(DLOG_WARN, LOG_TAG, fmt, ##args) +#define VCAM_LOGE(fmt, args...) VCAM_LOG_(DLOG_ERROR, LOG_TAG, fmt, ##args) + + +#endif /* __VC_AUDIO_MANAGER_DLOG__ */ -- 2.7.4 From b27e7cf430f9e5d89e5370c2d0d94de7f2588224 Mon Sep 17 00:00:00 2001 From: Suyeon Hwang Date: Thu, 9 Jul 2020 14:11:31 +0900 Subject: [PATCH 09/16] Remove audio type dependency from vcd_recorder Change-Id: I2942e9fc0eee43027284b4d3d5c6a040f94be2fd Signed-off-by: Suyeon Hwang --- audio-manager/inc/vc_audio_manager.h | 1 + audio-manager/src/vc_audio_manager.cpp | 38 +++++--- server/dependency_audio_manager.cpp | 33 ++++++- server/dependency_audio_manager.h | 14 +-- server/vcd_recorder.c | 158 +++++++++++---------------------- 5 files changed, 121 insertions(+), 123 deletions(-) diff --git a/audio-manager/inc/vc_audio_manager.h b/audio-manager/inc/vc_audio_manager.h index 16230dd..59354e2 100644 --- a/audio-manager/inc/vc_audio_manager.h +++ b/audio-manager/inc/vc_audio_manager.h @@ -29,6 +29,7 @@ typedef int (*dependency_audio_manager_feed_audio_data)(const void* data, const int vcd_dependency_initialize(sound_stream_info_h stream_info_h, dependency_audio_manager_feed_audio_data callback); int vcd_dependency_deinitialize(void); int vcd_dependency_set_audio_info(sound_stream_info_h stream_info_h, const char* audio_source_type, vce_audio_type_e type, int rate, int channel); +int vcd_dependency_get_audio_source_type(char** audio_source_type); int vcd_dependency_start_recording(void); int vcd_dependency_stop_recording(void); diff --git a/audio-manager/src/vc_audio_manager.cpp b/audio-manager/src/vc_audio_manager.cpp index e676d2b..32631f3 100644 --- a/audio-manager/src/vc_audio_manager.cpp +++ b/audio-manager/src/vc_audio_manager.cpp @@ -40,7 +40,6 @@ static audio_in_h g_audio_h = nullptr; static vce_audio_type_e g_audio_type = VCE_AUDIO_TYPE_PCM_S16_LE; static int g_audio_rate = 0; static int g_audio_channel = 0; -static char* g_audio_source_type = nullptr; volatile static bool g_is_recording = false; @@ -148,7 +147,6 @@ int vcd_dependency_initialize(sound_stream_info_h stream_info_h, dependency_audi return VCE_ERROR_OPERATION_FAILED; } - g_audio_source_type = strdup(VCE_AUDIO_ID_NONE); g_feed_audio_data = callback; g_is_recording = false; @@ -189,19 +187,23 @@ int vcd_dependency_set_audio_info(sound_stream_info_h stream_info_h, const char* return VCE_ERROR_INVALID_PARAMETER; } - if (nullptr == g_audio_h || nullptr == g_audio_source_type) { + if (nullptr == g_audio_h) { VCAM_LOGE("[ERROR] Audio in handle is not valid."); return VCE_ERROR_INVALID_STATE; } - if (0 == strncmp(g_audio_source_type, audio_source_type, strlen(g_audio_source_type)) || - (g_audio_type == type && g_audio_rate == rate && g_audio_channel == channel)) { + if (g_audio_type == type && g_audio_rate == rate && g_audio_channel == channel) { VCAM_LOGI("No changed information"); return VCE_ERROR_NONE; } - VCAM_LOGI("New audio type(%d) rate(%d) channel(%d)", type, rate, channel); - audio_in_destroy(g_audio_h); + VCAM_LOGI("New audio type(%d), rate(%d), channel(%d)", type, rate, channel); + + int ret = audio_in_destroy(g_audio_h); + if (0 != ret) { + VCAM_LOGE("[ERROR] Fail to audio in destroy. [ret(%d)]", ret); + return VCE_ERROR_OPERATION_FAILED; + } audio_channel_e audio_ch = AUDIO_CHANNEL_MONO; audio_sample_type_e audio_sample_type = AUDIO_SAMPLE_TYPE_U8; @@ -214,11 +216,10 @@ int vcd_dependency_set_audio_info(sound_stream_info_h stream_info_h, const char* return VCE_ERROR_INVALID_PARAMETER; } - int ret = 0; ret = audio_in_create(rate, audio_ch, audio_sample_type, &g_audio_h); if (AUDIO_IO_ERROR_NONE != ret) { VCAM_LOGE("[ERROR] Fail to create audio handle. [ret(%d)]", ret); - return ret; + return VCE_ERROR_OPERATION_FAILED; } if (0 != audio_in_set_sound_stream_info(g_audio_h, stream_info_h)) { @@ -230,9 +231,22 @@ int vcd_dependency_set_audio_info(sound_stream_info_h stream_info_h, const char* g_audio_channel = channel; VCAM_LOGI(""); - return ret; + return VCE_ERROR_NONE; +} + +int vcd_dependency_get_audio_source_type(char** audio_source_type) +{ + if (nullptr == audio_source_type) { + VCAM_LOGE("audio_source_type is null"); + return VCE_ERROR_INVALID_PARAMETER; + } + + *audio_source_type = strdup(VCE_AUDIO_ID_NONE); + + return VCE_ERROR_NONE; } + int vcd_dependency_start_recording(void) { VCAM_LOGI(""); @@ -272,7 +286,6 @@ int vcd_dependency_stop_recording(void) if (nullptr == g_audio_h) { VCAM_LOGE("[ERROR] Audio in handle is not valid."); - return VCE_ERROR_INVALID_STATE; } @@ -281,7 +294,8 @@ int vcd_dependency_stop_recording(void) ret = audio_in_unprepare(g_audio_h); if (AUDIO_IO_ERROR_NONE != ret) { VCAM_LOGE("[ERROR] Fail to stop audio : %d", ret); + return VCE_ERROR_OPERATION_FAILED; } - return ret; + return VCE_ERROR_NONE; } \ No newline at end of file diff --git a/server/dependency_audio_manager.cpp b/server/dependency_audio_manager.cpp index b604995..762a813 100644 --- a/server/dependency_audio_manager.cpp +++ b/server/dependency_audio_manager.cpp @@ -65,6 +65,8 @@ int dependency_audio_manager_initialize(sound_stream_info_h stream_info_h, depen (vcd_dependency_deinitialize)dlsym(g_lib_handle, VCD_DEPENDENCY_FUNC_DEINITIALIZE); g_interface.set_audio_info = (vcd_dependency_set_audio_info)dlsym(g_lib_handle, VCD_DEPENDENCY_FUNC_SET_AUDIO_INFO); + g_interface.get_audio_source_type = + (vcd_dependency_get_audio_source_type)dlsym(g_lib_handle, VCD_DEPENDENCY_FUNC_GET_AUDIO_SOURCE_TYPE); g_interface.start_recording = (vcd_dependency_start_recording)dlsym(g_lib_handle, VCD_DEPENDENCY_FUNC_START_RECORDING); g_interface.stop_recording = @@ -157,7 +159,36 @@ int dependency_audio_manager_set_audio_info(sound_stream_info_h stream_info_h, c return ret; } -int dependency_audio_manager_start_recording() +int dependency_audio_manager_get_audio_source_type(char** audio_source_type) +{ + SLOG(LOG_DEBUG, LOG_TAG, "@@@ Get audio source type"); + int ret = 0; + if (NULL != g_lib_handle) { + vcd_dependency_get_audio_source_type func = g_interface.get_audio_source_type; + + if (NULL == func) { + SLOG(LOG_ERROR, LOG_TAG, "[ERROR] symbol lookup failed : %s", VCD_DEPENDENCY_FUNC_GET_AUDIO_SOURCE_TYPE); + } else { + try { + ret = func(audio_source_type); + } catch (const std::exception& e) { + SLOG(LOG_ERROR, LOG_TAG, "[ERROR] %s of dependency module threw exception : %s", + VCD_DEPENDENCY_FUNC_GET_AUDIO_SOURCE_TYPE, e.what()); + } + + if (0 != ret) { + SLOG(LOG_ERROR, LOG_TAG, "[ERROR] Fail to initialize, ret(%d)", ret); + } + } + } else { + SLOG(LOG_ERROR, LOG_TAG, "[ERROR] g_lib_handle is not valid"); + } + + SLOG(LOG_DEBUG, LOG_TAG, "@@@"); + return ret; +} + +int dependency_audio_manager_start_recording(void) { SLOG(LOG_DEBUG, LOG_TAG, "@@@ Start recording"); int ret = 0; diff --git a/server/dependency_audio_manager.h b/server/dependency_audio_manager.h index caa0445..5f5ce7b 100644 --- a/server/dependency_audio_manager.h +++ b/server/dependency_audio_manager.h @@ -43,6 +43,8 @@ typedef int (*vcd_dependency_initialize)(sound_stream_info_h stream_info_h, depe typedef int (*vcd_dependency_deinitialize)(void); #define VCD_DEPENDENCY_FUNC_SET_AUDIO_INFO "vcd_dependency_set_audio_info" typedef int (*vcd_dependency_set_audio_info)(sound_stream_info_h stream_info_h, const char* audio_source_type, vce_audio_type_e type, int rate, int channel); +#define VCD_DEPENDENCY_FUNC_GET_AUDIO_SOURCE_TYPE "vcd_dependency_get_audio_source_type" +typedef int (*vcd_dependency_get_audio_source_type)(char** audio_source_type); #define VCD_DEPENDENCY_FUNC_START_RECORDING "vcd_dependency_start_recording" typedef int (*vcd_dependency_start_recording)(void); #define VCD_DEPENDENCY_FUNC_STOP_RECORDING "vcd_dependency_stop_recording" @@ -50,17 +52,19 @@ typedef int (*vcd_dependency_stop_recording)(void); typedef struct { - vcd_dependency_initialize initialize; - vcd_dependency_deinitialize deinitialize; - vcd_dependency_set_audio_info set_audio_info; - vcd_dependency_start_recording start_recording; - vcd_dependency_stop_recording stop_recording; + vcd_dependency_initialize initialize; + vcd_dependency_deinitialize deinitialize; + vcd_dependency_set_audio_info set_audio_info; + vcd_dependency_get_audio_source_type get_audio_source_type; + vcd_dependency_start_recording start_recording; + vcd_dependency_stop_recording stop_recording; } vcd_dependency_module_interface; int dependency_audio_manager_initialize(sound_stream_info_h stream_info_h, dependency_audio_manager_feed_audio_data callback); int dependency_audio_manager_deinitialize(void); int dependency_audio_manager_set_audio_info(sound_stream_info_h stream_info_h, const char* audio_source_type, vce_audio_type_e type, int rate, int channel); +int dependency_audio_manager_get_audio_source_type(char** audio_source_type); int dependency_audio_manager_start_recording(void); int dependency_audio_manager_stop_recording(void); diff --git a/server/vcd_recorder.c b/server/vcd_recorder.c index 969d5b4..0b75741 100644 --- a/server/vcd_recorder.c +++ b/server/vcd_recorder.c @@ -399,7 +399,7 @@ static int __feed_audio_data_cb(const void* data, const unsigned int length) fwrite(data, 1, BUFFER_LENGTH, g_normal_file); #endif - return 0; + return VCD_ERROR_NONE; } @@ -428,10 +428,6 @@ int vcd_recorder_create(vcd_recoder_audio_cb audio_cb, vcd_recorder_interrupt_cb /* set init value */ g_is_valid_audio_in = false; g_is_valid_bt_in = false; - g_current_audio_type = NULL; - - g_pcm_fp = NULL; - g_pcm_path = NULL; ret = sound_manager_add_device_connection_changed_cb(SOUND_DEVICE_IO_DIRECTION_IN_MASK, __device_connection_changed_cb, NULL, &g_device_id); if (0 != ret) @@ -479,6 +475,7 @@ int vcd_recorder_create(vcd_recoder_audio_cb audio_cb, vcd_recorder_interrupt_cb g_is_valid_bt_in = true; } #endif + /* Select default audio type */ if (true == g_is_valid_audio_in) { g_current_audio_type = strdup(VCE_AUDIO_ID_NONE); @@ -576,16 +573,16 @@ int vcd_recorder_destroy() return VCD_ERROR_NONE; } -static int __set_audio_source_type(const char* audio_type) +static int __set_audio_source_type(const char* audio_source_type) { - if (NULL == audio_type) { - SLOG(LOG_INFO, TAG_VCD, "[Recorder] Audio type is NULL"); + if (NULL == audio_source_type) { + SLOG(LOG_INFO, TAG_VCD, "[Recorder] Audio source type is NULL"); return VCD_ERROR_INVALID_PARAMETER; } if (NULL != g_current_audio_type) { - if (0 == strncmp(g_current_audio_type, audio_type, strlen(g_current_audio_type))) { - SLOG(LOG_INFO, TAG_VCD, "[Recorder] Current audio type is already set : %s", audio_type); + if (0 == strncmp(g_current_audio_type, audio_source_type, strlen(g_current_audio_type))) { + SLOG(LOG_INFO, TAG_VCD, "[Recorder] Current audio type is already set : %s", audio_source_type); return VCD_ERROR_NONE; } } else { @@ -593,35 +590,16 @@ static int __set_audio_source_type(const char* audio_type) return VCD_ERROR_INVALID_STATE; } - SLOG(LOG_INFO, TAG_VCD, "[Recorder] set audio type (%s)", audio_type); - vcd_engine_set_audio_type(audio_type); - - if (VCD_RECORDER_STATE_READY != g_recorder_state) { - if (NULL != g_current_audio_type) { - if ((!strncmp(g_current_audio_type, VCE_AUDIO_ID_NONE, strlen(g_current_audio_type)) && - strncmp(audio_type, VCE_AUDIO_ID_BLUETOOTH, strlen(audio_type)) && - strncmp(audio_type, VCE_AUDIO_ID_FFV, strlen(audio_type)) && - strncmp(audio_type, VCE_AUDIO_ID_WIFI, strlen(audio_type))) || - (strncmp(g_current_audio_type, VCE_AUDIO_ID_BLUETOOTH, strlen(g_current_audio_type)) && - strncmp(g_current_audio_type, VCE_AUDIO_ID_FFV, strlen(g_current_audio_type)) && - strncmp(g_current_audio_type, VCE_AUDIO_ID_WIFI, strlen(g_current_audio_type)) && - strncmp(g_current_audio_type, VCE_AUDIO_ID_NONE, strlen(g_current_audio_type)) && - !strncmp(audio_type, VCE_AUDIO_ID_NONE, strlen(audio_type)))) { - SLOG(LOG_INFO, TAG_VCD, "[Recorder] Skip stop recording while Recorder is NOT ready"); - } else { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Recorder is NOT ready"); - vcd_recorder_stop(); - //return VCD_ERROR_INVALID_STATE; - } - } - } + SLOG(LOG_INFO, TAG_VCD, "[Recorder] set audio type (%s)", audio_source_type); + vcd_engine_set_audio_type(audio_source_type); + // Set new audio source type if (NULL != g_current_audio_type) { free(g_current_audio_type); g_current_audio_type = NULL; } - g_current_audio_type = strdup(audio_type); + g_current_audio_type = strdup(audio_source_type); return VCD_ERROR_NONE; } @@ -647,17 +625,17 @@ int vcd_recorder_set(const char* audio_type, vce_audio_type_e type, int rate, in SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Audio-in is NOT valid"); return VCD_ERROR_OPERATION_REJECTED; } + } - ret = dependency_audio_manager_set_audio_info(g_stream_info_h, audio_type, type, rate, channel); - if (0 != ret) { - g_is_valid_audio_in = false; - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to set audio information"); - } + ret = dependency_audio_manager_set_audio_info(g_stream_info_h, audio_type, type, rate, channel); + if (0 != ret) { + g_is_valid_audio_in = false; + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to set audio information"); } SLOG(LOG_INFO, TAG_VCD, "[Recorder] Current audio type is changed : %s", g_current_audio_type); - return 0; + return VCD_ERROR_NONE; } int vcd_recorder_get(char** audio_type) @@ -666,14 +644,13 @@ int vcd_recorder_get(char** audio_type) return VCD_ERROR_INVALID_PARAMETER; } - if (NULL != g_current_audio_type) { - *audio_type = strdup(g_current_audio_type); - } else { + if (0 != dependency_audio_manager_get_audio_source_type(audio_type)) { SLOG(LOG_WARN, TAG_VCD, "[Recorder] Current audio type(%s) is NOT ready", *audio_type); *audio_type = NULL; + return VCD_ERROR_INVALID_STATE; } - return 0; + return VCD_ERROR_NONE; } // TODO: make common function? @@ -734,9 +711,8 @@ Eina_Bool __read_test_func(void *data) buffer_size = MIN(buffer_size, BUFFER_LENGTH); - // TODO: change to __feed_audio_data_cb - if (NULL != g_audio_cb && buffer_size != 0) - g_audio_cb(buffer, buffer_size); + if (buffer_size != 0) + __feed_audio_data_cb(buffer, buffer_size); float vol_db = get_volume_decibel(buffer, buffer_size); if (0 != vcdc_send_set_volume(vcd_client_manager_get_pid(), vol_db)) @@ -747,6 +723,7 @@ Eina_Bool __read_test_func(void *data) g_pcm_fp = NULL; return EINA_FALSE; } + return EINA_TRUE; } @@ -756,31 +733,6 @@ static void __timer_read_test_func(void *data) return; } -static void __check_audio_format() -{ - vce_audio_type_e type; - int rate; - int channel; - - int ret = vcd_engine_get_audio_format(VCE_AUDIO_ID_NONE, &type, &rate, &channel); - if (0 != ret) { - SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get audio format : %d", ret); - return; - } - - if (false == g_is_valid_audio_in) { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Audio-in is NOT valid"); - return; - } - - ret = dependency_audio_manager_set_audio_info(g_stream_info_h, VCE_AUDIO_ID_NONE, type, rate, channel); - if (0 != ret) { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to set audio information"); - g_is_valid_audio_in = false; - return; - } -} - int vcd_recorder_start_streaming() { SLOG(LOG_INFO, TAG_VCD, "[Recorder] start streaming"); @@ -822,7 +774,7 @@ int vcd_recorder_start_streaming() } #endif - return 0; + return VCD_ERROR_NONE; } int vcd_recorder_send_streaming(const void* buffer, const unsigned int length) @@ -849,7 +801,7 @@ int vcd_recorder_send_streaming(const void* buffer, const unsigned int length) fwrite(buffer, 1, length, g_normal_file); #endif - return 0; + return VCD_ERROR_NONE; } int vcd_recorder_stop_streaming() @@ -868,7 +820,7 @@ int vcd_recorder_stop_streaming() fclose(g_normal_file); #endif - return 0; + return VCD_ERROR_NONE; } int vcd_recorder_change_system_volume() @@ -897,7 +849,7 @@ int vcd_recorder_change_system_volume() } } - return 0; + return VCD_ERROR_NONE; } int vcd_recorder_recover_system_volume() @@ -927,7 +879,7 @@ int vcd_recorder_recover_system_volume() g_stream_for_volume_h = NULL; } - return 0; + return VCD_ERROR_NONE; } int vcd_recorder_start() @@ -955,19 +907,13 @@ int vcd_recorder_start() // For testing ecore_main_loop_thread_safe_call_async(__timer_read_test_func, NULL); } else { - if (NULL != g_current_audio_type && 0 == strncmp(VCE_AUDIO_ID_NONE, g_current_audio_type, strlen(VCE_AUDIO_ID_NONE))) { - /* check audio format */ - __check_audio_format(); + ret = dependency_audio_manager_start_recording(); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to start recording, [ret(%d)]", ret); + return VCD_ERROR_OPERATION_FAILED; } } - ret = dependency_audio_manager_start_recording(); - if (0 != ret) { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to start recording, [ret(%d)]", ret); - - return ret; - } - g_recorder_state = VCD_RECORDER_STATE_RECORDING; #ifdef BUF_SAVE_MODE @@ -1023,21 +969,22 @@ int vcd_recorder_stop() fclose(g_normal_file); #endif - if (g_pcm_path) - free(g_pcm_path); - g_pcm_path = NULL; - - if (g_pcm_fp) + if (NULL != g_pcm_fp) { fclose(g_pcm_fp); - g_pcm_fp = NULL; - - ret = dependency_audio_manager_stop_recording(); - if (0 != ret) { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to stop audio : %d", ret); - return ret; + g_pcm_fp = NULL; } - __set_audio_source_type(VCE_AUDIO_ID_NONE); + if (NULL != g_pcm_path) { + // For testing + free(g_pcm_path); + g_pcm_path = NULL; + } else { + ret = dependency_audio_manager_stop_recording(); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to stop audio : %d", ret); + return ret; + } + } return VCD_ERROR_NONE; } @@ -1049,15 +996,16 @@ int vcd_recorder_get_state() int vcd_recorder_set_pcm_path(const char *path) { - SLOG(LOG_INFO, TAG_VCD, "[Recorder] set pcm path : %s", path); - - if (path == NULL) - return 0; + if (path == NULL) { + return VCD_ERROR_INVALID_PARAMETER; + } - if (g_pcm_path) + SLOG(LOG_INFO, TAG_VCD, "[Recorder] set pcm path : %s", path); + if (NULL != g_pcm_path) { free(g_pcm_path); - g_pcm_path = NULL; + g_pcm_path = NULL; + } g_pcm_path = strdup(path); - return 0; + return VCD_ERROR_NONE; } -- 2.7.4 From fedaa38dc3b6b11eef712fac7d420fa33fd5816e Mon Sep 17 00:00:00 2001 From: Suyeon Hwang Date: Thu, 9 Jul 2020 14:33:34 +0900 Subject: [PATCH 10/16] Remove code only for TV device Change-Id: I0fa7dfbe48c72015d6a14bacea0bccc71bd4edde Signed-off-by: Suyeon Hwang --- CMakeLists.txt | 7 - audio-manager/src/vc_audio_manager.cpp | 36 +++- packaging/voice-control.spec | 12 -- server/vcd_recorder.c | 383 +++------------------------------ 4 files changed, 56 insertions(+), 382 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 091ba64..b9fabd8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,17 +45,10 @@ INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/include") ## Dependent packages ## INCLUDE(FindPkgConfig) -IF("${_TV_PRODUCT}" STREQUAL "TRUE") -pkg_check_modules(pkgs REQUIRED - aul buxton2 capi-appfw-app-control capi-appfw-app-manager capi-base-common capi-media-audio-io capi-media-sound-manager ecore-wl2 - capi-network-bluetooth capi-network-bluetooth-tv capi-system-info cynara-client cynara-session dbus-1 db-util dlog ecore glib-2.0 json-glib-1.0 libgum libtzplatform-config libxml-2.0 sqlite3 vconf msfapi farfield-voice-api gmock -) -ELSE() pkg_check_modules(pkgs REQUIRED aul buxton2 capi-appfw-app-control capi-appfw-app-manager capi-base-common capi-media-audio-io capi-media-sound-manager ecore-wl2 capi-system-info cynara-client cynara-session dbus-1 db-util dlog ecore glib-2.0 json-glib-1.0 libgum libtzplatform-config libxml-2.0 sqlite3 vconf gmock ) -ENDIF() ## API ## diff --git a/audio-manager/src/vc_audio_manager.cpp b/audio-manager/src/vc_audio_manager.cpp index 32631f3..e1253ae 100644 --- a/audio-manager/src/vc_audio_manager.cpp +++ b/audio-manager/src/vc_audio_manager.cpp @@ -49,14 +49,30 @@ static bool __convert_audio_channel(int channel, audio_channel_e* output) audio_channel_e audio_ch = AUDIO_CHANNEL_MONO; switch (channel) { - case 1: audio_ch = AUDIO_CHANNEL_MONO; break; - case 2: audio_ch = AUDIO_CHANNEL_STEREO; break; - case 3: audio_ch = AUDIO_CHANNEL_MULTI_3; break; - case 4: audio_ch = AUDIO_CHANNEL_MULTI_4; break; - case 5: audio_ch = AUDIO_CHANNEL_MULTI_5; break; - case 6: audio_ch = AUDIO_CHANNEL_MULTI_6; break; - case 7: audio_ch = AUDIO_CHANNEL_MULTI_7; break; - case 8: audio_ch = AUDIO_CHANNEL_MULTI_8; break; + case 1: + audio_ch = AUDIO_CHANNEL_MONO; + break; + case 2: + audio_ch = AUDIO_CHANNEL_STEREO; + break; + case 3: + audio_ch = AUDIO_CHANNEL_MULTI_3; + break; + case 4: + audio_ch = AUDIO_CHANNEL_MULTI_4; + break; + case 5: + audio_ch = AUDIO_CHANNEL_MULTI_5; + break; + case 6: + audio_ch = AUDIO_CHANNEL_MULTI_6; + break; + case 7: + audio_ch = AUDIO_CHANNEL_MULTI_7; + break; + case 8: + audio_ch = AUDIO_CHANNEL_MULTI_8; + break; default: VCAM_LOGE("[ERROR] Input channel is not supported. [channel(%d)]", channel); return false; @@ -97,7 +113,7 @@ static Eina_Bool __recorder_timer_func(void *data) int read_bytes = audio_in_read(g_audio_h, buffer, BUFFER_LENGTH); if (0 > read_bytes) { - VCAM_LOGW("[WARNING] Fail to read audio : %d", read_bytes); + VCAM_LOGW("Fail to read audio : %d", read_bytes); return ECORE_CALLBACK_DONE; } @@ -230,7 +246,6 @@ int vcd_dependency_set_audio_info(sound_stream_info_h stream_info_h, const char* g_audio_rate = rate; g_audio_channel = channel; - VCAM_LOGI(""); return VCE_ERROR_NONE; } @@ -246,7 +261,6 @@ int vcd_dependency_get_audio_source_type(char** audio_source_type) return VCE_ERROR_NONE; } - int vcd_dependency_start_recording(void) { VCAM_LOGI(""); diff --git a/packaging/voice-control.spec b/packaging/voice-control.spec index 8c36205..b4c4acc 100644 --- a/packaging/voice-control.spec +++ b/packaging/voice-control.spec @@ -33,12 +33,6 @@ BuildRequires: pkgconfig(libxml-2.0) BuildRequires: pkgconfig(sqlite3) BuildRequires: pkgconfig(pkgmgr-info) BuildRequires: pkgconfig(pkgmgr-installer) -%if "%{tizen_profile_name}" == "tv" -BuildRequires: pkgconfig(capi-network-bluetooth) -BuildRequires: pkgconfig(capi-network-bluetooth-tv) -BuildRequires: pkgconfig(msfapi) -BuildRequires: pkgconfig(farfield-voice-api) -%endif BuildRequires: pkgconfig(vconf) BuildRequires: cmake BuildRequires: pkgconfig(gmock) @@ -126,14 +120,8 @@ export FFLAGS="$FFLAGS -fprofile-arcs -ftest-coverage" export LDFLAGS="$LDFLAGS -lgcov" %endif -%if "%{tizen_profile_name}" == "tv" -export CFLAGS="$CFLAGS -DTV_PRODUCT" -cmake . -DCMAKE_INSTALL_PREFIX=/usr -DLIBDIR=%{_libdir} -DBINDIR=%{_bindir} -DINCLUDEDIR=%{_includedir} \ - -DTZ_SYS_RO_SHARE=%TZ_SYS_RO_SHARE -D_TV_PRODUCT=TRUE -DTZ_SYS_BIN=%TZ_SYS_BIN -DTZ_SYS_RO_PACKAGES=%TZ_SYS_RO_PACKAGES -DTZ_SYS_RO_APP=%TZ_SYS_RO_APP -%else cmake . -DCMAKE_INSTALL_PREFIX=/usr -DLIBDIR=%{_libdir} -DBINDIR=%{_bindir} -DINCLUDEDIR=%{_includedir} \ -DTZ_SYS_RO_SHARE=%TZ_SYS_RO_SHARE -DTZ_SYS_BIN=%TZ_SYS_BIN -DTZ_SYS_RO_PACKAGES=%TZ_SYS_RO_PACKAGES -DTZ_SYS_RO_APP=%TZ_SYS_RO_APP -%endif make %{?jobs:-j%jobs} %if 0%{?gcov:1} diff --git a/server/vcd_recorder.c b/server/vcd_recorder.c index 0b75741..74875e8 100644 --- a/server/vcd_recorder.c +++ b/server/vcd_recorder.c @@ -14,27 +14,10 @@ * limitations under the License. */ -#ifdef TV_PRODUCT -#define TV_BT_MODE -#define TV_MSF_WIFI_MODE -#define TV_FFV_MODE -#endif - #include #include #include #include -#ifdef TV_PRODUCT -#ifdef TV_BT_MODE -#include -#endif -#ifdef TV_MSF_WIFI_MODE -#include -#endif -#ifdef TV_FFV_MODE -#include -#endif -#endif #include "vcd_client_data.h" #include "vcd_config.h" @@ -62,20 +45,13 @@ static sound_stream_info_h g_stream_info_h = NULL; static sound_stream_info_h g_stream_for_volume_h = NULL; static virtual_sound_stream_h g_virtual_sound_stream_h = NULL; -static bool g_is_valid_audio_in = false; -static bool g_is_valid_bt_in = false; -static char* g_current_audio_type = NULL; static int g_buffer_count = 0; static int g_device_id = -1; static char* g_pcm_path = NULL; static FILE* g_pcm_fp = NULL; -#ifdef TV_FFV_MODE -farfield_voice_h g_farfieldvoice_h = NULL; -#endif - /* Sound buf save */ #if 0 @@ -87,165 +63,40 @@ static FILE* g_normal_file = NULL; static int g_count = 1; #endif -static float get_volume_decibel(const char* data, const unsigned int size); - -#ifdef TV_MSF_WIFI_MODE -static void __msf_wifi_audio_data_receive_cb(msf_wifi_voice_data_s *voice_data, void* user_data) -{ - if (0 != strncmp(g_current_audio_type, VCE_AUDIO_ID_WIFI, sizeof(VCE_AUDIO_ID_WIFI))) { - vcd_state_e state = vcd_config_get_service_state(); - if (VCD_STATE_READY == state) { - vcd_recorder_set(VCE_AUDIO_ID_WIFI, VCE_AUDIO_TYPE_PCM_S16_LE, 16000, 1); - } else { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] current audio type is (%s)", g_current_audio_type); - return; - } - } - - if (VCD_RECORDER_STATE_RECORDING != g_recorder_state) { - SLOG(LOG_WARN, TAG_VCD, "[Recorder] Not start yet, but send audio data vi Wi-Fi"); - vcd_recorder_start(); - } - - if (NULL != g_audio_cb) { - if (0 != g_audio_cb((void*)voice_data->audio_buf, (unsigned int)voice_data->length)) { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to read audio"); - vcd_recorder_stop(); - } - } - - /* Set volume */ - if (0 == g_buffer_count % 30) { - float vol_db = get_volume_decibel((char*)voice_data->audio_buf, (unsigned int)voice_data->length); - if (0 != vcdc_send_set_volume(vcd_client_manager_get_pid(), vol_db)) { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder] Fail to send recording volume(%f)", vol_db); - } - } - if (0 == g_buffer_count || 0 == g_buffer_count % 50) { - SLOG(LOG_WARN, TAG_VCD, "[Recorder][%d] Recording... : read_size(%ld)", g_buffer_count, voice_data->length); - - if (100000 == g_buffer_count) - g_buffer_count = 0; - } - - g_buffer_count++; - -#ifdef BUF_SAVE_MODE - /* write pcm buffer */ - fwrite(voice_data->audio_buf, 1, voice_data->length, g_normal_file); -#endif - return; -} - -#endif - - -#ifdef TV_BT_MODE -static int g_bt_extend_count; - -#define SMART_CONTROL_EXTEND_CMD 0x03 -#define SMART_CONTROL_START_CMD 0x04 - -static void _bt_cb_hid_state_changed(int result, bool connected, const char *remote_address, void *user_data) -{ - SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Bluetooth Event [%d] Received address [%s]", result, remote_address); - return; -} - -static void _bt_hid_audio_data_receive_cb(bt_hid_voice_data_s *voice_data, void *user_data) +// TODO: make common function? +static float get_volume_decibel(const char* data, const unsigned int size) { - if (0 != strncmp(g_current_audio_type, VCE_AUDIO_ID_BLUETOOTH, sizeof(VCE_AUDIO_ID_BLUETOOTH))) { - vcd_state_e state = vcd_config_get_service_state(); - if (VCD_STATE_READY == state) { - vcd_recorder_set(VCE_AUDIO_ID_BLUETOOTH, VCE_AUDIO_TYPE_PCM_S16_LE, 16000, 1); - } else { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] current audio type is (%s)", g_current_audio_type); - return; - } - } - - if (VCD_RECORDER_STATE_RECORDING != g_recorder_state) { - SLOG(LOG_WARN, TAG_VCD, "[Recorder] Not start yet, but send audio data vi Bluetooth"); - // vcd_recorder_start(); - } - - if (NULL != g_audio_cb) { - if (0 != g_audio_cb((void*)voice_data->audio_buf, (unsigned int)voice_data->length)) { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to read audio"); - vcd_recorder_stop(); - } - } - - /* Set volume */ - if (0 == g_buffer_count % 15) { - float vol_db = get_volume_decibel((char*)voice_data->audio_buf, (unsigned int)voice_data->length); - if (0 != vcdc_send_set_volume(vcd_client_manager_get_pid(), vol_db)) { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder] Fail to send recording volume(%f)", vol_db); - } - } - - if (0 == g_buffer_count || 0 == g_buffer_count % 50) { - SLOG(LOG_WARN, TAG_VCD, "[Recorder][%d] Recording... : read_size(%d)", g_buffer_count, voice_data->length); - - if (0 == g_bt_extend_count % 5 && 0 != g_buffer_count) { - const unsigned char input_data[2] = {SMART_CONTROL_EXTEND_CMD, 0x10 }; - if (BT_ERROR_NONE != bt_hid_send_rc_command(NULL, input_data, sizeof(input_data))) { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail bt_hid_send_rc_command"); - } else { - SLOG(LOG_INFO, TAG_VCD, "[Recorder] Extend bt audio recorder"); - } - } - g_bt_extend_count++; - - if (100000 == g_buffer_count) { - g_buffer_count = 0; - } - } + const int MAX_AMPLITUDE_MEAN_16 = 32768; - g_buffer_count++; + int i, depthByte; + int count = 0; -#ifdef BUF_SAVE_MODE - /* write pcm buffer */ - fwrite(voice_data->audio_buf, 1, voice_data->length, g_normal_file); -#endif - return; -} -#endif + float db = 0.0; + float rms = 0.0; + unsigned long long square_sum = 0; + short pcm16 = 0; -#ifdef TV_FFV_MODE -static void _ffv_audio_function_cb(void* data, unsigned int length, void* user_data) -{ - if (0 == g_buffer_count || 0 == g_buffer_count % 50) { - SLOG(LOG_INFO, TAG_VCD, "[Recorder INFO] farfield audio function callback is invoked"); + depthByte = 2; - if (100000 == g_buffer_count) { - g_buffer_count = 0; - } + for (i = 0; i < size; i += (depthByte<<1)) { + pcm16 = 0; + memcpy(&pcm16, data + i, sizeof(short)); + square_sum += pcm16 * pcm16; + count++; } - g_buffer_count++; - - if (0 != strncmp(g_current_audio_type, VCE_AUDIO_ID_FFV, sizeof(VCE_AUDIO_ID_FFV))) { - vcd_state_e state = vcd_config_get_service_state(); - if (VCD_STATE_READY == state) { - vcd_recorder_set(VCE_AUDIO_ID_FFV, VCE_AUDIO_TYPE_PCM_S16_LE, 16000, 1); - } else { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] current audio type is (%s)", g_current_audio_type); - return; - } + if (0 == count || 0 == square_sum) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] No data"); + rms = 1.0; + } else { + rms = sqrt((float)square_sum/count); } - if (NULL != g_audio_cb) { - if (0 != g_audio_cb(data, length)) { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to read audio"); - vcd_recorder_stop(); - } - } + db = 20 * log10(rms/MAX_AMPLITUDE_MEAN_16); + return db; } -#endif -#if 1 static const char* __get_focus_changed_reason_code(sound_stream_focus_change_reason_e reason) { switch (reason) { @@ -283,7 +134,6 @@ static void __recorder_focus_state_cb(sound_stream_info_h stream_info, sound_str } } } -#endif static int __apply_device_for_stream_routing() { @@ -423,13 +273,7 @@ int vcd_recorder_create(vcd_recoder_audio_cb audio_cb, vcd_recorder_interrupt_cb } } - int ret = 0; - - /* set init value */ - g_is_valid_audio_in = false; - g_is_valid_bt_in = false; - - ret = sound_manager_add_device_connection_changed_cb(SOUND_DEVICE_IO_DIRECTION_IN_MASK, __device_connection_changed_cb, NULL, &g_device_id); + int ret = sound_manager_add_device_connection_changed_cb(SOUND_DEVICE_IO_DIRECTION_IN_MASK, __device_connection_changed_cb, NULL, &g_device_id); if (0 != ret) SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to add device connection changed callback"); @@ -441,74 +285,14 @@ int vcd_recorder_create(vcd_recoder_audio_cb audio_cb, vcd_recorder_interrupt_cb if (0 != dependency_audio_manager_initialize(g_stream_info_h, __feed_audio_data_cb)) { SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to initialize dependency audio manager"); - g_is_valid_audio_in = false; - } else { - g_is_valid_audio_in = true; + return VCD_ERROR_OPERATION_FAILED; } g_audio_cb = audio_cb; g_interrupt_cb = interrupt_cb; g_recorder_state = VCD_RECORDER_STATE_READY; -#ifdef TV_FFV_MODE - g_farfieldvoice_h = farfield_voice_init(); - if (NULL == g_farfieldvoice_h) { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to init farfield_voice_init"); - } -#endif - -#ifdef TV_BT_MODE - bool is_bt_failed = false; - - if (false == is_bt_failed && BT_ERROR_NONE != bt_product_init()) { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to init bt"); - is_bt_failed = true; - } - - if (false == is_bt_failed && BT_ERROR_NONE != bt_hid_host_initialize(_bt_cb_hid_state_changed, NULL)) { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail bt_hid_host_initialize()"); - is_bt_failed = true; - } - - if (false == is_bt_failed) { - SLOG(LOG_INFO, TAG_VCD, "[Recorder] Bluetooth is available"); - g_is_valid_bt_in = true; - } -#endif - - /* Select default audio type */ - if (true == g_is_valid_audio_in) { - g_current_audio_type = strdup(VCE_AUDIO_ID_NONE); - } else { - if (true == g_is_valid_bt_in) { - g_current_audio_type = strdup(VCE_AUDIO_ID_BLUETOOTH); - } else { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] No valid audio"); - return -1; - } - } - - SLOG(LOG_INFO, TAG_VCD, "[Recorder] Audio type : %s", g_current_audio_type); - - /* Set audio feed callback */ -#ifdef TV_BT_MODE - if (BT_ERROR_NONE != bt_hid_set_audio_data_receive_cb(_bt_hid_audio_data_receive_cb, NULL)) { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail bt_hid_set_audio_data_receive_cb()"); - } -#endif -#ifdef TV_FFV_MODE - if (g_farfieldvoice_h) { - SLOG(LOG_INFO, TAG_VCD, "[Recorder INFO] Register farfield voice audio callback"); - farfield_voice_register_audio_cb(g_farfieldvoice_h, _ffv_audio_function_cb, NULL); - } -#endif -#ifdef TV_MSF_WIFI_MODE - if (MSFResult_OK != RegisterMSFAudioCallback(__msf_wifi_audio_data_receive_cb, NULL)) { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to start Wi-Fi audio"); - } -#endif - - return 0; + return ret; } int vcd_recorder_destroy() @@ -534,32 +318,8 @@ int vcd_recorder_destroy() SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to audio in destroy, ret(%d)", ret); } - -#ifdef TV_MSF_WIFI_MODE - UnRegisterMSFAudioCallback(); -#endif - -#ifdef TV_FFV_MODE - if (NULL != g_farfieldvoice_h) { - SLOG(LOG_INFO, TAG_VCD, "[Recorder INFO] Unregister farfield voice"); - farfield_voice_final(g_farfieldvoice_h); - g_farfieldvoice_h = NULL; - } -#endif - -#ifdef TV_BT_MODE - bt_hid_unset_audio_data_receive_cb(); - bt_hid_host_deinitialize(); - bt_product_deinit(); -#endif - g_audio_cb = NULL; - if (NULL != g_current_audio_type) { - free(g_current_audio_type); - g_current_audio_type = NULL; - } - if (NULL != g_pcm_path) { free(g_pcm_path); g_pcm_path = NULL; @@ -573,68 +333,23 @@ int vcd_recorder_destroy() return VCD_ERROR_NONE; } -static int __set_audio_source_type(const char* audio_source_type) +int vcd_recorder_set(const char* audio_type, vce_audio_type_e type, int rate, int channel) { - if (NULL == audio_source_type) { - SLOG(LOG_INFO, TAG_VCD, "[Recorder] Audio source type is NULL"); + if (NULL == audio_type) { + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] audio_type is NULL"); return VCD_ERROR_INVALID_PARAMETER; } - if (NULL != g_current_audio_type) { - if (0 == strncmp(g_current_audio_type, audio_source_type, strlen(g_current_audio_type))) { - SLOG(LOG_INFO, TAG_VCD, "[Recorder] Current audio type is already set : %s", audio_source_type); - return VCD_ERROR_NONE; - } - } else { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Recorder is NOT created"); - return VCD_ERROR_INVALID_STATE; - } - - SLOG(LOG_INFO, TAG_VCD, "[Recorder] set audio type (%s)", audio_source_type); - vcd_engine_set_audio_type(audio_source_type); - - // Set new audio source type - if (NULL != g_current_audio_type) { - free(g_current_audio_type); - g_current_audio_type = NULL; - } - - g_current_audio_type = strdup(audio_source_type); + SLOG(LOG_INFO, TAG_VCD, "[Recorder] set audio type (%s)", audio_type); + vcd_engine_set_audio_type(audio_type); - return VCD_ERROR_NONE; -} - -int vcd_recorder_set(const char* audio_type, vce_audio_type_e type, int rate, int channel) -{ int ret = -1; - ret = __set_audio_source_type(audio_type); - if (0 != ret) { - return ret; - } - - /* Check BT audio */ - if (0 == strncmp(VCE_AUDIO_ID_BLUETOOTH, audio_type, strlen(VCE_AUDIO_ID_BLUETOOTH))) { - if (false == g_is_valid_bt_in) { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder] BT audio is NOT valid"); - return VCD_ERROR_OPERATION_REJECTED; - } - } else if (0 == strncmp(VCE_AUDIO_ID_WIFI, audio_type, strlen(VCE_AUDIO_ID_WIFI))) { - } else if (0 == strncmp(VCE_AUDIO_ID_FFV, audio_type, strlen(VCE_AUDIO_ID_FFV))) { - } else { - if (false == g_is_valid_audio_in) { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Audio-in is NOT valid"); - return VCD_ERROR_OPERATION_REJECTED; - } - } - ret = dependency_audio_manager_set_audio_info(g_stream_info_h, audio_type, type, rate, channel); if (0 != ret) { - g_is_valid_audio_in = false; SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to set audio information"); + return VCD_ERROR_OPERATION_FAILED; } - SLOG(LOG_INFO, TAG_VCD, "[Recorder] Current audio type is changed : %s", g_current_audio_type); - return VCD_ERROR_NONE; } @@ -653,39 +368,6 @@ int vcd_recorder_get(char** audio_type) return VCD_ERROR_NONE; } -// TODO: make common function? -static float get_volume_decibel(const char* data, const unsigned int size) -{ - const int MAX_AMPLITUDE_MEAN_16 = 32768; - - int i, depthByte; - int count = 0; - - float db = 0.0; - float rms = 0.0; - unsigned long long square_sum = 0; - short pcm16 = 0; - - depthByte = 2; - - for (i = 0; i < size; i += (depthByte<<1)) { - pcm16 = 0; - memcpy(&pcm16, data + i, sizeof(short)); - square_sum += pcm16 * pcm16; - count++; - } - - if (0 == count || 0 == square_sum) { - SLOG(LOG_ERROR, TAG_VCD, "[ERROR] No data"); - rms = 1.0; - } else { - rms = sqrt((float)square_sum/count); - } - - db = 20 * log10(rms/MAX_AMPLITUDE_MEAN_16); - return db; -} - Eina_Bool __read_test_func(void *data) { if (VCD_RECORDER_STATE_RECORDING != g_recorder_state) { @@ -894,9 +576,6 @@ int vcd_recorder_start() } g_buffer_count = 0; -#ifdef TV_BT_MODE - g_bt_extend_count = 0; -#endif SLOG(LOG_INFO, TAG_VCD, "[Recorder] Enter, recorder state(%d)", g_recorder_state); if (VCD_RECORDER_STATE_RECORDING == g_recorder_state) { -- 2.7.4 From 49fcc09cfead50dc72c2f19327cd1d3a2034cc96 Mon Sep 17 00:00:00 2001 From: Suyeon Hwang Date: Thu, 3 Sep 2020 20:13:54 +0900 Subject: [PATCH 11/16] Implement new interface for sending streaming mode to dependency module Change-Id: I7d01effab7dae6380f3525dbbec595a041376d20 Signed-off-by: Suyeon Hwang --- audio-manager/inc/vc_audio_manager.h | 1 + audio-manager/src/vc_audio_manager.cpp | 15 +++++++++++++++ server/dependency_audio_manager.cpp | 31 +++++++++++++++++++++++++++++++ server/dependency_audio_manager.h | 5 +++++ server/vcd_dbus_server.c | 2 +- server/vcd_recorder.c | 10 ++++++++++ server/vcd_recorder.h | 2 ++ server/vcd_server.c | 4 +++- server/vcd_server.h | 2 +- 9 files changed, 69 insertions(+), 3 deletions(-) diff --git a/audio-manager/inc/vc_audio_manager.h b/audio-manager/inc/vc_audio_manager.h index 59354e2..4c41777 100644 --- a/audio-manager/inc/vc_audio_manager.h +++ b/audio-manager/inc/vc_audio_manager.h @@ -30,6 +30,7 @@ int vcd_dependency_initialize(sound_stream_info_h stream_info_h, dependency_audi int vcd_dependency_deinitialize(void); int vcd_dependency_set_audio_info(sound_stream_info_h stream_info_h, const char* audio_source_type, vce_audio_type_e type, int rate, int channel); int vcd_dependency_get_audio_source_type(char** audio_source_type); +int vcd_dependency_set_streaming_mode(vc_audio_streaming_mode_e mode); int vcd_dependency_start_recording(void); int vcd_dependency_stop_recording(void); diff --git a/audio-manager/src/vc_audio_manager.cpp b/audio-manager/src/vc_audio_manager.cpp index e1253ae..c595f01 100644 --- a/audio-manager/src/vc_audio_manager.cpp +++ b/audio-manager/src/vc_audio_manager.cpp @@ -25,6 +25,7 @@ #include #include "vce.h" +#include "voice_control_manager.h" #include "vc_audio_manager_dlog.h" #include "vc_audio_manager.h" @@ -38,6 +39,7 @@ static dependency_audio_manager_feed_audio_data g_feed_audio_data = nullptr; static audio_in_h g_audio_h = nullptr; static vce_audio_type_e g_audio_type = VCE_AUDIO_TYPE_PCM_S16_LE; +static vc_audio_streaming_mode_e g_streaming_mode = VC_AUDIO_STREAMING_MODE_VC_SERVICE; static int g_audio_rate = 0; static int g_audio_channel = 0; @@ -133,6 +135,7 @@ int vcd_dependency_initialize(sound_stream_info_h stream_info_h, dependency_audi { int ret = 0; + g_streaming_mode = VC_AUDIO_STREAMING_MODE_VC_SERVICE; g_audio_type = VCE_AUDIO_TYPE_PCM_S16_LE; g_audio_rate = 16000; g_audio_channel = 1; @@ -261,6 +264,18 @@ int vcd_dependency_get_audio_source_type(char** audio_source_type) return VCE_ERROR_NONE; } +int vcd_dependency_set_streaming_mode(vc_audio_streaming_mode_e mode) +{ + if (nullptr == g_audio_h) { + VCAM_LOGE("[ERROR] g_audio_h is not created"); + return VCE_ERROR_INVALID_STATE; + } + + g_streaming_mode = mode; + + return VCE_ERROR_NONE; +} + int vcd_dependency_start_recording(void) { VCAM_LOGI(""); diff --git a/server/dependency_audio_manager.cpp b/server/dependency_audio_manager.cpp index 762a813..8e2f6b0 100644 --- a/server/dependency_audio_manager.cpp +++ b/server/dependency_audio_manager.cpp @@ -67,6 +67,8 @@ int dependency_audio_manager_initialize(sound_stream_info_h stream_info_h, depen (vcd_dependency_set_audio_info)dlsym(g_lib_handle, VCD_DEPENDENCY_FUNC_SET_AUDIO_INFO); g_interface.get_audio_source_type = (vcd_dependency_get_audio_source_type)dlsym(g_lib_handle, VCD_DEPENDENCY_FUNC_GET_AUDIO_SOURCE_TYPE); + g_interface.set_streaming_mode = + (vcd_dependency_set_streaming_mode)dlsym(g_lib_handle, VCD_DEPENDENCY_FUNC_SET_STREAMING_MODE); g_interface.start_recording = (vcd_dependency_start_recording)dlsym(g_lib_handle, VCD_DEPENDENCY_FUNC_START_RECORDING); g_interface.stop_recording = @@ -188,6 +190,35 @@ int dependency_audio_manager_get_audio_source_type(char** audio_source_type) return ret; } +int dependency_audio_manager_set_streaming_mode(vc_audio_streaming_mode_e mode) +{ + SLOG(LOG_DEBUG, LOG_TAG, "@@@ Set streaming mode"); + int ret = 0; + if (NULL != g_lib_handle) { + vcd_dependency_set_streaming_mode func = g_interface.set_streaming_mode; + + if (NULL == func) { + SLOG(LOG_ERROR, LOG_TAG, "[ERROR] symbol lookup failed : %s", VCD_DEPENDENCY_FUNC_SET_STREAMING_MODE); + } else { + try { + ret = func(mode); + } catch (const std::exception& e) { + SLOG(LOG_ERROR, LOG_TAG, "[ERROR] %s of dependency module threw exception : %s", + VCD_DEPENDENCY_FUNC_SET_STREAMING_MODE, e.what()); + } + + if (0 != ret) { + SLOG(LOG_ERROR, LOG_TAG, "[ERROR] Fail to set streaming mode, ret(%d)", ret); + } + } + } else { + SLOG(LOG_ERROR, LOG_TAG, "[ERROR] g_lib_handle is not valid"); + } + + SLOG(LOG_DEBUG, LOG_TAG, "@@@"); + return ret; +} + int dependency_audio_manager_start_recording(void) { SLOG(LOG_DEBUG, LOG_TAG, "@@@ Start recording"); diff --git a/server/dependency_audio_manager.h b/server/dependency_audio_manager.h index 5f5ce7b..0eb5ebd 100644 --- a/server/dependency_audio_manager.h +++ b/server/dependency_audio_manager.h @@ -21,6 +21,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -45,6 +46,8 @@ typedef int (*vcd_dependency_deinitialize)(void); typedef int (*vcd_dependency_set_audio_info)(sound_stream_info_h stream_info_h, const char* audio_source_type, vce_audio_type_e type, int rate, int channel); #define VCD_DEPENDENCY_FUNC_GET_AUDIO_SOURCE_TYPE "vcd_dependency_get_audio_source_type" typedef int (*vcd_dependency_get_audio_source_type)(char** audio_source_type); +#define VCD_DEPENDENCY_FUNC_SET_STREAMING_MODE "vcd_dependency_set_streaming_mode" +typedef int (*vcd_dependency_set_streaming_mode)(vc_audio_streaming_mode_e mode); #define VCD_DEPENDENCY_FUNC_START_RECORDING "vcd_dependency_start_recording" typedef int (*vcd_dependency_start_recording)(void); #define VCD_DEPENDENCY_FUNC_STOP_RECORDING "vcd_dependency_stop_recording" @@ -56,6 +59,7 @@ typedef struct { vcd_dependency_deinitialize deinitialize; vcd_dependency_set_audio_info set_audio_info; vcd_dependency_get_audio_source_type get_audio_source_type; + vcd_dependency_set_streaming_mode set_streaming_mode; vcd_dependency_start_recording start_recording; vcd_dependency_stop_recording stop_recording; } vcd_dependency_module_interface; @@ -65,6 +69,7 @@ int dependency_audio_manager_initialize(sound_stream_info_h stream_info_h, depen int dependency_audio_manager_deinitialize(void); int dependency_audio_manager_set_audio_info(sound_stream_info_h stream_info_h, const char* audio_source_type, vce_audio_type_e type, int rate, int channel); int dependency_audio_manager_get_audio_source_type(char** audio_source_type); +int dependency_audio_manager_set_streaming_mode(vc_audio_streaming_mode_e mode); int dependency_audio_manager_start_recording(void); int dependency_audio_manager_stop_recording(void); diff --git a/server/vcd_dbus_server.c b/server/vcd_dbus_server.c index d7314de..d30dd2b 100755 --- a/server/vcd_dbus_server.c +++ b/server/vcd_dbus_server.c @@ -114,7 +114,7 @@ int vcd_dbus_server_mgr_initialize(DBusConnection* conn, DBusMessage* msg) ret = VCD_ERROR_OPERATION_FAILED; } else { vcd_config_set_audio_streaming_mode((vcd_audio_streaming_mode_e)streaming_mode); - ret = vcd_server_mgr_initialize(pid); + ret = vcd_server_mgr_initialize(pid, streaming_mode); service_state = vcd_server_get_service_state(); foreground = vcd_server_get_foreground(); daemon_pid = getpid(); diff --git a/server/vcd_recorder.c b/server/vcd_recorder.c index 74875e8..fc06fec 100644 --- a/server/vcd_recorder.c +++ b/server/vcd_recorder.c @@ -368,6 +368,16 @@ int vcd_recorder_get(char** audio_type) return VCD_ERROR_NONE; } +int vcd_recorder_set_audio_streaming_mode(vcd_audio_streaming_mode_e mode) +{ + if (0 != dependency_audio_manager_set_streaming_mode((vc_audio_streaming_mode_e)mode)) { + SLOG(LOG_WARN, TAG_VCD, "[Recorder] Fail to set audio mode to dependency module(%d)", mode); + return VCD_ERROR_OPERATION_FAILED; + } + + return VCD_ERROR_NONE; +} + Eina_Bool __read_test_func(void *data) { if (VCD_RECORDER_STATE_RECORDING != g_recorder_state) { diff --git a/server/vcd_recorder.h b/server/vcd_recorder.h index 8e1b015..f075cae 100644 --- a/server/vcd_recorder.h +++ b/server/vcd_recorder.h @@ -43,6 +43,8 @@ int vcd_recorder_set(const char* audio_type, vce_audio_type_e type, int rate, in int vcd_recorder_get(char** audio_type); +int vcd_recorder_set_audio_streaming_mode(vcd_audio_streaming_mode_e mode); + int vcd_recorder_start_streaming(); int vcd_recorder_send_streaming(const void* buffer, const unsigned int length); diff --git a/server/vcd_server.c b/server/vcd_server.c index 8c290cf..a89732f 100644 --- a/server/vcd_server.c +++ b/server/vcd_server.c @@ -1659,7 +1659,7 @@ static Eina_Bool __vcd_send_service_state(void *data) /* * API for manager */ -int vcd_server_mgr_initialize(int pid) +int vcd_server_mgr_initialize(int pid, vcd_audio_streaming_mode_e mode) { /* check if pid is valid */ if (false == vcd_client_manager_is_valid(pid)) { @@ -1678,6 +1678,8 @@ int vcd_server_mgr_initialize(int pid) if (0 != vcdc_send_manager_pid(pid)) SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send manager pid"); + vcd_recorder_set_audio_streaming_mode(mode); + ecore_timer_add(0.05, __vcd_send_service_state, NULL); SLOG(LOG_ERROR, TAG_VCD, "[Server Success] Manager initialize : pid(%d)", pid); diff --git a/server/vcd_server.h b/server/vcd_server.h index e675b0b..7597b3d 100644 --- a/server/vcd_server.h +++ b/server/vcd_server.h @@ -45,7 +45,7 @@ int vcd_server_get_foreground(); /* * For manager */ -int vcd_server_mgr_initialize(int pid); +int vcd_server_mgr_initialize(int pid, vcd_audio_streaming_mode_e mode); int vcd_server_mgr_finalize(int pid); -- 2.7.4 From dd5ed31c1ff0d58f18bc327fc3fe6c9c5865e62d Mon Sep 17 00:00:00 2001 From: Suyeon Hwang Date: Mon, 7 Sep 2020 12:27:48 +0900 Subject: [PATCH 12/16] Clean up and Add temporary code for applying new architecture into TV device Change-Id: I975e49001ffb8782c6601393b42ae678ae20622f Signed-off-by: Suyeon Hwang --- audio-manager/src/vc_audio_manager.cpp | 16 ++++++++++++++++ packaging/voice-control.spec | 6 ++++++ server/dependency_audio_manager.h | 4 ++++ 3 files changed, 26 insertions(+) diff --git a/audio-manager/src/vc_audio_manager.cpp b/audio-manager/src/vc_audio_manager.cpp index c595f01..79cf981 100644 --- a/audio-manager/src/vc_audio_manager.cpp +++ b/audio-manager/src/vc_audio_manager.cpp @@ -135,6 +135,11 @@ int vcd_dependency_initialize(sound_stream_info_h stream_info_h, dependency_audi { int ret = 0; + if (nullptr != g_audio_h) { + VCAM_LOGE("Already initialized"); + return VCE_ERROR_INVALID_STATE; + } + g_streaming_mode = VC_AUDIO_STREAMING_MODE_VC_SERVICE; g_audio_type = VCE_AUDIO_TYPE_PCM_S16_LE; g_audio_rate = 16000; @@ -176,6 +181,12 @@ int vcd_dependency_deinitialize(void) { VCAM_LOGI(""); int ret = 0; + + if (nullptr == g_audio_h) { + VCAM_LOGE("Not initialized"); + return VCE_ERROR_INVALID_STATE; + } + if (g_is_recording) { ret = audio_in_unprepare(g_audio_h); if (0 != ret) { @@ -254,6 +265,11 @@ int vcd_dependency_set_audio_info(sound_stream_info_h stream_info_h, const char* int vcd_dependency_get_audio_source_type(char** audio_source_type) { + if (nullptr == g_audio_h) { + VCAM_LOGE("[ERROR] g_audio_h is not created"); + return VCE_ERROR_INVALID_STATE; + } + if (nullptr == audio_source_type) { VCAM_LOGE("audio_source_type is null"); return VCE_ERROR_INVALID_PARAMETER; diff --git a/packaging/voice-control.spec b/packaging/voice-control.spec index b4c4acc..d8e5792 100644 --- a/packaging/voice-control.spec +++ b/packaging/voice-control.spec @@ -120,9 +120,15 @@ export FFLAGS="$FFLAGS -fprofile-arcs -ftest-coverage" export LDFLAGS="$LDFLAGS -lgcov" %endif +%if "%{tizen_profile_name}" == "tv" +export CFLAGS="$CFLAGS -DTV_PRODUCT" +cmake . -DCMAKE_INSTALL_PREFIX=/usr -DLIBDIR=%{_libdir} -DBINDIR=%{_bindir} -DINCLUDEDIR=%{_includedir} \ + -DTZ_SYS_RO_SHARE=%TZ_SYS_RO_SHARE -D_TV_PRODUCT=TRUE -DTZ_SYS_BIN=%TZ_SYS_BIN -DTZ_SYS_RO_PACKAGES=%TZ_SYS_RO_PACKAGES -DTZ_SYS_RO_APP=%TZ_SYS_RO_APP +%else cmake . -DCMAKE_INSTALL_PREFIX=/usr -DLIBDIR=%{_libdir} -DBINDIR=%{_bindir} -DINCLUDEDIR=%{_includedir} \ -DTZ_SYS_RO_SHARE=%TZ_SYS_RO_SHARE -DTZ_SYS_BIN=%TZ_SYS_BIN -DTZ_SYS_RO_PACKAGES=%TZ_SYS_RO_PACKAGES -DTZ_SYS_RO_APP=%TZ_SYS_RO_APP make %{?jobs:-j%jobs} +%endif %if 0%{?gcov:1} mkdir -p gcov-obj diff --git a/server/dependency_audio_manager.h b/server/dependency_audio_manager.h index 0eb5ebd..9568379 100644 --- a/server/dependency_audio_manager.h +++ b/server/dependency_audio_manager.h @@ -31,7 +31,11 @@ extern "C" { *** Definitions for dependencies *************************************************************************************/ #define VCD_DEPENDENCY_DEFAULT_PATH tzplatform_mkpath(tzplatform_getid("TZ_SYS_RO_SHARE"), "voice/vc/1.0/dependency-audio-manager") +#ifdef TV_PRODUCT +#define VCD_DEPENDENCY_DEFAULT_FILENAME "libaudio-manager-vd.so" +#else #define VCD_DEPENDENCY_DEFAULT_FILENAME "libvc-audio-manager.so" +#endif #define VCD_DEPENDENCY_MODULE_PATH "db/voice/vc/dependency_module_path" -- 2.7.4 From b9f532e083e790772d79e37c611954db7b137151 Mon Sep 17 00:00:00 2001 From: Suyeon Hwang Date: Tue, 8 Jun 2021 17:06:51 +0900 Subject: [PATCH 13/16] Update version (1.65.1) Change-Id: I552088d4af3663b6525ba49c88fc6d650bab8fff Signed-off-by: Suyeon Hwang --- CMakeLists.txt | 2 +- packaging/voice-control.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b9fabd8..ca3789f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,7 +26,7 @@ PROJECT(vc) SET(PREFIX ${CMAKE_INSTALL_PREFIX}) SET(EXEC_PREFIX "${PREFIX}") -SET(VERSION 1.65.0) +SET(VERSION 1.65.1) FIND_PROGRAM(UNAME NAMES uname) EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH") diff --git a/packaging/voice-control.spec b/packaging/voice-control.spec index d8e5792..e13906d 100644 --- a/packaging/voice-control.spec +++ b/packaging/voice-control.spec @@ -1,6 +1,6 @@ Name: voice-control Summary: Voice control client library and daemon -Version: 1.65.0 +Version: 1.65.1 Release: 1 Group: Graphics & UI Framework/Voice Framework License: Apache-2.0 -- 2.7.4 From b30077d39d5bab1e6e2f838127c35589fbe9454d Mon Sep 17 00:00:00 2001 From: Suyeon Hwang Date: Tue, 20 Jul 2021 11:33:41 +0900 Subject: [PATCH 14/16] Make TC for 'vc_get_system_command_list()' Change-Id: I21e3163e12f8eee92eedb1bd5c254f45674ceaea Signed-off-by: Suyeon Hwang --- tests/org.tizen.vc-unittests.xml | 2 + tests/src/vc_unittests.cpp | 109 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+) diff --git a/tests/org.tizen.vc-unittests.xml b/tests/org.tizen.vc-unittests.xml index 663ba43..571a9e9 100644 --- a/tests/org.tizen.vc-unittests.xml +++ b/tests/org.tizen.vc-unittests.xml @@ -5,9 +5,11 @@ Voice Control unittests + http://tizen.org/privilege/recorder + http://tizen.org/privilege/voicecontrol.manager diff --git a/tests/src/vc_unittests.cpp b/tests/src/vc_unittests.cpp index 531f36f..0320972 100644 --- a/tests/src/vc_unittests.cpp +++ b/tests/src/vc_unittests.cpp @@ -19,13 +19,50 @@ #include #include +#include #include "system_info_mock.h" #include "cynara_mock.h" static int g_vc_init = false; static vc_state_e g_vc_state = VC_STATE_NONE; +static vc_state_e g_vc_mgr_state = VC_STATE_NONE; +static vc_service_state_e g_vc_mgr_service_state = VC_SERVICE_STATE_NONE; static bool g_vc_supported = false; +static bool __is_mgr_state_changed(vc_state_e state, int wait_delay) +{ + int max_count = wait_delay * 10; + int count = 0; + while (max_count > count && state != g_vc_mgr_state) { + ecore_main_loop_iterate(); + usleep(100000); + count++; + } + + if (state != g_vc_mgr_state) { + return false; + } + + return true; +} + +static bool __is_mgr_service_state_changed(vc_service_state_e state, int wait_delay) +{ + int max_count = wait_delay * 10; + int count = 0; + while (max_count > count && state != g_vc_mgr_service_state) { + ecore_main_loop_iterate(); + usleep(100000); + count++; + } + + if (state != g_vc_mgr_service_state) { + return false; + } + + return true; +} + static void __vc_result_cb(vc_result_event_e event, vc_cmd_list_h vc_cmd_list, const char* result, void* user_data) { } @@ -44,6 +81,16 @@ static void __vc_state_changed_cb(vc_state_e previous, vc_state_e current, void* g_vc_state = current; } +static void __vc_mgr_state_changed_cb(vc_state_e previous, vc_state_e current, void* user_data) +{ + g_vc_mgr_state = current; +} + +static void __vc_mgr_service_state_changed_cb(vc_service_state_e previous, vc_service_state_e current, void* user_data) +{ + g_vc_mgr_service_state = current; +} + static void __vc_service_state_changed_cb(vc_service_state_e previous, vc_service_state_e current, void* user_data) { } @@ -57,6 +104,27 @@ static bool __vc_cmd_list_cb(vc_cmd_h vc_command, void* user_data) return true; } +static void __vc_mgr_ready() +{ + vc_cmd_h system_command = nullptr; + EXPECT_EQ(vc_cmd_create(&system_command), VC_ERROR_NONE); + EXPECT_EQ(vc_cmd_set_command(system_command, "test"), VC_ERROR_NONE); + EXPECT_EQ(vc_cmd_set_type(system_command, VC_COMMAND_TYPE_SYSTEM), VC_ERROR_NONE); + + vc_cmd_list_h commands = nullptr; + EXPECT_EQ(vc_cmd_list_create(&commands), VC_ERROR_NONE); + EXPECT_EQ(vc_cmd_list_add(commands, system_command), VC_ERROR_NONE); + + EXPECT_EQ(vc_mgr_initialize(), VC_ERROR_NONE); + EXPECT_EQ(vc_mgr_set_state_changed_cb(__vc_mgr_state_changed_cb, nullptr), VC_ERROR_NONE); + EXPECT_EQ(vc_mgr_set_service_state_changed_cb(__vc_mgr_service_state_changed_cb, nullptr), VC_ERROR_NONE); + EXPECT_EQ(vc_mgr_prepare(), VC_ERROR_NONE); + ASSERT_EQ(true, __is_mgr_state_changed(VC_STATE_READY, 5)); + ASSERT_EQ(true, __is_mgr_service_state_changed(VC_SERVICE_STATE_READY, 5)); + + EXPECT_EQ(vc_mgr_set_command_list(commands), VC_ERROR_NONE); +} + namespace { class VCTest : public testing::Test { @@ -688,6 +756,47 @@ TEST_F(VCTest, vc_get_system_command_list_p) } /** + * @testcase utc_vc_get_system_command_list_p2 + * @since_tizen 3.0 + * @description Positive UTC for get the system command list when system command is registered + */ +TEST_F(VCTest, vc_get_system_command_list_p2) +{ + if (false == g_vc_supported) { + EXPECT_EQ(g_vc_init, false); + + int ret = VC_ERROR_NONE; + vc_cmd_list_h list = NULL; + ret = vc_get_system_command_list(&list); + EXPECT_EQ(ret, VC_ERROR_NOT_SUPPORTED); + } else { + EXPECT_EQ(g_vc_init, true); + + __vc_mgr_ready(); + + int ret = VC_ERROR_NONE; + ret = vc_prepare(); + EXPECT_EQ(ret, VC_ERROR_NONE); + + while (VC_STATE_READY != g_vc_state) { + ecore_main_loop_iterate(); + } + + vc_cmd_list_h list = NULL; + ret = vc_get_system_command_list(&list); + EXPECT_EQ(ret, VC_ERROR_NONE); + + int count = 0; + ret = vc_cmd_list_get_count(list, &count); + EXPECT_EQ(ret, VC_ERROR_NONE); + EXPECT_GT(count, 0); + + ret = vc_unprepare(); + EXPECT_EQ(ret, VC_ERROR_NONE); + } +} + +/** * @testcase utc_vc_get_system_command_list_n * @since_tizen 3.0 * @description Negative UTC for get the system command list (Invalid parameter) -- 2.7.4 From ef07b0acadbe4ff2742ee651274439071b91f1f0 Mon Sep 17 00:00:00 2001 From: Suyeon Hwang Date: Tue, 20 Jul 2021 17:15:12 +0900 Subject: [PATCH 15/16] Fix name for better readability Change-Id: I038f749213b8aadfddc2b91a48824287a4ab2878 Signed-off-by: Suyeon Hwang --- client/vc_mgr.c | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/client/vc_mgr.c b/client/vc_mgr.c index e9703c6..559a276 100755 --- a/client/vc_mgr.c +++ b/client/vc_mgr.c @@ -44,9 +44,9 @@ #define VC_MANAGER_CONFIG_HANDLE 100000 -static Ecore_Timer* g_m_connect_timer = NULL; -static Ecore_Idler* g_m_connect_idler = NULL; -static int g_retry_connect_count = 0; +static Ecore_Timer* g_send_hello_timer = NULL; +static Ecore_Idler* g_request_init_timer = NULL; +static int g_send_hello_count = 0; static Ecore_Timer* g_m_set_volume_timer = NULL; @@ -361,15 +361,15 @@ int vc_mgr_deinitialize(void) __vc_mgr_internal_unprepare(); /* no break. need to next step*/ case VC_STATE_INITIALIZED: - if (NULL != g_m_connect_timer) { + if (NULL != g_send_hello_timer) { SLOG(LOG_DEBUG, TAG_VCM, "Connect Timer is deleted"); - ecore_timer_del(g_m_connect_timer); - g_m_connect_timer = NULL; + ecore_timer_del(g_send_hello_timer); + g_send_hello_timer = NULL; } - if (g_m_connect_idler) { + if (g_request_init_timer) { SLOG(LOG_DEBUG, TAG_VCM, "Connect idler is deleted"); - ecore_idler_del(g_m_connect_idler); - g_m_connect_idler = NULL; + ecore_idler_del(g_request_init_timer); + g_request_init_timer = NULL; } vc_config_mgr_unset_lang_cb(g_vc_m->handle + VC_MANAGER_CONFIG_HANDLE); @@ -412,7 +412,7 @@ int vc_mgr_deinitialize(void) return VC_ERROR_NONE; } -static Eina_Bool __vc_mgr_connect_daemon(void *data) +static Eina_Bool __request_initialize(void *data) { /* request initialization */ int ret = -1; @@ -443,7 +443,7 @@ static Eina_Bool __vc_mgr_connect_daemon(void *data) ecore_main_loop_thread_safe_call_async(__vc_mgr_notify_error, (void*)g_vc_m); SLOG(LOG_DEBUG, TAG_VCM, "@@@"); - g_m_connect_idler = NULL; + g_request_init_timer = NULL; return EINA_FALSE; } else if (0 != ret) { @@ -484,43 +484,43 @@ static Eina_Bool __vc_mgr_connect_daemon(void *data) } } else { SLOG(LOG_ERROR, TAG_VCM, "[Not ERROR] g_vc_m is not valid. It is destroyed."); //LCOV_EXCL_LINE - g_m_connect_idler = NULL; + g_request_init_timer = NULL; return EINA_FALSE; } SLOG(LOG_ERROR, TAG_VCM, "@@@"); - g_m_connect_idler = NULL; + g_request_init_timer = NULL; return EINA_FALSE; } -static Eina_Bool __vc_mgr_prepare_daemon(void *data) +static Eina_Bool __send_hello_message(void *data) { /* Send hello */ if (0 != vc_mgr_dbus_request_hello()) { - if (g_retry_connect_count == 20) { - g_retry_connect_count = 0; + if (g_send_hello_count == 20) { + g_send_hello_count = 0; SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to request hello !! send error to manager"); __vc_mgr_cb_error(VC_ERROR_TIMED_OUT, -1, "voice_framework.error.vcfw.connect_engine_fail"); - g_m_connect_timer = NULL; + g_send_hello_timer = NULL; return EINA_FALSE; } else { - g_retry_connect_count++; + g_send_hello_count++; return EINA_TRUE; } } SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Connect daemon"); - if (NULL == g_m_connect_idler) { + if (NULL == g_request_init_timer) { SLOG(LOG_INFO, TAG_VCM, "[DEBUG] Create a new idler for preparation"); - g_m_connect_idler = ecore_idler_add(__vc_mgr_connect_daemon, NULL); + g_request_init_timer = ecore_idler_add(__request_initialize, NULL); } else { SLOG(LOG_INFO, TAG_VCM, "[INFO] idler handle is already created"); } - g_m_connect_timer = NULL; + g_send_hello_timer = NULL; return EINA_FALSE; } @@ -551,11 +551,11 @@ int vc_mgr_prepare(void) return VC_ERROR_INVALID_STATE; } - if (NULL == g_m_connect_timer) { - g_retry_connect_count = 0; + if (NULL == g_send_hello_timer) { + g_send_hello_count = 0; SLOG(LOG_INFO, TAG_VCM, "[DEBUG] Create a new timer for preparation"); ecore_thread_main_loop_begin(); - g_m_connect_timer = ecore_timer_add(0.02, __vc_mgr_prepare_daemon, NULL); + g_send_hello_timer = ecore_timer_add(0.02, __send_hello_message, NULL); ecore_thread_main_loop_end(); } else { SLOG(LOG_INFO, TAG_VCM, "[INFO] timer handle is already created"); -- 2.7.4 From 2480ccacdb0b956be2fe64dc855ed4f18b0317f9 Mon Sep 17 00:00:00 2001 From: Suyeon Hwang Date: Tue, 20 Jul 2021 17:29:17 +0900 Subject: [PATCH 16/16] Use ecore timer to make testable Change-Id: Ib43ee0b2d1501507bc41a2b1695d323fa0d43d44 Signed-off-by: Suyeon Hwang --- client/vc_mgr.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/vc_mgr.c b/client/vc_mgr.c index 559a276..5c0a44f 100755 --- a/client/vc_mgr.c +++ b/client/vc_mgr.c @@ -45,7 +45,7 @@ #define VC_MANAGER_CONFIG_HANDLE 100000 static Ecore_Timer* g_send_hello_timer = NULL; -static Ecore_Idler* g_request_init_timer = NULL; +static Ecore_Timer* g_request_init_timer = NULL; static int g_send_hello_count = 0; static Ecore_Timer* g_m_set_volume_timer = NULL; @@ -368,7 +368,7 @@ int vc_mgr_deinitialize(void) } if (g_request_init_timer) { SLOG(LOG_DEBUG, TAG_VCM, "Connect idler is deleted"); - ecore_idler_del(g_request_init_timer); + ecore_timer_del(g_request_init_timer); g_request_init_timer = NULL; } @@ -515,7 +515,7 @@ static Eina_Bool __send_hello_message(void *data) if (NULL == g_request_init_timer) { SLOG(LOG_INFO, TAG_VCM, "[DEBUG] Create a new idler for preparation"); - g_request_init_timer = ecore_idler_add(__request_initialize, NULL); + g_request_init_timer = ecore_timer_add(0.0, __request_initialize, NULL); } else { SLOG(LOG_INFO, TAG_VCM, "[INFO] idler handle is already created"); } -- 2.7.4