2 * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
4 * Licensed under the Flora License, Version 1.1 (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
8 * http://floralicense.org/license/
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.
20 #include "screen_reader_tts.h"
21 #include "screen_reader_vconf.h"
24 // ---------------------------- DEBUG HELPERS ------------------------------
28 static int last_utt_id;
29 static Eina_Bool pause_state = EINA_FALSE;
30 static Eina_Bool flush_flag = EINA_FALSE;
31 static Eina_Strbuf *txt_keep_buff = NULL;
33 static void(*on_utterance_end)(void);
35 static void _text_keep(const char *txt)
37 if (!txt_keep_buff) return;
38 if (eina_strbuf_length_get(txt_keep_buff) > 0) eina_strbuf_append(txt_keep_buff, ", ");
39 eina_strbuf_append(txt_keep_buff, txt);
42 static char * get_tts_error( int r )
50 case TTS_ERROR_INVALID_PARAMETER:
54 case TTS_ERROR_OUT_OF_MEMORY:
56 return "out of memory";
58 case TTS_ERROR_OPERATION_FAILED:
62 case TTS_ERROR_INVALID_STATE:
68 return "uknown error";
73 static char * get_tts_state( tts_state_e r )
77 case TTS_STATE_CREATED:
85 case TTS_STATE_PLAYING:
89 case TTS_STATE_PAUSED:
95 return "uknown state";
100 //-------------------------------------------------------------------------------------------------
102 void set_utterance_cb( void(*uter_cb)(void))
104 on_utterance_end = uter_cb;
108 bool get_supported_voices_cb(tts_h tts, const char* language, int voice_type, void* user_data)
110 DEBUG("LANG: %s; TYPE: %d", language, voice_type);
112 Service_Data *sd = user_data;
113 Voice_Info *vi = calloc(1, sizeof(Voice_Info));
117 return ECORE_CALLBACK_CANCEL;
120 if(asprintf(&vi->language, "%s",language) < 0)
124 return ECORE_CALLBACK_CANCEL;
127 vi->voice_type = voice_type;
129 sd->available_languages = eina_list_append(sd->available_languages, vi);
131 return ECORE_CALLBACK_RENEW;
134 static void __tts_test_utt_started_cb(tts_h tts, int utt_id, void* user_data)
136 DEBUG("Utterance started : utt id(%d) \n", utt_id);
140 static void __tts_test_utt_completed_cb(tts_h tts, int utt_id, void* user_data)
142 DEBUG("Utterance completed : utt id(%d) \n", utt_id);
143 if(last_utt_id - utt_id > FLUSH_LIMIT)
144 flush_flag = EINA_TRUE;
148 flush_flag = EINA_FALSE;
151 #ifndef SCREEN_READER_TV
152 if(last_utt_id == utt_id)
154 DEBUG("LAST UTTERANCE");
155 pause_state = EINA_FALSE;
163 bool tts_init(void *data)
165 DEBUG( "--------------------- TTS_init START ---------------------");
166 Service_Data *sd = data;
168 int r = tts_create( &sd->tts );
169 DEBUG( "Create tts %d (%s)", r, get_tts_error( r ) );
171 r = tts_set_mode( sd->tts, TTS_MODE_SCREEN_READER );
172 DEBUG( "Set tts mode SR %d (%s)", r, get_tts_error( r ) );
174 r = tts_prepare( sd->tts );
175 DEBUG( "Prepare tts %d (%s)", r, get_tts_error( r ) );
177 tts_set_state_changed_cb(sd->tts, state_changed_cb, sd);
179 tts_set_utterance_started_cb(sd->tts, __tts_test_utt_started_cb, sd);
180 tts_set_utterance_completed_cb(sd->tts, __tts_test_utt_completed_cb, sd);
182 DEBUG( "---------------------- TTS_init END ----------------------\n\n");
183 txt_keep_buff = eina_strbuf_new();
187 Eina_Bool tts_pause_get(void)
189 DEBUG( "PAUSE STATE: %d", pause_state);
193 void tts_stop_set(void)
195 Service_Data *sd = get_pointer_to_service_data_struct();
199 Eina_Bool tts_pause_set(Eina_Bool pause_switch)
201 Service_Data *sd = get_pointer_to_service_data_struct();
207 pause_state = EINA_TRUE;
209 if(tts_pause(sd->tts))
211 pause_state = EINA_FALSE;
215 else if(!pause_switch)
217 pause_state = EINA_FALSE;
219 if(tts_play(sd->tts))
221 pause_state = EINA_TRUE;
228 void tts_speak(char *text_to_speak, Eina_Bool flush_switch)
231 Service_Data *sd = get_pointer_to_service_data_struct();
237 tts_get_state(sd->tts, &state);
239 if (state != TTS_STATE_PLAYING &&
240 state != TTS_STATE_PAUSED &&
241 state != TTS_STATE_READY)
243 if (text_to_speak) _text_keep(text_to_speak);
247 if (flush_flag || flush_switch)
249 if (state == TTS_STATE_PLAYING ||
250 state == TTS_STATE_PAUSED)
252 ret = tts_stop(sd->tts);
253 if (TTS_ERROR_NONE != ret)
255 DEBUG("Fail to stop TTS: resultl(%d)", ret);
260 DEBUG( "tts_speak\n");
261 DEBUG( "text to say:%s\n", text_to_speak);
262 if ( !text_to_speak ) return;
263 if ( !text_to_speak[0] ) return;
265 if((ret = tts_add_text( sd->tts, text_to_speak, NULL, TTS_VOICE_TYPE_AUTO, TTS_SPEED_AUTO, &speak_id)))
269 case TTS_ERROR_INVALID_PARAMETER:
270 DEBUG("FAILED tts_add_text: error: TTS_ERROR_INVALID_PARAMETER");
272 case TTS_ERROR_INVALID_STATE:
273 DEBUG("FAILED tts_add_text: error: TTS_ERROR_INVALID_STATE, tts_state: %d", state);
275 case TTS_ERROR_INVALID_VOICE:
276 DEBUG("FAILED tts_add_text: error: TTS_ERROR_INVALID_VOICE");
278 case TTS_ERROR_OPERATION_FAILED:
279 DEBUG("FAILED tts_add_text: error: TTS_ERROR_OPERATION_FAILED");
281 case TTS_ERROR_NOT_SUPPORTED:
282 DEBUG("FAILED tts_add_text: error: TTS_ERROR_NOT_SUPPORTED");
285 DEBUG("FAILED tts_add_text: error: not recognized");
290 DEBUG("added id to:%d\n", speak_id);
291 last_utt_id = speak_id;
294 Eina_Bool update_supported_voices(void *data)
299 Service_Data *sd = data;
301 int res = tts_get_state(sd->tts, &state);
303 if(res != TTS_ERROR_NONE)
305 DEBUG("CANNOT RETRIVE STATE");
309 if(state == TTS_STATE_READY)
311 tts_foreach_supported_voices(sd->tts, get_supported_voices_cb, sd);
315 sd->update_language_list = EINA_TRUE;
322 void state_changed_cb(tts_h tts, tts_state_e previous, tts_state_e current, void* user_data)
326 DEBUG("TTS is currently paused. Resume to start reading");
330 DEBUG("++++++++++++++++state_changed_cb\n++++++++++++++++++");
331 DEBUG("current state:%s and previous state:%s\n", get_tts_state(current), get_tts_state(previous));
332 Service_Data *sd = user_data;
334 if (TTS_STATE_CREATED == previous && TTS_STATE_READY == current)
337 update_supported_voices(sd);
341 if (!txt_keep_buff) return;
342 if (!eina_strbuf_length_get(txt_keep_buff)) return;
344 txt = eina_strbuf_string_steal(txt_keep_buff);
345 eina_strbuf_free(txt_keep_buff);
346 txt_keep_buff = NULL;
348 tts_speak(txt, EINA_FALSE);
352 else if (current == TTS_STATE_READY || current == TTS_STATE_PAUSED)
354 DEBUG("TTS state == %s!", get_tts_state(current));
359 DEBUG("TTS state != ready or paused!\n");
363 void spi_stop( void *data)
367 ERROR("Invalid parameter");
371 Service_Data *sd = data;
372 sd->update_language_list = false;
373 free((char*)sd->text_from_dbus);
374 free(sd->current_value);
375 sd->text_from_dbus = NULL;
376 sd->current_value = NULL;