Fix bugs
[platform/core/uifw/stt.git] / server / sttd_recorder.c
1 /*
2 *  Copyright (c) 2011-2016 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 #ifdef TV_PRODUCT
15 #define TV_BT_MODE
16 #endif
17
18 #include <audio_io.h>
19 #include <Ecore.h>
20 #include <math.h>
21 #include <pthread.h>
22 #include <sound_manager.h>
23 #ifdef TV_BT_MODE
24 #include <bluetooth.h>
25 #endif
26
27 #include "stt_defs.h"
28 #include "sttd_dbus.h"
29 #include "sttd_recorder.h"
30 #include "sttd_main.h"
31 #include "sttp.h"
32
33
34 #define FRAME_LENGTH 160
35 #define BUFFER_LENGTH FRAME_LENGTH * 2
36
37 static pthread_mutex_t sttd_audio_in_handle_mutex = PTHREAD_MUTEX_INITIALIZER;
38
39 typedef enum {
40         STTD_RECORDER_STATE_NONE = -1,
41         STTD_RECORDER_STATE_READY = 0,  /**< Recorder is ready to start */
42         STTD_RECORDER_STATE_RECORDING   /**< In the middle of recording */
43 } sttd_recorder_state;
44
45 typedef struct {
46         int                     engine_id;
47         int                     uid;
48         audio_in_h              audio_h;
49         sttp_audio_type_e       audio_type;
50 } stt_recorder_s;
51
52 static GSList *g_recorder_list;
53
54 static int g_recording_engine_id;
55
56 static stt_recorder_audio_cb    g_audio_cb;
57
58 static sound_stream_info_h      g_stream_info_h;
59
60 static stt_recorder_interrupt_cb        g_interrupt_cb;
61
62 static sttd_recorder_state      g_recorder_state = STTD_RECORDER_STATE_NONE;
63
64 static int g_buffer_count;
65
66 /* Sound buf save for test */
67 /*
68 #define BUF_SAVE_MODE
69 */
70 #ifdef BUF_SAVE_MODE
71 static char g_temp_file_name[128] = {'\0',};
72
73 static FILE* g_pFile;
74
75 static int g_count = 1;
76 #endif
77
78 #ifdef TV_BT_MODE
79 static float get_volume_decibel(char* data, int size, sttp_audio_type_e type);
80
81 static stt_recorder_s* __get_recorder(int engine_id);
82
83 static int g_bt_extend_count;
84
85 #define SMART_CONTROL_EXTEND_CMD        0x03
86 #define SMART_CONTROL_START_CMD         0x04
87
88 static void _bt_cb_hid_state_changed(int result, bool connected, const char *remote_address, void *user_data)
89 {
90         SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Bluetooth Event [%d] Received address [%s]", result, remote_address);
91 }
92
93 static void _bt_hid_audio_data_receive_cb(bt_hid_voice_data_s *voice_data, void *user_data)
94 {
95         if (STTD_RECORDER_STATE_RECORDING != g_recorder_state) {
96                 /* SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Exit audio reading normal func"); */
97                 return;
98         }
99
100         if (NULL != g_audio_cb) {
101                 if (0 != g_audio_cb((void*)voice_data->audio_buf, (unsigned int)voice_data->length)) {
102                         SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail to read audio");
103                         sttd_recorder_stop(g_recording_engine_id);
104                 }
105
106                 stt_recorder_s* recorder;
107                 recorder = __get_recorder(g_recording_engine_id);
108                 if (NULL == recorder) {
109                         return;
110                 }
111
112                 float vol_db = get_volume_decibel((char*)voice_data->audio_buf, (int)voice_data->length, recorder->audio_type);
113                 if (0 != sttdc_send_set_volume(recorder->uid, vol_db)) {
114                         SLOG(LOG_ERROR, TAG_STTD, "[Recorder] Fail to send recording volume(%f)", vol_db);
115                 }
116         }
117         
118         if (0 == g_buffer_count || 0 == g_buffer_count % 50) {
119                 SLOG(LOG_WARN, TAG_STTD, "[Recorder][%d] Recording... : read_size(%d)", g_buffer_count, voice_data->length);
120
121                 if (0 == g_bt_extend_count % 5 && 0 != g_buffer_count) {
122                         const unsigned char input_data[2] = {SMART_CONTROL_EXTEND_CMD, 0x10 };
123                         if (BT_ERROR_NONE != bt_hid_send_rc_command(NULL, input_data, sizeof(input_data))) {
124                                 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail bt_hid_send_rc_command(NULL, %s, %d)", input_data, sizeof(input_data));
125                         } else {
126                                 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Extend bt audio recorder");
127                         }
128                 }
129                 g_bt_extend_count++;
130                 
131                 if (100000 == g_buffer_count) {
132                         g_buffer_count = 0;
133                 }
134         }
135
136         g_buffer_count++;
137
138 #ifdef BUF_SAVE_MODE
139         /* write pcm buffer */
140         fwrite(data, 1, len, g_pFile);
141 #endif
142         return;
143 }
144 #endif
145
146
147 const char* __stt_get_focus_changed_reason_code(sound_stream_focus_change_reason_e reason)
148 {
149         switch (reason) {
150         case SOUND_STREAM_FOCUS_CHANGED_BY_MEDIA:                       return "SOUND_STREAM_FOCUS_CHANGED_BY_MEDIA";
151         case SOUND_STREAM_FOCUS_CHANGED_BY_SYSTEM:                      return "SOUND_STREAM_FOCUS_CHANGED_BY_SYSTEM";
152         case SOUND_STREAM_FOCUS_CHANGED_BY_ALARM:                       return "SOUND_STREAM_FOCUS_CHANGED_BY_ALARM";
153         case SOUND_STREAM_FOCUS_CHANGED_BY_NOTIFICATION:        return "SOUND_STREAM_FOCUS_CHANGED_BY_NOTIFICATION";
154         case SOUND_STREAM_FOCUS_CHANGED_BY_EMERGENCY:           return "SOUND_STREAM_FOCUS_CHANGED_BY_EMERGENCY";
155         case SOUND_STREAM_FOCUS_CHANGED_BY_VOICE_INFORMATION:   return "SOUND_STREAM_FOCUS_CHANGED_BY_VOICE_INFORMATION";
156         case SOUND_STREAM_FOCUS_CHANGED_BY_VOICE_RECOGNITION:   return "SOUND_STREAM_FOCUS_CHANGED_BY_VOICE_RECOGNITION";
157         case SOUND_STREAM_FOCUS_CHANGED_BY_RINGTONE:            return "SOUND_STREAM_FOCUS_CHANGED_BY_RINGTONE";
158         case SOUND_STREAM_FOCUS_CHANGED_BY_VOIP:                        return "SOUND_STREAM_FOCUS_CHANGED_BY_VOIP";
159         case SOUND_STREAM_FOCUS_CHANGED_BY_CALL:                        return "SOUND_STREAM_FOCUS_CHANGED_BY_CALL";
160         case SOUND_STREAM_FOCUS_CHANGED_BY_MEDIA_EXTERNAL_ONLY: return "SOUND_STREAM_FOCUS_CHANGED_BY_MEDIA_EXTERNAL_ONLY";
161         default:                                                                                        return "Undefined reason code";
162         }
163 }
164
165 void __recorder_focus_state_cb(sound_stream_info_h stream_info, sound_stream_focus_change_reason_e reason, const char *extra_info, void *user_data)
166 {
167         SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Focus state changed cb");
168
169         if (stream_info != g_stream_info_h) {
170                 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Invalid stream info handle");
171                 return;
172         }
173
174         int ret;
175         sound_stream_focus_state_e state_for_recording;
176         ret = sound_manager_get_focus_state(g_stream_info_h, NULL, &state_for_recording);
177         if (SOUND_MANAGER_ERROR_NONE != ret) {
178                 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail to get focus state");
179                 return;
180         }
181
182         SLOG(LOG_WARN, TAG_STTD, "[Recorder] focus state changed to (%d) with reason(%s)", (int)state_for_recording, __stt_get_focus_changed_reason_code(reason));
183         
184         if (STTD_RECORDER_STATE_RECORDING == g_recorder_state && SOUND_STREAM_FOCUS_STATE_RELEASED == state_for_recording) {
185                 SLOG(LOG_WARN, TAG_STTD, "[Recorder] Focus released as interrupt");
186                 if (NULL != g_interrupt_cb) {
187                         g_interrupt_cb();
188                 }
189         }
190 }
191
192
193 int sttd_recorder_initialize(stt_recorder_audio_cb audio_cb, stt_recorder_interrupt_cb interrupt_cb)
194 {
195         if (NULL == audio_cb || NULL == interrupt_cb) {
196                 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Input param is NOT valid");
197                 return STTD_ERROR_INVALID_PARAMETER;
198         }
199
200         if (STTD_RECORDER_STATE_NONE != g_recorder_state) {
201                 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Current state of recorder is recording");
202                 return STTD_ERROR_INVALID_STATE;
203         }
204
205         if (0 != pthread_mutex_init(&sttd_audio_in_handle_mutex, NULL)) {
206                 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail to initialize audio in handle mutex.");
207         }
208
209         g_audio_cb = audio_cb;
210         g_interrupt_cb = interrupt_cb;
211         g_recorder_state = STTD_RECORDER_STATE_NONE;
212         g_recording_engine_id = -1;
213
214         if (0 != sound_manager_create_stream_information(SOUND_STREAM_TYPE_VOICE_RECOGNITION, __recorder_focus_state_cb, NULL, &g_stream_info_h)) {
215                 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail to create stream info");
216         }
217
218 #ifdef TV_BT_MODE
219         if (BT_ERROR_NONE != bt_initialize()) {
220                 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail to init bt");
221                 return STTD_ERROR_OPERATION_FAILED;
222         }
223
224         if (BT_ERROR_NONE != bt_hid_host_initialize(_bt_cb_hid_state_changed, NULL)) {
225                 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail bt_hid_host_initialize()");
226                 return STTD_ERROR_OPERATION_FAILED;
227         }
228 #endif
229
230         return 0;
231 }
232
233 int sttd_recorder_deinitialize()
234 {
235         if (0 != pthread_mutex_destroy(&sttd_audio_in_handle_mutex)) {
236                 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to destroy audio in handle mutex.");
237         }
238
239         if (0 != sound_manager_destroy_stream_information(g_stream_info_h)) {
240                 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail to destroy stream info");
241         }
242
243         /* Remove all recorder */
244         GSList *iter = NULL;
245         stt_recorder_s *recorder = NULL;
246
247         iter = g_slist_nth(g_recorder_list, 0);
248
249         while (NULL != iter) {
250                 recorder = iter->data;
251
252                 if (NULL != recorder) {
253                         g_recorder_list = g_slist_remove(g_recorder_list, recorder);
254                         if(recorder->audio_h) {
255                                 audio_in_destroy(recorder->audio_h);
256                                 recorder->audio_h = NULL;
257                         }
258                         free(recorder);
259                 }
260
261                 iter = g_slist_nth(g_recorder_list, 0);
262         }
263
264 #ifdef TV_BT_MODE
265         bt_hid_host_deinitialize ();
266
267         bt_deinitialize();
268 #endif
269
270         g_recorder_state = STTD_RECORDER_STATE_NONE;
271
272         return 0;
273 }
274
275 static stt_recorder_s* __get_recorder(int engine_id)
276 {
277         GSList *iter = NULL;
278         stt_recorder_s *recorder = NULL;
279
280         iter = g_slist_nth(g_recorder_list, 0);
281
282         while (NULL != iter) {
283                 recorder = iter->data;
284
285                 if (recorder->engine_id == engine_id) {
286                         return recorder;
287                 }
288
289                 iter = g_slist_next(iter);
290         }
291
292         return NULL;
293 }
294
295 int sttd_recorder_set_audio_session()
296 {
297         return 0;
298 }
299
300 int sttd_recorder_unset_audio_session()
301 {
302         return 0;
303 }
304
305 int sttd_recorder_create(int engine_id, int uid, sttp_audio_type_e type, int channel, unsigned int sample_rate)
306 {
307         /* Check engine id is valid */
308         if (NULL != __get_recorder(engine_id)) {
309                 SLOG(LOG_WARN, TAG_STTD, "[Recorder WARNING] Engine id is already registered");
310                 return STTD_ERROR_INVALID_PARAMETER;
311         }
312
313         audio_in_h temp_in_h = NULL;
314
315 #ifndef TV_BT_MODE
316         audio_channel_e audio_ch;
317         audio_sample_type_e audio_type;
318
319         switch (channel) {
320         case 1: audio_ch = AUDIO_CHANNEL_MONO;          break;
321         case 2: audio_ch = AUDIO_CHANNEL_STEREO;        break;
322         default:
323                 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Input channel is not supported");
324                 return STTD_ERROR_OPERATION_FAILED;
325                 break;
326         }
327
328         switch (type) {
329         case STTP_AUDIO_TYPE_PCM_S16_LE:        audio_type = AUDIO_SAMPLE_TYPE_S16_LE;  break;
330         case STTP_AUDIO_TYPE_PCM_U8:            audio_type = AUDIO_SAMPLE_TYPE_U8;      break;
331         default:
332                 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Invalid Audio Type");
333                 return STTD_ERROR_OPERATION_FAILED;
334                 break;
335         }
336
337         int ret;
338         ret = audio_in_create(sample_rate, audio_ch, audio_type, &temp_in_h);
339         if (AUDIO_IO_ERROR_NONE != ret) {
340                 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail to create audio handle : %d", ret);
341                 return STTD_ERROR_OPERATION_FAILED;
342         }
343 #else
344         if (BT_ERROR_NONE != bt_hid_set_audio_data_receive_cb(_bt_hid_audio_data_receive_cb, NULL)) {
345                 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail bt_hid_set_audio_data_receive_cb()");
346                 return STTD_ERROR_OPERATION_FAILED;
347         }
348 #endif
349
350         stt_recorder_s* recorder;
351         recorder = (stt_recorder_s*)calloc(1, sizeof(stt_recorder_s));
352         if (NULL == recorder) {
353 #ifndef TV_BT_MODE
354                 if (temp_in_h) {
355                         audio_in_destroy(temp_in_h);
356                         temp_in_h = NULL;
357                 }
358 #endif
359                 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail to allocate memory");
360                 return STTD_ERROR_OUT_OF_MEMORY;
361         }
362
363         recorder->engine_id = engine_id;
364         recorder->uid = uid;
365         recorder->audio_h = temp_in_h;
366         recorder->audio_type = type;
367
368         g_recorder_list = g_slist_append(g_recorder_list, recorder);
369
370         g_recorder_state = STTD_RECORDER_STATE_READY;
371
372         return 0;
373 }
374
375 int sttd_recorder_destroy(int engine_id)
376 {
377         // critical section required because this function can be called from stt engine thread context
378         SLOG(LOG_WARN, TAG_STTD, "[Recorder WARNING] Enter critical section");
379         pthread_mutex_lock(&sttd_audio_in_handle_mutex);
380
381         /* Check engine id is valid */
382         stt_recorder_s* recorder;
383         recorder = __get_recorder(engine_id);
384         if (NULL == recorder) {
385                 SLOG(LOG_WARN, TAG_STTD, "[Recorder WARNING] Engine id is not valid");
386                 pthread_mutex_unlock(&sttd_audio_in_handle_mutex);
387                 return STTD_ERROR_INVALID_PARAMETER;
388         }
389
390 #ifndef TV_BT_MODE
391         int ret;
392         if (STTD_RECORDER_STATE_RECORDING == g_recorder_state) {
393                 if (recorder->audio_h) {
394                         ret = audio_in_unprepare(recorder->audio_h);
395                         if (AUDIO_IO_ERROR_NONE != ret) {
396                                 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail to unprepare audioin : %d", ret);
397                         }
398                 }
399
400                 g_recorder_state = STTD_RECORDER_STATE_READY;
401         }
402
403         if (recorder->audio_h) {
404                 ret = audio_in_destroy(recorder->audio_h);
405                 if (AUDIO_IO_ERROR_NONE != ret) {
406                         SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail to destroy audioin : %d", ret);
407                 }
408                 recorder->audio_h = NULL;
409         }
410 #else 
411         if (STTD_RECORDER_STATE_RECORDING == g_recorder_state) {
412                 g_recorder_state = STTD_RECORDER_STATE_READY;
413         }
414
415         bt_hid_unset_audio_data_receive_cb();
416 #endif
417
418         g_recorder_list = g_slist_remove(g_recorder_list, recorder);
419
420         free(recorder);
421
422         pthread_mutex_unlock(&sttd_audio_in_handle_mutex);
423         SLOG(LOG_WARN, TAG_STTD, "[Recorder WARNING] Leave critical section");
424
425         return 0;
426 }
427
428 static float get_volume_decibel(char* data, int size, sttp_audio_type_e type)
429 {
430         #define MAX_AMPLITUDE_MEAN_16   32768
431         #define MAX_AMPLITUDE_MEAN_08   128
432
433         int i, depthByte;
434         int count = 0;
435
436         float db = 0.0;
437         float rms = 0.0;
438         unsigned long long square_sum = 0;
439
440         if (type == STTP_AUDIO_TYPE_PCM_S16_LE)
441                 depthByte = 2;
442         else
443                 depthByte = 1;
444
445         for (i = 0; i < size; i += (depthByte<<1)) {
446                 if (depthByte == 2) {
447                         short pcm16 = 0;
448                         memcpy(&pcm16, data + i, sizeof(short));
449                         square_sum += pcm16 * pcm16;
450                 } else {
451                         char pcm8 = 0;
452                         memcpy(&pcm8, data + i, sizeof(char));
453                         square_sum += pcm8 * pcm8;
454                 }
455                 count++;
456         }
457
458         if (0 == count)
459                 rms = 0.0;
460         else
461                 rms = sqrt(square_sum/count);
462
463         if (depthByte == 2)
464                 db = 20 * log10(rms/MAX_AMPLITUDE_MEAN_16);
465         else
466                 db = 20 * log10(rms/MAX_AMPLITUDE_MEAN_08);
467
468         return db;
469 }
470
471 #ifndef TV_BT_MODE
472 Eina_Bool __read_audio_func(void *data)
473 {
474         int read_byte = -1;
475         static char g_buffer[BUFFER_LENGTH];
476
477         /* Check engine id is valid */
478         stt_recorder_s* recorder;
479         recorder = __get_recorder(g_recording_engine_id);
480         if (NULL == recorder) {
481                 return EINA_FALSE;
482         }
483
484         if (STTD_RECORDER_STATE_READY == g_recorder_state) {
485                 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Exit audio reading func");
486                 return EINA_FALSE;
487         }
488
489         read_byte = audio_in_read(recorder->audio_h, g_buffer, BUFFER_LENGTH);
490         if (0 > read_byte) {
491                 SLOG(LOG_WARN, TAG_STTD, "[Recorder WARNING] Fail to read audio : %d", read_byte);
492                 g_recorder_state = STTD_RECORDER_STATE_READY;
493                 return EINA_FALSE;
494         }
495
496         if (0 != g_audio_cb(g_buffer, read_byte)) {
497                 SLOG(LOG_WARN, TAG_STTD, "[Recorder WARNING] Fail audio callback");
498                 sttd_recorder_stop(g_recording_engine_id);
499                 return EINA_FALSE;
500         }
501
502         if (0 == g_buffer_count % 30) {
503                 float vol_db = get_volume_decibel(g_buffer, BUFFER_LENGTH, recorder->audio_type);
504                 if (0 != sttdc_send_set_volume(recorder->uid, vol_db)) {
505                         SLOG(LOG_ERROR, TAG_STTD, "[Recorder] Fail to send recording volume(%f)", vol_db);
506                 }
507         }
508
509         /* Audio read log */
510         if (0 == g_buffer_count % 50) {
511                 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder][%d] Recording... : read_size(%d)", g_buffer_count, read_byte);
512
513                 if (100000 == g_buffer_count) {
514                         g_buffer_count = 0;
515                 }
516         }
517
518         g_buffer_count++;
519
520 #ifdef BUF_SAVE_MODE
521         /* write pcm buffer */
522         fwrite(g_buffer, 1, BUFFER_LENGTH, g_pFile);
523 #endif
524
525         return EINA_TRUE;
526 }
527 #endif
528
529 int sttd_recorder_start(int engine_id)
530 {
531         if (STTD_RECORDER_STATE_RECORDING == g_recorder_state)
532                 return 0;
533
534         int ret = -1;
535 #ifndef TV_BT_MODE
536         /* Check engine id is valid */
537         stt_recorder_s* recorder;
538         recorder = __get_recorder(engine_id);
539         if (NULL == recorder) {
540                 SLOG(LOG_WARN, TAG_STTD, "[Recorder WARNING] Engine id is not valid");
541                 return STTD_ERROR_INVALID_PARAMETER;
542         }
543
544         ret = sound_manager_acquire_focus(g_stream_info_h, SOUND_STREAM_FOCUS_FOR_RECORDING, NULL);
545         if (SOUND_MANAGER_ERROR_NONE != ret) {
546                 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail to acquire focus : %d", ret);
547         } else {
548                 ret = audio_in_set_stream_info(recorder->audio_h, g_stream_info_h);
549                 if (AUDIO_IO_ERROR_NONE != ret) {
550                         SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail to set stream info");
551                 }
552         }
553         
554         ret = audio_in_prepare(recorder->audio_h);
555         if (AUDIO_IO_ERROR_NONE != ret) {
556                 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail to start audio : %d", ret);
557                 return STTD_ERROR_RECORDER_BUSY;
558         }
559
560         /* Add ecore timer to read audio data */
561         ecore_timer_add(0, __read_audio_func, NULL);
562
563 #else
564         g_bt_extend_count = 0;
565         const unsigned char input_data[2] = {SMART_CONTROL_START_CMD, 0x00 };
566         int bt_retry = 0;
567         bool started = false;
568         while (5 > bt_retry) {
569                 ret = bt_hid_send_rc_command(NULL, input_data, sizeof(input_data));
570                 if (BT_ERROR_NONE == ret) {
571                         SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Start bt audio recorder");
572                         started = true;
573                         break;
574                 } else if (BT_ERROR_NOW_IN_PROGRESS == ret) {
575                         SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail bt_hid_send_rc_command(NULL, %s, %d)", input_data, sizeof(input_data));
576                         usleep(50000);
577                         bt_retry++;
578                 } else {
579                         break;
580                 }
581         }
582         if (false == started) {
583                 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail to start bt audio");
584                 return STTD_ERROR_OPERATION_FAILED;
585         }
586 #endif
587         g_recorder_state = STTD_RECORDER_STATE_RECORDING;
588         g_recording_engine_id = engine_id;
589
590         g_buffer_count = 0;
591
592 #ifdef BUF_SAVE_MODE
593         g_count++;
594
595         snprintf(g_temp_file_name, sizeof(g_temp_file_name), "/tmp/stt_temp_%d_%d", getpid(), g_count);
596         SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Temp file name=[%s]", g_temp_file_name);
597
598         /* open test file */
599         g_pFile = fopen(g_temp_file_name, "wb+");
600         if (!g_pFile) {
601                 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] File not found!");
602                 return -1;
603         }
604 #endif
605
606         return 0;
607 }
608
609 int sttd_recorder_stop(int engine_id)
610 {
611         if (STTD_RECORDER_STATE_READY == g_recorder_state)
612                 return 0;
613
614         /* Check engine id is valid */
615         stt_recorder_s* recorder;
616         recorder = __get_recorder(engine_id);
617         if (NULL == recorder) {
618                 SLOG(LOG_WARN, TAG_STTD, "[Recorder WARNING] Engine id is not valid");
619                 return STTD_ERROR_INVALID_PARAMETER;
620         }
621
622         int ret;
623 #ifndef TV_BT_MODE
624         ret = audio_in_unprepare(recorder->audio_h);
625         if (AUDIO_IO_ERROR_NONE != ret) {
626                 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail to unprepare audioin : %d", ret);
627         }
628 #else 
629         int bt_retry = 0;
630         bool stopped = false;
631         while (5 > bt_retry) {
632                 ret = bt_hid_rc_stop_sending_voice(NULL);
633                 if (BT_ERROR_NONE == ret) {
634                         SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Stop bt audio");
635                         stopped = true;
636                         break;
637                 } else if (BT_ERROR_NOW_IN_PROGRESS == ret) {
638                         SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail bt_hid_rc_stop_sending_voice()");
639                         usleep(50000);
640                         bt_retry++;
641                 } else {
642                         break;
643                 }
644         }
645         if (false == stopped) {
646                 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail to stop bt audio");
647                 return STTD_ERROR_OPERATION_FAILED;
648         }
649 #endif
650
651         g_recorder_state = STTD_RECORDER_STATE_READY;
652         g_recording_engine_id = -1;
653
654         ret = sound_manager_release_focus(g_stream_info_h, SOUND_STREAM_FOCUS_FOR_RECORDING, NULL);
655         if (SOUND_MANAGER_ERROR_NONE != ret) {
656                 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail to release focus :%d", ret);
657         }
658
659 #ifdef BUF_SAVE_MODE
660         fclose(g_pFile);
661 #endif
662
663         return 0;
664 }