e2bee43066c3f7e3a84dec022e4164f7bd06230c
[platform/core/uifw/voice-control.git] / server / vcd_recorder.c
1 /*
2  * Copyright (c) 2011-2017 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #ifdef TV_PRODUCT
18 #define TV_BT_MODE
19 #define TV_MSF_WIFI_MODE
20 #endif
21
22 #include <audio_io.h>
23 #include <math.h>
24 #include <sound_manager.h>
25 #include <sound_manager_internal.h>
26 #ifdef TV_PRODUCT
27 #ifdef TV_BT_MODE
28 #include <bluetooth_product.h>
29 #endif
30 #ifdef TV_MSF_WIFI_MODE
31 #include <MSFVoiceInterface.h>
32 #endif
33 #endif
34
35 #include "vcd_client_data.h"
36 #include "vcd_config.h"
37 #include "vcd_dbus.h"
38 #include "vcd_engine_agent.h"
39 #include "vcd_recorder.h"
40 #include "vcd_main.h"
41 #include "voice_control_plugin_engine.h"
42
43 #define FRAME_LENGTH 160
44 #define BUFFER_LENGTH FRAME_LENGTH * 2
45
46 #define FOCUS_SERVER_READY              "/tmp/.focus_server_ready"
47
48 #define VCP_AUDIO_ID_NONE               "VC_AUDIO_ID_NONE"              /**< None audio id */
49
50 static vcd_recorder_state_e     g_recorder_state = VCD_RECORDER_STATE_READY;
51
52 static vcd_recoder_audio_cb     g_audio_cb = NULL;
53
54 static vcd_recorder_interrupt_cb        g_interrupt_cb = NULL;
55
56 static audio_in_h       g_audio_h;
57
58 static sound_stream_info_h      g_stream_info_h;
59
60 static vcp_audio_type_e g_audio_type;
61
62 static int      g_audio_rate;
63
64 static int              g_audio_channel;
65
66 static char     g_normal_buffer[BUFFER_LENGTH + 10];
67
68 static bool     g_is_valid_audio_in = false;
69
70 static bool     g_is_valid_bt_in = false;
71
72 static char*    g_current_audio_type = NULL;
73
74 static int      g_buffer_count;
75
76 static int      g_device_id = -1;
77
78 /* Sound buf save */
79 /*
80 #define BUF_SAVE_MODE
81  */
82
83 #ifdef BUF_SAVE_MODE
84 static FILE* g_normal_file;
85
86 static int g_count = 1;
87 #endif
88
89 static float get_volume_decibel(char* data, int size);
90
91 #ifdef TV_MSF_WIFI_MODE
92 static void __msf_wifi_audio_data_receive_cb(msf_wifi_voice_data_s *voice_data, void* user_data)
93 {
94         if (0 != strncmp(g_current_audio_type, VCP_AUDIO_ID_MSF, sizeof(VCP_AUDIO_ID_MSF))) {
95                 vcd_state_e state = vcd_config_get_service_state();
96                 if (VCD_STATE_READY == state) {
97                         vcd_recorder_set(VCP_AUDIO_ID_MSF, VCP_AUDIO_TYPE_PCM_S16_LE, 16000, 1);
98                 } else {
99                         SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] current audio type is (%s)", g_current_audio_type);
100                         return;
101                 }
102         }
103
104         if (VCD_RECORDER_STATE_RECORDING != g_recorder_state) {
105                 SLOG(LOG_WARN, TAG_VCD, "[Recorder] Not start yet, but send audio data vi MSF");
106                 vcd_recorder_start();
107         }
108
109         if (NULL != g_audio_cb) {
110                 if (0 != g_audio_cb((void*)voice_data->audio_buf, (unsigned int)voice_data->length)) {
111                         SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to read audio");
112                         vcd_recorder_stop();
113                 }
114         }
115
116         /* Set volume */
117         if (0 == g_buffer_count % 30) {
118                 float vol_db = get_volume_decibel((char*)voice_data->audio_buf, (unsigned int)voice_data->length);
119                 if (0 != vcdc_send_set_volume(vcd_client_manager_get_pid(), vol_db)) {
120                         SLOG(LOG_ERROR, TAG_VCD, "[Recorder] Fail to send recording volume(%f)", vol_db);
121                 }
122         }
123
124         if (0 == g_buffer_count || 0 == g_buffer_count % 50) {
125                 SLOG(LOG_WARN, TAG_VCD, "[Recorder][%d] Recording... : read_size(%ld)", g_buffer_count, voice_data->length);
126
127                 if (100000 == g_buffer_count)
128                         g_buffer_count = 0;
129         }
130
131         g_buffer_count++;
132
133 #ifdef BUF_SAVE_MODE
134         /* write pcm buffer */
135         fwrite(voice_data->audio_buf, 1, voice_data->length, g_normal_file);
136 #endif
137         return;
138 }
139
140 #endif
141
142
143 #ifdef TV_BT_MODE
144 static int g_bt_extend_count;
145
146 #define SMART_CONTROL_EXTEND_CMD        0x03
147 #define SMART_CONTROL_START_CMD         0x04
148
149 static void _bt_cb_hid_state_changed(int result, bool connected, const char *remote_address, void *user_data)
150 {
151         SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Bluetooth Event [%d] Received address [%s]", result, remote_address);
152         return;
153 }
154
155 static void _bt_hid_audio_data_receive_cb(bt_hid_voice_data_s *voice_data, void *user_data)
156 {
157         if (0 != strncmp(g_current_audio_type, VCP_AUDIO_ID_BLUETOOTH, sizeof(VCP_AUDIO_ID_BLUETOOTH))) {
158                 vcd_state_e state = vcd_config_get_service_state();
159                 if (VCD_STATE_READY == state) {
160                         vcd_recorder_set(VCP_AUDIO_ID_BLUETOOTH, VCP_AUDIO_TYPE_PCM_S16_LE, 16000, 1);
161                 } else {
162                         SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] current audio type is (%s)", g_current_audio_type);
163                         return;
164                 }
165         }
166
167         if (VCD_RECORDER_STATE_RECORDING != g_recorder_state) {
168                 SLOG(LOG_WARN, TAG_VCD, "[Recorder] Not start yet, but send audio data vi Bluetooth");
169                 //              vcd_recorder_start();
170         }
171
172         if (NULL != g_audio_cb) {
173                 if (0 != g_audio_cb((void*)voice_data->audio_buf, (unsigned int)voice_data->length)) {
174                         SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to read audio");
175                         vcd_recorder_stop();
176                 }
177         }
178
179         /* Set volume */
180         if (0 == g_buffer_count % 15) {
181                 float vol_db = get_volume_decibel((char*)voice_data->audio_buf, (unsigned int)voice_data->length);
182                 if (0 != vcdc_send_set_volume(vcd_client_manager_get_pid(), vol_db)) {
183                         SLOG(LOG_ERROR, TAG_VCD, "[Recorder] Fail to send recording volume(%f)", vol_db);
184                 }
185         }
186
187         if (0 == g_buffer_count || 0 == g_buffer_count % 50) {
188                 SLOG(LOG_WARN, TAG_VCD, "[Recorder][%d] Recording... : read_size(%d)", g_buffer_count, voice_data->length);
189
190                 if (0 == g_bt_extend_count % 5 && 0 != g_buffer_count) {
191                         const unsigned char input_data[2] = {SMART_CONTROL_EXTEND_CMD, 0x10 };
192                         if (BT_ERROR_NONE != bt_hid_send_rc_command(NULL, input_data, sizeof(input_data))) {
193                                 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail bt_hid_send_rc_command");
194                         } else {
195                                 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Extend bt audio recorder");
196                         }
197                 }
198                 g_bt_extend_count++;
199
200                 if (100000 == g_buffer_count) {
201                         g_buffer_count = 0;
202                 }
203         }
204
205         g_buffer_count++;
206
207 #ifdef BUF_SAVE_MODE
208         /* write pcm buffer */
209         fwrite(voice_data->audio_buf, 1, voice_data->length, g_normal_file);
210 #endif
211         return;
212 }
213
214 #endif
215
216 #if 1
217 static const char* __get_focus_changed_reason_code(sound_stream_focus_change_reason_e reason)
218 {
219         switch (reason) {
220         case SOUND_STREAM_FOCUS_CHANGED_BY_MEDIA:               return "SOUND_STREAM_FOCUS_CHANGED_BY_MEDIA";
221         case SOUND_STREAM_FOCUS_CHANGED_BY_SYSTEM:              return "SOUND_STREAM_FOCUS_CHANGED_BY_SYSTEM";
222         case SOUND_STREAM_FOCUS_CHANGED_BY_ALARM:               return "SOUND_STREAM_FOCUS_CHANGED_BY_ALARM";
223         case SOUND_STREAM_FOCUS_CHANGED_BY_NOTIFICATION:        return "SOUND_STREAM_FOCUS_CHANGED_BY_NOTIFICATION";
224         case SOUND_STREAM_FOCUS_CHANGED_BY_EMERGENCY:           return "SOUND_STREAM_FOCUS_CHANGED_BY_EMERGENCY";
225         case SOUND_STREAM_FOCUS_CHANGED_BY_VOICE_INFORMATION:   return "SOUND_STREAM_FOCUS_CHANGED_BY_VOICE_INFORMATION";
226         case SOUND_STREAM_FOCUS_CHANGED_BY_VOICE_RECOGNITION:   return "SOUND_STREAM_FOCUS_CHANGED_BY_VOICE_RECOGNITION";
227         case SOUND_STREAM_FOCUS_CHANGED_BY_RINGTONE:            return "SOUND_STREAM_FOCUS_CHANGED_BY_RINGTONE";
228         case SOUND_STREAM_FOCUS_CHANGED_BY_VOIP:                return "SOUND_STREAM_FOCUS_CHANGED_BY_VOIP";
229         case SOUND_STREAM_FOCUS_CHANGED_BY_CALL:                return "SOUND_STREAM_FOCUS_CHANGED_BY_CALL";
230         case SOUND_STREAM_FOCUS_CHANGED_BY_MEDIA_EXTERNAL_ONLY: return "SOUND_STREAM_FOCUS_CHANGED_BY_MEDIA_EXTERNAL_ONLY";
231         default:                                                return "Undefined reason code";
232         }
233 }
234
235 static void __recorder_focus_state_cb(sound_stream_info_h stream_info, sound_stream_focus_mask_e focus_mask, sound_stream_focus_state_e focus_state,
236                 sound_stream_focus_change_reason_e reason, int sound_behavior, const char *extra_info, void *user_data)
237 {
238         SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Focus state changed cb");
239
240         if (stream_info != g_stream_info_h) {
241                 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Invalid stream info handle");
242                 return;
243         }
244
245         SLOG(LOG_WARN, TAG_VCD, "[Recorder] focus state chagned to (%d) with reason (%s)", (int)focus_state, __get_focus_changed_reason_code(reason));
246
247         if (VCD_RECORDER_STATE_RECORDING == g_recorder_state && SOUND_STREAM_FOCUS_STATE_RELEASED == focus_state) {
248                 SLOG(LOG_WARN, TAG_VCD, "[Recorder] Focus released as interrupt");
249                 if (NULL != g_interrupt_cb) {
250                         g_interrupt_cb();
251                 }
252         }
253 }
254 #endif
255
256 static int __apply_device_for_stream_routing()
257 {
258         sound_device_list_h device_list = NULL;
259         sound_device_h device = NULL;
260         sound_device_type_e type;
261         sound_device_io_direction_e io_direction;
262
263         if (0 != sound_manager_get_device_list(SOUND_DEVICE_IO_DIRECTION_IN_MASK, &device_list)) {
264                 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to get current device list");
265                 return -1;
266         }
267
268         int ret = -1;
269         while (0 == sound_manager_get_next_device(device_list, &device)) {
270                 if (0 != sound_manager_get_device_type(device, &type)) {
271                         SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to get device tyep");
272                         continue;
273                 }
274                 if (0 != sound_manager_get_device_io_direction(device, &io_direction)) {
275                         SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to get device io direction");
276                         continue;
277                 }
278                 if (SOUND_DEVICE_USB_AUDIO == type && SOUND_DEVICE_IO_DIRECTION_IN == io_direction) {
279                         if (0 != sound_manager_add_device_for_stream_routing(g_stream_info_h, device)) {
280                                 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to add device");
281                                 continue;
282                         }
283                         if (0 != sound_manager_apply_stream_routing(g_stream_info_h)) {
284                                 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to apply stream routing");
285                                 continue;
286                         }
287                         ret = 0;
288                         break;
289                 }
290         }
291
292         sound_manager_free_device_list(device_list);
293         device_list = NULL;
294
295         if (0 != ret) {
296                 SLOG(LOG_WARN, TAG_VCD, "[Recorder] No device");
297         } else {
298                 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Apply device for stream routing");
299         }
300         return ret;
301 }
302
303 static void __device_connection_changed_cb(sound_device_h device, bool is_connected, void *user_data)
304 {
305         sound_device_type_e type;
306         if (is_connected) {
307                 if (0 != sound_manager_get_device_type(device, &type)) {
308                         SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to get device tyep");
309                         return;
310                 }
311                 if (type == SOUND_DEVICE_USB_AUDIO) {
312                         bool is_recording_state = false;
313                         if (VCD_RECORDER_STATE_RECORDING == g_recorder_state) {
314                                 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Stop recorder");
315                                 vcd_recorder_stop();
316                                 is_recording_state = true;
317                         }
318                         if (0 != sound_manager_remove_device_for_stream_routing(g_stream_info_h, device))
319                                 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to remove device");
320
321                         if (0 != sound_manager_add_device_for_stream_routing(g_stream_info_h, device)) {
322                                 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to add device");
323                                 return;
324                         }
325                         if (0 != sound_manager_apply_stream_routing(g_stream_info_h)) {
326                                 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR} Fail to apply stream routing");
327                                 return;
328                         }
329                         if (true == is_recording_state) {
330                                 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Start recorder");
331                                 vcd_recorder_start();
332                         }
333                         SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Apply device for stream routing");
334                 }
335         }
336         return;
337 }
338
339 int vcd_recorder_create(vcd_recoder_audio_cb audio_cb, vcd_recorder_interrupt_cb interrupt_cb)
340 {
341         if (NULL == audio_cb || NULL == interrupt_cb) {
342                 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Input param is NOT valid");
343                 return VCD_ERROR_INVALID_PARAMETER;
344         }
345
346         /* check focus server */
347         int cnt = 0;
348         while (1) {
349                 if (0 == access(FOCUS_SERVER_READY, F_OK)) {
350                         SLOG(LOG_ERROR, TAG_VCD, "[Recorder SUCCESS] focus server is available");
351                         break;
352                 } else {
353                         if (0 == cnt++ % 10)
354                                 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] focus server is not available");
355                         usleep(50000);
356                 }
357         }
358
359         int ret = 0;
360
361         /* set init value */
362         g_is_valid_audio_in = false;
363         g_is_valid_bt_in = false;
364         g_current_audio_type = NULL;
365
366         g_audio_type = VCP_AUDIO_TYPE_PCM_S16_LE;
367         g_audio_rate = 16000;
368         g_audio_channel = 1;
369
370         audio_channel_e audio_ch;
371         audio_sample_type_e audio_type;
372
373         SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] AUdio type(%d) rate(%d) channel(%d)", g_audio_type, g_audio_rate, g_audio_channel);
374
375         switch (g_audio_channel) {
376         case 1: audio_ch = AUDIO_CHANNEL_MONO;          break;
377         case 2: audio_ch = AUDIO_CHANNEL_STEREO;        break;
378         default:
379                 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Input channel is not supported");
380                 return VCD_ERROR_OPERATION_FAILED;
381                 break;
382         }
383
384         switch (g_audio_type) {
385         case VCP_AUDIO_TYPE_PCM_S16_LE: audio_type = AUDIO_SAMPLE_TYPE_S16_LE;  break;
386         case VCP_AUDIO_TYPE_PCM_U8:     audio_type = AUDIO_SAMPLE_TYPE_U8;      break;
387         default:
388                 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Invalid Audio Type");
389                 return VCD_ERROR_OPERATION_FAILED;
390                 break;
391         }
392
393         ret = audio_in_create(g_audio_rate, audio_ch, audio_type, &g_audio_h);
394         if (AUDIO_IO_ERROR_NONE == ret) {
395                 g_is_valid_audio_in = true;
396         } else {
397                 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Rate(%d) Channel(%d) Type(%d)", g_audio_rate, audio_ch, audio_type);
398                 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to create audio handle : %d", ret);
399                 g_is_valid_audio_in = false;
400         }
401
402         ret = sound_manager_add_device_connection_changed_cb(SOUND_DEVICE_IO_DIRECTION_IN_MASK, __device_connection_changed_cb, NULL, &g_device_id);
403         if (0 != ret)
404                 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to add device connection changed callback");
405
406         if (0 != sound_manager_create_stream_information_internal(SOUND_STREAM_TYPE_VOICE_RECOGNITION_SERVICE, __recorder_focus_state_cb, NULL, &g_stream_info_h)) {
407                 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to create stream info");
408         } else {
409                 __apply_device_for_stream_routing();
410         }
411
412         if (0 != audio_in_set_sound_stream_info(g_audio_h, g_stream_info_h)) {
413                 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to set stream info");
414         }
415
416         g_audio_cb = audio_cb;
417         g_interrupt_cb = interrupt_cb;
418         g_recorder_state = VCD_RECORDER_STATE_READY;
419
420 #ifdef TV_BT_MODE
421
422         bool is_bt_failed = false;
423
424         if (false == is_bt_failed && BT_ERROR_NONE != bt_product_init()) {
425                 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to init bt");
426                 is_bt_failed = true;
427         }
428
429         if (false == is_bt_failed && BT_ERROR_NONE != bt_hid_host_initialize(_bt_cb_hid_state_changed, NULL)) {
430                 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail bt_hid_host_initialize()");
431                 is_bt_failed = true;
432         }
433
434         if (false == is_bt_failed && BT_ERROR_NONE != bt_hid_set_audio_data_receive_cb(_bt_hid_audio_data_receive_cb, NULL)) {
435                 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail bt_hid_set_audio_data_receive_cb()");
436                 is_bt_failed = true;
437         }
438
439
440         if (false == is_bt_failed) {
441                 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Bluetooth is available");
442                 g_is_valid_bt_in = true;
443         }
444 #endif
445         /* Select default audio type */
446         if (true == g_is_valid_audio_in) {
447                 g_current_audio_type = strdup(VCP_AUDIO_ID_NONE);
448         } else {
449                 if (true == g_is_valid_bt_in) {
450                         g_current_audio_type = strdup(VCP_AUDIO_ID_BLUETOOTH);
451                 } else {
452                         SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] No valid audio");
453                         return -1;
454                 }
455         }
456
457         SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Audio type : %s", g_current_audio_type);
458
459         return 0;
460 }
461
462 int vcd_recorder_destroy()
463 {
464         if (VCD_RECORDER_STATE_RECORDING == g_recorder_state) {
465                 if (0 == strncmp(VCP_AUDIO_ID_BLUETOOTH, g_current_audio_type, strlen(VCP_AUDIO_ID_BLUETOOTH))) {
466 #ifdef TV_BT_MODE
467                         bt_hid_unset_audio_data_receive_cb();
468 #endif
469                 } else if (0 == strncmp(VCP_AUDIO_ID_MSF, g_current_audio_type, strlen(VCP_AUDIO_ID_MSF))) {
470 #ifdef TV_MSF_WIFI_MODE
471                         UnRegisterMSFAudioCallback();
472 #endif
473                 } else {
474                         audio_in_unprepare(g_audio_h);
475                 }
476                 g_recorder_state = VCD_RECORDER_STATE_READY;
477         }
478
479         int ret = sound_manager_remove_device_connection_changed_cb(g_device_id);
480         if (0 != ret)
481                 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to remove device connection changed callback, ret(%d)", ret);
482
483         ret = sound_manager_destroy_stream_information(g_stream_info_h);
484         if (0 != ret)
485                 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to destroy stream info, ret(%d)", ret);
486
487         audio_in_destroy(g_audio_h);
488
489 #ifdef TV_BT_MODE
490         bt_hid_unset_audio_data_receive_cb();
491
492         bt_hid_host_deinitialize();
493
494         bt_product_deinit();
495 #endif
496
497         g_audio_cb = NULL;
498
499         if (NULL != g_current_audio_type) {
500                 free(g_current_audio_type);
501                 g_current_audio_type = NULL;
502         }
503
504         return 0;
505 }
506
507 int vcd_recorder_set(const char* audio_type, vcp_audio_type_e type, int rate, int channel)
508 {
509         if (NULL == audio_type) {
510                 return VCD_ERROR_INVALID_PARAMETER;
511         }
512
513         if (NULL != g_current_audio_type) {
514                 if (0 == strncmp(g_current_audio_type, audio_type, strlen(g_current_audio_type))) {
515                         SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Current audio type is already set : %s", audio_type);
516                         return 0;
517                 }
518         } else {
519                 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Recorder is NOT created");
520                 return VCD_ERROR_INVALID_STATE;
521         }
522
523         SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] set audio type (%s)", audio_type);
524         vcd_engine_set_audio_type(audio_type);
525
526         if (VCD_RECORDER_STATE_READY != g_recorder_state) {
527                 if ((!strncmp(g_current_audio_type, VCP_AUDIO_ID_NONE, strlen(g_current_audio_type)) &&
528                                         strncmp(audio_type, VCP_AUDIO_ID_BLUETOOTH, strlen(audio_type)) &&
529                                         strncmp(audio_type, VCP_AUDIO_ID_MSF, strlen(audio_type))) ||
530                                 (strncmp(g_current_audio_type, VCP_AUDIO_ID_BLUETOOTH, strlen(g_current_audio_type)) &&
531                                  strncmp(g_current_audio_type, VCP_AUDIO_ID_MSF, strlen(g_current_audio_type)) &&
532                                  strncmp(g_current_audio_type, VCP_AUDIO_ID_NONE, strlen(g_current_audio_type)) &&
533                                  !strncmp(audio_type, VCP_AUDIO_ID_NONE, strlen(audio_type)))) {
534                         SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Skip stop recording while Recorder is NOT ready");
535                 } else {
536                         SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Recorder is NOT ready");
537                         vcd_recorder_stop();
538                         //return VCD_ERROR_INVALID_STATE;
539                 }
540         }
541
542         int ret = -1;
543         /* Check BT audio */
544         if (0 == strncmp(VCP_AUDIO_ID_BLUETOOTH, audio_type, strlen(VCP_AUDIO_ID_BLUETOOTH))) {
545                 if (false == g_is_valid_bt_in) {
546                         SLOG(LOG_ERROR, TAG_VCD, "[Recorder] BT audio is NOT valid");
547                         return VCD_ERROR_OPERATION_REJECTED;
548                 }
549
550                 if (NULL != g_current_audio_type) {
551                         free(g_current_audio_type);
552                         g_current_audio_type = NULL;
553                 }
554
555                 g_current_audio_type = strdup(audio_type);
556         } else if (0 == strncmp(VCP_AUDIO_ID_MSF, audio_type, strlen(VCP_AUDIO_ID_MSF))) {
557                 if (NULL != g_current_audio_type) {
558                         free(g_current_audio_type);
559                         g_current_audio_type = NULL;
560                 }
561
562                 g_current_audio_type = strdup(audio_type);
563         } else {
564                 if (false == g_is_valid_audio_in) {
565                         SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Audio-in is NOT valid");
566                         return VCD_ERROR_OPERATION_REJECTED;
567                 }
568
569                 if (g_audio_type != type || g_audio_rate != rate || g_audio_channel != channel) {
570                         SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] New audio type(%d) rate(%d) channel(%d)", type, rate, channel);
571                         audio_in_destroy(g_audio_h);
572
573                         audio_channel_e audio_ch;
574                         audio_sample_type_e audio_type;
575
576                         switch (channel) {
577                         case 1: audio_ch = AUDIO_CHANNEL_MONO;          break;
578                         case 2: audio_ch = AUDIO_CHANNEL_STEREO;        break;
579                         default:
580                                 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Input channel is not supported");
581                                 return VCD_ERROR_OPERATION_FAILED;
582                                 break;
583                         }
584
585                         switch (type) {
586                         case VCP_AUDIO_TYPE_PCM_S16_LE: audio_type = AUDIO_SAMPLE_TYPE_S16_LE;  break;
587                         case VCP_AUDIO_TYPE_PCM_U8:     audio_type = AUDIO_SAMPLE_TYPE_U8;      break;
588                         default:
589                                 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Invalid Audio Type");
590                                 return VCD_ERROR_OPERATION_FAILED;
591                                 break;
592                         }
593
594                         ret = audio_in_create(rate, audio_ch, audio_type, &g_audio_h);
595                         if (AUDIO_IO_ERROR_NONE != ret) {
596                                 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to create audio handle : %d", ret);
597                                 g_is_valid_audio_in = false;
598                                 return VCD_ERROR_OPERATION_FAILED;
599                         }
600
601                         if (0 != audio_in_set_sound_stream_info(g_audio_h, g_stream_info_h)) {
602                                 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to set stream info");
603                         }
604
605                         g_audio_type = type;
606                         g_audio_rate = rate;
607                         g_audio_channel = channel;
608                 }
609
610 #ifdef TV_BT_MODE
611                 if (NULL != g_current_audio_type) {
612                         free(g_current_audio_type);
613                         g_current_audio_type = NULL;
614                 }
615
616                 g_current_audio_type = strdup(audio_type);
617 #endif
618         }
619
620         SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Current audio type is changed : %s", g_current_audio_type);
621
622         return 0;
623 }
624
625 int vcd_recorder_get(char** audio_type)
626 {
627         if (NULL == audio_type) {
628                 return VCD_ERROR_INVALID_PARAMETER;
629         }
630
631         if (NULL != g_current_audio_type) {
632                 *audio_type = strdup(g_current_audio_type);
633         } else {
634                 SLOG(LOG_WARN, TAG_VCD, "[Recorder] Current audio type(%s) is NOT ready", *audio_type);
635                 *audio_type = NULL;
636         }
637
638         return 0;
639 }
640
641 static float get_volume_decibel(char* data, int size)
642 {
643 #define MAX_AMPLITUDE_MEAN_16 32768
644
645         int i, depthByte;
646         int count = 0;
647
648         float db = 0.0;
649         float rms = 0.0;
650         unsigned long long square_sum = 0;
651         short pcm16 = 0;
652
653         depthByte = 2;
654
655         for (i = 0; i < size; i += (depthByte<<1)) {
656                 pcm16 = 0;
657                 memcpy(&pcm16, data + i, sizeof(short));
658                 square_sum += pcm16 * pcm16;
659                 count++;
660         }
661
662         if (0 == count || 0 == square_sum) {
663                 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] No data");
664                 rms = 1.0;
665         } else {
666                 rms = sqrt((float)square_sum/count);
667         }
668
669         db = 20 * log10(rms/MAX_AMPLITUDE_MEAN_16);
670         return db;
671 }
672
673 Eina_Bool __read_normal_func(void *data)
674 {
675         int ret = -1;
676
677         if (VCD_RECORDER_STATE_RECORDING != g_recorder_state) {
678                 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Exit audio reading normal func");
679                 return EINA_FALSE;
680         }
681
682         memset(g_normal_buffer, '\0', BUFFER_LENGTH + 10);
683
684         ret = audio_in_read(g_audio_h, g_normal_buffer, BUFFER_LENGTH);
685         if (0 > ret) {
686                 SLOG(LOG_WARN, TAG_VCD, "[Recorder WARNING] Fail to read audio : %d", ret);
687                 g_recorder_state = VCD_RECORDER_STATE_READY;
688                 return EINA_FALSE;
689         }
690
691         if (NULL != g_audio_cb) {
692                 if (0 != g_audio_cb(g_normal_buffer, BUFFER_LENGTH)) {
693                         SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to read audio : %d", ret);
694                         vcd_recorder_stop();
695                         return EINA_FALSE;
696                 }
697         }
698
699         /* Set volume */
700         if (0 == g_buffer_count % 30) {
701                 float vol_db = get_volume_decibel(g_normal_buffer, BUFFER_LENGTH);
702                 if (0 != vcdc_send_set_volume(vcd_client_manager_get_pid(), vol_db)) {
703                         SLOG(LOG_ERROR, TAG_VCD, "[Recorder] Fail to send recording volume(%f)", vol_db);
704                 }
705         }
706
707         if (0 == g_buffer_count || 0 == g_buffer_count % 50) {
708                 SLOG(LOG_WARN, TAG_VCD, "[Recorder][%d] Recording... : read_size(%d)", g_buffer_count, ret);
709
710                 if (100000 == g_buffer_count) {
711                         g_buffer_count = 0;
712                 }
713         }
714
715         g_buffer_count++;
716
717 #ifdef BUF_SAVE_MODE
718         /* write pcm buffer */
719         fwrite(g_normal_buffer, 1, BUFFER_LENGTH, g_normal_file);
720 #endif
721
722         return EINA_TRUE;
723 }
724
725 static void __timer_read_normal_func(void *data)
726 {
727         SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] before __read_normal_func");
728         ecore_timer_add(0, __read_normal_func, NULL);
729         return;
730 }
731
732 static void __check_audio_format()
733 {
734         vcp_audio_type_e type;
735         int rate;
736         int channel;
737
738         int ret = vcd_engine_get_audio_format(VCP_AUDIO_ID_NONE, &type, &rate, &channel);
739         if (0 != ret) {
740                 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get audio format : %d", ret);
741                 return;
742         }
743
744         if (false == g_is_valid_audio_in) {
745                 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Audio-in is NOT valid");
746                 return;
747         }
748
749         if (g_audio_type != type || g_audio_rate != rate || g_audio_channel != channel) {
750                 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] New audio type(%d) rate(%d) channel(%d)", type, rate, channel);
751                 audio_in_destroy(g_audio_h);
752
753                 audio_channel_e audio_ch;
754                 audio_sample_type_e audio_type;
755
756                 switch (channel) {
757                 case 1: audio_ch = AUDIO_CHANNEL_MONO;          break;
758                 case 2: audio_ch = AUDIO_CHANNEL_STEREO;        break;
759                 default:
760                         SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Input channel is not supported");
761                         return;
762                         break;
763                 }
764
765                 switch (type) {
766                 case VCP_AUDIO_TYPE_PCM_S16_LE: audio_type = AUDIO_SAMPLE_TYPE_S16_LE;  break;
767                 case VCP_AUDIO_TYPE_PCM_U8:     audio_type = AUDIO_SAMPLE_TYPE_U8;      break;
768                 default:
769                         SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Invalid Audio Type");
770                         return;
771                         break;
772                 }
773
774                 ret = audio_in_create(rate, audio_ch, audio_type, &g_audio_h);
775                 if (AUDIO_IO_ERROR_NONE != ret) {
776                         SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to create audio handle : %d", ret);
777                         g_is_valid_audio_in = false;
778                         return;
779                 }
780
781                 if (0 != audio_in_set_sound_stream_info(g_audio_h, g_stream_info_h)) {
782                         SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to set stream info");
783                 }
784
785                 g_audio_type = type;
786                 g_audio_rate = rate;
787                 g_audio_channel = channel;
788         } else {
789                 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] audio type(%d) rate(%d) channel(%d)", g_audio_type, g_audio_rate, g_audio_channel);
790         }
791 }
792
793
794
795 int vcd_recorder_start()
796 {
797         int ret = -1;
798         g_buffer_count = 0;
799
800         SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Enter, recorder state(%d)", g_recorder_state);
801
802         if (VCD_RECORDER_STATE_RECORDING == g_recorder_state)   return 0;
803
804         bool started = false;
805         SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] audio type : %s", g_current_audio_type);
806
807         if (NULL != g_current_audio_type) {
808                 if (0 == strncmp(VCP_AUDIO_ID_BLUETOOTH, g_current_audio_type, strlen(VCP_AUDIO_ID_BLUETOOTH))) {
809 #ifdef TV_BT_MODE
810                         const unsigned char input_data[2] = {SMART_CONTROL_START_CMD, 0x00};
811                         int bt_retry = 0;
812                         while (5 > bt_retry) {
813                                 ret = bt_hid_send_rc_command(NULL, input_data, sizeof(input_data));
814                                 if (BT_ERROR_NONE == ret) {
815                                         SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Start bt audio recorder");
816                                         started = true;
817                                         break;
818                                 } else if (BT_ERROR_NOW_IN_PROGRESS == ret) {
819                                         SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail bt_hid_send_rc_command : %d", ret);
820                                         usleep(50000);
821                                         bt_retry++;
822                                 } else {
823                                         break;
824                                 }
825                         }
826                         if (false == started) {
827                                 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to start bt audio");
828                                 return VCD_ERROR_OPERATION_FAILED;
829                         }
830
831                         g_bt_extend_count = 0;
832 #endif
833                 } else if (0 == strncmp(VCP_AUDIO_ID_MSF, g_current_audio_type, strlen(VCP_AUDIO_ID_MSF))) {
834                         SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] call RegisterMSFAudioCallback() function");
835 #ifdef TV_MSF_WIFI_MODE
836
837                         ret = RegisterMSFAudioCallback(__msf_wifi_audio_data_receive_cb, NULL);
838                         SLOG(LOG_ERROR, TAG_VCD, "[Recorder] ret = %d", ret);
839                         if (MSFResult_OK == ret) {
840                                 started = true;
841                         } else {
842                                 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to start MSF(wifi) audio");
843                                 return VCD_ERROR_OPERATION_FAILED;
844                         }
845 #endif
846                 }
847         }
848
849         SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] started = %d", started);
850         if (false == started) {
851                 /* check audio format */
852                 __check_audio_format();
853 #if 0
854                 ret = sound_manager_acquire_focus(g_stream_info_h, SOUND_STREAM_FOCUS_FOR_RECORDING, NULL);
855                 if (SOUND_MANAGER_ERROR_NONE != ret) {
856                         SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to acquire focus : %d", ret);
857                 } else {
858                         ret = audio_in_set_sound_stream_info(g_audio_h, g_stream_info_h);
859                         if (AUDIO_IO_ERROR_NONE != ret) {
860                                 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to set stream info : %d", ret);
861                         }
862                 }
863 #endif
864
865                 ret = audio_in_prepare(g_audio_h);
866                 if (AUDIO_IO_ERROR_NONE != ret) {
867                         if (AUDIO_IO_ERROR_SOUND_POLICY == ret) {
868                                 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Audio is busy.");
869                                 return VCD_ERROR_RECORDER_BUSY;
870                         } else {
871                                 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to start audio : %d", ret);
872                         }
873                         return VCD_ERROR_OPERATION_FAILED;
874                 }
875
876                 /* Add ecore timer to read audio data */
877                 ecore_main_loop_thread_safe_call_async(__timer_read_normal_func, NULL);
878                 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Start audio in recorder");
879         }
880
881         g_recorder_state = VCD_RECORDER_STATE_RECORDING;
882
883 #ifdef BUF_SAVE_MODE
884         char normal_file_name[128] = {'\0',};
885         g_count++;
886
887         while (1) {
888                 snprintf(normal_file_name, sizeof(normal_file_name), "/tmp/vc_normal_%d_%d", getpid(), g_count);
889                 ret = access(normal_file_name, 0);
890
891                 if (0 == ret) {
892                         SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] File is already exist");
893                         if (0 == remove(normal_file_name)) {
894                                 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Remove file");
895                                 break;
896                         } else {
897                                 g_count++;
898                         }
899                 } else {
900                         break;
901                 }
902         }
903
904         SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] File normal name : %s", normal_file_name);
905
906         /* open test file */
907         g_normal_file = fopen(normal_file_name, "wb+x");
908         if (!g_normal_file) {
909                 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] File not found!");
910         }
911 #endif
912         return 0;
913 }
914
915 int vcd_recorder_stop()
916 {
917         int ret = -1;
918
919         if (VCD_RECORDER_STATE_READY == g_recorder_state)
920                 return 0;
921
922         g_recorder_state = VCD_RECORDER_STATE_READY;
923
924 #ifdef BUF_SAVE_MODE
925         fclose(g_normal_file);
926 #endif
927
928         bool stoped = false;
929
930         if (NULL != g_current_audio_type) {
931                 if (0 == strncmp(VCP_AUDIO_ID_BLUETOOTH, g_current_audio_type, strlen(VCP_AUDIO_ID_BLUETOOTH))) {
932 #ifdef TV_BT_MODE
933                         int bt_retry = 0;
934                         while (5 > bt_retry) {
935                                 ret = bt_hid_rc_stop_sending_voice(NULL);
936                                 if (BT_ERROR_NONE == ret) {
937                                         SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Stop bt audio recorder");
938                                         stoped = true;
939                                         break;
940                                 } else if (BT_ERROR_NOW_IN_PROGRESS == ret) {
941                                         SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail bt_hid_rc_stop_sending_voice()");
942                                         usleep(50000);
943                                         bt_retry++;
944                                 } else {
945                                         break;
946                                 }
947                         }
948                         if (NULL != g_current_audio_type &&
949                                         (!strncmp(g_current_audio_type, VCP_AUDIO_ID_BLUETOOTH, sizeof(VCP_AUDIO_ID_BLUETOOTH)) ||
950                                          !strncmp(g_current_audio_type, VCP_AUDIO_ID_MSF, sizeof(VCP_AUDIO_ID_MSF)))) {
951                                 SLOG(LOG_DEBUG, TAG_VCD, "[DEBUG] Recorder reset to NONE");
952                                 vcd_recorder_set(VCP_AUDIO_ID_NONE, g_audio_type, g_audio_rate, g_audio_channel);
953                         }
954
955                         if (false == stoped) {
956                                 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to stop bt audio");
957                                 return VCD_ERROR_OPERATION_FAILED;
958                         }
959 #endif
960                 } else if (0 == strncmp(VCP_AUDIO_ID_MSF, g_current_audio_type, strlen(VCP_AUDIO_ID_MSF))) {
961 #ifdef TV_MSF_WIFI_MODE
962                         UnRegisterMSFAudioCallback();
963                         if (NULL != g_current_audio_type &&
964                                         (!strncmp(g_current_audio_type, VCP_AUDIO_ID_BLUETOOTH, sizeof(VCP_AUDIO_ID_BLUETOOTH)) ||
965                                          !strncmp(g_current_audio_type, VCP_AUDIO_ID_MSF, sizeof(VCP_AUDIO_ID_MSF)))) {
966                                 SLOG(LOG_DEBUG, TAG_VCD, "[DEBUG] Recorder reset to NONE");
967                                 vcd_recorder_set(VCP_AUDIO_ID_NONE, g_audio_type, g_audio_rate, g_audio_channel);
968                         }
969                         stoped = true;
970 #endif
971                 } else  {
972                         SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] current audio type is NONE");
973                 }
974         }
975
976         if (false == stoped) {
977                 ret = audio_in_unprepare(g_audio_h);
978                 if (AUDIO_IO_ERROR_NONE != ret) {
979                         SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to stop audio : %d", ret);
980                         return VCD_ERROR_OPERATION_FAILED;
981                 }
982
983 #if 0
984                 ret = sound_manager_release_focus(g_stream_info_h, SOUND_STREAM_FOCUS_FOR_RECORDING, NULL);
985                 if (SOUND_MANAGER_ERROR_NONE != ret) {
986                         SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to release focus : %d", ret);
987                 }
988 #endif
989         }
990
991         return 0;
992 }
993
994 int vcd_recorder_get_state()
995 {
996         return g_recorder_state;
997 }