Add client API for letting know personal voices list to client 70/315170/1
authordyamy-lee <dyamy.lee@samsung.com>
Wed, 24 Jul 2024 08:25:52 +0000 (17:25 +0900)
committerdyamy-lee <dyamy.lee@samsung.com>
Fri, 26 Jul 2024 04:15:55 +0000 (13:15 +0900)
The client can know personal voices list with tts_foreach_supported_personal_voices() API

Change-Id: I0fc8eb5713183ae429d1ea163ccd42a6590acea4

client/tts.c
client/tts_client.c
client/tts_client.h
client/tts_core.c
client/tts_core.h
common/tts_config_mgr.c
common/tts_config_mgr.h
include/tts.h

index 096841979e52a358f582009ff3f62740303af565..d367875e47d391489ac81368f2f223bdddf08914 100644 (file)
@@ -580,6 +580,37 @@ int tts_foreach_supported_voices(tts_h tts, tts_supported_voice_cb callback, voi
        return TTS_ERROR_NONE;
 }
 
+int tts_foreach_supported_personal_voices(tts_h tts, tts_supported_personal_voice_cb callback, void* user_data)
+{
+       RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
+
+       SLOG(LOG_INFO, TAG_TTSC, "@@@ Foreach supported personal voices");
+
+       RETVM_IF(NULL == callback, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Input parameter is null");
+
+       tts_client_s* client = tts_client_get(tts);
+       RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts);
+
+       int ret = 0;
+       char* current_engine = NULL;
+       ret = tts_config_mgr_get_engine(&current_engine);
+       if (0 != ret || NULL == current_engine) {
+               SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get current engine : %d", ret);
+               return __tts_convert_config_error_code(ret);
+       }
+
+       ret = tts_core_foreach_supported_personal_voices(client, current_engine, callback, user_data);
+       free(current_engine);
+
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Result : %d", ret);
+               return ret;
+       }
+
+       SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
+       return TTS_ERROR_NONE;
+}
+
 int tts_get_default_voice(tts_h tts, char** lang, int* vctype)
 {
        RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);
index 1648d3d9a5da1a303431eed272e58fe6c5aa56bc..24aa2ed17f0571f67a2401348ad4d384c165b120 100644 (file)
@@ -135,6 +135,12 @@ static inline void __set_supported_voice_cb(tts_client_s* client, tts_supported_
        client->supported_voice_user_data = user_data;
 }
 
+static inline void __set_supported_personal_voice_cb(tts_client_s* client, tts_supported_personal_voice_cb callback, void* user_data)
+{
+       client->supported_personal_voice_cb = callback;
+       client->supported_personal_voice_user_data = user_data;
+}
+
 static inline void __set_service_state_changed_cb(tts_client_s* client, tts_service_state_changed_cb callback, void* user_data)
 {
        if (callback != NULL) {
@@ -726,6 +732,14 @@ void tts_client_set_supported_voice_cb(tts_client_s* client, tts_supported_voice
        __set_supported_voice_cb(client, callback, user_data);
 }
 
+void tts_client_set_supported_personal_voice_cb(tts_client_s* client, tts_supported_personal_voice_cb callback, void* user_data)
+{
+       if (false == tts_client_is_valid_client(client)) {
+               return;
+       }
+       __set_supported_personal_voice_cb(client, callback, user_data);
+}
+
 void tts_client_set_service_state_changed_cb(tts_client_s* client, tts_service_state_changed_cb callback, void* user_data)
 {
        if (false == tts_client_is_valid_client(client)) {
@@ -864,6 +878,14 @@ tts_supported_voice_cb tts_client_get_supported_voice_cb(tts_client_s* client)
        return client->supported_voice_cb;
 }
 
+tts_supported_personal_voice_cb tts_client_get_supported_personal_voice_cb(tts_client_s* client)
+{
+       if (false == tts_client_is_valid_client(client)) {
+               return NULL;
+       }
+       return client->supported_personal_voice_cb;
+}
+
 void* tts_client_get_supported_voice_user_data(tts_client_s* client)
 {
        if (false == tts_client_is_valid_client(client)) {
@@ -872,6 +894,14 @@ void* tts_client_get_supported_voice_user_data(tts_client_s* client)
        return client->supported_voice_user_data;
 }
 
+void* tts_client_get_supported_personal_voice_user_data(tts_client_s* client)
+{
+       if (false == tts_client_is_valid_client(client)) {
+               return NULL;
+       }
+       return client->supported_personal_voice_user_data;
+}
+
 tts_service_state_changed_cb tts_client_get_service_state_changed_cb(tts_client_s* client)
 {
        if (false == tts_client_is_valid_client(client)) {
@@ -939,4 +969,5 @@ void tts_client_unset_all_cb(tts_client_s* client)
        __set_supported_voice_cb(client, NULL, NULL);
        __set_service_state_changed_cb(client, NULL, NULL);
        __set_synthesized_pcm_cb(client, NULL, NULL);
+       __set_supported_personal_voice_cb(client, NULL, NULL);
 }
\ No newline at end of file
index 594581e4d70ccae017f8eb67c1b6dea9ef454139..71562eec49f6ccd75e1f4222629b48c6f399f0bc 100644 (file)
@@ -57,6 +57,8 @@ typedef struct {
        void*                           service_state_changed_user_data;
        tts_synthesized_pcm_cb          synthesized_pcm_cb;
        void*                           synthesized_pcm_user_data;
+       tts_supported_personal_voice_cb         supported_personal_voice_cb;
+       void*                           supported_personal_voice_user_data;
 
        int registered_event_mask;
 
@@ -163,6 +165,7 @@ void tts_client_set_screen_reader_changed_cb(tts_client_s* client, tts_screen_re
 void tts_client_set_supported_voice_cb(tts_client_s* client, tts_supported_voice_cb callback, void* user_data);
 void tts_client_set_service_state_changed_cb(tts_client_s* client, tts_service_state_changed_cb callback, void* user_data);
 void tts_client_set_synthesized_pcm_cb(tts_client_s* client, tts_synthesized_pcm_cb callback, void* user_data);
+void tts_client_set_supported_personal_voice_cb(tts_client_s* client, tts_supported_personal_voice_cb callback, void* user_data);
 
 tts_state_changed_cb tts_client_get_state_changed_cb(tts_client_s* client);
 void* tts_client_get_state_changed_user_data(tts_client_s* client);
@@ -194,6 +197,9 @@ void* tts_client_get_service_state_changed_user_data(tts_client_s* client);
 tts_synthesized_pcm_cb tts_client_get_synthesized_pcm_cb(tts_client_s* client);
 void* tts_client_get_synthesized_pcm_user_data(tts_client_s* client);
 
+tts_supported_personal_voice_cb tts_client_get_supported_personal_voice_cb(tts_client_s* client);
+void* tts_client_get_supported_personal_voice_user_data(tts_client_s* client);
+
 int tts_client_get_registered_event_mask(tts_client_s* client);
 
 void tts_client_unset_all_cb(tts_client_s* client);
index 58974cd29c780ebfb45e2348e067abf9d9799b5f..5c0f49bc037093f3f84b32e7a6e38ba12f67367c 100644 (file)
@@ -587,6 +587,24 @@ static bool __supported_voice_cb(const char* engine_id, const char* language, in
        return callback(tts_client_get_handle(client), language, type, data);
 }
 
+static bool __supported_personal_voice_cb(const char* language, const char* unique_id, const char* display_name, const char* device_name, void* user_data)
+{
+       unsigned int uid = (uintptr_t)user_data;
+       tts_client_s* client = tts_client_get_by_uid(uid);
+       RETVM_IF(NULL == client, false, "[ERROR] uid(%u) is not valid.", uid);
+
+       /* call callback function */
+       tts_supported_personal_voice_cb callback = tts_client_get_supported_personal_voice_cb(client);
+       void* data = tts_client_get_supported_personal_voice_user_data(client);
+
+       if (NULL == callback) {
+               SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get callback.");
+               return false;
+       }
+
+       return callback(tts_client_get_handle(client), language, unique_id, display_name, device_name, data);
+}
+
 static bool __is_screen_reader_turned_on()
 {
        SLOG(LOG_DEBUG, TAG_TTSC, "[DEBUG] Update screen reader state");
@@ -1275,6 +1293,23 @@ int tts_core_foreach_supported_voices(tts_client_s* client, const char* engine_i
        return TTS_ERROR_NONE;
 }
 
+int tts_core_foreach_supported_personal_voices(tts_client_s* client, const char* engine_id, tts_supported_personal_voice_cb callback, void* user_data)
+{
+       RETVM_IF(false == tts_client_is_valid_client(client), TTS_ERROR_INVALID_PARAMETER, "[ERROR] Client is invalid.");
+
+       tts_client_set_supported_personal_voice_cb(client, callback, user_data);
+       uintptr_t uid = tts_client_get_uid(client);
+       int ret = tts_config_mgr_get_personal_voice_list(engine_id, __supported_personal_voice_cb, (void*)uid);
+       tts_client_set_supported_personal_voice_cb(client, NULL, NULL);
+
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get voice list");
+               return TTS_ERROR_OPERATION_FAILED;
+       }
+
+       return TTS_ERROR_NONE;
+}
+
 static void set_service_out_for_each_client(gpointer data, gpointer user_data)
 {
        unsigned int instant_reprepare_uid = TTS_INVALID_UID;
index 24da3a50b198c571477ce50db31ab166d835a5e3..4103e3db1f517670bc59514a8d940c2f0ddccdfe 100644 (file)
@@ -48,6 +48,7 @@ int tts_core_prepare_sync(tts_client_s* client);
 int tts_core_unprepare(tts_client_s* client);
 
 int tts_core_foreach_supported_voices(tts_client_s* client, const char* engine_id, tts_supported_voice_cb callback, void* user_data);
+int tts_core_foreach_supported_personal_voices(tts_client_s* client, const char* engine_id, tts_supported_personal_voice_cb callback, void* user_data);
 
 // called by tts_ipc
 int tts_core_add_text(tts_client_s* client, const char* text, const char* language, int voice_type, int speed, int* utt_id);
index dc83591e5e67baab60f0cee25dcaefa524ea6d26..7650786072887b5204df8ab2f95c2d1df3a7967c 100644 (file)
@@ -2466,3 +2466,61 @@ int tts_config_mgr_update_personal_voice(const char* engine_id, const char* lang
 
        return 0;
 }
+
+int tts_config_mgr_get_personal_voice_list(const char* engine_id, tts_config_supported_personal_voice_cb callback, void* user_data)
+{
+       int ret = __check_precondition();
+       if (TTS_CONFIG_ERROR_NONE != ret) {
+               SLOG(LOG_ERROR, TAG_TTSCONFIG, "Precondition is not met (%s)", get_error_message(ret));
+               return ret;
+       }
+
+       SLOG(LOG_DEBUG, TAG_TTSCONFIG, "[DEBUG] engine id = %s", engine_id);
+       if (NULL == engine_id) {
+               SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Input Parameter is null");
+               return TTS_CONFIG_ERROR_INVALID_PARAMETER;
+       }
+
+       if (NULL == callback) {
+               SLOG(LOG_ERROR, TAG_TTSCONFIG, "tts_config_mgr_get_personal_voice_list callback is not set");
+               return TTS_CONFIG_ERROR_INVALID_PARAMETER;
+       }
+
+       char filepath[512] = {'\0',};
+
+       memset(filepath, '\0', 512);
+       snprintf(filepath, 512, "%s/%s-%s", TTS_DOWNLOAD_PERSONAL_INFO, engine_id, "personal.xml");
+
+       tts_personal_info_s* info = NULL;
+       ret = tts_parser_get_personal_info(filepath, &info);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to get personal information");
+               return TTS_CONFIG_ERROR_OPERATION_FAILED;
+       }
+
+       GSList *iter_personal_voice = NULL;
+       tts_config_personal_s* personal_voice = NULL;
+       if (g_slist_length(info->personal_voices) > 0) {
+               /* Get a first item */
+               iter_personal_voice = g_slist_nth(info->personal_voices, 0);
+
+               int j = 1;
+               while (NULL != iter_personal_voice) {
+                       /*Get handle data from list*/
+                       personal_voice = iter_personal_voice->data;
+
+                       SLOG(LOG_DEBUG, TAG_TTSCONFIG, "[%dth] lang(%s) unique_id(%s) display_name(%s) device_name(%s)", j, personal_voice->language, personal_voice->unique_id, personal_voice->display_name, personal_voice->device_name);
+                       if (false == callback(personal_voice->language, personal_voice->unique_id, personal_voice->display_name, personal_voice->device_name, user_data))
+                               break;
+
+                       /*Get next item*/
+                       iter_personal_voice = g_slist_next(iter_personal_voice);
+                       j++;
+               }
+       } else {
+               SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] No personal voices list");
+               return TTS_CONFIG_ERROR_INVALID_VOICE;
+       }
+
+       return TTS_CONFIG_ERROR_NONE;
+}
index 3f6f694ecfa770dc5830cc75721fc11ab76a4eeb..ae3eeb79873fb2389a9a8065366ddedc1146b2fe 100644 (file)
@@ -72,6 +72,8 @@ typedef void (*tts_config_bg_volume_ratio_changed_cb)(double value, void* user_d
 
 typedef void (*tts_config_screen_reader_changed_cb)(bool value, void* user_data);
 
+typedef bool (*tts_config_supported_personal_voice_cb)(const char* language, const char* unique_id, const char* display_name, const char* device_name, void* user_data);
+
 
 int tts_config_mgr_initialize(unsigned int uid, tts_config_client_type_e client_type);
 
@@ -130,6 +132,7 @@ int tts_config_mgr_get_instant_reprepare_client(unsigned int *uid);
 int tts_config_mgr_set_instant_reprepare_client(const unsigned int uid);
 
 int tts_config_mgr_update_personal_voice(const char* engine_id, const char* language, const char* unique_id, const char* display_name, const char* device_name);
+int tts_config_mgr_get_personal_voice_list(const char* engine_id, tts_config_supported_personal_voice_cb callback, void* user_data);
 
 
 #ifdef __cplusplus
index 739e1df3284e5e4bd0c3febeb7a89777cbe208f2..542680047bf0d5161e63c486f929d96c860afdee 100644 (file)
@@ -275,6 +275,21 @@ typedef void (*tts_error_cb)(tts_h tts, int utt_id, tts_error_e reason, void* us
 */
 typedef bool(*tts_supported_voice_cb)(tts_h tts, const char* language, int voice_type, void* user_data);
 
+/**
+ * @brief Called to retrieve the supported personal vocie.
+ * @since_tizen 9.0
+ * @param[in] tts The TTS handle
+ * @param[in] language Language specified as ISO 3166 alpha-2 two letter country-code followed by ISO 639-1 for the two-letter language code (for example, "ko_KR" for Korean, "en_US" for American English)
+ * @param[in] unique_id A unique identifier string for personal voice resource
+ * @param[in] display_name A display name that will be shown in UI for user selection
+ * @param[in] device_name A device name used for identifying the source target
+ * @param[in] user_data The user data passed from the foreach function
+ * @return @c true to continue with the next iteration of the loop,
+ *         @c false to break out of the loop
+ * @pre tts_foreach_supported_personal_voices() will invoke this callback function.
+ * @see tts_foreach_supported_personal_voices()
+*/
+typedef bool(*tts_supported_personal_voice_cb)(tts_h tts, const char* language, const char* unique_id, const char* display_name, const char* device_name, void* user_data);
 
 /**
  * @brief Called when the default voice is changed.
@@ -513,6 +528,18 @@ int tts_prepare_sync(tts_h tts);
 */
 int tts_foreach_supported_voices(tts_h tts, tts_supported_voice_cb callback, void* user_data);
 
+/**
+ * @brief Retrieves all supported personal voices of the current engine using callback function.
+ * @since_tiaen 9.0
+ * @param[in] tts The TTS handle
+ * @param[in] callback The callback function to invoke
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #TTS_ERROR_NONE Successful
+ * @post This function invokes tts_supported_personal_voice_cb() repeatedly for getting personal voices.
+*/
+int tts_foreach_supported_personal_voices(tts_h tts, tts_supported_personal_voice_cb callback, void* user_data);
 
 /**
  * @brief Gets the default voice set by the user.