#include <audio_io.h>
#include <math.h>
#include <sound_manager.h>
+#include <sound_manager_internal.h>
#ifdef TV_PRODUCT
#ifdef TV_BT_MODE
#include <bluetooth_product.h>
#define FRAME_LENGTH 160
#define BUFFER_LENGTH FRAME_LENGTH * 2
+#define FOCUS_SERVER_READY "/tmp/.focus_server_ready"
+
#define VCP_AUDIO_ID_NONE "VC_AUDIO_ID_NONE" /**< None audio id */
static vcd_recorder_state_e g_recorder_state = VCD_RECORDER_STATE_READY;
static audio_in_h g_audio_h;
-#if 0
+#if 1
static sound_stream_info_h g_stream_info_h;
#endif
static vcp_audio_type_e g_audio_type;
-static unsigned int g_audio_rate;
+static int g_audio_rate;
static int g_audio_channel;
if (0 != strncmp(g_current_audio_type, VCP_AUDIO_ID_MSF, sizeof(VCP_AUDIO_ID_MSF))) {
vcd_state_e state = vcd_config_get_service_state();
if (VCD_STATE_READY == state) {
- vcd_engine_set_audio_type(VCP_AUDIO_ID_MSF);
vcd_recorder_set(VCP_AUDIO_ID_MSF, VCP_AUDIO_TYPE_PCM_S16_LE, 16000, 1);
} else {
SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] current audio type is (%s)", g_current_audio_type);
if (VCD_RECORDER_STATE_RECORDING != g_recorder_state) {
SLOG(LOG_WARN, TAG_VCD, "[Recorder] Not start yet, but send audio data vi MSF");
+ vcd_recorder_start();
}
if (NULL != g_audio_cb) {
if (0 != strncmp(g_current_audio_type, VCP_AUDIO_ID_BLUETOOTH, sizeof(VCP_AUDIO_ID_BLUETOOTH))) {
vcd_state_e state = vcd_config_get_service_state();
if (VCD_STATE_READY == state) {
- vcd_engine_set_audio_type(VCP_AUDIO_ID_BLUETOOTH);
vcd_recorder_set(VCP_AUDIO_ID_BLUETOOTH, VCP_AUDIO_TYPE_PCM_S16_LE, 16000, 1);
} else {
SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] current audio type is (%s)", g_current_audio_type);
if (VCD_RECORDER_STATE_RECORDING != g_recorder_state) {
SLOG(LOG_WARN, TAG_VCD, "[Recorder] Not start yet, but send audio data vi Bluetooth");
+ vcd_recorder_start();
}
if (NULL != g_audio_cb) {
#endif
-#if 0
+#if 1
static const char* __get_focus_changed_reason_code(sound_stream_focus_change_reason_e reason)
{
switch (reason) {
}
}
-static 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)
+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,
+ sound_stream_focus_change_reason_e reason, int sound_behavior, const char *extra_info, void *user_data)
{
SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Focus state changed cb");
return;
}
- int ret;
- sound_stream_focus_state_e state_for_recording;
- ret = sound_manager_get_focus_state(g_stream_info_h, NULL, &state_for_recording);
- if (SOUND_MANAGER_ERROR_NONE != ret) {
- SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to get focus state");
- return;
- }
-
- SLOG(LOG_WARN, TAG_VCD, "[Recorder] focus state chagned to (%d) with reason (%s)", (int)state_for_recording, __get_focus_changed_reason_code(reason));
+ SLOG(LOG_WARN, TAG_VCD, "[Recorder] focus state chagned to (%d) with reason (%s)", (int)focus_state, __get_focus_changed_reason_code(reason));
- if (VCD_RECORDER_STATE_RECORDING == g_recorder_state && SOUND_STREAM_FOCUS_STATE_RELEASED == state_for_recording) {
+ if (VCD_RECORDER_STATE_RECORDING == g_recorder_state && SOUND_STREAM_FOCUS_STATE_RELEASED == focus_state) {
SLOG(LOG_WARN, TAG_VCD, "[Recorder] Focus released as interrupt");
if (NULL != g_interrupt_cb) {
g_interrupt_cb();
}
#endif
+static int __apply_device_for_stream_routing()
+{
+ sound_device_list_h device_list = NULL;
+ sound_device_h device = NULL;
+ sound_device_type_e type;
+ sound_device_io_direction_e io_direction;
+
+ if (0 != sound_manager_get_current_device_list(SOUND_DEVICE_IO_DIRECTION_IN_MASK, &device_list)) {
+ SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to get current device list");
+ return -1;
+ }
+
+ int ret = 0;
+ while (0 == (ret = sound_manager_get_next_device(device_list, &device))) {
+ if (0 != sound_manager_get_device_type(device, &type)) {
+ SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to get device tyep");
+ continue;
+ }
+ if (0 != sound_manager_get_device_io_direction(device, &io_direction)) {
+ SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to get device io direction");
+ continue;
+ }
+ if (SOUND_DEVICE_USB_AUDIO == type && SOUND_DEVICE_IO_DIRECTION_IN == io_direction) {
+ if (0 != sound_manager_add_device_for_stream_routing(g_stream_info_h, device)) {
+ SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to add device");
+ continue;
+ }
+ if (0 != sound_manager_apply_stream_routing(g_stream_info_h)) {
+ SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR} Fail to apply stream routing");
+ continue;
+ }
+ SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Apply device for stream routing");
+ return 0;
+ }
+ }
+
+ SLOG(LOG_WARN, TAG_VCD, "[Recorder] No device");
+ return -1;
+}
+
int vcd_recorder_create(vcd_recoder_audio_cb audio_cb, vcd_recorder_interrupt_cb interrupt_cb)
{
if (NULL == audio_cb || NULL == interrupt_cb) {
return VCD_ERROR_INVALID_PARAMETER;
}
+ /* check focus server */
+ int cnt = 0;
+ while (1) {
+ if (0 == access(FOCUS_SERVER_READY, F_OK)) {
+ SLOG(LOG_ERROR, TAG_VCD, "[Recorder SUCCESS] focus server is available");
+ break;
+ } else {
+ if (0 == cnt++ % 10)
+ SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] focus server is not available");
+ usleep(50000);
+ }
+ }
+
int ret = 0;
/* set init value */
audio_channel_e audio_ch;
audio_sample_type_e audio_type;
+ SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] AUdio type(%d) rate(%d) channel(%d)", g_audio_type, g_audio_rate, g_audio_channel);
+
switch (g_audio_channel) {
case 1: audio_ch = AUDIO_CHANNEL_MONO; break;
case 2: audio_ch = AUDIO_CHANNEL_STEREO; break;
g_is_valid_audio_in = false;
}
-#if 0
- if (0 != sound_manager_create_stream_information(SOUND_STREAM_TYPE_VOICE_RECOGNITION, __recorder_focus_state_cb, NULL, &g_stream_info_h)) {
+#if 1
+ if (0 != sound_manager_create_stream_information_internal(SOUND_STREAM_TYPE_VOICE_RECOGNITION_SERVICE, __recorder_focus_state_cb, NULL, &g_stream_info_h)) {
SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to create stream info");
+ } else {
+ __apply_device_for_stream_routing();
+ }
+
+ if (0 != audio_in_set_sound_stream_info(g_audio_h, g_stream_info_h)) {
+ SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to set stream info");
}
#endif
}
#endif
/* Select default audio type */
- if (true == g_is_valid_bt_in) {
- g_current_audio_type = strdup(VCP_AUDIO_ID_BLUETOOTH);
- } else {
+ if (true == g_is_valid_audio_in) {
g_current_audio_type = strdup(VCP_AUDIO_ID_NONE);
+ } else {
+ if (true == g_is_valid_bt_in) {
+ g_current_audio_type = strdup(VCP_AUDIO_ID_BLUETOOTH);
+ } else {
+ SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] No valid audio");
+ return -1;
+ }
}
SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Audio type : %s", g_current_audio_type);
}
}
+ SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] set audio type (%s)", audio_type);
+ vcd_engine_set_audio_type(audio_type);
+
if (VCD_RECORDER_STATE_READY != g_recorder_state) {
- SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Recorder is NOT ready");
- return VCD_ERROR_INVALID_STATE;
+ if ((!strncmp(g_current_audio_type, VCP_AUDIO_ID_NONE, strlen(g_current_audio_type)) &&
+ strncmp(audio_type, VCP_AUDIO_ID_BLUETOOTH, strlen(audio_type)) &&
+ strncmp(audio_type, VCP_AUDIO_ID_MSF, strlen(audio_type))) ||
+ (strncmp(g_current_audio_type, VCP_AUDIO_ID_BLUETOOTH, strlen(g_current_audio_type)) &&
+ strncmp(g_current_audio_type, VCP_AUDIO_ID_MSF, strlen(g_current_audio_type)) &&
+ strncmp(g_current_audio_type, VCP_AUDIO_ID_NONE, strlen(g_current_audio_type)) &&
+ !strncmp(audio_type, VCP_AUDIO_ID_NONE, strlen(audio_type)))) {
+ SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Skip stop recording while Recorder is NOT ready");
+ } else {
+ SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Recorder is NOT ready");
+ vcd_recorder_stop();
+ //return VCD_ERROR_INVALID_STATE;
+ }
}
int ret = -1;
}
if (g_audio_type != type || g_audio_rate != rate || g_audio_channel != channel) {
+ SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] New audio type(%d) rate(%d) channel(%d)", type, rate, channel);
audio_in_destroy(g_audio_h);
audio_channel_e audio_ch;
return VCD_ERROR_OPERATION_FAILED;
}
+ if (0 != audio_in_set_sound_stream_info(g_audio_h, g_stream_info_h)) {
+ SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to set stream info");
+ }
+
g_audio_type = type;
g_audio_rate = rate;
g_audio_channel = channel;
return EINA_TRUE;
}
+static void __check_audio_format()
+{
+ vcp_audio_type_e type;
+ int rate;
+ int channel;
+
+ int ret = vcd_engine_get_audio_format(VCP_AUDIO_ID_NONE, &type, &rate, &channel);
+ if (0 != ret) {
+ SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get audio format : %d", ret);
+ return;
+ }
+
+ if (false == g_is_valid_audio_in) {
+ SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Audio-in is NOT valid");
+ return;
+ }
+
+ if (g_audio_type != type || g_audio_rate != rate || g_audio_channel != channel) {
+ SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] New audio type(%d) rate(%d) channel(%d)", type, rate, channel);
+ audio_in_destroy(g_audio_h);
+
+ audio_channel_e audio_ch;
+ audio_sample_type_e audio_type;
+
+ switch (channel) {
+ case 1: audio_ch = AUDIO_CHANNEL_MONO; break;
+ case 2: audio_ch = AUDIO_CHANNEL_STEREO; break;
+ default:
+ SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Input channel is not supported");
+ return;
+ break;
+ }
+
+ switch (type) {
+ case VCP_AUDIO_TYPE_PCM_S16_LE: audio_type = AUDIO_SAMPLE_TYPE_S16_LE; break;
+ case VCP_AUDIO_TYPE_PCM_U8: audio_type = AUDIO_SAMPLE_TYPE_U8; break;
+ default:
+ SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Invalid Audio Type");
+ return;
+ break;
+ }
+
+ ret = audio_in_create(rate, audio_ch, audio_type, &g_audio_h);
+ if (AUDIO_IO_ERROR_NONE != ret) {
+ SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to create audio handle : %d", ret);
+ g_is_valid_audio_in = false;
+ return;
+ }
+
+ if (0 != audio_in_set_sound_stream_info(g_audio_h, g_stream_info_h)) {
+ SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to set stream info");
+ }
+
+ g_audio_type = type;
+ g_audio_rate = rate;
+ g_audio_channel = channel;
+ } else {
+ SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] audio type(%d) rate(%d) channel(%d)", g_audio_type, g_audio_rate, g_audio_channel);
+ }
+}
+
+
+
int vcd_recorder_start()
{
int ret = -1;
SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] started = %d", started);
if (false == started) {
+ /* check audio format */
+ __check_audio_format();
#if 0
ret = sound_manager_acquire_focus(g_stream_info_h, SOUND_STREAM_FOCUS_FOR_RECORDING, NULL);
if (SOUND_MANAGER_ERROR_NONE != ret) {
break;
}
}
+ if (NULL != g_current_audio_type &&
+ (!strncmp(g_current_audio_type, VCP_AUDIO_ID_BLUETOOTH, sizeof(VCP_AUDIO_ID_BLUETOOTH)) ||
+ !strncmp(g_current_audio_type, VCP_AUDIO_ID_MSF, sizeof(VCP_AUDIO_ID_MSF)))) {
+ SLOG(LOG_DEBUG, TAG_VCD, "[DEBUG] Recorder reset to NONE");
+ vcd_recorder_set(VCP_AUDIO_ID_NONE, g_audio_type, g_audio_rate, g_audio_channel);
+ }
+
if (false == stoped) {
SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to stop bt audio");
return VCD_ERROR_OPERATION_FAILED;
} else if (0 == strncmp(VCP_AUDIO_ID_MSF, g_current_audio_type, strlen(VCP_AUDIO_ID_MSF))) {
#ifdef TV_MSF_WIFI_MODE
UnRegisterMSFAudioCallback();
+ if (NULL != g_current_audio_type &&
+ (!strncmp(g_current_audio_type, VCP_AUDIO_ID_BLUETOOTH, sizeof(VCP_AUDIO_ID_BLUETOOTH)) ||
+ !strncmp(g_current_audio_type, VCP_AUDIO_ID_MSF, sizeof(VCP_AUDIO_ID_MSF)))) {
+ SLOG(LOG_DEBUG, TAG_VCD, "[DEBUG] Recorder reset to NONE");
+ vcd_recorder_set(VCP_AUDIO_ID_NONE, g_audio_type, g_audio_rate, g_audio_channel);
+ }
stoped = true;
#endif
+ } else {
+ SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] current audio type is NONE");
}
}
#endif
}
- if (NULL != g_current_audio_type && 0 != strncmp(g_current_audio_type, VCP_AUDIO_ID_NONE, sizeof(VCP_AUDIO_ID_NONE))) {
- vcd_recorder_set(VCP_AUDIO_ID_NONE, VCP_AUDIO_TYPE_PCM_S16_LE, 16000, 1);
- vcd_engine_set_audio_type(VCP_AUDIO_ID_NONE);
- }
-
return 0;
}