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) {
35 if(cur == STT_STATE_CREATED)
36 return (const char *) "STT_STATE_CREATED";
38 else if(cur == STT_STATE_READY)
39 return (const char *) "STT_STATE_READY";
41 else if(cur == STT_STATE_RECORDING)
42 return (const char *) "STT_STATE_RECORDING";
44 else if(cur == STT_STATE_PROCESSING)
45 return (const char *) "STT_STATE_PROCESSING";
48 return (const char *) "ABNORMAL CASE";
52 SttManager::SttManager(ISttFeedback& feedback)
53 : ifeedback(feedback),
62 int ret = stt_create(&handle);
64 if(ret != STT_ERROR_NONE)
65 throw SttException(ret, ErrorString((stt_error_e)ret));
68 * Set default properties
73 catch(SttException &e) {
74 PRINTFUNC(DLOG_ERROR, "reason : %s", e.what());
81 SttManager::~SttManager() {
84 EnableFeedback(false);
89 catch(SttException &e) {
90 PRINTFUNC(DLOG_ERROR, "reason : %s", e.what());
95 void SttManager::Prepare() {
98 * Prepare stt service.
101 int ret = stt_prepare(handle);
103 if(ret != STT_ERROR_NONE)
104 throw SttException(ret, ErrorString((stt_error_e)ret));
109 void SttManager::UnPrepare() {
112 * UnPrepare stt service.
115 int ret = stt_unprepare(handle);
117 if(ret != STT_ERROR_NONE)
118 throw SttException(ret, ErrorString((stt_error_e)ret));
123 void SttManager::Start() {
125 if(!Validate((int) READY)) {
126 throw SttException((int) STT_ERROR_INVALID_STATE, "INVALID STATE - !STT_STATE_READY");
129 PRINTFUNC(DLOG_DEBUG, "HERE");
137 asrtype = STT_RECOGNITION_TYPE_FREE_PARTIAL;
142 // stt_is_samsung_asr(&bval);
144 if( bval == true && !language.compare("en_GB")) {
145 PRINTFUNC(DLOG_DEBUG, "en_GB requested, change to en_US");
146 ret = stt_start(handle, "en_US", asrtype.c_str());
148 ret = stt_start(handle, language.c_str(), asrtype.c_str());
151 if(ret != STT_ERROR_NONE)
152 throw SttException(ret, ErrorString((stt_error_e)ret));
157 void SttManager::Stop() {
159 if(!Validate((int) RECORDING)) {
160 throw SttException((int) STT_ERROR_INVALID_STATE, "INVALID STATE - !STT_STATE_RECORDING");
167 int ret = stt_stop(handle);
169 if(ret != STT_ERROR_NONE)
170 throw SttException(ret, ErrorString((stt_error_e)ret));
175 void SttManager::Cancel() {
178 PRINTFUNC(DLOG_WARN, "iscancelled (%d)", iscancelled);
182 if(!Validate((int) (RECORDING|PROCESSING))) {
183 throw SttException((int) STT_ERROR_INVALID_STATE, "INVALID STATE - !(STT_STATE_RECORDING or STT_STATE_PROCESSING)");
187 * Cancel stt service (recording, processing)
190 int ret = stt_cancel(handle);
192 if(ret != STT_ERROR_NONE)
193 throw SttException(ret, ErrorString((stt_error_e)ret));
196 PRINTFUNC(DLOG_INFO, "iscancelled (%d)", iscancelled);
202 bool SttManager::Validate(int state) {
206 int ret = stt_get_state(handle, &cur);
207 if(ret != STT_ERROR_NONE) {
211 PRINTFUNC(DLOG_DEBUG, "validate state - %d", state);
212 PRINTFUNC(DLOG_DEBUG, "stt deamon state - %s",
213 cur == STT_STATE_CREATED ? "STT_STATE_CREATED" :
214 cur == STT_STATE_READY ? "STT_STATE_READY" :
215 cur == STT_STATE_RECORDING ? "STT_STATE_RECORDING" :
216 cur == STT_STATE_PROCESSING ? "STT_STATE_PROCESSING" : "ABNORMAL");
219 case STT_STATE_CREATED :
220 if(state & CREATE) return true;
222 case STT_STATE_READY :
223 if(state & READY) return true;
225 case STT_STATE_RECORDING :
226 if(state & RECORDING) return true;
228 case STT_STATE_PROCESSING :
229 if(state & PROCESSING) return true;
240 void SttManager::Initialize() {
242 /** Todo. add routine to intialize */
245 void SttManager::PrintResultState(stt_result_event_e result_type)
249 switch (result_type) {
250 case STT_RESULT_EVENT_FINAL_RESULT :
251 result = "STT_RESULT_EVENT_FINAL_RESULT";
253 case STT_RESULT_EVENT_PARTIAL_RESULT :
254 result = "STT_RESULT_EVENT_PARTIAL_RESULT";
256 case STT_RESULT_EVENT_ERROR :
257 result = "STT_RESULT_EVENT_ERROR";
264 PRINTFUNC(DLOG_INFO, "result type : %s", result.c_str());
268 void SttManager::on_result(
270 stt_result_event_e event,
276 PrintResultState(event);
279 PRINTFUNC(DLOG_ERROR, "user_data null");
280 throw SttException((int)STT_ERROR_INVALID_PARAMETER, "invalid self reference");
283 SttManager& manager = *((SttManager *) user_data);
285 std::vector<std::string> results;
287 PRINTFUNC(DLOG_INFO, "result size : %d, msg : %s", size, msg);
289 for(size_t i = 0; i < (size_t) size; i++) {
291 results.push_back(std::string(data[i]));
295 manager.ifeedback.OnResult(manager.asrtype, event, results, std::string(msg));
297 manager.ifeedback.OnResult(manager.asrtype, event, results, std::string(""));
302 void SttManager::PrintState(stt_state_e previous, stt_state_e current)
308 case STT_STATE_READY :
309 prev = "STT_STATE_READY";
311 case STT_STATE_CREATED :
312 prev = "STT_STATE_CREATED";
314 case STT_STATE_RECORDING :
315 prev = "STT_STATE_RECORDING";
317 case STT_STATE_PROCESSING :
318 prev = "STT_STATE_PROCESSING";
326 case STT_STATE_READY :
327 curr = "STT_STATE_READY";
329 case STT_STATE_CREATED :
330 curr = "STT_STATE_CREATED";
332 case STT_STATE_RECORDING :
333 curr = "STT_STATE_RECORDING";
335 case STT_STATE_PROCESSING :
336 curr = "STT_STATE_PROCESSING";
343 PRINTFUNC(DLOG_INFO, "previous: %s(%d), current: %s(%d)", prev.c_str(), previous, curr.c_str(), current);
347 void SttManager::on_state_changed(
349 stt_state_e previous,
353 PrintState(previous, current);
356 throw SttException((int)STT_ERROR_INVALID_PARAMETER, "invalid self reference");
358 SttManager& manager = *((SttManager *) user_data);
360 if(current== STT_STATE_READY) {
361 if(previous == STT_STATE_CREATED) {
362 manager.EnableSilenceDetection();
363 manager.ifeedback.AutoStart();
365 else if(previous == STT_STATE_RECORDING) {
367 std::vector<std::string> results;
368 manager.ifeedback.OnResult(manager.asrtype, STT_RESULT_EVENT_ERROR, results, msg);
371 manager.ifeedback.SttIdle();
374 else if(current == STT_STATE_RECORDING) {
375 manager.ifeedback.SttRecording();
377 else if(current == STT_STATE_PROCESSING) {
378 if(!manager.iscancelled) {
379 PRINTFUNC(DLOG_INFO, "iscancelled (%d)", manager.iscancelled);
380 manager.ifeedback.SttProcessing();
383 manager.iscancelled = false;
384 PRINTFUNC(DLOG_INFO, "iscancelled (%d)", manager.iscancelled);
389 void SttManager::PrintErrorState(stt_error_e reason)
394 case STT_ERROR_OUT_OF_MEMORY :
395 res = "STT_ERROR_OUT_OF_MEMORY";
397 case STT_ERROR_IO_ERROR :
398 res = "STT_ERROR_IO_ERROR";
400 case STT_ERROR_INVALID_PARAMETER :
401 res = "STT_ERROR_INVALID_PARAMETER";
403 case STT_ERROR_TIMED_OUT :
404 res = "STT_ERROR_TIMED_OUT";
406 case STT_ERROR_RECORDER_BUSY :
407 res = "STT_ERROR_RECORDER_BUSY";
409 case STT_ERROR_OUT_OF_NETWORK :
410 res = "STT_ERROR_OUT_OF_NETWORK";
412 case STT_ERROR_PERMISSION_DENIED :
413 res = "STT_ERROR_PERMISSION_DENIED";
415 case STT_ERROR_NOT_SUPPORTED :
416 res = "STT_ERROR_NOT_SUPPORTED";
418 case STT_ERROR_INVALID_STATE :
419 res = "STT_ERROR_INVALID_STATE";
421 case STT_ERROR_INVALID_LANGUAGE :
422 res = "STT_ERROR_INVALID_LANGUAGE";
424 case STT_ERROR_ENGINE_NOT_FOUND :
425 res = "STT_ERROR_ENGINE_NOT_FOUND";
427 case STT_ERROR_OPERATION_FAILED :
428 res = "STT_ERROR_OPERATION_FAILED";
430 case STT_ERROR_NOT_SUPPORTED_FEATURE :
431 res = "STT_ERROR_NOT_SUPPORTED_FEATURE";
434 res = "UNKNOWN ERROR REASON";
438 PRINTFUNC(DLOG_INFO, "Error reason %s(%d)", res.c_str(), reason);
443 void SttManager::on_error(
448 PRINTFUNC(DLOG_INFO, "stt-daemon error (%d)", reason);
451 throw SttException((int)STT_ERROR_INVALID_PARAMETER, "invalid self reference");
453 SttManager& manager = *((SttManager *) user_data);
454 manager.ifeedback.OnError(reason);
459 void SttManager::SetLanguage(std::string language) {
461 this->language = language;
466 void SttManager::EnableFeedback(bool enabled) {
468 int ret = STT_ERROR_NONE;
470 void *udata = static_cast<void *>(this);
473 ret = stt_set_recognition_result_cb(handle, on_result, udata);
474 if(STT_ERROR_NONE != ret)
475 throw SttException(ret, ErrorString((stt_error_e)ret));
477 ret = stt_set_error_cb(handle, on_error, udata);
478 if(STT_ERROR_NONE != ret)
479 throw SttException(ret, ErrorString((stt_error_e)ret));
481 ret = stt_set_state_changed_cb(handle, on_state_changed, udata);
482 if(STT_ERROR_NONE != ret)
483 throw SttException(ret, ErrorString((stt_error_e)ret));
486 ret = stt_unset_error_cb(handle);
487 if(STT_ERROR_NONE != ret)
488 throw SttException(ret, ErrorString((stt_error_e)ret));
490 ret = stt_unset_state_changed_cb(handle);
491 if(STT_ERROR_NONE != ret)
492 throw SttException(ret, ErrorString((stt_error_e)ret));
494 ret = stt_unset_recognition_result_cb(handle);
495 if(STT_ERROR_NONE != ret)
496 throw SttException(ret, ErrorString((stt_error_e)ret));
502 const char* SttManager::ErrorString(int ecode) {
504 const char *str = NULL;
507 case STT_ERROR_OUT_OF_MEMORY:
508 str = (const char *) "STT_ERROR_OUT_OF_MEMORY";
510 case STT_ERROR_IO_ERROR:
511 str = (const char *) "STT_ERROR_IO_ERROR";
513 case STT_ERROR_INVALID_PARAMETER:
514 str = (const char *) "STT_ERROR_INVALID_PARAMETER";
516 case STT_ERROR_TIMED_OUT:
517 str = (const char *) "STT_ERROR_TIMED_OUT";
519 case STT_ERROR_RECORDER_BUSY:
520 str = (const char *) "STT_ERROR_RECORDER_BUSY";
522 case STT_ERROR_OUT_OF_NETWORK:
523 str = (const char *) "STT_ERROR_OUT_OF_NETWORK";
525 case STT_ERROR_INVALID_STATE:
526 str = (const char *) " STT_ERROR_INVALID_STATE";
528 case STT_ERROR_INVALID_LANGUAGE:
529 str = (const char *) "STT_ERROR_INVALID_LANGUAGE";
531 case STT_ERROR_ENGINE_NOT_FOUND:
532 str = (const char *) "STT_ERROR_ENGINE_NOT_FOUND";
534 case STT_ERROR_OPERATION_FAILED:
535 str = (const char *) "STT_ERROR_OPERATION_FAILED";
537 case STT_ERROR_NOT_SUPPORTED_FEATURE:
538 str = (const char *) "STT_ERROR_NOT_SUPPORTED_FEATURE";
547 void SttManager::SoundFeedback() {
550 int is_sound_vibe = 0;
552 if(vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &is_sound)) {
553 PRINTFUNC(DLOG_ERROR, "get sound status failed.");
556 if(vconf_get_bool(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, &is_sound_vibe)) {
557 PRINTFUNC(DLOG_ERROR, "get vibe status failed.");
560 if(is_sound || is_sound_vibe) {
561 stt_set_start_sound(handle, "/usr/share/ise-voice-input/audio/voice_start.wav");
562 stt_set_stop_sound(handle, "/usr/share/ise-voice-input/audio/voice_stop.wav");
565 stt_unset_start_sound(handle);
566 stt_unset_stop_sound(handle);
572 void SttManager::EnableSilenceDetection(bool enabled) {
574 stt_option_silence_detection_e s_option;
577 s_option = STT_OPTION_SILENCE_DETECTION_TRUE;
579 s_option = STT_OPTION_SILENCE_DETECTION_FALSE;
581 int ret = stt_set_silence_detection(handle, s_option);
582 if (STT_ERROR_NONE != ret) {
587 ErrorString((stt_error_e) ret)
591 PRINTFUNC(NO_PRINT, "stt_set_silence_detection Successful");