2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <vconf-keys.h>
22 #include "SttManager.h"
24 using namespace is::stt;
33 static inline const char *stt_state_str(stt_state_e cur) {
34 if (cur == STT_STATE_CREATED)
35 return (const char *) "STT_STATE_CREATED";
37 else if (cur == STT_STATE_READY)
38 return (const char *) "STT_STATE_READY";
40 else if (cur == STT_STATE_RECORDING)
41 return (const char *) "STT_STATE_RECORDING";
43 else if (cur == STT_STATE_PROCESSING)
44 return (const char *) "STT_STATE_PROCESSING";
47 return (const char *) "ABNORMAL CASE";
50 SttManager::SttManager(ISttFeedback& feedback)
51 : ifeedback(feedback),
59 int ret = stt_create(&handle);
61 if(ret != STT_ERROR_NONE)
62 throw SttException(ret, ErrorString((stt_error_e)ret));
65 * Set default properties
70 catch(SttException &e) {
71 PRINTFUNC(DLOG_ERROR, "reason : %s", e.what());
76 SttManager::~SttManager() {
78 EnableFeedback(false);
83 catch(SttException &e) {
84 PRINTFUNC(DLOG_ERROR, "reason : %s", e.what());
89 void SttManager::Prepare() {
91 * Prepare stt service.
94 int ret = stt_prepare(handle);
96 if(ret != STT_ERROR_NONE)
97 throw SttException(ret, ErrorString((stt_error_e)ret));
100 void SttManager::UnPrepare() {
102 * UnPrepare stt service.
105 int ret = stt_unprepare(handle);
107 if (ret != STT_ERROR_NONE)
108 throw SttException(ret, ErrorString((stt_error_e)ret));
111 void SttManager::Start() {
112 if(!Validate((int) READY)) {
113 throw SttException((int) STT_ERROR_INVALID_STATE, "INVALID STATE - !STT_STATE_READY");
116 PRINTFUNC(DLOG_DEBUG, "HERE");
124 asrtype = STT_RECOGNITION_TYPE_FREE_PARTIAL;
129 // stt_is_samsung_asr(&bval);
131 if( bval == true && !language.compare("en_GB")) {
132 PRINTFUNC(DLOG_DEBUG, "en_GB requested, change to en_US");
133 ret = stt_start(handle, "en_US", asrtype.c_str());
135 ret = stt_start(handle, language.c_str(), asrtype.c_str());
138 if(ret != STT_ERROR_NONE)
139 throw SttException(ret, ErrorString((stt_error_e)ret));
142 void SttManager::Stop() {
143 if(!Validate((int) RECORDING)) {
144 throw SttException((int) STT_ERROR_INVALID_STATE, "INVALID STATE - !STT_STATE_RECORDING");
151 int ret = stt_stop(handle);
153 if(ret != STT_ERROR_NONE)
154 throw SttException(ret, ErrorString((stt_error_e)ret));
157 void SttManager::Cancel() {
159 PRINTFUNC(DLOG_WARN, "iscancelled (%d)", iscancelled);
163 if(!Validate((int) (RECORDING|PROCESSING))) {
164 throw SttException((int) STT_ERROR_INVALID_STATE, "INVALID STATE - !(STT_STATE_RECORDING or STT_STATE_PROCESSING)");
168 * Cancel stt service (recording, processing)
171 int ret = stt_cancel(handle);
173 if(ret != STT_ERROR_NONE)
174 throw SttException(ret, ErrorString((stt_error_e)ret));
177 PRINTFUNC(DLOG_INFO, "iscancelled (%d)", iscancelled);
183 bool SttManager::Validate(int state) {
186 int ret = stt_get_state(handle, &cur);
187 if (ret != STT_ERROR_NONE) {
191 PRINTFUNC(DLOG_DEBUG, "validate state - %d", state);
192 PRINTFUNC(DLOG_DEBUG, "stt deamon state - %s",
193 cur == STT_STATE_CREATED ? "STT_STATE_CREATED" :
194 cur == STT_STATE_READY ? "STT_STATE_READY" :
195 cur == STT_STATE_RECORDING ? "STT_STATE_RECORDING" :
196 cur == STT_STATE_PROCESSING ? "STT_STATE_PROCESSING" : "ABNORMAL");
199 case STT_STATE_CREATED :
200 if (state & CREATE) return true;
202 case STT_STATE_READY :
203 if (state & READY) return true;
205 case STT_STATE_RECORDING :
206 if (state & RECORDING) return true;
208 case STT_STATE_PROCESSING :
209 if (state & PROCESSING) return true;
218 void SttManager::Initialize() {
219 /** Todo. add routine to intialize */
222 void SttManager::PrintResultState(stt_result_event_e result_type)
226 switch (result_type) {
227 case STT_RESULT_EVENT_FINAL_RESULT :
228 result = "STT_RESULT_EVENT_FINAL_RESULT";
230 case STT_RESULT_EVENT_PARTIAL_RESULT :
231 result = "STT_RESULT_EVENT_PARTIAL_RESULT";
233 case STT_RESULT_EVENT_ERROR :
234 result = "STT_RESULT_EVENT_ERROR";
240 PRINTFUNC(DLOG_INFO, "result type : %s", result.c_str());
243 void SttManager::on_result(
245 stt_result_event_e event,
250 PrintResultState(event);
253 PRINTFUNC(DLOG_ERROR, "user_data null");
254 throw SttException((int)STT_ERROR_INVALID_PARAMETER, "invalid self reference");
257 SttManager& manager = *((SttManager *) user_data);
259 std::vector<std::string> results;
261 PRINTFUNC(DLOG_INFO, "result size : %d, msg : %s", size, msg);
263 for (size_t i = 0; i < (size_t) size; i++) {
265 results.push_back(std::string(data[i]));
269 manager.ifeedback.OnResult(manager.asrtype, event, results, std::string(msg));
271 manager.ifeedback.OnResult(manager.asrtype, event, results, std::string(""));
275 void SttManager::PrintState(stt_state_e previous, stt_state_e current)
281 case STT_STATE_READY :
282 prev = "STT_STATE_READY";
284 case STT_STATE_CREATED :
285 prev = "STT_STATE_CREATED";
287 case STT_STATE_RECORDING :
288 prev = "STT_STATE_RECORDING";
290 case STT_STATE_PROCESSING :
291 prev = "STT_STATE_PROCESSING";
299 case STT_STATE_READY :
300 curr = "STT_STATE_READY";
302 case STT_STATE_CREATED :
303 curr = "STT_STATE_CREATED";
305 case STT_STATE_RECORDING :
306 curr = "STT_STATE_RECORDING";
308 case STT_STATE_PROCESSING :
309 curr = "STT_STATE_PROCESSING";
315 PRINTFUNC(DLOG_INFO, "previous: %s(%d), current: %s(%d)", prev.c_str(), previous, curr.c_str(), current);
318 void SttManager::on_state_changed(
320 stt_state_e previous,
323 PrintState(previous, current);
326 throw SttException((int)STT_ERROR_INVALID_PARAMETER, "invalid self reference");
328 SttManager& manager = *((SttManager *) user_data);
330 if (current== STT_STATE_READY) {
331 if (previous == STT_STATE_CREATED) {
332 manager.EnableSilenceDetection();
333 manager.ifeedback.AutoStart();
334 } else if (previous == STT_STATE_RECORDING) {
336 std::vector<std::string> results;
337 manager.ifeedback.OnResult(manager.asrtype, STT_RESULT_EVENT_ERROR, results, msg);
339 manager.ifeedback.SttIdle();
341 } else if (current == STT_STATE_RECORDING) {
342 manager.ifeedback.SttRecording();
343 } else if (current == STT_STATE_PROCESSING) {
344 if (!manager.iscancelled) {
345 PRINTFUNC(DLOG_INFO, "iscancelled (%d)", manager.iscancelled);
346 manager.ifeedback.SttProcessing();
348 manager.iscancelled = false;
349 PRINTFUNC(DLOG_INFO, "iscancelled (%d)", manager.iscancelled);
354 void SttManager::PrintErrorState(stt_error_e reason)
359 case STT_ERROR_OUT_OF_MEMORY :
360 res = "STT_ERROR_OUT_OF_MEMORY";
362 case STT_ERROR_IO_ERROR :
363 res = "STT_ERROR_IO_ERROR";
365 case STT_ERROR_INVALID_PARAMETER :
366 res = "STT_ERROR_INVALID_PARAMETER";
368 case STT_ERROR_TIMED_OUT :
369 res = "STT_ERROR_TIMED_OUT";
371 case STT_ERROR_RECORDER_BUSY :
372 res = "STT_ERROR_RECORDER_BUSY";
374 case STT_ERROR_OUT_OF_NETWORK :
375 res = "STT_ERROR_OUT_OF_NETWORK";
377 case STT_ERROR_PERMISSION_DENIED :
378 res = "STT_ERROR_PERMISSION_DENIED";
380 case STT_ERROR_NOT_SUPPORTED :
381 res = "STT_ERROR_NOT_SUPPORTED";
383 case STT_ERROR_INVALID_STATE :
384 res = "STT_ERROR_INVALID_STATE";
386 case STT_ERROR_INVALID_LANGUAGE :
387 res = "STT_ERROR_INVALID_LANGUAGE";
389 case STT_ERROR_ENGINE_NOT_FOUND :
390 res = "STT_ERROR_ENGINE_NOT_FOUND";
392 case STT_ERROR_OPERATION_FAILED :
393 res = "STT_ERROR_OPERATION_FAILED";
395 case STT_ERROR_NOT_SUPPORTED_FEATURE :
396 res = "STT_ERROR_NOT_SUPPORTED_FEATURE";
399 res = "UNKNOWN ERROR REASON";
402 PRINTFUNC(DLOG_INFO, "Error reason %s(%d)", res.c_str(), reason);
405 void SttManager::on_error(
409 PRINTFUNC(DLOG_INFO, "stt-daemon error (%d)", reason);
412 throw SttException((int)STT_ERROR_INVALID_PARAMETER, "invalid self reference");
414 SttManager& manager = *((SttManager *) user_data);
415 manager.ifeedback.OnError(reason);
418 void SttManager::SetLanguage(std::string language) {
419 this->language = language;
422 void SttManager::EnableFeedback(bool enabled) {
423 int ret = STT_ERROR_NONE;
425 void *udata = static_cast<void *>(this);
428 ret = stt_set_recognition_result_cb(handle, on_result, udata);
429 if (STT_ERROR_NONE != ret)
430 throw SttException(ret, ErrorString((stt_error_e)ret));
432 ret = stt_set_error_cb(handle, on_error, udata);
433 if (STT_ERROR_NONE != ret)
434 throw SttException(ret, ErrorString((stt_error_e)ret));
436 ret = stt_set_state_changed_cb(handle, on_state_changed, udata);
437 if (STT_ERROR_NONE != ret)
438 throw SttException(ret, ErrorString((stt_error_e)ret));
440 ret = stt_unset_error_cb(handle);
441 if (STT_ERROR_NONE != ret)
442 throw SttException(ret, ErrorString((stt_error_e)ret));
444 ret = stt_unset_state_changed_cb(handle);
445 if (STT_ERROR_NONE != ret)
446 throw SttException(ret, ErrorString((stt_error_e)ret));
448 ret = stt_unset_recognition_result_cb(handle);
449 if (STT_ERROR_NONE != ret)
450 throw SttException(ret, ErrorString((stt_error_e)ret));
454 const char* SttManager::ErrorString(int ecode) {
455 const char *str = NULL;
458 case STT_ERROR_OUT_OF_MEMORY:
459 str = (const char *) "STT_ERROR_OUT_OF_MEMORY";
461 case STT_ERROR_IO_ERROR:
462 str = (const char *) "STT_ERROR_IO_ERROR";
464 case STT_ERROR_INVALID_PARAMETER:
465 str = (const char *) "STT_ERROR_INVALID_PARAMETER";
467 case STT_ERROR_TIMED_OUT:
468 str = (const char *) "STT_ERROR_TIMED_OUT";
470 case STT_ERROR_RECORDER_BUSY:
471 str = (const char *) "STT_ERROR_RECORDER_BUSY";
473 case STT_ERROR_OUT_OF_NETWORK:
474 str = (const char *) "STT_ERROR_OUT_OF_NETWORK";
476 case STT_ERROR_INVALID_STATE:
477 str = (const char *) " STT_ERROR_INVALID_STATE";
479 case STT_ERROR_INVALID_LANGUAGE:
480 str = (const char *) "STT_ERROR_INVALID_LANGUAGE";
482 case STT_ERROR_ENGINE_NOT_FOUND:
483 str = (const char *) "STT_ERROR_ENGINE_NOT_FOUND";
485 case STT_ERROR_OPERATION_FAILED:
486 str = (const char *) "STT_ERROR_OPERATION_FAILED";
488 case STT_ERROR_NOT_SUPPORTED_FEATURE:
489 str = (const char *) "STT_ERROR_NOT_SUPPORTED_FEATURE";
495 void SttManager::SoundFeedback() {
497 int is_sound_vibe = 0;
499 if (vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &is_sound)) {
500 PRINTFUNC(DLOG_ERROR, "get sound status failed.");
503 if (vconf_get_bool(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, &is_sound_vibe)) {
504 PRINTFUNC(DLOG_ERROR, "get vibe status failed.");
507 if (is_sound || is_sound_vibe) {
508 stt_set_start_sound(handle, "/usr/share/ise-voice-input/audio/voice_start.wav");
509 stt_set_stop_sound(handle, "/usr/share/ise-voice-input/audio/voice_stop.wav");
511 stt_unset_start_sound(handle);
512 stt_unset_stop_sound(handle);
518 void SttManager::EnableSilenceDetection(bool enabled) {
519 stt_option_silence_detection_e s_option;
522 s_option = STT_OPTION_SILENCE_DETECTION_TRUE;
524 s_option = STT_OPTION_SILENCE_DETECTION_FALSE;
526 int ret = stt_set_silence_detection(handle, s_option);
527 if (STT_ERROR_NONE != ret) {
532 ErrorString((stt_error_e) ret));
534 PRINTFUNC(NO_PRINT, "stt_set_silence_detection Successful");