TTS / src /

main.c

  1. /*
  2. * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the License);
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an AS IS BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16.  
  17.  
  18. #include "main.h"
  19.  
  20. enum {
  21. MAIN_LIST = 0,
  22. VOICE_LIST,
  23. TEXT_LIST
  24. };
  25.  
  26. typedef struct appdata {
  27. Evas_Object *win;
  28. Evas_Object *conform;
  29. Evas_Object *naviframe;
  30. Evas_Object *genlist;
  31. Evas_Object *entry;
  32. Evas_Object *text_list;
  33.  
  34. Elm_Object_Item *voice;
  35. Elm_Object_Item *speed;
  36. Elm_Object_Item *show_text;
  37. Elm_Object_Item *play_pause;
  38.  
  39. int current_contents;
  40. } appdata_s;
  41.  
  42. typedef enum {
  43. ADD_TEXT_TITLE = 0,
  44. VOICE_BUTTON,
  45. TEXT_ENTRY,
  46. ADD_TEXT_BUTTON,
  47. SHOW_TEXT_BUTTON,
  48. PLAY_TITLE,
  49. PLAY_PAUSE_BUTTON,
  50. STOP_BUTTON
  51. } item_index_e;
  52.  
  53. static Elm_Genlist_Item_Class *g_itc_group_title = NULL;
  54. static Elm_Genlist_Item_Class *g_itc_button_1line = NULL;
  55. static Elm_Genlist_Item_Class *g_itc_button_2line = NULL;
  56. static Elm_Genlist_Item_Class *g_itc_entry = NULL;
  57.  
  58. typedef struct {
  59. char *language;
  60. int voice_type;
  61. } tts_voice_s;
  62.  
  63. typedef struct {
  64. char *text;
  65. int utt_id;
  66. } tts_text_s;
  67.  
  68. static tts_h g_tts;
  69. static GList *g_tts_voice_list = NULL;
  70. static tts_voice_s *g_current_voice = NULL;
  71. static tts_state_e g_current_state;
  72. static GList *g_tts_text_list = NULL;
  73.  
  74. static char *
  75. __genlist_text_get(void *data, Evas_Object *obj, const char *part)
  76. {
  77. item_index_e idx = (item_index_e)data;
  78.  
  79. if (VOICE_BUTTON == idx) {
  80. if (!strcmp("elm.text", part)) {
  81. return strdup("Select Voice");
  82. } else if (!strcmp("elm.text.sub", part)) {
  83. dlog_print(DLOG_DEBUG, LOG_TAG, "");
  84. if (NULL != g_current_voice) {
  85. if (NULL != g_current_voice->language) {
  86. char voice[64] = {'\0',};
  87. snprintf(voice, 64, "%s, %d", g_current_voice->language, g_current_voice->voice_type);
  88. return strdup(voice);
  89. }
  90. }
  91. }
  92. } else if (SHOW_TEXT_BUTTON == idx) {
  93. if (!strcmp("elm.text", part)) {
  94. return strdup("Show Text");
  95. } else if (!strcmp("elm.text.end", part)) {
  96. char num[8] = {'\0',};
  97. snprintf(num, 8, "%d", g_list_length(g_tts_text_list));
  98. return strdup(num);
  99. }
  100. } else if (!strcmp("elm.text", part)) {
  101. if (ADD_TEXT_BUTTON == idx) {
  102. return strdup("Add Text");
  103. } else if (PLAY_PAUSE_BUTTON == idx) {
  104. if (TTS_STATE_PLAYING == g_current_state) {
  105. return strdup("Pause");
  106. } else {
  107. return strdup("Play");
  108. }
  109. } else if (STOP_BUTTON == idx) {
  110. return strdup("Stop");
  111. }
  112. } else if (!strcmp("elm.text.main", part)) {
  113. if (ADD_TEXT_TITLE == idx) {
  114. return strdup("Add Text");
  115. } else if (PLAY_TITLE == idx) {
  116. return strdup("Play");
  117. }
  118. }
  119.  
  120. return NULL;
  121. }
  122.  
  123. static Evas_Object *
  124. __genlist_content_get(void *data, Evas_Object *obj, const char *part)
  125. {
  126. appdata_s *ad = (appdata_s *)data;
  127.  
  128. ad->entry = elm_entry_add(obj);
  129. elm_entry_single_line_set(ad->entry, EINA_TRUE);
  130. elm_entry_scrollable_set(ad->entry, EINA_TRUE);
  131. evas_object_size_hint_weight_set(ad->entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
  132. evas_object_size_hint_align_set(ad->entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
  133. elm_object_part_text_set(ad->entry, "elm.guide", "Tab here to input text for add");
  134. elm_entry_input_panel_show_on_demand_set(ad->entry, EINA_TRUE);
  135.  
  136. return ad->entry;
  137. }
  138.  
  139. static bool
  140. __tts_supported_voice_cb(tts_h tts, const char* language, int voice_type, void* user_data)
  141. {
  142. if (NULL != language) {
  143. tts_voice_s *tmp = (tts_voice_s *)calloc(1, sizeof(tts_voice_s));
  144. if (NULL == tmp) {
  145. dlog_print(DLOG_ERROR, LOG_TAG, "Fail to memory allocation");
  146. return false;
  147. }
  148. tmp->language = strdup(language);
  149. tmp->voice_type = voice_type;
  150. g_tts_voice_list = g_list_append(g_tts_voice_list, tmp);
  151. dlog_print(DLOG_DEBUG, LOG_TAG, "+ Language(%s), Type(%d)", language, voice_type);
  152. return true;
  153. }
  154. return false;
  155. }
  156.  
  157. static Eina_Bool
  158. __naviframe_sub_item_pop_cb(void *data, Elm_Object_Item *it)
  159. {
  160. dlog_print(DLOG_DEBUG, LOG_TAG, "");
  161. appdata_s *ad = (appdata_s *)data;
  162. ad->current_contents = MAIN_LIST;
  163. return EINA_TRUE;
  164. }
  165.  
  166. static void
  167. __list_clicked_cb(void *data, Evas_Object *obj, void *event_info)
  168. {
  169. appdata_s *ad = (appdata_s *)data;
  170. elm_naviframe_item_pop(ad->naviframe);
  171. elm_genlist_item_update(ad->voice);
  172. }
  173.  
  174. static void
  175. __voice_selected_cb(void *data, Evas_Object *obj, void *event_info)
  176. {
  177. Elm_Object_Item *it = event_info;
  178. elm_list_item_selected_set(it, EINA_FALSE);
  179.  
  180. int idx = (int)data;
  181. dlog_print(DLOG_DEBUG, LOG_TAG, "(%d) voice selected", idx);
  182.  
  183. GList *iter = NULL;
  184. iter = g_list_nth(g_tts_voice_list, idx);
  185. if (NULL != iter) {
  186. tts_voice_s *tmp = iter->data;
  187. if (NULL != tmp) {
  188. if (NULL != tmp->language) {
  189. if (NULL != g_current_voice->language) {
  190. free(g_current_voice->language);
  191. }
  192. g_current_voice->language = strdup(tmp->language);
  193. g_current_voice->voice_type = tmp->voice_type;
  194. }
  195. }
  196. }
  197. }
  198.  
  199. static void
  200. __show_voice_list(appdata_s *ad)
  201. {
  202. dlog_print(DLOG_DEBUG, LOG_TAG, "");
  203. Evas_Object *list = elm_list_add(ad->naviframe);
  204. elm_list_mode_set(list, ELM_LIST_COMPRESS);
  205. evas_object_smart_callback_add(list, "selected", __list_clicked_cb, ad);
  206.  
  207. GList *iter = NULL;
  208. if (NULL != g_tts_voice_list) {
  209. iter = g_list_first(g_tts_voice_list);
  210.  
  211. while (NULL != iter) {
  212. tts_voice_s *tmp = iter->data;
  213. if (NULL != tmp) {
  214. if (NULL != tmp->language) {
  215. free(tmp->language);
  216. tmp->language = NULL;
  217. }
  218. free(tmp);
  219. tmp = NULL;
  220. }
  221. g_tts_voice_list = g_list_remove_link(g_tts_voice_list, iter);
  222. iter = g_list_first(g_tts_voice_list);
  223. }
  224. }
  225.  
  226. dlog_print(DLOG_DEBUG, LOG_TAG, "== Supported Voice");
  227. if (0 != tts_foreach_supported_voices(g_tts, __tts_supported_voice_cb, ad)) {
  228. dlog_print(DLOG_ERROR, LOG_TAG, "Fail to get supported voice");
  229. }
  230.  
  231. int i;
  232. for (i = 0; i < g_list_length(g_tts_voice_list); i++) {
  233. iter = g_list_nth(g_tts_voice_list, i);
  234. if (NULL != iter) {
  235. tts_voice_s *tmp = iter->data;
  236. if (NULL != tmp) {
  237. char voice[64] = {'\0',};
  238. snprintf(voice, 64, "%s, %d", tmp->language, tmp->voice_type);
  239. elm_list_item_append(list, voice, NULL, NULL, __voice_selected_cb, (void *)i);
  240. }
  241. }
  242. }
  243. elm_list_go(list);
  244.  
  245. Elm_Object_Item *voice_item = elm_naviframe_item_push(ad->naviframe, "Voice", NULL, NULL, list, NULL);
  246. elm_naviframe_item_pop_cb_set(voice_item, __naviframe_sub_item_pop_cb, ad);
  247. ad->current_contents = VOICE_LIST;
  248. }
  249.  
  250. static void
  251. __voice_item_selected_cb(void *data, Evas_Object *obj, void *event_info)
  252. {
  253. Elm_Object_Item *item = (Elm_Object_Item *)event_info;
  254. elm_genlist_item_selected_set(item, EINA_FALSE);
  255.  
  256. appdata_s *ad = (appdata_s *)data;
  257.  
  258. __show_voice_list(ad);
  259.  
  260. elm_genlist_item_update(item);
  261. elm_object_focus_set(ad->entry, EINA_FALSE);
  262. }
  263.  
  264. static void
  265. __add_text_item_selected_cb(void *data, Evas_Object *obj, void *event_info)
  266. {
  267. Elm_Object_Item *item = (Elm_Object_Item *)event_info;
  268. elm_genlist_item_selected_set(item, EINA_FALSE);
  269.  
  270. appdata_s *ad = (appdata_s *)data;
  271.  
  272. const char *text = elm_entry_entry_get(ad->entry);
  273. if (NULL != text) {
  274. dlog_print(DLOG_DEBUG, LOG_TAG, "Add text (%s)", text);
  275. int utt_id;
  276. if (NULL != g_current_voice) {
  277. if (NULL != g_current_voice->language) {
  278. if (0 != tts_add_text(g_tts, text, g_current_voice->language, g_current_voice->voice_type, TTS_SPEED_AUTO, &utt_id)) {
  279. dlog_print(DLOG_DEBUG, LOG_TAG, "Fail to add text");
  280. } else {
  281. tts_text_s *tmp = (tts_text_s *)calloc(1, sizeof(tts_text_s));
  282. if (NULL == tmp) {
  283. dlog_print(DLOG_ERROR, LOG_TAG, "Fail to memory allocation");
  284. } else {
  285. tmp->text = strdup(text);
  286. tmp->utt_id = utt_id;
  287. g_tts_text_list = g_list_append(g_tts_text_list, tmp);
  288. }
  289. }
  290. }
  291. }
  292. }
  293.  
  294. elm_entry_entry_set(ad->entry, "");
  295. elm_genlist_item_update(item);
  296. elm_object_focus_set(ad->entry, EINA_FALSE);
  297. elm_genlist_item_update(ad->show_text);
  298. }
  299.  
  300. static void
  301. __show_text_list(appdata_s *ad)
  302. {
  303. dlog_print(DLOG_DEBUG, LOG_TAG, "");
  304. ad->text_list = elm_list_add(ad->naviframe);
  305. elm_list_mode_set(ad->text_list, ELM_LIST_COMPRESS);
  306. elm_list_select_mode_set(ad->text_list, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
  307. evas_object_smart_callback_add(ad->text_list, "selected", __list_clicked_cb, ad);
  308.  
  309. int i;
  310. GList *iter = NULL;
  311. for (i = 0; i < g_list_length(g_tts_text_list); i++) {
  312. iter = g_list_nth(g_tts_text_list, i);
  313. if (NULL != iter) {
  314. tts_text_s *tmp = iter->data;
  315. if (NULL != tmp) {
  316. if (NULL != tmp->text) {
  317. elm_list_item_append(ad->text_list, tmp->text, NULL, NULL, NULL, NULL);
  318. }
  319. }
  320. }
  321. }
  322. elm_list_go(ad->text_list);
  323.  
  324. Elm_Object_Item *voice_item = elm_naviframe_item_push(ad->naviframe, "Text List", NULL, NULL, ad->text_list, NULL);
  325. elm_naviframe_item_pop_cb_set(voice_item, __naviframe_sub_item_pop_cb, ad);
  326. ad->current_contents = TEXT_LIST;
  327. }
  328.  
  329. static void
  330. __show_text_item_selected_cb(void *data, Evas_Object *obj, void *event_info)
  331. {
  332. Elm_Object_Item *item = (Elm_Object_Item *)event_info;
  333. elm_genlist_item_selected_set(item, EINA_FALSE);
  334.  
  335. appdata_s *ad = (appdata_s *)data;
  336.  
  337. __show_text_list(ad);
  338.  
  339. elm_genlist_item_update(item);
  340. elm_object_focus_set(ad->entry, EINA_FALSE);
  341. }
  342.  
  343. static void
  344. __play_pause_item_selected_cb(void *data, Evas_Object *obj, void *event_info)
  345. {
  346. Elm_Object_Item *item = (Elm_Object_Item *)event_info;
  347. elm_genlist_item_selected_set(item, EINA_FALSE);
  348.  
  349. appdata_s *ad = (appdata_s *)data;
  350.  
  351. if (TTS_STATE_READY == g_current_state || TTS_STATE_PAUSED == g_current_state) {
  352. if (0 != tts_play(g_tts)) {
  353. dlog_print(DLOG_ERROR, LOG_TAG, "Fail to start");
  354. }
  355. } else if (TTS_STATE_PLAYING == g_current_state) {
  356. if (0 != tts_pause(g_tts)) {
  357. dlog_print(DLOG_ERROR, LOG_TAG, "Fail to pause");
  358. }
  359. }
  360.  
  361. elm_genlist_item_update(item);
  362. elm_object_focus_set(ad->entry, EINA_FALSE);
  363. }
  364.  
  365. static void
  366. __stop_item_selected_cb(void *data, Evas_Object *obj, void *event_info)
  367. {
  368. Elm_Object_Item *item = (Elm_Object_Item *)event_info;
  369. elm_genlist_item_selected_set(item, EINA_FALSE);
  370.  
  371. appdata_s *ad = (appdata_s *)data;
  372.  
  373. if (0 != tts_stop(g_tts)) {
  374. dlog_print(DLOG_ERROR, LOG_TAG, "Fail to stop");
  375. }
  376.  
  377. GList *iter = NULL;
  378. if (NULL != g_tts_text_list) {
  379. iter = g_list_first(g_tts_text_list);
  380.  
  381. while (NULL != iter) {
  382. tts_text_s *tmp = iter->data;
  383. if (NULL != tmp) {
  384. if (NULL != tmp->text) {
  385. free(tmp->text);
  386. tmp->text = NULL;
  387. }
  388. free(tmp);
  389. tmp = NULL;
  390. }
  391. g_tts_text_list = g_list_remove_link(g_tts_text_list, iter);
  392. iter = g_list_first(g_tts_text_list);
  393. }
  394. }
  395.  
  396. elm_genlist_item_update(item);
  397. elm_genlist_item_update(ad->play_pause);
  398. elm_genlist_item_update(ad->show_text);
  399. elm_object_focus_set(ad->entry, EINA_FALSE);
  400. }
  401.  
  402. static void
  403. create_contents(appdata_s *ad)
  404. {
  405. /* Genlist */
  406. ad->genlist = elm_genlist_add(ad->naviframe);
  407. elm_genlist_mode_set(ad->genlist, ELM_LIST_COMPRESS);
  408. elm_genlist_homogeneous_set(ad->genlist, EINA_TRUE);
  409. g_itc_group_title = elm_genlist_item_class_new();
  410. if (NULL == g_itc_group_title) {
  411. dlog_print(DLOG_ERROR, LOG_TAG, "Fail to item class new");
  412. return;
  413. }
  414. g_itc_group_title->item_style = "groupindex";
  415. g_itc_group_title->func.text_get = __genlist_text_get;
  416. g_itc_group_title->func.content_get = NULL;
  417. g_itc_group_title->func.state_get = NULL;
  418. g_itc_group_title->func.del = NULL;
  419.  
  420. g_itc_button_1line = elm_genlist_item_class_new();
  421. if (NULL == g_itc_button_1line) {
  422. dlog_print(DLOG_ERROR, LOG_TAG, "Fail to item class new");
  423. return;
  424. }
  425. g_itc_button_1line->item_style = "type1";
  426. g_itc_button_1line->func.text_get = __genlist_text_get;
  427. g_itc_button_1line->func.content_get = NULL;
  428. g_itc_button_1line->func.state_get = NULL;
  429. g_itc_button_1line->func.del = NULL;
  430.  
  431. g_itc_button_2line = elm_genlist_item_class_new();
  432. if (NULL == g_itc_button_2line) {
  433. dlog_print(DLOG_ERROR, LOG_TAG, "Fail to item class new");
  434. return;
  435. }
  436. g_itc_button_2line->item_style = "type1";
  437. g_itc_button_2line->func.text_get = __genlist_text_get;
  438. g_itc_button_2line->func.content_get = NULL;
  439. g_itc_button_2line->func.state_get = NULL;
  440. g_itc_button_2line->func.del = NULL;
  441.  
  442. g_itc_entry = elm_genlist_item_class_new();
  443. if (NULL == g_itc_entry) {
  444. dlog_print(DLOG_ERROR, LOG_TAG, "Fail to item class new");
  445. return;
  446. }
  447. g_itc_entry->item_style = "full";
  448. g_itc_entry->func.text_get = NULL;
  449. g_itc_entry->func.content_get = __genlist_content_get;
  450. g_itc_entry->func.state_get = NULL;
  451. g_itc_entry->func.del = NULL;
  452.  
  453. /* Add Text - Title */
  454. Elm_Object_Item *it;
  455. it = elm_genlist_item_append(ad->genlist, g_itc_group_title, (void *)ADD_TEXT_TITLE, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
  456. elm_genlist_item_select_mode_set(it, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
  457.  
  458. /* Voice - 2line */
  459. ad->voice = elm_genlist_item_append(ad->genlist, g_itc_button_2line, (void *)VOICE_BUTTON, NULL, ELM_GENLIST_ITEM_NONE, __voice_item_selected_cb, ad);
  460.  
  461. /* Text - entry */
  462. elm_genlist_item_append(ad->genlist, g_itc_entry, (void *)ad, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
  463.  
  464. /* Add text - button */
  465. elm_genlist_item_append(ad->genlist, g_itc_button_1line, (void *)ADD_TEXT_BUTTON, NULL, ELM_GENLIST_ITEM_NONE, __add_text_item_selected_cb, ad);
  466.  
  467. /* Show text - button */
  468. ad->show_text = elm_genlist_item_append(ad->genlist, g_itc_button_1line, (void *)SHOW_TEXT_BUTTON, NULL, ELM_GENLIST_ITEM_NONE, __show_text_item_selected_cb, ad);
  469.  
  470. /* Play - Title */
  471. it = elm_genlist_item_append(ad->genlist, g_itc_group_title, (void *)PLAY_TITLE, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
  472. elm_genlist_item_select_mode_set(it, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
  473.  
  474. /* Play & Pause - button */
  475. ad->play_pause = elm_genlist_item_append(ad->genlist, g_itc_button_1line, (void *)PLAY_PAUSE_BUTTON, NULL, ELM_GENLIST_ITEM_NONE, __play_pause_item_selected_cb, ad);
  476.  
  477. /* Stop - button */
  478. elm_genlist_item_append(ad->genlist, g_itc_button_1line, (void *)STOP_BUTTON, NULL, ELM_GENLIST_ITEM_NONE, __stop_item_selected_cb, ad);
  479.  
  480. elm_genlist_select_mode_set(ad->genlist, ELM_OBJECT_SELECT_MODE_NONE);
  481.  
  482. evas_object_show(ad->genlist);
  483. }
  484.  
  485. static Eina_Bool
  486. __naviframe_item_pop_cb(void *data, Elm_Object_Item *it)
  487. {
  488. dlog_print(DLOG_DEBUG, LOG_TAG, "");
  489. ui_app_exit();
  490. return EINA_TRUE;
  491. }
  492.  
  493. static void
  494. create_base_gui(appdata_s *ad)
  495. {
  496. /* Window */
  497. ad->win = elm_win_util_standard_add(PACKAGE, PACKAGE);
  498. elm_win_autodel_set(ad->win, EINA_TRUE);
  499.  
  500. if (elm_win_wm_rotation_supported_get(ad->win)) {
  501. int rots[4] = { 0, 90, 180, 270 };
  502. elm_win_wm_rotation_available_rotations_set(ad->win, (const int *)(&rots), 4);
  503. }
  504.  
  505. /* Conformant */
  506. ad->conform = elm_conformant_add(ad->win);
  507. elm_win_indicator_mode_set(ad->win, ELM_WIN_INDICATOR_SHOW);
  508. elm_win_indicator_opacity_set(ad->win, ELM_WIN_INDICATOR_OPAQUE);
  509. evas_object_size_hint_weight_set(ad->conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
  510. elm_win_resize_object_add(ad->win, ad->conform);
  511. evas_object_show(ad->conform);
  512.  
  513. /* Naviframe */
  514. ad->naviframe = elm_naviframe_add(ad->conform);
  515. eext_object_event_callback_add(ad->naviframe, EEXT_CALLBACK_BACK, eext_naviframe_back_cb, NULL);
  516. evas_object_size_hint_weight_set(ad->naviframe, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
  517. evas_object_size_hint_align_set(ad->naviframe, EVAS_HINT_FILL, EVAS_HINT_FILL);
  518. elm_object_part_content_set(ad->conform, "elm.swallow.content", ad->naviframe);
  519. evas_object_show(ad->naviframe);
  520.  
  521. /* Contents */
  522. create_contents(ad);
  523. Elm_Object_Item *main_item = elm_naviframe_item_push(ad->naviframe, "TTS", NULL, NULL, ad->genlist, NULL);
  524. elm_naviframe_item_title_enabled_set(main_item, EINA_TRUE, EINA_TRUE);
  525. elm_naviframe_item_pop_cb_set(main_item, __naviframe_item_pop_cb, ad);
  526. elm_object_content_set(ad->conform, ad->naviframe);
  527. ad->current_contents = MAIN_LIST;
  528.  
  529. /* Show window after base gui is set up */
  530. evas_object_show(ad->win);
  531. }
  532.  
  533. static void
  534. __tts_state_changed_cb(tts_h tts, tts_state_e previous, tts_state_e current, void* user_data)
  535. {
  536. appdata_s *ad = (appdata_s *)user_data;
  537. dlog_print(DLOG_DEBUG, LOG_TAG, "== State is changed (%d) to (%d)", previous, current);
  538. if (TTS_STATE_CREATED == previous && TTS_STATE_READY == current) {
  539. elm_genlist_select_mode_set(ad->genlist, ELM_OBJECT_SELECT_MODE_DEFAULT);
  540. }
  541. g_current_state = current;
  542. }
  543.  
  544. static void
  545. __tts_utterance_completed_cb(tts_h tts, int utt_id, void* user_data)
  546. {
  547. dlog_print(DLOG_DEBUG, LOG_TAG, "== Utterance (%d) is completed", utt_id);
  548. appdata_s *ad = (appdata_s *)user_data;
  549.  
  550. GList *iter = NULL;
  551. if (NULL != g_tts_text_list) {
  552. iter = g_list_first(g_tts_text_list);
  553.  
  554. while (NULL != iter) {
  555. tts_text_s *tmp = iter->data;
  556. if (NULL != tmp) {
  557. if (tmp->utt_id == utt_id) {
  558. if (NULL != tmp->text) {
  559. free(tmp->text);
  560. tmp->text = NULL;
  561. }
  562. free(tmp);
  563. tmp = NULL;
  564. g_tts_text_list = g_list_remove_link(g_tts_text_list, iter);
  565. break;
  566. }
  567. iter = g_list_next(g_tts_text_list);
  568. }
  569. }
  570. }
  571.  
  572. if (TEXT_LIST == ad->current_contents) {
  573. elm_list_clear(ad->text_list);
  574.  
  575. int i;
  576. iter = NULL;
  577. for (i = 0; i < g_list_length(g_tts_text_list); i++) {
  578. iter = g_list_nth(g_tts_text_list, i);
  579. if (NULL != iter) {
  580. tts_text_s *tmp = iter->data;
  581. if (NULL != tmp) {
  582. if (NULL != tmp->text) {
  583. elm_list_item_append(ad->text_list, tmp->text, NULL, NULL, NULL, NULL);
  584. }
  585. }
  586. }
  587. }
  588. elm_list_go(ad->text_list);
  589. }
  590.  
  591. elm_genlist_item_update(ad->show_text);
  592. }
  593.  
  594. static int
  595. init_tts(appdata_s *ad)
  596. {
  597. if (0 != tts_create(&g_tts)) {
  598. dlog_print(DLOG_ERROR, LOG_TAG, "Fail to tts create");
  599. return -1;
  600. }
  601.  
  602. if (0 != tts_set_state_changed_cb(g_tts, __tts_state_changed_cb, ad)) {
  603. dlog_print(DLOG_ERROR, LOG_TAG, "Fail to set state changed cb");
  604. tts_destroy(g_tts);
  605. return -1;
  606. }
  607.  
  608. if (0 != tts_set_utterance_completed_cb(g_tts, __tts_utterance_completed_cb, ad)) {
  609. dlog_print(DLOG_ERROR, LOG_TAG, "Fail to set utt completed cb");
  610. tts_destroy(g_tts);
  611. return -1;
  612. }
  613.  
  614. char *language = NULL;
  615. int voice_type;
  616. if (0 != tts_get_default_voice(g_tts, &language, &voice_type)) {
  617. dlog_print(DLOG_ERROR, LOG_TAG, "Fail to get default voice");
  618. tts_destroy(g_tts);
  619. return -1;
  620. }
  621. if (NULL != language) {
  622. g_current_voice = (tts_voice_s *)calloc(1, sizeof(tts_voice_s));
  623. if (NULL == g_current_voice) {
  624. dlog_print(DLOG_ERROR, LOG_TAG, "Fail to memory allocation");
  625. } else {
  626. g_current_voice->language = strdup(language);
  627. g_current_voice->voice_type = voice_type;
  628. }
  629. free(language);
  630. }
  631.  
  632. if (0 != tts_prepare(g_tts)) {
  633. dlog_print(DLOG_ERROR, LOG_TAG, "Fail to tts prepare");
  634. tts_destroy(g_tts);
  635. return -1;
  636. }
  637.  
  638. return 0;
  639. }
  640.  
  641. static void
  642. deinit_tts(appdata_s *ad)
  643. {
  644. if (NULL != g_current_voice) {
  645. if (NULL != g_current_voice->language) {
  646. free(g_current_voice->language);
  647. g_current_voice->language = NULL;
  648. }
  649. free(g_current_voice);
  650. g_current_voice = NULL;
  651. }
  652. if (0 != tts_destroy(g_tts)) {
  653. dlog_print(DLOG_ERROR, LOG_TAG, "Fail to tts destroy");
  654. }
  655. }
  656.  
  657. static bool
  658. app_create(void *data)
  659. {
  660. /* Hook to take necessary actions before main event loop starts
  661. Initialize UI resources and application's data
  662. If this function returns true, the main loop of application starts
  663. If this function returns false, the application is terminated */
  664. appdata_s *ad = data;
  665.  
  666. create_base_gui(ad);
  667.  
  668. if (0 != init_tts(ad)) {
  669. dlog_print(DLOG_ERROR, LOG_TAG, "Fail to init tts");
  670. return false;
  671. }
  672.  
  673. return true;
  674. }
  675.  
  676. static void
  677. app_control(app_control_h app_control, void *data)
  678. {
  679. /* Handle the launch request. */
  680. }
  681.  
  682. static void
  683. app_pause(void *data)
  684. {
  685. /* Take necessary actions when application becomes invisible. */
  686. }
  687.  
  688. static void
  689. app_resume(void *data)
  690. {
  691. /* Take necessary actions when application becomes visible. */
  692. }
  693.  
  694. static void
  695. app_terminate(void *data)
  696. {
  697. appdata_s *ad = data;
  698. /* Release all resources. */
  699. deinit_tts(ad);
  700. }
  701.  
  702. static void
  703. ui_app_lang_changed(app_event_info_h event_info, void *user_data)
  704. {
  705. /*APP_EVENT_LANGUAGE_CHANGED*/
  706. char *locale = NULL;
  707. system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_LANGUAGE, &locale);
  708. elm_language_set(locale);
  709. free(locale);
  710. return;
  711. }
  712.  
  713. static void
  714. ui_app_orient_changed(app_event_info_h event_info, void *user_data)
  715. {
  716. /*APP_EVENT_DEVICE_ORIENTATION_CHANGED*/
  717. return;
  718. }
  719.  
  720. static void
  721. ui_app_region_changed(app_event_info_h event_info, void *user_data)
  722. {
  723. /*APP_EVENT_REGION_FORMAT_CHANGED*/
  724. }
  725.  
  726. static void
  727. ui_app_low_battery(app_event_info_h event_info, void *user_data)
  728. {
  729. /*APP_EVENT_LOW_BATTERY*/
  730. }
  731.  
  732. static void
  733. ui_app_low_memory(app_event_info_h event_info, void *user_data)
  734. {
  735. /*APP_EVENT_LOW_MEMORY*/
  736. }
  737.  
  738. int
  739. main(int argc, char *argv[])
  740. {
  741. appdata_s ad = {0,};
  742. int ret = 0;
  743.  
  744. ui_app_lifecycle_callback_s event_callback = {0,};
  745. app_event_handler_h handlers[5] = {NULL, };
  746.  
  747. event_callback.create = app_create;
  748. event_callback.terminate = app_terminate;
  749. event_callback.pause = app_pause;
  750. event_callback.resume = app_resume;
  751. event_callback.app_control = app_control;
  752.  
  753. ui_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY, ui_app_low_battery, &ad);
  754. ui_app_add_event_handler(&handlers[APP_EVENT_LOW_MEMORY], APP_EVENT_LOW_MEMORY, ui_app_low_memory, &ad);
  755. ui_app_add_event_handler(&handlers[APP_EVENT_DEVICE_ORIENTATION_CHANGED], APP_EVENT_DEVICE_ORIENTATION_CHANGED, ui_app_orient_changed, &ad);
  756. ui_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED, ui_app_lang_changed, &ad);
  757. ui_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED], APP_EVENT_REGION_FORMAT_CHANGED, ui_app_region_changed, &ad);
  758. ui_app_remove_event_handler(handlers[APP_EVENT_LOW_MEMORY]);
  759.  
  760. ret = ui_app_main(argc, argv, &event_callback, &ad);
  761. if (ret != APP_ERROR_NONE) {
  762. dlog_print(DLOG_ERROR, LOG_TAG, "app_main() is failed. err = %d", ret);
  763. }
  764.  
  765. return ret;
  766. }