2 * Copyright (c) 2011-2017 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #define TV_MSF_WIFI_MODE
24 #include <sound_manager.h>
25 #include <sound_manager_internal.h>
28 #include <bluetooth_product.h>
30 #ifdef TV_MSF_WIFI_MODE
31 #include <MSFVoiceInterface.h>
35 #include "vcd_client_data.h"
36 #include "vcd_config.h"
38 #include "vcd_engine_agent.h"
39 #include "vcd_recorder.h"
42 #define FRAME_LENGTH 160
43 #define BUFFER_LENGTH FRAME_LENGTH * 2
45 #define FOCUS_SERVER_READY "/tmp/.focus_server_ready"
47 #define VCE_AUDIO_ID_NONE "VC_AUDIO_ID_NONE" /**< None audio id */
49 static vcd_recorder_state_e g_recorder_state = VCD_RECORDER_STATE_READY;
51 static vcd_recoder_audio_cb g_audio_cb = NULL;
53 static vcd_recorder_interrupt_cb g_interrupt_cb = NULL;
55 static audio_in_h g_audio_h;
57 static sound_stream_info_h g_stream_info_h;
59 static vce_audio_type_e g_audio_type;
61 static int g_audio_rate;
63 static int g_audio_channel;
65 static char g_normal_buffer[BUFFER_LENGTH + 10];
67 static bool g_is_valid_audio_in = false;
69 static bool g_is_valid_bt_in = false;
71 static char* g_current_audio_type = NULL;
73 static int g_buffer_count;
75 static int g_device_id = -1;
83 static FILE* g_normal_file;
85 static int g_count = 1;
88 static float get_volume_decibel(char* data, int size);
90 #ifdef TV_MSF_WIFI_MODE
91 static void __msf_wifi_audio_data_receive_cb(msf_wifi_voice_data_s *voice_data, void* user_data)
93 if (0 != strncmp(g_current_audio_type, VCE_AUDIO_ID_WIFI, sizeof(VCE_AUDIO_ID_WIFI))) {
94 vcd_state_e state = vcd_config_get_service_state();
95 if (VCD_STATE_READY == state) {
96 vcd_recorder_set(VCE_AUDIO_ID_WIFI, VCE_AUDIO_TYPE_PCM_S16_LE, 16000, 1);
98 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] current audio type is (%s)", g_current_audio_type);
103 if (VCD_RECORDER_STATE_RECORDING != g_recorder_state) {
104 SLOG(LOG_WARN, TAG_VCD, "[Recorder] Not start yet, but send audio data vi Wi-Fi");
105 vcd_recorder_start();
108 if (NULL != g_audio_cb) {
109 if (0 != g_audio_cb((void*)voice_data->audio_buf, (unsigned int)voice_data->length)) {
110 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to read audio");
116 if (0 == g_buffer_count % 30) {
117 float vol_db = get_volume_decibel((char*)voice_data->audio_buf, (unsigned int)voice_data->length);
118 if (0 != vcdc_send_set_volume(vcd_client_manager_get_pid(), vol_db)) {
119 SLOG(LOG_ERROR, TAG_VCD, "[Recorder] Fail to send recording volume(%f)", vol_db);
123 if (0 == g_buffer_count || 0 == g_buffer_count % 50) {
124 SLOG(LOG_WARN, TAG_VCD, "[Recorder][%d] Recording... : read_size(%ld)", g_buffer_count, voice_data->length);
126 if (100000 == g_buffer_count)
133 /* write pcm buffer */
134 fwrite(voice_data->audio_buf, 1, voice_data->length, g_normal_file);
143 static int g_bt_extend_count;
145 #define SMART_CONTROL_EXTEND_CMD 0x03
146 #define SMART_CONTROL_START_CMD 0x04
148 static void _bt_cb_hid_state_changed(int result, bool connected, const char *remote_address, void *user_data)
150 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Bluetooth Event [%d] Received address [%s]", result, remote_address);
154 static void _bt_hid_audio_data_receive_cb(bt_hid_voice_data_s *voice_data, void *user_data)
156 if (0 != strncmp(g_current_audio_type, VCE_AUDIO_ID_BLUETOOTH, sizeof(VCE_AUDIO_ID_BLUETOOTH))) {
157 vcd_state_e state = vcd_config_get_service_state();
158 if (VCD_STATE_READY == state) {
159 vcd_recorder_set(VCE_AUDIO_ID_BLUETOOTH, VCE_AUDIO_TYPE_PCM_S16_LE, 16000, 1);
161 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] current audio type is (%s)", g_current_audio_type);
166 if (VCD_RECORDER_STATE_RECORDING != g_recorder_state) {
167 SLOG(LOG_WARN, TAG_VCD, "[Recorder] Not start yet, but send audio data vi Bluetooth");
168 // vcd_recorder_start();
171 if (NULL != g_audio_cb) {
172 if (0 != g_audio_cb((void*)voice_data->audio_buf, (unsigned int)voice_data->length)) {
173 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to read audio");
179 if (0 == g_buffer_count % 15) {
180 float vol_db = get_volume_decibel((char*)voice_data->audio_buf, (unsigned int)voice_data->length);
181 if (0 != vcdc_send_set_volume(vcd_client_manager_get_pid(), vol_db)) {
182 SLOG(LOG_ERROR, TAG_VCD, "[Recorder] Fail to send recording volume(%f)", vol_db);
186 if (0 == g_buffer_count || 0 == g_buffer_count % 50) {
187 SLOG(LOG_WARN, TAG_VCD, "[Recorder][%d] Recording... : read_size(%d)", g_buffer_count, voice_data->length);
189 if (0 == g_bt_extend_count % 5 && 0 != g_buffer_count) {
190 const unsigned char input_data[2] = {SMART_CONTROL_EXTEND_CMD, 0x10 };
191 if (BT_ERROR_NONE != bt_hid_send_rc_command(NULL, input_data, sizeof(input_data))) {
192 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail bt_hid_send_rc_command");
194 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Extend bt audio recorder");
199 if (100000 == g_buffer_count) {
207 /* write pcm buffer */
208 fwrite(voice_data->audio_buf, 1, voice_data->length, g_normal_file);
216 static const char* __get_focus_changed_reason_code(sound_stream_focus_change_reason_e reason)
219 case SOUND_STREAM_FOCUS_CHANGED_BY_MEDIA: return "SOUND_STREAM_FOCUS_CHANGED_BY_MEDIA";
220 case SOUND_STREAM_FOCUS_CHANGED_BY_SYSTEM: return "SOUND_STREAM_FOCUS_CHANGED_BY_SYSTEM";
221 case SOUND_STREAM_FOCUS_CHANGED_BY_ALARM: return "SOUND_STREAM_FOCUS_CHANGED_BY_ALARM";
222 case SOUND_STREAM_FOCUS_CHANGED_BY_NOTIFICATION: return "SOUND_STREAM_FOCUS_CHANGED_BY_NOTIFICATION";
223 case SOUND_STREAM_FOCUS_CHANGED_BY_EMERGENCY: return "SOUND_STREAM_FOCUS_CHANGED_BY_EMERGENCY";
224 case SOUND_STREAM_FOCUS_CHANGED_BY_VOICE_INFORMATION: return "SOUND_STREAM_FOCUS_CHANGED_BY_VOICE_INFORMATION";
225 case SOUND_STREAM_FOCUS_CHANGED_BY_VOICE_RECOGNITION: return "SOUND_STREAM_FOCUS_CHANGED_BY_VOICE_RECOGNITION";
226 case SOUND_STREAM_FOCUS_CHANGED_BY_RINGTONE: return "SOUND_STREAM_FOCUS_CHANGED_BY_RINGTONE";
227 case SOUND_STREAM_FOCUS_CHANGED_BY_VOIP: return "SOUND_STREAM_FOCUS_CHANGED_BY_VOIP";
228 case SOUND_STREAM_FOCUS_CHANGED_BY_CALL: return "SOUND_STREAM_FOCUS_CHANGED_BY_CALL";
229 case SOUND_STREAM_FOCUS_CHANGED_BY_MEDIA_EXTERNAL_ONLY: return "SOUND_STREAM_FOCUS_CHANGED_BY_MEDIA_EXTERNAL_ONLY";
230 default: return "Undefined reason code";
234 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,
235 sound_stream_focus_change_reason_e reason, int sound_behavior, const char *extra_info, void *user_data)
237 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Focus state changed cb");
239 if (stream_info != g_stream_info_h) {
240 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Invalid stream info handle");
244 SLOG(LOG_WARN, TAG_VCD, "[Recorder] focus state changed to (%d) with reason (%s)", (int)focus_state, __get_focus_changed_reason_code(reason));
246 if (VCD_RECORDER_STATE_RECORDING == g_recorder_state && SOUND_STREAM_FOCUS_STATE_RELEASED == focus_state) {
247 SLOG(LOG_WARN, TAG_VCD, "[Recorder] Focus released as interrupt");
248 if (NULL != g_interrupt_cb) {
255 static int __apply_device_for_stream_routing()
257 sound_device_list_h device_list = NULL;
258 sound_device_h device = NULL;
259 sound_device_type_e type;
260 sound_device_io_direction_e io_direction;
262 if (0 != sound_manager_get_device_list(SOUND_DEVICE_IO_DIRECTION_IN_MASK, &device_list)) {
263 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to get current device list");
268 while (0 == sound_manager_get_next_device(device_list, &device)) {
269 if (0 != sound_manager_get_device_type(device, &type)) {
270 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to get device type");
273 if (0 != sound_manager_get_device_io_direction(device, &io_direction)) {
274 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to get device io direction");
277 if (SOUND_DEVICE_USB_AUDIO == type && SOUND_DEVICE_IO_DIRECTION_IN == io_direction) {
278 if (0 != sound_manager_add_device_for_stream_routing(g_stream_info_h, device)) {
279 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to add device");
282 if (0 != sound_manager_apply_stream_routing(g_stream_info_h)) {
283 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to apply stream routing");
291 sound_manager_free_device_list(device_list);
295 SLOG(LOG_WARN, TAG_VCD, "[Recorder] No device");
297 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Apply device for stream routing");
302 static void __device_connection_changed_cb(sound_device_h device, bool is_connected, void *user_data)
304 sound_device_type_e type;
306 if (0 != sound_manager_get_device_type(device, &type)) {
307 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to get device type");
310 if (type == SOUND_DEVICE_USB_AUDIO) {
311 bool is_recording_state = false;
312 if (VCD_RECORDER_STATE_RECORDING == g_recorder_state) {
313 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Stop recorder");
315 is_recording_state = true;
317 if (0 != sound_manager_remove_device_for_stream_routing(g_stream_info_h, device))
318 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to remove device");
320 if (0 != sound_manager_add_device_for_stream_routing(g_stream_info_h, device)) {
321 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to add device");
324 if (0 != sound_manager_apply_stream_routing(g_stream_info_h)) {
325 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR} Fail to apply stream routing");
328 if (true == is_recording_state) {
329 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Start recorder");
330 vcd_recorder_start();
332 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Apply device for stream routing");
338 int vcd_recorder_create(vcd_recoder_audio_cb audio_cb, vcd_recorder_interrupt_cb interrupt_cb)
340 if (NULL == audio_cb || NULL == interrupt_cb) {
341 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Input param is NOT valid");
342 return VCD_ERROR_INVALID_PARAMETER;
345 /* check focus server */
348 if (0 == access(FOCUS_SERVER_READY, F_OK)) {
349 SLOG(LOG_ERROR, TAG_VCD, "[Recorder SUCCESS] focus server is available");
353 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] focus server is not available");
361 g_is_valid_audio_in = false;
362 g_is_valid_bt_in = false;
363 g_current_audio_type = NULL;
365 g_audio_type = VCE_AUDIO_TYPE_PCM_S16_LE;
366 g_audio_rate = 16000;
369 audio_channel_e audio_ch;
370 audio_sample_type_e audio_type;
372 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Audio type(%d) rate(%d) channel(%d)", g_audio_type, g_audio_rate, g_audio_channel);
374 switch (g_audio_channel) {
375 case 1: audio_ch = AUDIO_CHANNEL_MONO; break;
376 case 2: audio_ch = AUDIO_CHANNEL_STEREO; break;
378 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Input channel is not supported");
379 return VCD_ERROR_OPERATION_FAILED;
383 switch (g_audio_type) {
384 case VCE_AUDIO_TYPE_PCM_S16_LE: audio_type = AUDIO_SAMPLE_TYPE_S16_LE; break;
385 case VCE_AUDIO_TYPE_PCM_U8: audio_type = AUDIO_SAMPLE_TYPE_U8; break;
387 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Invalid Audio Type");
388 return VCD_ERROR_OPERATION_FAILED;
392 ret = audio_in_create(g_audio_rate, audio_ch, audio_type, &g_audio_h);
393 if (AUDIO_IO_ERROR_NONE == ret) {
394 g_is_valid_audio_in = true;
396 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Rate(%d) Channel(%d) Type(%d)", g_audio_rate, audio_ch, audio_type);
397 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to create audio handle : %d", ret);
398 g_is_valid_audio_in = false;
401 ret = sound_manager_add_device_connection_changed_cb(SOUND_DEVICE_IO_DIRECTION_IN_MASK, __device_connection_changed_cb, NULL, &g_device_id);
403 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to add device connection changed callback");
405 if (0 != sound_manager_create_stream_information_internal(SOUND_STREAM_TYPE_VOICE_RECOGNITION_SERVICE, __recorder_focus_state_cb, NULL, &g_stream_info_h)) {
406 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to create stream info");
408 __apply_device_for_stream_routing();
411 if (0 != audio_in_set_sound_stream_info(g_audio_h, g_stream_info_h)) {
412 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to set stream info");
415 g_audio_cb = audio_cb;
416 g_interrupt_cb = interrupt_cb;
417 g_recorder_state = VCD_RECORDER_STATE_READY;
421 bool is_bt_failed = false;
423 if (false == is_bt_failed && BT_ERROR_NONE != bt_product_init()) {
424 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to init bt");
428 if (false == is_bt_failed && BT_ERROR_NONE != bt_hid_host_initialize(_bt_cb_hid_state_changed, NULL)) {
429 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail bt_hid_host_initialize()");
433 if (false == is_bt_failed && BT_ERROR_NONE != bt_hid_set_audio_data_receive_cb(_bt_hid_audio_data_receive_cb, NULL)) {
434 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail bt_hid_set_audio_data_receive_cb()");
439 if (false == is_bt_failed) {
440 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Bluetooth is available");
441 g_is_valid_bt_in = true;
444 /* Select default audio type */
445 if (true == g_is_valid_audio_in) {
446 g_current_audio_type = strdup(VCE_AUDIO_ID_NONE);
448 if (true == g_is_valid_bt_in) {
449 g_current_audio_type = strdup(VCE_AUDIO_ID_BLUETOOTH);
451 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] No valid audio");
456 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Audio type : %s", g_current_audio_type);
461 int vcd_recorder_destroy()
463 if (VCD_RECORDER_STATE_RECORDING == g_recorder_state) {
464 if (0 == strncmp(VCE_AUDIO_ID_BLUETOOTH, g_current_audio_type, strlen(VCE_AUDIO_ID_BLUETOOTH))) {
466 bt_hid_unset_audio_data_receive_cb();
468 } else if (0 == strncmp(VCE_AUDIO_ID_WIFI, g_current_audio_type, strlen(VCE_AUDIO_ID_WIFI))) {
469 #ifdef TV_MSF_WIFI_MODE
470 UnRegisterMSFAudioCallback();
473 audio_in_unprepare(g_audio_h);
475 g_recorder_state = VCD_RECORDER_STATE_READY;
478 int ret = sound_manager_remove_device_connection_changed_cb(g_device_id);
480 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to remove device connection changed callback, ret(%d)", ret);
482 ret = sound_manager_destroy_stream_information(g_stream_info_h);
484 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to destroy stream info, ret(%d)", ret);
486 ret = audio_in_destroy(g_audio_h);
488 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to audio in destroy, ret(%d)", ret);
491 bt_hid_unset_audio_data_receive_cb();
493 bt_hid_host_deinitialize();
500 if (NULL != g_current_audio_type) {
501 free(g_current_audio_type);
502 g_current_audio_type = NULL;
508 int vcd_recorder_set(const char* audio_type, vce_audio_type_e type, int rate, int channel)
510 if (NULL == audio_type) {
511 return VCD_ERROR_INVALID_PARAMETER;
514 if (NULL != g_current_audio_type) {
515 if (0 == strncmp(g_current_audio_type, audio_type, strlen(g_current_audio_type))) {
516 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Current audio type is already set : %s", audio_type);
520 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Recorder is NOT created");
521 return VCD_ERROR_INVALID_STATE;
524 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] set audio type (%s)", audio_type);
525 vcd_engine_set_audio_type(audio_type);
527 if (VCD_RECORDER_STATE_READY != g_recorder_state) {
528 if (NULL != g_current_audio_type) {
529 if ((!strncmp(g_current_audio_type, VCE_AUDIO_ID_NONE, strlen(g_current_audio_type)) &&
530 strncmp(audio_type, VCE_AUDIO_ID_BLUETOOTH, strlen(audio_type)) &&
531 strncmp(audio_type, VCE_AUDIO_ID_WIFI, strlen(audio_type))) ||
532 (strncmp(g_current_audio_type, VCE_AUDIO_ID_BLUETOOTH, strlen(g_current_audio_type)) &&
533 strncmp(g_current_audio_type, VCE_AUDIO_ID_WIFI, strlen(g_current_audio_type)) &&
534 strncmp(g_current_audio_type, VCE_AUDIO_ID_NONE, strlen(g_current_audio_type)) &&
535 !strncmp(audio_type, VCE_AUDIO_ID_NONE, strlen(audio_type)))) {
536 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Skip stop recording while Recorder is NOT ready");
538 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Recorder is NOT ready");
540 //return VCD_ERROR_INVALID_STATE;
547 if (0 == strncmp(VCE_AUDIO_ID_BLUETOOTH, audio_type, strlen(VCE_AUDIO_ID_BLUETOOTH))) {
548 if (false == g_is_valid_bt_in) {
549 SLOG(LOG_ERROR, TAG_VCD, "[Recorder] BT audio is NOT valid");
550 return VCD_ERROR_OPERATION_REJECTED;
553 if (NULL != g_current_audio_type) {
554 free(g_current_audio_type);
555 g_current_audio_type = NULL;
558 g_current_audio_type = strdup(audio_type);
559 } else if (0 == strncmp(VCE_AUDIO_ID_WIFI, audio_type, strlen(VCE_AUDIO_ID_WIFI))) {
560 if (NULL != g_current_audio_type) {
561 free(g_current_audio_type);
562 g_current_audio_type = NULL;
565 g_current_audio_type = strdup(audio_type);
567 if (false == g_is_valid_audio_in) {
568 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Audio-in is NOT valid");
569 return VCD_ERROR_OPERATION_REJECTED;
572 if (g_audio_type != type || g_audio_rate != rate || g_audio_channel != channel) {
573 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] New audio type(%d) rate(%d) channel(%d)", type, rate, channel);
574 audio_in_destroy(g_audio_h);
576 audio_channel_e audio_ch;
577 audio_sample_type_e audio_sample_type;
580 case 1: audio_ch = AUDIO_CHANNEL_MONO; break;
581 case 2: audio_ch = AUDIO_CHANNEL_STEREO; break;
583 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Input channel is not supported");
584 return VCD_ERROR_OPERATION_FAILED;
589 case VCE_AUDIO_TYPE_PCM_S16_LE: audio_sample_type = AUDIO_SAMPLE_TYPE_S16_LE; break;
590 case VCE_AUDIO_TYPE_PCM_U8: audio_sample_type = AUDIO_SAMPLE_TYPE_U8; break;
592 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Invalid Audio Type");
593 return VCD_ERROR_OPERATION_FAILED;
597 ret = audio_in_create(rate, audio_ch, audio_sample_type, &g_audio_h);
598 if (AUDIO_IO_ERROR_NONE != ret) {
599 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to create audio handle : %d", ret);
600 g_is_valid_audio_in = false;
601 return VCD_ERROR_OPERATION_FAILED;
604 if (0 != audio_in_set_sound_stream_info(g_audio_h, g_stream_info_h)) {
605 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to set stream info");
610 g_audio_channel = channel;
614 if (NULL != g_current_audio_type) {
615 free(g_current_audio_type);
616 g_current_audio_type = NULL;
619 g_current_audio_type = strdup(audio_type);
623 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Current audio type is changed : %s", g_current_audio_type);
628 int vcd_recorder_get(char** audio_type)
630 if (NULL == audio_type) {
631 return VCD_ERROR_INVALID_PARAMETER;
634 if (NULL != g_current_audio_type) {
635 *audio_type = strdup(g_current_audio_type);
637 SLOG(LOG_WARN, TAG_VCD, "[Recorder] Current audio type(%s) is NOT ready", *audio_type);
644 static float get_volume_decibel(char* data, int size)
646 #define MAX_AMPLITUDE_MEAN_16 32768
653 unsigned long long square_sum = 0;
658 for (i = 0; i < size; i += (depthByte<<1)) {
660 memcpy(&pcm16, data + i, sizeof(short));
661 square_sum += pcm16 * pcm16;
665 if (0 == count || 0 == square_sum) {
666 SLOG(LOG_ERROR, TAG_VCD, "[ERROR] No data");
669 rms = sqrt((float)square_sum/count);
672 db = 20 * log10(rms/MAX_AMPLITUDE_MEAN_16);
676 Eina_Bool __read_normal_func(void *data)
680 if (VCD_RECORDER_STATE_RECORDING != g_recorder_state) {
681 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Exit audio reading normal func");
685 memset(g_normal_buffer, '\0', BUFFER_LENGTH + 10);
687 ret = audio_in_read(g_audio_h, g_normal_buffer, BUFFER_LENGTH);
689 SLOG(LOG_WARN, TAG_VCD, "[Recorder WARNING] Fail to read audio : %d", ret);
690 g_recorder_state = VCD_RECORDER_STATE_READY;
694 if (NULL != g_audio_cb) {
695 if (0 != g_audio_cb(g_normal_buffer, BUFFER_LENGTH)) {
696 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to read audio : %d", ret);
703 if (0 == g_buffer_count % 30) {
704 float vol_db = get_volume_decibel(g_normal_buffer, BUFFER_LENGTH);
705 if (0 != vcdc_send_set_volume(vcd_client_manager_get_pid(), vol_db)) {
706 SLOG(LOG_ERROR, TAG_VCD, "[Recorder] Fail to send recording volume(%f)", vol_db);
710 if (0 == g_buffer_count || 0 == g_buffer_count % 50) {
711 SLOG(LOG_WARN, TAG_VCD, "[Recorder][%d] Recording... : read_size(%d)", g_buffer_count, ret);
713 if (100000 == g_buffer_count) {
721 /* write pcm buffer */
722 fwrite(g_normal_buffer, 1, BUFFER_LENGTH, g_normal_file);
728 static void __timer_read_normal_func(void *data)
730 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] before __read_normal_func");
731 ecore_timer_add(0, __read_normal_func, NULL);
735 static void __check_audio_format()
737 vce_audio_type_e type;
741 int ret = vcd_engine_get_audio_format(VCE_AUDIO_ID_NONE, &type, &rate, &channel);
743 SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get audio format : %d", ret);
747 if (false == g_is_valid_audio_in) {
748 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Audio-in is NOT valid");
752 if (g_audio_type != type || g_audio_rate != rate || g_audio_channel != channel) {
753 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] New audio type(%d) rate(%d) channel(%d)", type, rate, channel);
754 audio_in_destroy(g_audio_h);
756 audio_channel_e audio_ch;
757 audio_sample_type_e audio_type;
760 case 1: audio_ch = AUDIO_CHANNEL_MONO; break;
761 case 2: audio_ch = AUDIO_CHANNEL_STEREO; break;
763 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Input channel is not supported");
769 case VCE_AUDIO_TYPE_PCM_S16_LE: audio_type = AUDIO_SAMPLE_TYPE_S16_LE; break;
770 case VCE_AUDIO_TYPE_PCM_U8: audio_type = AUDIO_SAMPLE_TYPE_U8; break;
772 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Invalid Audio Type");
777 ret = audio_in_create(rate, audio_ch, audio_type, &g_audio_h);
778 if (AUDIO_IO_ERROR_NONE != ret) {
779 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to create audio handle : %d", ret);
780 g_is_valid_audio_in = false;
784 if (0 != audio_in_set_sound_stream_info(g_audio_h, g_stream_info_h)) {
785 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to set stream info");
790 g_audio_channel = channel;
792 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] audio type(%d) rate(%d) channel(%d)", g_audio_type, g_audio_rate, g_audio_channel);
798 int vcd_recorder_start()
803 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Enter, recorder state(%d)", g_recorder_state);
805 if (VCD_RECORDER_STATE_RECORDING == g_recorder_state) return 0;
807 bool started = false;
808 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] audio type : %s", g_current_audio_type);
810 if (NULL != g_current_audio_type) {
811 if (0 == strncmp(VCE_AUDIO_ID_BLUETOOTH, g_current_audio_type, strlen(VCE_AUDIO_ID_BLUETOOTH))) {
813 const unsigned char input_data[2] = {SMART_CONTROL_START_CMD, 0x00};
815 while (5 > bt_retry) {
816 ret = bt_hid_send_rc_command(NULL, input_data, sizeof(input_data));
817 if (BT_ERROR_NONE == ret) {
818 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Start bt audio recorder");
821 } else if (BT_ERROR_NOW_IN_PROGRESS == ret) {
822 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail bt_hid_send_rc_command : %d", ret);
829 if (false == started) {
830 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to start bt audio");
831 return VCD_ERROR_OPERATION_FAILED;
834 g_bt_extend_count = 0;
836 } else if (0 == strncmp(VCE_AUDIO_ID_WIFI, g_current_audio_type, strlen(VCE_AUDIO_ID_WIFI))) {
837 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] call RegisterMSFAudioCallback() function");
838 #ifdef TV_MSF_WIFI_MODE
840 ret = RegisterMSFAudioCallback(__msf_wifi_audio_data_receive_cb, NULL);
841 SLOG(LOG_ERROR, TAG_VCD, "[Recorder] ret = %d", ret);
842 if (MSFResult_OK == ret) {
845 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to start Wi-Fi audio");
846 return VCD_ERROR_OPERATION_FAILED;
852 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] started = %d", started);
853 if (false == started) {
854 /* check audio format */
855 __check_audio_format();
857 ret = sound_manager_acquire_focus(g_stream_info_h, SOUND_STREAM_FOCUS_FOR_RECORDING, NULL);
858 if (SOUND_MANAGER_ERROR_NONE != ret) {
859 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to acquire focus : %d", ret);
861 ret = audio_in_set_sound_stream_info(g_audio_h, g_stream_info_h);
862 if (AUDIO_IO_ERROR_NONE != ret) {
863 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to set stream info : %d", ret);
868 ret = audio_in_prepare(g_audio_h);
869 if (AUDIO_IO_ERROR_NONE != ret) {
870 if (AUDIO_IO_ERROR_SOUND_POLICY == ret) {
871 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Audio is busy.");
872 return VCD_ERROR_RECORDER_BUSY;
874 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to start audio : %d", ret);
876 return VCD_ERROR_OPERATION_FAILED;
879 /* Add ecore timer to read audio data */
880 ecore_main_loop_thread_safe_call_async(__timer_read_normal_func, NULL);
881 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Start audio in recorder");
884 g_recorder_state = VCD_RECORDER_STATE_RECORDING;
887 char normal_file_name[128] = {'\0',};
891 snprintf(normal_file_name, sizeof(normal_file_name), "/tmp/vc_normal_%d_%d", getpid(), g_count);
892 ret = access(normal_file_name, 0);
895 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] File is already exist");
896 if (0 == remove(normal_file_name)) {
897 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Remove file");
907 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] File normal name : %s", normal_file_name);
910 g_normal_file = fopen(normal_file_name, "wb+x");
911 if (!g_normal_file) {
912 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] File not found!");
918 int vcd_recorder_stop()
922 if (VCD_RECORDER_STATE_READY == g_recorder_state)
925 g_recorder_state = VCD_RECORDER_STATE_READY;
928 fclose(g_normal_file);
933 if (NULL != g_current_audio_type) {
934 if (0 == strncmp(VCE_AUDIO_ID_BLUETOOTH, g_current_audio_type, strlen(VCE_AUDIO_ID_BLUETOOTH))) {
937 while (5 > bt_retry) {
938 ret = bt_hid_rc_stop_sending_voice(NULL);
939 if (BT_ERROR_NONE == ret) {
940 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Stop bt audio recorder");
943 } else if (BT_ERROR_NOW_IN_PROGRESS == ret) {
944 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail bt_hid_rc_stop_sending_voice()");
951 if (NULL != g_current_audio_type &&
952 (!strncmp(g_current_audio_type, VCE_AUDIO_ID_BLUETOOTH, sizeof(VCE_AUDIO_ID_BLUETOOTH)) ||
953 !strncmp(g_current_audio_type, VCE_AUDIO_ID_WIFI, sizeof(VCE_AUDIO_ID_WIFI)))) {
954 SLOG(LOG_DEBUG, TAG_VCD, "[DEBUG] Recorder reset to NONE");
955 vcd_recorder_set(VCE_AUDIO_ID_NONE, g_audio_type, g_audio_rate, g_audio_channel);
958 if (false == stoped) {
959 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to stop bt audio");
960 return VCD_ERROR_OPERATION_FAILED;
963 } else if (0 == strncmp(VCE_AUDIO_ID_WIFI, g_current_audio_type, strlen(VCE_AUDIO_ID_WIFI))) {
964 #ifdef TV_MSF_WIFI_MODE
965 UnRegisterMSFAudioCallback();
966 if (NULL != g_current_audio_type &&
967 (!strncmp(g_current_audio_type, VCE_AUDIO_ID_BLUETOOTH, sizeof(VCE_AUDIO_ID_BLUETOOTH)) ||
968 !strncmp(g_current_audio_type, VCE_AUDIO_ID_WIFI, sizeof(VCE_AUDIO_ID_WIFI)))) {
969 SLOG(LOG_DEBUG, TAG_VCD, "[DEBUG] Recorder reset to NONE");
970 vcd_recorder_set(VCE_AUDIO_ID_NONE, g_audio_type, g_audio_rate, g_audio_channel);
975 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] current audio type is NONE");
979 if (false == stoped) {
980 ret = audio_in_unprepare(g_audio_h);
981 if (AUDIO_IO_ERROR_NONE != ret) {
982 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to stop audio : %d", ret);
983 return VCD_ERROR_OPERATION_FAILED;
987 ret = sound_manager_release_focus(g_stream_info_h, SOUND_STREAM_FOCUS_FOR_RECORDING, NULL);
988 if (SOUND_MANAGER_ERROR_NONE != ret) {
989 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to release focus : %d", ret);
997 int vcd_recorder_get_state()
999 return g_recorder_state;