Merge with Tizen 2.3
[platform/core/uifw/stt.git] / common / stt_engine.c
1 /*
2 *  Copyright (c) 2011-2014 Samsung Electronics Co., Ltd All Rights Reserved 
3 *  Licensed under the Apache License, Version 2.0 (the "License");
4 *  you may not use this file except in compliance with the License.
5 *  You may obtain a copy of the License at
6 *  http://www.apache.org/licenses/LICENSE-2.0
7 *  Unless required by applicable law or agreed to in writing, software
8 *  distributed under the License is distributed on an "AS IS" BASIS,
9 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 *  See the License for the specific language governing permissions and
11 *  limitations under the License.
12 */
13
14 #include <dlog.h>
15 #include <dlfcn.h>
16 #include <dirent.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <stdbool.h>
20
21 #include "stt_engine.h"
22
23 /*
24 * Internal data structure
25 */
26
27 typedef struct {
28         int     engine_id;
29         char*   engine_path;
30         void    *handle;
31
32         sttpe_funcs_s*  pefuncs;
33         sttpd_funcs_s*  pdfuncs;
34
35         int (*sttp_load_engine)(sttpd_funcs_s* pdfuncs, sttpe_funcs_s* pefuncs);
36         int (*sttp_unload_engine)();
37 }sttengine_s;
38
39 extern const char* stt_tag();
40
41 /** stt engine list */
42 static GSList *g_engine_list;
43
44 static const char* __stt_get_engine_error_code(sttp_error_e err)
45 {
46         switch(err) {
47         case STTP_ERROR_NONE:                   return "STTP_ERROR_NONE";
48         case STTP_ERROR_OUT_OF_MEMORY:          return "STTP_ERROR_OUT_OF_MEMORY";
49         case STTP_ERROR_IO_ERROR:               return "STTP_ERROR_IO_ERROR";
50         case STTP_ERROR_INVALID_PARAMETER:      return "STTP_ERROR_INVALID_PARAMETER";
51         case STTP_ERROR_OUT_OF_NETWORK:         return "STTP_ERROR_OUT_OF_NETWORK";
52         case STTP_ERROR_INVALID_STATE:          return "STTP_ERROR_INVALID_STATE";
53         case STTP_ERROR_INVALID_LANGUAGE:       return "STTP_ERROR_INVALID_LANGUAGE";
54         case STTP_ERROR_OPERATION_FAILED:       return "STTP_ERROR_OPERATION_FAILED";
55         case STTP_ERROR_NOT_SUPPORTED_FEATURE:  return "STTP_ERROR_NOT_SUPPORTED_FEATURE";
56         default:
57                 return "Invalid error code";
58         }
59 }
60
61 static sttengine_s* __get_engine(int engine_id)
62 {
63         /* check whether engine id is valid or not.*/
64         GSList *iter = NULL;
65         sttengine_s *engine = NULL;
66
67         if (g_slist_length(g_engine_list) > 0) {
68                 /*Get a first item*/
69                 iter = g_slist_nth(g_engine_list, 0);
70
71                 while (NULL != iter) {
72                         /*Get handle data from list*/
73                         engine = iter->data;
74
75                         if (engine_id == engine->engine_id) {
76                                 return engine;
77                         }
78
79                         /*Get next item*/
80                         iter = g_slist_next(iter);
81                 }
82         }
83
84         return NULL;
85 }
86
87 /* Register engine id */
88 int stt_engine_load(int engine_id, const char* filepath)
89 {
90         if (NULL == filepath || engine_id < 0) {
91                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter"); 
92                 return STTP_ERROR_INVALID_PARAMETER;
93         }
94
95         sttengine_s* engine = NULL;
96         engine = __get_engine(engine_id);
97         if (NULL != engine) {
98                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is already loaded", engine_id);
99                 return 0;
100         }
101
102         SECURE_SLOG(LOG_DEBUG, stt_tag(), "[Engine] Load engine id(%d), path(%s)", engine_id, filepath);
103
104         /* allocation memory */
105         engine = (sttengine_s*)calloc(1, sizeof(sttengine_s));
106
107         /* load engine */
108         char *error;
109
110         engine->handle = dlopen(filepath, RTLD_LAZY);
111         if (!engine->handle) {
112                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine] Invalid engine (Fail dlopen) : %s", filepath);
113                 free(engine);
114                 return STTP_ERROR_OPERATION_FAILED;
115         }
116
117         engine->pefuncs = (sttpe_funcs_s*)calloc(1, sizeof(sttpe_funcs_s));
118         engine->pdfuncs = (sttpd_funcs_s*)calloc(1, sizeof(sttpd_funcs_s));
119
120         engine->sttp_unload_engine = NULL;
121         engine->sttp_load_engine = NULL;
122
123         engine->sttp_unload_engine = (int (*)())dlsym(engine->handle, "sttp_unload_engine");
124         if (NULL != (error = dlerror()) || NULL == engine->sttp_unload_engine) {
125                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to link daemon to sttp_unload_engine() : %s", error);
126                 dlclose(engine->handle);
127                 free(engine->pefuncs);
128                 free(engine->pdfuncs);
129                 free(engine);
130                 return STTP_ERROR_OPERATION_FAILED;
131         }
132
133         engine->sttp_load_engine = (int (*)(sttpd_funcs_s*, sttpe_funcs_s*) )dlsym(engine->handle, "sttp_load_engine");
134         if (NULL != (error = dlerror()) || NULL == engine->sttp_load_engine) {
135                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to link daemon to sttp_load_engine() : %s", error);
136                 dlclose(engine->handle);
137                 free(engine->pefuncs);
138                 free(engine->pdfuncs);
139                 free(engine);
140                 return STTP_ERROR_OPERATION_FAILED;
141         }
142
143         engine->engine_id = engine_id;
144         engine->engine_path = strdup(filepath);
145
146         engine->pdfuncs->version = 1;
147         engine->pdfuncs->size = sizeof(sttpd_funcs_s);
148         
149         int ret = engine->sttp_load_engine(engine->pdfuncs, engine->pefuncs); 
150         if (0 != ret) {
151                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail sttp_load_engine() : %s", __stt_get_engine_error_code(ret));
152                 dlclose(engine->handle);
153                 free(engine->pefuncs);
154                 free(engine->pdfuncs);
155                 free(engine->engine_path);
156                 free(engine);
157                 return STTP_ERROR_OPERATION_FAILED;
158         }
159
160         /* engine error check */
161         if (engine->pefuncs->size != sizeof(sttpe_funcs_s)) {
162                 SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine is not valid : function size is not matched");
163         }
164
165         if (NULL == engine->pefuncs->initialize ||
166                 NULL == engine->pefuncs->deinitialize ||
167                 NULL == engine->pefuncs->foreach_langs ||
168                 NULL == engine->pefuncs->is_valid_lang ||
169                 NULL == engine->pefuncs->support_silence ||
170                 NULL == engine->pefuncs->support_recognition_type ||
171                 NULL == engine->pefuncs->get_audio_format ||
172                 NULL == engine->pefuncs->set_silence_detection ||
173                 NULL == engine->pefuncs->start ||
174                 NULL == engine->pefuncs->set_recording ||
175                 NULL == engine->pefuncs->stop ||
176                 NULL == engine->pefuncs->cancel ||
177                 NULL == engine->pefuncs->foreach_result_time)
178                 /* Current unused functions
179                 NULL == engine->pefuncs->start_file_recognition ||
180                 */
181         {
182                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] The engine functions are NOT valid");
183                 dlclose(engine->handle);
184                 free(engine->pefuncs);
185                 free(engine->pdfuncs);
186                 free(engine->engine_path);
187                 free(engine);
188
189                 return STTP_ERROR_OPERATION_FAILED; 
190         }
191
192         SECURE_SLOG(LOG_DEBUG, stt_tag(), "[Engine Success] Load engine : version(%d), size(%d)",engine->pefuncs->version, engine->pefuncs->size);
193
194         g_engine_list = g_slist_append(g_engine_list, engine);
195
196         return 0;
197 }
198
199 /* Unregister engine id */
200 int stt_engine_unload(int engine_id)
201 {
202         sttengine_s* engine = NULL;
203         engine = __get_engine(engine_id);
204         if (NULL == engine) {
205                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is invalid", engine_id);
206                 return STTP_ERROR_INVALID_PARAMETER;
207         }
208
209         /* unload engine */
210         engine->sttp_unload_engine();
211         dlclose(engine->handle);
212         
213         if (NULL != engine->engine_path)        free(engine->engine_path);
214         if (NULL != engine->pefuncs)            free(engine->pefuncs);
215         if (NULL != engine->pdfuncs)            free(engine->pdfuncs);
216
217         g_engine_list = g_slist_remove(g_engine_list, engine);
218
219         free(engine);
220         
221         return 0;
222 }
223
224
225 /* Initialize / Deinitialize */
226 int stt_engine_initialize(int engine_id, sttpe_result_cb result_cb, sttpe_silence_detected_cb silence_cb)
227 {
228         if (NULL == result_cb || NULL == silence_cb) {
229                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter"); 
230                 return STTP_ERROR_INVALID_PARAMETER;
231         }
232
233         sttengine_s* engine = NULL;
234         engine = __get_engine(engine_id);
235         if (NULL == engine) {
236                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is invalid", engine_id);
237                 return STTP_ERROR_INVALID_PARAMETER;
238         }
239
240         int ret;
241         ret = engine->pefuncs->initialize(result_cb, silence_cb);
242         if (0 != ret) {
243                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to initialize : %s", __stt_get_engine_error_code(ret));
244                 return STTP_ERROR_OPERATION_FAILED;
245         }
246
247         return 0;
248 }
249
250 int stt_engine_deinitialize(int engine_id)
251 {
252         sttengine_s* engine = NULL;
253         engine = __get_engine(engine_id);
254         if (NULL == engine) {
255                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is invalid", engine_id);
256                 return STTP_ERROR_INVALID_PARAMETER;
257         }
258
259         int ret;
260         ret = engine->pefuncs->deinitialize();
261         if (0 != ret) {
262                 SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] Fail to deinitialize : %s", __stt_get_engine_error_code(ret));
263         }
264
265         return 0;
266 }
267
268 static bool __supported_language_cb(const char* language, void* user_data)
269 {
270         GSList** lang_list = (GSList**)user_data;
271
272         if (NULL == language || NULL == lang_list) {
273                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Input parameter is NULL in callback!!!!");
274                 return false;
275         }
276
277         char* temp_lang = g_strdup(language);
278
279         *lang_list = g_slist_append(*lang_list, temp_lang);
280
281         return true;
282 }
283
284 /* Get option */
285 int stt_engine_get_supported_langs(int engine_id, GSList** lang_list)
286 {
287         if (NULL == lang_list) {
288                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter"); 
289                 return STTP_ERROR_INVALID_PARAMETER;
290         }
291
292         sttengine_s* engine = NULL;
293         engine = __get_engine(engine_id);
294         if (NULL == engine) {
295                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is invalid", engine_id);
296                 return STTP_ERROR_INVALID_PARAMETER;
297         }
298
299         int ret;
300         ret = engine->pefuncs->foreach_langs(__supported_language_cb, (void*)lang_list);
301         if (0 != ret) {
302                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] get language list error : %s", __stt_get_engine_error_code(ret));
303                 return STTP_ERROR_OPERATION_FAILED;
304         }
305
306         return 0;
307 }
308
309 int stt_engine_is_valid_language(int engine_id, const char* language, bool *is_valid)
310 {
311         if (NULL == language || NULL == is_valid) {
312                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter"); 
313                 return STTP_ERROR_INVALID_PARAMETER;
314         }
315
316         sttengine_s* engine = NULL;
317         engine = __get_engine(engine_id);
318         if (NULL == engine) {
319                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is invalid", engine_id);
320                 return STTP_ERROR_INVALID_PARAMETER;
321         }
322         
323         bool result;
324         result = engine->pefuncs->is_valid_lang(language);
325
326         *is_valid = result;
327
328         return 0;
329 }
330
331 int stt_engine_get_first_language(int engine_id, char** language)
332 {
333         if (NULL == language) {
334                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter"); 
335                 return STTP_ERROR_INVALID_PARAMETER;
336         }
337
338         sttengine_s* engine = NULL;
339         engine = __get_engine(engine_id);
340         if (NULL == engine) {
341                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is invalid", engine_id);
342                 return STTP_ERROR_INVALID_PARAMETER;
343         }
344
345         GSList* lang_list = NULL;
346         int ret;
347         ret = engine->pefuncs->foreach_langs(__supported_language_cb, &lang_list);
348         if (0 != ret) {
349                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] get language list error : %s", __stt_get_engine_error_code(ret));
350                 return STTP_ERROR_OPERATION_FAILED;
351         }
352
353         GSList *iter = NULL;
354         char* data = NULL;
355
356         iter = g_slist_nth(lang_list, 0);
357         if (NULL != iter) {
358                 data = iter->data;
359
360                 if (true == engine->pefuncs->is_valid_lang(data)) {
361                         *language = strdup(data);
362                 } else {
363                         ret = STTP_ERROR_OPERATION_FAILED;
364                 }
365         }
366
367         /* if list have item */
368         if (g_slist_length(lang_list) > 0) {
369                 /* Get a first item */
370                 iter = g_slist_nth(lang_list, 0);
371
372                 while (NULL != iter) {
373                         data = iter->data;
374
375                         if (NULL != data)
376                                 free(data);
377
378                         lang_list = g_slist_remove_link(lang_list, iter);
379
380                         iter = g_slist_nth(lang_list, 0);
381                 }
382         }
383
384         return ret;
385 }
386
387 int stt_engine_support_silence(int engine_id, bool* support)
388 {
389         if (NULL == support) {
390                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter"); 
391                 return STTP_ERROR_INVALID_PARAMETER;
392         }
393
394         sttengine_s* engine = NULL;
395         engine = __get_engine(engine_id);
396         if (NULL == engine) {
397                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is invalid", engine_id);
398                 return STTP_ERROR_INVALID_PARAMETER;
399         }
400
401         bool result;
402         result = engine->pefuncs->support_silence();
403         *support = result;
404
405         return 0;
406 }
407
408 int stt_engine_support_recognition_type(int engine_id, const char* type, bool* support)
409 {
410         if (NULL == type || NULL == support) {
411                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter"); 
412                 return STTP_ERROR_INVALID_PARAMETER;
413         }
414
415         sttengine_s* engine = NULL;
416         engine = __get_engine(engine_id);
417         if (NULL == engine) {
418                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is invalid", engine_id);
419                 return STTP_ERROR_INVALID_PARAMETER;
420         }
421
422         bool result;
423         if (NULL != engine->pefuncs->support_recognition_type) {
424                 result = engine->pefuncs->support_recognition_type(type);
425                 *support = result;
426                 return 0;
427         }
428
429         return STTP_ERROR_OPERATION_FAILED;
430 }
431
432 int stt_engine_get_audio_type(int engine_id, sttp_audio_type_e* types, int* rate, int* channels)
433 {
434         if (NULL == types || NULL == rate || NULL == channels) {
435                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter"); 
436                 return STTP_ERROR_INVALID_PARAMETER;
437         }
438
439         sttengine_s* engine = NULL;
440         engine = __get_engine(engine_id);
441         if (NULL == engine) {
442                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is invalid", engine_id);
443                 return STTP_ERROR_INVALID_PARAMETER;
444         }
445
446         int ret;
447         ret = engine->pefuncs->get_audio_format(types, rate, channels);
448         if (0 != ret) {
449                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to get audio format : %s", __stt_get_engine_error_code(ret));
450                 return STTP_ERROR_OPERATION_FAILED;
451         }
452
453         return 0;
454 }
455
456 /* Set option */
457 int stt_engine_set_silence_detection(int engine_id, bool value)
458 {
459         sttengine_s* engine = NULL;
460         engine = __get_engine(engine_id);
461         if (NULL == engine) {
462                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is invalid", engine_id);
463                 return STTP_ERROR_INVALID_PARAMETER;
464         }
465
466         int ret = engine->pefuncs->set_silence_detection(value);
467         if (STTP_ERROR_NOT_SUPPORTED_FEATURE == ret) {
468                 SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] Not support silence detection"); 
469                 return STTP_ERROR_NOT_SUPPORTED_FEATURE;
470         } else if (0 != ret) {
471                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to set silence detection : %d", ret); 
472                 return STTP_ERROR_OPERATION_FAILED;
473         }
474         
475         return 0;
476 }
477
478 int stt_engine_check_app_agreed(int engine_id, const char* appid, bool* value)
479 {
480         sttengine_s* engine = NULL;
481         engine = __get_engine(engine_id);
482         if (NULL == engine) {
483                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is invalid", engine_id);
484                 return STTP_ERROR_INVALID_PARAMETER;
485         }
486
487         if (NULL == engine->pefuncs->check_app_agreed) {
488                 SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] Not support app agreement. All app is available");
489                 *value = true;
490                 return 0;
491         }
492
493         int ret = engine->pefuncs->check_app_agreed(appid, value);
494         if (0 != ret) {
495                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to get app agreement : %s", __stt_get_engine_error_code(ret));
496                 *value = false;
497                 return STTP_ERROR_OPERATION_FAILED;
498         }
499         
500         return 0;
501 }
502
503 /* Recognition */
504 int stt_engine_recognize_start(int engine_id, const char* lang, const char* recognition_type, void* user_param)
505 {
506         if (NULL == lang || NULL == recognition_type) {
507                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter"); 
508                 return STTP_ERROR_INVALID_PARAMETER;
509         }
510
511         sttengine_s* engine = NULL;
512         engine = __get_engine(engine_id);
513         if (NULL == engine) {
514                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is invalid", engine_id);
515                 return STTP_ERROR_INVALID_PARAMETER;
516         }
517
518         int ret = engine->pefuncs->start(lang, recognition_type, user_param);
519         if (0 != ret) {
520                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to start recognition : %s", __stt_get_engine_error_code(ret));
521                 return STTP_ERROR_OPERATION_FAILED;
522         }
523
524         return 0;
525 }
526
527 int stt_engine_set_recording_data(int engine_id, const void* data, unsigned int length)
528 {
529         if (NULL == data) {
530                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter"); 
531                 return STTP_ERROR_INVALID_PARAMETER;
532         }
533
534         sttengine_s* engine = NULL;
535         engine = __get_engine(engine_id);
536         if (NULL == engine) {
537                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is invalid", engine_id);
538                 return STTP_ERROR_INVALID_PARAMETER;
539         }
540
541         int ret = engine->pefuncs->set_recording(data, length);
542         if (0 != ret) {
543                 SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] Fail to set recording : %s", __stt_get_engine_error_code(ret));
544                 return STTP_ERROR_OPERATION_FAILED;
545         }
546
547         return 0;
548 }
549
550 int stt_engine_recognize_stop(int engine_id)
551 {
552         sttengine_s* engine = NULL;
553         engine = __get_engine(engine_id);
554         if (NULL == engine) {
555                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is invalid", engine_id);
556                 return STTP_ERROR_INVALID_PARAMETER;
557         }
558
559         int ret = engine->pefuncs->stop();
560         if (0 != ret) {
561                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to stop : %s", __stt_get_engine_error_code(ret));
562                 return STTP_ERROR_OPERATION_FAILED;
563         }
564
565         return 0;
566 }
567
568 int stt_engine_recognize_cancel(int engine_id)
569 {
570         sttengine_s* engine = NULL;
571         engine = __get_engine(engine_id);
572         if (NULL == engine) {
573                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is invalid", engine_id);
574                 return STTP_ERROR_INVALID_PARAMETER;
575         }
576
577         int ret = engine->pefuncs->cancel();
578         if (0 != ret) {
579                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to cancel : %s", __stt_get_engine_error_code(ret));
580                 return STTP_ERROR_OPERATION_FAILED;
581         }
582
583         return 0;
584 }
585
586 int stt_engine_foreach_result_time(int engine_id, void* time_info, sttpe_result_time_cb callback, void* user_data)
587 {
588         sttengine_s* engine = NULL;
589         engine = __get_engine(engine_id);
590         if (NULL == engine) {
591                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is invalid", engine_id);
592                 return STTP_ERROR_INVALID_PARAMETER;
593         }
594
595         int ret = engine->pefuncs->foreach_result_time(time_info, callback, user_data);
596         if (0 != ret) {
597                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to foreach result time : %s", __stt_get_engine_error_code(ret));
598                 return STTP_ERROR_OPERATION_FAILED;
599         }
600         
601         return 0;
602 }
603
604 int stt_engine_recognize_start_file(int engine_id, const char* lang, const char* recognition_type, 
605                                      const char* filepath, sttp_audio_type_e audio_type, int sample_rate, void* user_param)
606 {
607         if (NULL == filepath || NULL == lang || NULL == recognition_type) {
608                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter"); 
609                 return STTP_ERROR_INVALID_PARAMETER;
610         }
611
612         sttengine_s* engine = NULL;
613         engine = __get_engine(engine_id);
614         if (NULL == engine) {
615                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is invalid", engine_id);
616                 return STTP_ERROR_INVALID_PARAMETER;
617         }
618
619         if (NULL == engine->pefuncs->start_file) {
620                 SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine API is invalid");
621                 return STTP_ERROR_NOT_SUPPORTED_FEATURE;
622         }
623
624         int ret = engine->pefuncs->start_file(lang, recognition_type, filepath, audio_type, sample_rate, user_param);
625         if (0 != ret) {
626                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to start file recognition : %s", __stt_get_engine_error_code(ret));
627                 return STTP_ERROR_OPERATION_FAILED;
628         }
629
630         return 0;
631 }
632
633 int stt_engine_recognize_cancel_file(int engine_id)
634 {
635         sttengine_s* engine = NULL;
636         engine = __get_engine(engine_id);
637         if (NULL == engine) {
638                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is invalid", engine_id);
639                 return STTP_ERROR_INVALID_PARAMETER;
640         }
641
642         if (NULL == engine->pefuncs->cancel_file) {
643                 SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine API is invalid");
644                 return STTP_ERROR_NOT_SUPPORTED_FEATURE;
645         }
646
647         int ret = engine->pefuncs->cancel_file();
648         if (0 != ret) {
649                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to start file recognition : %s", __stt_get_engine_error_code(ret));
650                 return STTP_ERROR_OPERATION_FAILED;
651         }
652
653         return 0;
654 }