2 * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
4 * This file is a modified version of BSD licensed file and
5 * licensed under the Flora License, Version 1.1 (the License);
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://floralicense.org/license/
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an AS IS BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 * Please, see the LICENSE file for the original copyright owner and
24 #include "screen_reader_tts.h"
25 #include "screen_reader_vconf.h"
28 // ---------------------------- DEBUG HELPERS ------------------------------
32 static int last_utt_id;
33 static Eina_Bool pause_state = EINA_FALSE;
34 static Eina_Bool flush_flag = EINA_FALSE;
35 static Eina_Strbuf *txt_keep_buff = NULL;
37 static void(*on_utterance_end)(void);
39 static void _text_keep(const char *txt)
41 if (!txt_keep_buff) return;
42 if (eina_strbuf_length_get(txt_keep_buff) > 0) eina_strbuf_append(txt_keep_buff, ", ");
43 eina_strbuf_append(txt_keep_buff, txt);
46 static char * get_tts_error( int r )
54 case TTS_ERROR_INVALID_PARAMETER:
58 case TTS_ERROR_OUT_OF_MEMORY:
60 return "out of memory";
62 case TTS_ERROR_OPERATION_FAILED:
66 case TTS_ERROR_INVALID_STATE:
72 return "uknown error";
77 static char * get_tts_state( tts_state_e r )
81 case TTS_STATE_CREATED:
89 case TTS_STATE_PLAYING:
93 case TTS_STATE_PAUSED:
99 return "uknown state";
104 //-------------------------------------------------------------------------------------------------
106 void set_utterance_cb( void(*uter_cb)(void))
108 on_utterance_end = uter_cb;
112 bool get_supported_voices_cb(tts_h tts, const char* language, int voice_type, void* user_data)
114 DEBUG("LANG: %s; TYPE: %d", language, voice_type);
116 Service_Data *sd = user_data;
117 Voice_Info *vi = calloc(1, sizeof(Voice_Info));
121 return ECORE_CALLBACK_CANCEL;
124 if(asprintf(&vi->language, "%s",language) < 0)
128 return ECORE_CALLBACK_CANCEL;
131 vi->voice_type = voice_type;
133 sd->available_languages = eina_list_append(sd->available_languages, vi);
135 return ECORE_CALLBACK_RENEW;
138 static void __tts_test_utt_started_cb(tts_h tts, int utt_id, void* user_data)
140 DEBUG("Utterance started : utt id(%d) \n", utt_id);
144 static void __tts_test_utt_completed_cb(tts_h tts, int utt_id, void* user_data)
146 DEBUG("Utterance completed : utt id(%d) \n", utt_id);
147 if(last_utt_id - utt_id > FLUSH_LIMIT)
148 flush_flag = EINA_TRUE;
152 flush_flag = EINA_FALSE;
155 #ifndef SCREEN_READER_TV
156 if(last_utt_id == utt_id)
158 DEBUG("LAST UTTERANCE");
159 pause_state = EINA_FALSE;
167 bool tts_init(void *data)
169 DEBUG( "--------------------- TTS_init START ---------------------");
170 Service_Data *sd = data;
172 int r = tts_create( &sd->tts );
173 DEBUG( "Create tts %d (%s)", r, get_tts_error( r ) );
175 r = tts_set_mode( sd->tts, TTS_MODE_SCREEN_READER );
176 DEBUG( "Set tts mode SR %d (%s)", r, get_tts_error( r ) );
178 r = tts_prepare( sd->tts );
179 DEBUG( "Prepare tts %d (%s)", r, get_tts_error( r ) );
181 tts_set_state_changed_cb(sd->tts, state_changed_cb, sd);
183 tts_set_utterance_started_cb(sd->tts, __tts_test_utt_started_cb, sd);
184 tts_set_utterance_completed_cb(sd->tts, __tts_test_utt_completed_cb, sd);
186 DEBUG( "---------------------- TTS_init END ----------------------\n\n");
187 txt_keep_buff = eina_strbuf_new();
191 Eina_Bool tts_pause_get(void)
193 DEBUG( "PAUSE STATE: %d", pause_state);
197 void tts_stop_set(void)
199 Service_Data *sd = get_pointer_to_service_data_struct();
203 Eina_Bool tts_pause_set(Eina_Bool pause_switch)
205 Service_Data *sd = get_pointer_to_service_data_struct();
211 pause_state = EINA_TRUE;
213 if(tts_pause(sd->tts))
215 pause_state = EINA_FALSE;
219 else if(!pause_switch)
221 pause_state = EINA_FALSE;
223 if(tts_play(sd->tts))
225 pause_state = EINA_TRUE;
232 void tts_speak(char *text_to_speak, Eina_Bool flush_switch)
235 Service_Data *sd = get_pointer_to_service_data_struct();
241 tts_get_state(sd->tts, &state);
243 if (state != TTS_STATE_PLAYING &&
244 state != TTS_STATE_PAUSED &&
245 state != TTS_STATE_READY)
247 if (text_to_speak) _text_keep(text_to_speak);
251 if (flush_flag || flush_switch)
253 if (state == TTS_STATE_PLAYING ||
254 state == TTS_STATE_PAUSED)
256 ret = tts_stop(sd->tts);
257 if (TTS_ERROR_NONE != ret)
259 DEBUG("Fail to stop TTS: resultl(%d)", ret);
264 DEBUG( "tts_speak\n");
265 DEBUG( "text to say:%s\n", text_to_speak);
266 if ( !text_to_speak ) return;
267 if ( !text_to_speak[0] ) return;
269 if((ret = tts_add_text( sd->tts, text_to_speak, NULL, TTS_VOICE_TYPE_AUTO, TTS_SPEED_AUTO, &speak_id)))
273 case TTS_ERROR_INVALID_PARAMETER:
274 DEBUG("FAILED tts_add_text: error: TTS_ERROR_INVALID_PARAMETER");
276 case TTS_ERROR_INVALID_STATE:
277 DEBUG("FAILED tts_add_text: error: TTS_ERROR_INVALID_STATE, tts_state: %d", state);
279 case TTS_ERROR_INVALID_VOICE:
280 DEBUG("FAILED tts_add_text: error: TTS_ERROR_INVALID_VOICE");
282 case TTS_ERROR_OPERATION_FAILED:
283 DEBUG("FAILED tts_add_text: error: TTS_ERROR_OPERATION_FAILED");
285 case TTS_ERROR_NOT_SUPPORTED:
286 DEBUG("FAILED tts_add_text: error: TTS_ERROR_NOT_SUPPORTED");
289 DEBUG("FAILED tts_add_text: error: not recognized");
294 DEBUG("added id to:%d\n", speak_id);
295 last_utt_id = speak_id;
298 Eina_Bool update_supported_voices(void *data)
303 Service_Data *sd = data;
305 int res = tts_get_state(sd->tts, &state);
307 if(res != TTS_ERROR_NONE)
309 DEBUG("CANNOT RETRIVE STATE");
313 if(state == TTS_STATE_READY)
315 tts_foreach_supported_voices(sd->tts, get_supported_voices_cb, sd);
319 sd->update_language_list = EINA_TRUE;
326 void state_changed_cb(tts_h tts, tts_state_e previous, tts_state_e current, void* user_data)
330 DEBUG("TTS is currently paused. Resume to start reading");
334 DEBUG("++++++++++++++++state_changed_cb\n++++++++++++++++++");
335 DEBUG("current state:%s and previous state:%s\n", get_tts_state(current), get_tts_state(previous));
336 Service_Data *sd = user_data;
338 if (TTS_STATE_CREATED == previous && TTS_STATE_READY == current)
341 update_supported_voices(sd);
345 if (!txt_keep_buff) return;
346 if (!eina_strbuf_length_get(txt_keep_buff)) return;
348 txt = eina_strbuf_string_steal(txt_keep_buff);
349 eina_strbuf_free(txt_keep_buff);
350 txt_keep_buff = NULL;
352 tts_speak(txt, EINA_FALSE);
356 else if (current == TTS_STATE_READY || current == TTS_STATE_PAUSED)
358 DEBUG("TTS state == %s!", get_tts_state(current));
363 DEBUG("TTS state != ready or paused!\n");
367 void spi_stop( void *data)
371 ERROR("Invalid parameter");
375 Service_Data *sd = data;
376 sd->update_language_list = false;
377 free((char*)sd->text_from_dbus);
378 free(sd->current_value);
379 sd->text_from_dbus = NULL;
380 sd->current_value = NULL;