2 * Copyright (c) 2011-2015 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>
27 #include <bluetooth.h>
29 #ifdef TV_MSF_WIFI_MODE
30 #include <MSFVoiceInterface.h>
34 #include "vcd_client_data.h"
36 #include "vcd_recorder.h"
38 #include "voice_control_plugin_engine.h"
40 #define FRAME_LENGTH 160
41 #define BUFFER_LENGTH FRAME_LENGTH * 2
43 #define VCP_AUDIO_ID_NONE "VC_AUDIO_ID_NONE" /**< None audio id */
45 static vcd_recorder_state_e g_recorder_state = VCD_RECORDER_STATE_READY;
47 static vcd_recoder_audio_cb g_audio_cb = NULL;
49 static vcd_recorder_interrupt_cb g_interrupt_cb = NULL;
51 static audio_in_h g_audio_h;
53 static vcp_audio_type_e g_audio_type;
55 static unsigned int g_audio_rate;
57 static int g_audio_channel;
59 static char g_normal_buffer[BUFFER_LENGTH + 10];
61 static bool g_is_valid_audio_in = false;
63 static bool g_is_valid_bt_in = false;
65 static char* g_current_audio_type = NULL;
67 static int g_buffer_count;
75 static FILE* g_normal_file;
77 static int g_count = 1;
80 static float get_volume_decibel(char* data, int size);
82 #ifdef TV_MSF_WIFI_MODE
83 static void __msf_wifi_audio_data_receive_cb(msf_wifi_voice_data_s *voice_data, void* user_data)
85 if (VCD_RECORDER_STATE_RECORDING != g_recorder_state) {
86 /*SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Exit audio reading normal func");*/
90 if (NULL != g_audio_cb) {
91 if (0 != g_audio_cb((void*)voice_data->audio_buf, (unsigned int)voice_data->length)) {
92 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to read audio");
98 if (0 == g_buffer_count % 30) {
99 float vol_db = get_volume_decibel((char*)voice_data->audio_buf, (unsigned int)voice_data->length);
100 if (0 != vcdc_send_set_volume(vcd_client_manager_get_pid(), vol_db)) {
101 SLOG(LOG_ERROR, TAG_VCD, "[Recorder] Fail to send recording volume(%f)", vol_db);
105 if (0 == g_buffer_count || 0 == g_buffer_count % 50) {
106 SLOG(LOG_WARN, TAG_VCD, "[Recorder][%d] Recording... : read_size(%d)", g_buffer_count, voice_data->length);
108 if (100000 == g_buffer_count)
115 /* write pcm buffer */
116 fwrite(voice_data->audio_buf, 1, voice_data->length, g_normal_file);
125 static int g_bt_extend_count;
127 #define SMART_CONTROL_EXTEND_CMD 0x03
128 #define SMART_CONTROL_START_CMD 0x04
130 static void _bt_cb_hid_state_changed(int result, bool connected, const char *remote_address, void *user_data)
132 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Bluetooth Event [%d] Received address [%s]", result, remote_address);
136 static void _bt_hid_audio_data_receive_cb(bt_hid_voice_data_s *voice_data, void *user_data)
138 if (VCD_RECORDER_STATE_RECORDING != g_recorder_state) {
139 /*SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Exit audio reading normal func");*/
143 if (NULL != g_audio_cb) {
144 if (0 != g_audio_cb((void*)voice_data->audio_buf, (unsigned int)voice_data->length)) {
145 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to read audio");
151 if (0 == g_buffer_count % 30) {
152 float vol_db = get_volume_decibel((char*)voice_data->audio_buf, (unsigned int)voice_data->length);
153 if (0 != vcdc_send_set_volume(vcd_client_manager_get_pid(), vol_db)) {
154 SLOG(LOG_ERROR, TAG_VCD, "[Recorder] Fail to send recording volume(%f)", vol_db);
158 if (0 == g_buffer_count || 0 == g_buffer_count % 50) {
159 SLOG(LOG_WARN, TAG_VCD, "[Recorder][%d] Recording... : read_size(%d)", g_buffer_count, voice_data->length);
161 if (0 == g_bt_extend_count % 5 && 0 != g_buffer_count) {
162 const unsigned char input_data[2] = {SMART_CONTROL_EXTEND_CMD, 0x10 };
163 if (BT_ERROR_NONE != bt_hid_send_rc_command(NULL, input_data, sizeof(input_data))) {
164 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail bt_hid_send_rc_command(NULL, %s, %d)", input_data, sizeof(input_data));
166 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Extend bt audio recorder");
171 if (100000 == g_buffer_count) {
179 /* write pcm buffer */
180 fwrite(voice_data->audio_buf, 1, voice_data->length, g_normal_file);
187 int vcd_recorder_create(vcd_recoder_audio_cb audio_cb, vcd_recorder_interrupt_cb interrupt_cb)
189 if (NULL == audio_cb || NULL == interrupt_cb) {
190 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Input param is NOT valid");
191 return VCD_ERROR_INVALID_PARAMETER;
197 g_is_valid_audio_in = false;
198 g_is_valid_bt_in = false;
199 g_current_audio_type = NULL;
201 g_audio_type = VCP_AUDIO_TYPE_PCM_S16_LE;
202 g_audio_rate = 16000;
205 audio_channel_e audio_ch;
206 audio_sample_type_e audio_type;
208 switch (g_audio_channel) {
209 case 1: audio_ch = AUDIO_CHANNEL_MONO; break;
210 case 2: audio_ch = AUDIO_CHANNEL_STEREO; break;
212 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Input channel is not supported");
213 return VCD_ERROR_OPERATION_FAILED;
217 switch (g_audio_type) {
218 case VCP_AUDIO_TYPE_PCM_S16_LE: audio_type = AUDIO_SAMPLE_TYPE_S16_LE; break;
219 case VCP_AUDIO_TYPE_PCM_U8: audio_type = AUDIO_SAMPLE_TYPE_U8; break;
221 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Invalid Audio Type");
222 return VCD_ERROR_OPERATION_FAILED;
226 ret = audio_in_create(g_audio_rate, audio_ch, audio_type, &g_audio_h);
227 if (AUDIO_IO_ERROR_NONE == ret) {
228 g_is_valid_audio_in = true;
230 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Rate(%d) Channel(%d) Type(%d)", g_audio_rate, audio_ch, audio_type);
231 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to create audio handle : %d", ret);
232 g_is_valid_audio_in = false;
235 g_audio_cb = audio_cb;
236 g_interrupt_cb = interrupt_cb;
237 g_recorder_state = VCD_RECORDER_STATE_READY;
241 bool is_bt_failed = false;
243 if (false == is_bt_failed && BT_ERROR_NONE != bt_initialize()) {
244 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to init bt");
248 if (false == is_bt_failed && BT_ERROR_NONE != bt_hid_host_initialize(_bt_cb_hid_state_changed, NULL)) {
249 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail bt_hid_host_initialize()");
253 if (false == is_bt_failed && BT_ERROR_NONE != bt_hid_set_audio_data_receive_cb(_bt_hid_audio_data_receive_cb, NULL)) {
254 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail bt_hid_set_audio_data_receive_cb()");
259 if (false == is_bt_failed) {
260 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Bluetooth is available");
261 g_is_valid_bt_in = true;
264 /* Select default audio type */
265 if (true == g_is_valid_bt_in) {
266 g_current_audio_type = strdup(VCP_AUDIO_ID_BLUETOOTH);
268 g_current_audio_type = strdup(VCP_AUDIO_ID_NONE);
271 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Audio type : %s", g_current_audio_type);
276 int vcd_recorder_destroy()
278 if (VCD_RECORDER_STATE_RECORDING == g_recorder_state) {
279 if (0 == strncmp(VCP_AUDIO_ID_BLUETOOTH, g_current_audio_type, strlen(VCP_AUDIO_ID_BLUETOOTH))) {
281 bt_hid_unset_audio_data_receive_cb();
283 } else if (0 == strncmp(VCP_AUDIO_ID_MSF, g_current_audio_type, strlen(VCP_AUDIO_ID_MSF))) {
284 #ifdef TV_MSF_WIFI_MODE
285 UnRegisterMSFAudioCallback();
288 audio_in_unprepare(g_audio_h);
290 g_recorder_state = VCD_RECORDER_STATE_READY;
293 audio_in_destroy(g_audio_h);
296 bt_hid_unset_audio_data_receive_cb();
298 bt_hid_host_deinitialize();
305 if (NULL != g_current_audio_type) {
306 free(g_current_audio_type);
307 g_current_audio_type = NULL;
313 int vcd_recorder_set(const char* audio_type, vcp_audio_type_e type, int rate, int channel)
315 if (NULL == audio_type) {
316 return VCD_ERROR_INVALID_PARAMETER;
319 if (NULL != g_current_audio_type) {
320 if (0 == strncmp(g_current_audio_type, audio_type, strlen(g_current_audio_type))) {
321 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Current audio type is already set : %s", audio_type);
326 if (VCD_RECORDER_STATE_READY != g_recorder_state) {
327 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Recorder is NOT ready");
328 return VCD_ERROR_INVALID_STATE;
333 if (0 == strncmp(VCP_AUDIO_ID_BLUETOOTH, audio_type, strlen(VCP_AUDIO_ID_BLUETOOTH))) {
334 if (false == g_is_valid_bt_in) {
335 SLOG(LOG_ERROR, TAG_VCD, "[Recorder] BT audio is NOT valid");
336 return VCD_ERROR_OPERATION_REJECTED;
339 if (NULL != g_current_audio_type) {
340 free(g_current_audio_type);
341 g_current_audio_type = NULL;
344 g_current_audio_type = strdup(audio_type);
345 } else if (0 == strncmp(VCP_AUDIO_ID_MSF, audio_type, strlen(VCP_AUDIO_ID_MSF))) {
346 if (NULL != g_current_audio_type) {
347 free(g_current_audio_type);
348 g_current_audio_type = NULL;
351 g_current_audio_type = strdup(audio_type);
353 if (false == g_is_valid_audio_in) {
354 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Audio-in is NOT valid");
355 return VCD_ERROR_OPERATION_REJECTED;
358 if (g_audio_type != type || g_audio_rate != rate || g_audio_channel != channel) {
359 audio_in_destroy(g_audio_h);
361 audio_channel_e audio_ch;
362 audio_sample_type_e audio_type;
365 case 1: audio_ch = AUDIO_CHANNEL_MONO; break;
366 case 2: audio_ch = AUDIO_CHANNEL_STEREO; break;
368 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Input channel is not supported");
369 return VCD_ERROR_OPERATION_FAILED;
374 case VCP_AUDIO_TYPE_PCM_S16_LE: audio_type = AUDIO_SAMPLE_TYPE_S16_LE; break;
375 case VCP_AUDIO_TYPE_PCM_U8: audio_type = AUDIO_SAMPLE_TYPE_U8; break;
377 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Invalid Audio Type");
378 return VCD_ERROR_OPERATION_FAILED;
382 ret = audio_in_create(rate, audio_ch, audio_type, &g_audio_h);
383 if (AUDIO_IO_ERROR_NONE != ret) {
384 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to create audio handle : %d", ret);
385 g_is_valid_audio_in = false;
386 return VCD_ERROR_OPERATION_FAILED;
391 g_audio_channel = channel;
395 if (NULL != g_current_audio_type) {
396 free(g_current_audio_type);
397 g_current_audio_type = NULL;
400 g_current_audio_type = strdup(audio_type);
404 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Current audio type is changed : %s", g_current_audio_type);
409 int vcd_recorder_get(char** audio_type)
411 if (NULL == audio_type) {
412 return VCD_ERROR_INVALID_PARAMETER;
415 if (NULL != g_current_audio_type) {
416 *audio_type = strdup(g_current_audio_type);
418 SLOG(LOG_WARN, TAG_VCD, "[Recorder] Current audio type is NOT ready", audio_type);
425 static float get_volume_decibel(char* data, int size)
427 #define MAX_AMPLITUDE_MEAN_16 32768
434 unsigned long long square_sum = 0;
439 for (i = 0; i < size; i += (depthByte<<1)) {
441 memcpy(&pcm16, data + i, sizeof(short));
442 square_sum += pcm16 * pcm16;
449 rms = sqrt(square_sum/count);
451 db = 20 * log10(rms/MAX_AMPLITUDE_MEAN_16);
455 Eina_Bool __read_normal_func(void *data)
459 if (VCD_RECORDER_STATE_RECORDING != g_recorder_state) {
460 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Exit audio reading normal func");
464 memset(g_normal_buffer, '\0', BUFFER_LENGTH + 10);
466 ret = audio_in_read(g_audio_h, g_normal_buffer, BUFFER_LENGTH);
468 SLOG(LOG_WARN, TAG_VCD, "[Recorder WARNING] Fail to read audio : %d", ret);
469 g_recorder_state = VCD_RECORDER_STATE_READY;
473 if (NULL != g_audio_cb) {
474 if (0 != g_audio_cb(g_normal_buffer, BUFFER_LENGTH)) {
475 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to read audio : %d", ret);
482 if (0 == g_buffer_count % 30) {
483 float vol_db = get_volume_decibel(g_normal_buffer, BUFFER_LENGTH);
484 if (0 != vcdc_send_set_volume(vcd_client_manager_get_pid(), vol_db)) {
485 SLOG(LOG_ERROR, TAG_VCD, "[Recorder] Fail to send recording volume(%f)", vol_db);
489 if (0 == g_buffer_count || 0 == g_buffer_count % 50) {
490 SLOG(LOG_WARN, TAG_VCD, "[Recorder][%d] Recording... : read_size(%d)", g_buffer_count, ret);
492 if (100000 == g_buffer_count) {
500 /* write pcm buffer */
501 fwrite(g_normal_buffer, 1, BUFFER_LENGTH, g_normal_file);
507 int vcd_recorder_start()
512 SLOG(LOG_ERROR, TAG_VCD, "[Recorder] Enter, recorder state(%d)", g_recorder_state);
514 if (VCD_RECORDER_STATE_RECORDING == g_recorder_state) return 0;
516 bool started = false;
517 SLOG(LOG_ERROR, TAG_VCD, "[Recorder] audio type : %s", g_current_audio_type);
519 if (NULL != g_current_audio_type) {
520 if (0 == strncmp(VCP_AUDIO_ID_BLUETOOTH, g_current_audio_type, strlen(VCP_AUDIO_ID_BLUETOOTH))) {
522 const unsigned char input_data[2] = {SMART_CONTROL_START_CMD, 0x00};
524 while (5 > bt_retry) {
525 ret = bt_hid_send_rc_command(NULL, input_data, sizeof(input_data));
526 if (BT_ERROR_NONE == ret) {
527 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Start bt audio recorder");
530 } else if (BT_ERROR_NOW_IN_PROGRESS == ret) {
531 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail bt_hid_send_rc_command(NULL, %s, %d) : %d", input_data, sizeof(input_data), ret);
538 if (false == started) {
539 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to start bt audio");
540 return VCD_ERROR_OPERATION_FAILED;
543 g_bt_extend_count = 0;
545 } else if (0 == strncmp(VCP_AUDIO_ID_MSF, g_current_audio_type, strlen(VCP_AUDIO_ID_MSF))) {
546 SLOG(LOG_ERROR, TAG_VCD, "[Recorder] call RegisterMSFAudioCallback() function");
547 #ifdef TV_MSF_WIFI_MODE
549 ret = RegisterMSFAudioCallback(__msf_wifi_audio_data_receive_cb, NULL);
550 SLOG(LOG_ERROR, TAG_VCD, "[Recorder] ret = %d", ret);
551 if (MSFResult_OK == ret) {
554 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to start MSF(wifi) audio");
555 return VCD_ERROR_OPERATION_FAILED;
561 SLOG(LOG_ERROR, TAG_VCD, "[Recorder] started = %d", started);
562 if (false == started) {
563 ret = audio_in_prepare(g_audio_h);
564 if (AUDIO_IO_ERROR_NONE != ret) {
565 if (AUDIO_IO_ERROR_SOUND_POLICY == ret) {
566 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Audio is busy.");
567 return VCD_ERROR_RECORDER_BUSY;
569 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to start audio : %d", ret);
571 return VCD_ERROR_OPERATION_FAILED;
574 /* Add ecore timer to read audio data */
575 ecore_timer_add(0, __read_normal_func, NULL);
576 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Start audio in recorder");
579 g_recorder_state = VCD_RECORDER_STATE_RECORDING;
582 char normal_file_name[128] = {'\0',};
585 snprintf(normal_file_name, sizeof(normal_file_name), "/tmp/vc_normal_%d_%d", getpid(), g_count);
586 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] File normal name : %s", normal_file_name);
589 g_normal_file = fopen(normal_file_name, "wb+");
590 if (!g_normal_file) {
591 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] File not found!");
597 int vcd_recorder_stop()
601 if (VCD_RECORDER_STATE_READY == g_recorder_state)
604 g_recorder_state = VCD_RECORDER_STATE_READY;
607 fclose(g_normal_file);
612 if (NULL != g_current_audio_type) {
613 if (0 == strncmp(VCP_AUDIO_ID_BLUETOOTH, g_current_audio_type, strlen(VCP_AUDIO_ID_BLUETOOTH))) {
616 while (5 > bt_retry) {
617 ret = bt_hid_rc_stop_sending_voice(NULL);
618 if (BT_ERROR_NONE == ret) {
619 SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Stop bt audio recorder");
622 } else if (BT_ERROR_NOW_IN_PROGRESS == ret) {
623 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail bt_hid_rc_stop_sending_voice()");
630 if (false == stoped) {
631 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to stop bt audio");
632 return VCD_ERROR_OPERATION_FAILED;
635 } else if (0 == strncmp(VCP_AUDIO_ID_MSF, g_current_audio_type, strlen(VCP_AUDIO_ID_MSF))) {
636 #ifdef TV_MSF_WIFI_MODE
637 UnRegisterMSFAudioCallback();
643 if (false == stoped) {
644 ret = audio_in_unprepare(g_audio_h);
645 if (AUDIO_IO_ERROR_NONE != ret) {
646 SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to stop audio : %d", ret);
647 return VCD_ERROR_OPERATION_FAILED;
653 int vcd_recorder_get_state()
655 return g_recorder_state;