| #include "AudioParamParser.h" |
| #include "AudioParamParserPriv.h" |
| #include "xml_parser_def.h" |
| #include "default_para.h" |
| #include "speech_drv.h" |
| #include "modem_afe_ctrl.h" |
| #include "audio_ctrl_service_inner_api.h" |
| |
| #include "speech_UT_header.h" |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <unistd.h> |
| #include <limits.h> |
| #include <pthread.h> |
| #include <sys/types.h> |
| #include <sys/stat.h> |
| #include <fcntl.h> |
| #include <errno.h> |
| #include <assert.h> |
| |
| #include <syslog.h> |
| #include <samplerate.h> |
| |
| //#define RECORD_USE_UT_SOURCE |
| //#define PLAYBACK_USE_UT_SINK |
| #include <log/log.h> |
| #define ALOGD SLOGD |
| #define ALOGI SLOGI |
| #define ALOGW SLOGW |
| #define ALOGE SLOGE |
| #ifdef LOG_TAG |
| #undef LOG_TAG |
| #endif |
| #define LOG_TAG "audio-ctrl-service" |
| |
| //#define UT_LOG |
| #ifdef UT_LOG |
| #define AUDIO_V_LOG ALOGD |
| #else |
| #define AUDIO_V_LOG |
| #endif |
| |
| #define SPEECH_DRV_RETRY_TIME 3 |
| #define SPEECH_DRV_RETRY_US 20000 //20ms |
| #define SPEECH_DRV_BGS_INTERVAL_US 20000 //20ms |
| |
| #define MAX_REC_BUF_SIZE 3200//16000Hz 16bytes 100ms |
| #define MD_PCM_RECORD_HEADER_SYNC 0x1234 |
| |
| char *g_record_buf; |
| int g_want_to_speech_off_after_record_off; |
| |
| int g_record_buf_size; |
| int g_record_read_virt_idx; |
| int g_record_write_virt_idx; |
| int g_record_virt_boundry; |
| |
| int g_is_bgs_on; |
| |
| /* SRC for inCall record UL*/ |
| |
| #define RECORD_SRC_BUF_SIZE 160 //in frame |
| #define RECORD_DST_BUF_SIZE 320 //in frame |
| #define RECORD_SRC_RATIO 2.0 |
| const int g_converter_type = SRC_SINC_MEDIUM_QUALITY; |
| SRC_DATA g_incall_record_src_data; |
| SRC_STATE *g_incall_record_src_state; |
| float *g_incall_record_src_buffer; |
| float *g_incall_record_dst_buffer; |
| int16_t g_incall_record_dst_int_buffer[RECORD_DST_BUF_SIZE]; |
| |
| pthread_mutex_t g_mutex_record = PTHREAD_MUTEX_INITIALIZER; |
| pthread_mutex_t g_mutex_playback = PTHREAD_MUTEX_INITIALIZER; |
| |
| /* modem pcm record package header*/ |
| typedef struct md_pcm_record_header { |
| uint16_t u16SyncWord; |
| uint16_t u16RawPcmDir; |
| uint16_t u16Freq; |
| uint16_t u16Length; |
| uint16_t u16Channel; |
| uint16_t u16BitFormat; |
| } MD_PCM_RECORD_HEADER; |
| |
| |
| static void parameterChanged(AppHandle *appHandle, const char *audioTypeName); |
| |
| static void *speech_flow_upper_func_operator(void *arg); |
| static void *speech_flow_lower_func_operator(void *arg); |
| static void *speech_flow_dummy_sender(void *arg); |
| |
| static void updateVolume(int xmlType); |
| static void updateDlGain(void); |
| static void updateUlGain(void); |
| |
| const struct xml_param paramVolume[PARAM_NUM] = { |
| { |
| .id = XML_SPEECH_VOLUME, |
| .xml_type_name = "SpeechVol", |
| .update_xml_callback = updateVolume, |
| }, |
| { |
| .id = XML_VOLUME, |
| .xml_type_name = "Volume", |
| .update_xml_callback = updateVolume, |
| }, |
| { |
| .id = XML_GAIN_MAP_DL, |
| .xml_type_name = "VolumeGainMapUL", |
| .update_xml_callback = updateVolume, |
| }, |
| { |
| .id = XML_GAIN_MAP_UL, |
| .xml_type_name = "VolumeGainMap", |
| .update_xml_callback = updateVolume, |
| }, |
| }; |
| #define DL_VOLUME_IDX_MIN 1 |
| #define DL_VOLUME_IDX_MAX 7 |
| |
| static int g_is_speech_on; |
| static int g_current_output_device; |
| |
| static int g_bt_wbs_on = FUNC_SET_BT_WB_default; |
| static int g_bt_client_has_ecnr; |
| static int g_volume_index; |
| static int g_speaker_type; |
| |
| |
| /* IPC variable*/ |
| static pthread_t g_pthread_speech_flow_upper_rcv; |
| static pthread_t g_pthread_speech_flow_lower_rcv; |
| static pthread_t g_pthread_speech_flow_dummy_send; |
| |
| static int g_ipc_upper_rcv_handler; |
| static int g_ipc_upper_send_handler; |
| static int g_ipc_lower_rcv_handler; |
| static int g_ipc_lower_send_handler; |
| |
| |
| int main() { |
| int paramIndex = 0; |
| AppOps *appOps = NULL; |
| AppHandle *appHandle = NULL; |
| struct stat st = {0}; |
| |
| #if !defined(MTK_DUMMY_AUDIO_PARSER) |
| appOps = appOpsGetInstance(); |
| if (appOps == NULL) { |
| ALOGE("%s(), line %d ERROR", __func__, __LINE__); |
| return 1; |
| } else { |
| appHandle = appOps->appHandleGetInstance(); |
| |
| /* Wait for initial done */ |
| usleep(100 * 1000);//100ms |
| |
| /* Set the debug level to warn*/ |
| appOps->appSetDebugLevel(WARN_LEVEL); |
| |
| /* register callback func */ |
| appOps->appHandleRegXmlChangedCb(appHandle, parameterChanged); |
| } |
| #endif |
| if (stat("/tmp/audio_ctrl_service", &st) == -1) { |
| mkdir("/tmp/audio_ctrl_service", 0700); |
| } |
| |
| /* for service init */ |
| mkfifo(ACS_IPC_FOR_UPPER_RCV, 0600); |
| mkfifo(ACS_IPC_FOR_UPPER_SEND, 0600); |
| mkfifo(ACS_IPC_FOR_LOWER_RCV, 0600); |
| mkfifo(ACS_IPC_FOR_LOWER_SEND, 0600); |
| |
| pthread_create(&g_pthread_speech_flow_upper_rcv, NULL, speech_flow_upper_func_operator, NULL); |
| pthread_create(&g_pthread_speech_flow_lower_rcv, NULL, speech_flow_lower_func_operator, NULL); |
| pthread_create(&g_pthread_speech_flow_dummy_send, NULL, speech_flow_dummy_sender, NULL); |
| |
| while (1) { |
| sleep(1000000); |
| } |
| #if !defined(MTK_DUMMY_AUDIO_PARSER) |
| /* Release appHandle resources */ |
| appOps->appHandleUninit(appHandle); |
| #endif |
| |
| return 0; |
| } |
| |
| static void *speech_flow_upper_func_operator(void *arg) { |
| char buf[IPC_DATA_SIZE_MAX]; |
| int size = 0, function_type = 0, first_param = 0; |
| int str_output_size = 0; |
| int func_result; |
| char *first_param_str; |
| char *second_param_str; |
| char buf_response[IPC_DATA_SIZE_MAX]; |
| char *buf_for_get_data = buf; //use the buffer to get data out for ioplugin |
| |
| ALOGD("%s()", __func__); |
| g_ipc_upper_rcv_handler = open(ACS_IPC_FOR_UPPER_RCV, O_RDONLY); |
| g_ipc_upper_send_handler = open(ACS_IPC_FOR_UPPER_SEND, O_WRONLY); |
| set_phonecall_rate(PHONECALL_SAMPLE_RATE); |
| g_volume_index = 4;//valid range: 0~7, 0 for mute |
| g_current_output_device = AUDIO_DEVICE_OUT_SPEAKER; |
| g_speaker_type = AUDIO_SPK_EXTAMP_LO; |
| |
| while (1) { |
| size = read(g_ipc_upper_rcv_handler, buf, IPC_DATA_SIZE_MAX); |
| if (!size) { |
| ALOGE("%s(), IPC data size=%d, reset fifo!", __func__, size); |
| close(g_ipc_upper_rcv_handler); |
| g_ipc_upper_rcv_handler = open(ACS_IPC_FOR_UPPER_RCV, O_RDONLY); |
| continue; |
| } |
| /* finish string */ |
| buf[size] = '\0'; |
| |
| /* parse string */ |
| strtok_r(buf, ",", &first_param_str); |
| function_type = atoi(buf); |
| AUDIO_V_LOG("%s(), function_type=%d", __func__, function_type); |
| switch (function_type) { |
| case FUNC_AUDIO_CTRL_SERVICE_SPEECH_ON: |
| first_param = atoi(first_param_str); |
| pthread_mutex_lock(&g_mutex_record); //for g_want_to_speech_off_after_record_off |
| func_result = audio_ctrl_service_speech_on_inner(first_param, AUDIO_DEVICE_OUT_SPEAKER); |
| pthread_mutex_unlock(&g_mutex_record); |
| str_output_size = sprintf(buf_response, "%d", func_result); |
| break; |
| case FUNC_AUDIO_CTRL_M2M_CALL_ON: |
| first_param = atoi(first_param_str); |
| strtok_r(first_param_str, ",", &second_param_str); |
| pthread_mutex_lock(&g_mutex_playback); |
| func_result = audio_ctrl_service_M2M_Call_on_inner(first_param); |
| pthread_mutex_unlock(&g_mutex_playback); |
| str_output_size = sprintf(buf_response, "%d", func_result); |
| break; |
| case FUNC_AUDIO_CTRL_ECALL_ON: |
| first_param = atoi(first_param_str); |
| pthread_mutex_lock(&g_mutex_playback); |
| func_result = audio_ctrl_service_ECall_on_inner(first_param); |
| pthread_mutex_unlock(&g_mutex_playback); |
| str_output_size = sprintf(buf_response, "%d", func_result); |
| break; |
| case FUNC_AUDIO_CTRL_SERVICE_SET_DL_VOLUME: |
| case FUNC_AUDIO_CTRL_SERVICE_SET_BT_DL_GAIN: |
| first_param = atoi(first_param_str); |
| func_result = audio_ctrl_service_set_volume_index_inner(first_param); |
| str_output_size = sprintf(buf_response, "%d", func_result); |
| break; |
| case FUNC_AUDIO_CTRL_SERVICE_GET_BT_DL_GAIN: |
| func_result = audio_ctrl_service_get_volume_index_inner(); |
| str_output_size = sprintf(buf_response, "%d", func_result); |
| break; |
| case FUNC_AUDIO_CTRL_SERVICE_SET_SPEAKER_TYPE: |
| first_param = atoi(first_param_str); |
| func_result = audio_ctrl_service_set_speaker_type_inner(first_param); |
| str_output_size = sprintf(buf_response, "%d", func_result); |
| break; |
| |
| #if defined(MTK_SPEECH_RECORD_SUPPORT) |
| case FUNC_AUDIO_CTRL_INCALL_RECORD_START: |
| first_param = atoi(first_param_str); |
| pthread_mutex_lock(&g_mutex_record); |
| func_result = audio_ctrl_service_inCall_record_start_inner(first_param); |
| pthread_mutex_unlock(&g_mutex_record); |
| str_output_size = sprintf(buf_response, "%d", func_result); |
| break; |
| case FUNC_AUDIO_CTRL_INCALL_RECORD_STOP: |
| pthread_mutex_lock(&g_mutex_record); |
| func_result = audio_ctrl_service_inCall_record_stop_inner(); |
| pthread_mutex_unlock(&g_mutex_record); |
| str_output_size = sprintf(buf_response, "%d", func_result); |
| break; |
| case FUNC_AUDIO_CTRL_INCALL_RECORD_POINTER: |
| pthread_mutex_lock(&g_mutex_record); |
| func_result = audio_ctrl_service_inCall_record_pointer_inner(); |
| pthread_mutex_unlock(&g_mutex_record); |
| str_output_size = sprintf(buf_response, "%d", func_result); |
| break; |
| case FUNC_AUDIO_CTRL_INCALL_RECORD_GET_WATERMARK: |
| pthread_mutex_lock(&g_mutex_record); |
| func_result = audio_ctrl_service_inCall_record_get_watermark_inner(); |
| pthread_mutex_unlock(&g_mutex_record); |
| str_output_size = sprintf(buf_response, "%d", func_result); |
| break; |
| case FUNC_AUDIO_CTRL_INCALL_RECORD_GET_DATA: |
| first_param = atoi(first_param_str); |
| //use the "buf" to get data out for ioplugin |
| pthread_mutex_lock(&g_mutex_record); |
| func_result = audio_ctrl_service_inCall_record_get_data_inner |
| (first_param, buf_for_get_data); |
| pthread_mutex_unlock(&g_mutex_record); |
| str_output_size = sprintf(buf_response, "%d,", func_result); |
| if (func_result > 0) { |
| memcpy(buf_response + str_output_size, buf_for_get_data, |
| func_result); |
| str_output_size += func_result; |
| } |
| break; |
| #endif |
| #if defined(MTK_SPEECH_BGS_SUPPORT) |
| case FUNC_AUDIO_CTRL_INCALL_PLAYBACK_START: |
| pthread_mutex_lock(&g_mutex_playback); |
| func_result = audio_ctrl_service_inCall_playback_start_inner(); |
| pthread_mutex_unlock(&g_mutex_playback); |
| str_output_size = sprintf(buf_response, "%d", func_result); |
| break; |
| case FUNC_AUDIO_CTRL_INCALL_PLAYBACK_STOP: |
| pthread_mutex_lock(&g_mutex_playback); |
| func_result = audio_ctrl_service_inCall_playback_stop_inner(); |
| pthread_mutex_unlock(&g_mutex_playback); |
| str_output_size = sprintf(buf_response, "%d", func_result); |
| break; |
| case FUNC_AUDIO_CTRL_INCALL_PLAYBACK_SEND_DATA: |
| first_param = atoi(first_param_str); |
| strtok_r(first_param_str, ",", &second_param_str); |
| pthread_mutex_lock(&g_mutex_playback); |
| func_result = audio_ctrl_service_inCall_playback_send_data_inner |
| (first_param, second_param_str); |
| pthread_mutex_unlock(&g_mutex_playback); |
| str_output_size = sprintf(buf_response, "%d", func_result); |
| break; |
| case FUNC_AUDIO_CTRL_INCALL_PLAYBACK_SIMULATION: |
| first_param = atoi(first_param_str); |
| pthread_mutex_lock(&g_mutex_playback); |
| func_result = audio_ctrl_service_inCall_playback_simulation(first_param); |
| pthread_mutex_unlock(&g_mutex_playback); |
| str_output_size = sprintf(buf_response, "%d", func_result); |
| break; |
| #endif |
| case FUNC_AUDIO_CTRL_SERVICE_IS_SPEECH_ON: |
| func_result = audio_ctrl_service_is_speech_on_inner(AUDIO_DEVICE_OUT_SPEAKER); |
| str_output_size = sprintf(buf_response, "%d", func_result); |
| break; |
| case FUNC_AUDIO_CTRL_SERVICE_GET_RECORD_PERIOD_SIZE: |
| func_result = audio_ctrl_service_get_record_period_size_inner(); |
| str_output_size = sprintf(buf_response, "%d", func_result); |
| break; |
| case FUNC_AUDIO_CTRL_SERVICE_GET_PLAYBACK_PERIOD_SIZE: |
| func_result = audio_ctrl_service_get_playback_period_size_inner(); |
| str_output_size = sprintf(buf_response, "%d", func_result); |
| break; |
| case FUNC_AUDIO_CTRL_SERVICE_GET_RECORD_MAX_BUFFER_SIZE: |
| func_result = audio_ctrl_service_get_record_max_buffer_size_inner(); |
| str_output_size = sprintf(buf_response, "%d", func_result); |
| break; |
| case FUNC_AUDIO_CTRL_SERVICE_GET_PLAYBACK_MAX_BUFFER_SIZE: |
| func_result = audio_ctrl_service_get_playback_max_buffer_size_inner(); |
| str_output_size = sprintf(buf_response, "%d", func_result); |
| break; |
| |
| #if defined(MTK_SPEECH_VM_SUPPORT) |
| case FUNC_AUDIO_CTRL_SERVICE_VMLOG_ON: |
| first_param = atoi(first_param_str); |
| func_result = audio_ctrl_service_vmlog_on_inner(first_param); |
| str_output_size = sprintf(buf_response, "%d", func_result); |
| break; |
| case FUNC_AUDIO_CTRL_SERVICE_GET_VMLOG_ON: |
| func_result = audio_ctrl_service_get_vmlog_on_inner(); |
| str_output_size = sprintf(buf_response, "%d", func_result); |
| break; |
| #endif |
| case FUNC_AUDIO_CTRL_SERVICE_BT_SPEECH_ON: |
| first_param = atoi(first_param_str); |
| func_result = audio_ctrl_service_speech_on_inner(first_param, AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET); |
| str_output_size = sprintf(buf_response, "%d", func_result); |
| break; |
| case FUNC_AUDIO_CTRL_SERVICE_IS_BT_SPEECH_ON: |
| func_result = audio_ctrl_service_is_speech_on_inner(AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET); |
| str_output_size = sprintf(buf_response, "%d", func_result); |
| break; |
| case FUNC_AUDIO_CTRL_SERVICE_SET_BT_WBS: |
| first_param = atoi(first_param_str); |
| func_result = audio_ctrl_service_set_bt_wbs_inner(first_param); |
| str_output_size = sprintf(buf_response, "%d", func_result); |
| break; |
| case FUNC_AUDIO_CTRL_SERVICE_GET_BT_WBS: |
| func_result = audio_ctrl_service_get_bt_wbs_inner(); |
| str_output_size = sprintf(buf_response, "%d", func_result); |
| break; |
| #if !defined(MTK_AUDIO_BRINGUP) |
| case FUNC_AUDIO_CTRL_SERVICE_SET_BT_CLIENT_HAS_ECNR: |
| first_param = atoi(first_param_str); |
| func_result = audio_ctrl_service_set_bt_client_has_ecnr_inner(first_param); |
| str_output_size = sprintf(buf_response, "%d", func_result); |
| break; |
| case FUNC_AUDIO_CTRL_SERVICE_GET_BT_CLIENT_HAS_ECNR: |
| func_result = audio_ctrl_service_get_bt_client_has_ecnr_inner(); |
| str_output_size = sprintf(buf_response, "%d", func_result); |
| break; |
| case FUNC_AUDIO_CTRL_SERVICE_SET_USE_BT_IN_CALL: |
| first_param = atoi(first_param_str); |
| func_result = audio_ctrl_service_set_use_bt_in_call_inner(first_param); |
| str_output_size = sprintf(buf_response, "%d", func_result); |
| break; |
| #endif |
| case FUNC_AUDIO_CTRL_SERVICE_GET_USE_BT_IN_CALL: |
| func_result = audio_ctrl_service_get_use_bt_in_call_inner(); |
| str_output_size = sprintf(buf_response, "%d", func_result); |
| break; |
| case FUNC_AUDIO_CTRL_SERVICE_RESET_INNER: |
| func_result = audio_ctrl_service_reset_inner(); |
| str_output_size = sprintf(buf_response, "%d", func_result); |
| break; |
| case FUNC_AUDIO_CTRL_SERVICE_SET_DL_MUTE: |
| first_param = atoi(first_param_str); |
| func_result = audio_ctrl_service_set_mute_inner(SPEECH_DL, first_param); |
| str_output_size = sprintf(buf_response, "%d", func_result); |
| break; |
| case FUNC_AUDIO_CTRL_SERVICE_SET_UL_MUTE: |
| first_param = atoi(first_param_str); |
| func_result = audio_ctrl_service_set_mute_inner(SPEECH_UL, first_param); |
| str_output_size = sprintf(buf_response, "%d", func_result); |
| break; |
| case FUNC_AUDIO_CTRL_SERVICE_GET_MUTE: |
| first_param = atoi(first_param_str); |
| func_result = audio_ctrl_service_get_mute_inner(first_param); |
| str_output_size = sprintf(buf_response, "%d", func_result); |
| break; |
| default: |
| break; |
| } |
| |
| /*send result*/ |
| write(g_ipc_upper_send_handler, buf_response, str_output_size); |
| |
| } |
| close(g_ipc_upper_send_handler); |
| close(g_ipc_upper_rcv_handler); |
| } |
| |
| static void *speech_flow_lower_func_operator(void *arg) { |
| char buf[IPC_DATA_SIZE_MAX]; |
| int size = 0, function_type = 0, first_param = 0; |
| int str_output_size = 0; |
| int func_result; |
| char *first_param_str; |
| char *second_param_str; |
| char buf_response[IPC_DATA_SIZE_MAX]; |
| char *buf_for_get_data = buf; //use the buffer to get data out for ioplugin |
| |
| AUDIO_V_LOG("%s()", __func__); |
| g_ipc_lower_rcv_handler = open(ACS_IPC_FOR_LOWER_RCV, O_RDONLY); |
| g_ipc_lower_send_handler = open(ACS_IPC_FOR_LOWER_SEND, O_WRONLY); |
| while (1) { |
| size = read(g_ipc_lower_rcv_handler, buf, IPC_DATA_SIZE_MAX); |
| if (!size) { |
| ALOGE("%s(), IPC data size=%d, reset fifo!", __func__, size); |
| close(g_ipc_lower_rcv_handler); |
| g_ipc_lower_rcv_handler = open(ACS_IPC_FOR_LOWER_RCV, O_RDONLY); |
| continue; |
| } |
| /* finish string */ |
| buf[size] = '\0'; |
| |
| /* parse string */ |
| strtok_r(buf, ",", &first_param_str); |
| function_type = atoi(buf); |
| switch (function_type) { |
| #if defined(MTK_SPEECH_RECORD_SUPPORT) |
| case FUNC_AUDIO_CTRL_INCALL_SERVICE_RECORD_DATA_CB: |
| first_param = atoi(first_param_str); |
| strtok_r(first_param_str, ",", &second_param_str); |
| pthread_mutex_lock(&g_mutex_record); |
| func_result = audio_ctrl_service_inCall_record_data_cb_inner |
| (first_param, second_param_str); |
| pthread_mutex_unlock(&g_mutex_record); |
| str_output_size = sprintf(buf_response, "%d", func_result); |
| break; |
| #endif |
| default: |
| break; |
| } |
| |
| /*send result*/ |
| write(g_ipc_lower_send_handler, buf_response, str_output_size); |
| |
| } |
| close(g_ipc_lower_send_handler); |
| close(g_ipc_lower_rcv_handler); |
| } |
| |
| |
| static void *speech_flow_dummy_sender(void *arg) { |
| int dummy_handler = 0; |
| AUDIO_V_LOG("%s()", __func__); |
| dummy_handler = open(ACS_IPC_FOR_UPPER_RCV, O_WRONLY); |
| dummy_handler = open(ACS_IPC_FOR_LOWER_RCV, O_WRONLY); |
| while (1) { |
| sleep(1000000); |
| } |
| close(dummy_handler); |
| } |
| |
| static void parameterChanged(AppHandle *appHandle, const char *audioTypeName) { |
| AppOps *appOps = NULL; |
| int paramIndex; |
| AUDIO_V_LOG("%s()", __func__); |
| #if defined(MTK_DUMMY_AUDIO_PARSER) |
| return; |
| #else |
| appOps = appOpsGetInstance(); |
| if (appOps == NULL) { |
| ALOGE("%s(), LINE %d ERROR", __func__, __LINE__); |
| return; |
| } |
| |
| if (appOps->appHandleReloadAudioType(appHandle, audioTypeName) == APP_ERROR) { |
| ALOGE("%s(), Reload xml fail! (audioType = %s)", __func__, audioTypeName); |
| return; |
| } |
| |
| for (paramIndex = 0; paramIndex < PARAM_NUM; paramIndex++) { |
| if (!strcmp(audioTypeName, paramVolume[paramIndex].xml_type_name) |
| && paramVolume[paramIndex].update_xml_callback) { |
| paramVolume[paramIndex].update_xml_callback(paramVolume[paramIndex].id); |
| } |
| } |
| #endif |
| } |
| |
| |
| static void updateUlAnalogGain() { |
| int ul_ana_gain = 0, ret = 0; |
| |
| /* digital part */ |
| #if !defined(MTK_AUDIO_BRINGUP) |
| ul_ana_gain = speechdrv_get_ul_analog_gain(); |
| #endif |
| ALOGD("%s(), get ul analog gain value: %d, valid range(0~30 dB)", __func__, ul_ana_gain); |
| /* analog part */ |
| ret = set_UL_analog_gain(ul_ana_gain); |
| if (ret < 0) |
| ALOGE("%s(), set ul analog volume error, gain value: %d, errno: %d", |
| __func__, ul_ana_gain, ret); |
| } |
| |
| static void updateDlAnalogGain(void) { |
| int dl_ana_gain = 0, ret = 0; |
| |
| /* analog part */ |
| #if !defined(MTK_AUDIO_BRINGUP) |
| dl_ana_gain = speechdrv_get_dl_analog_gain(); |
| #endif |
| ALOGD("%s(), get dl analog gain value: %d, valid range(-40~8 dB)", __func__, dl_ana_gain); |
| |
| /* analog part */ |
| ret = set_DL_analog_gain(dl_ana_gain); |
| if (ret < 0) |
| ALOGE("%s(), set dl analog volume error, gain value: %d, errno: %d", |
| __func__, dl_ana_gain, ret); |
| } |
| |
| static void updateDigitalGain() { |
| int ret = 0, retry_counter_analog = 5, retry = 1; |
| int retry_speech_drv_ite = 0; |
| int dl_ana_gain = 0; |
| |
| /* digital part ul/dl*/ |
| do { |
| #if !defined(MTK_AUDIO_BRINGUP) |
| ret = speechdrv_set_volume_index(g_volume_index, g_current_output_device); |
| #endif |
| ++retry_speech_drv_ite; |
| if (!ret) { |
| break; |
| } |
| usleep(SPEECH_DRV_RETRY_US); |
| } while (ret && retry_speech_drv_ite < SPEECH_DRV_RETRY_TIME); |
| |
| if (ret < 0) |
| ALOGE("%s(), set dl volume index error, g_volume_index: %d, errno: %d", |
| __func__, g_volume_index, ret); |
| |
| } |
| |
| static void updateVolume(int xmlType) { |
| ALOGD("%s(), xml name = %s", __func__, paramVolume[xmlType].xml_type_name); |
| updateDigitalGain(); |
| if (xmlType != XML_GAIN_MAP_UL) { |
| updateDlAnalogGain(); |
| } |
| if (xmlType != XML_GAIN_MAP_DL) { |
| updateUlAnalogGain(); |
| } |
| } |
| |
| //for bring up |
| int audio_ctrl_service_speech_on_inner(int enable, int output_device) { |
| int ret; |
| int retry_ite = 0; |
| int device_mode = 0; |
| int input_device; |
| int outputDevice; |
| |
| ALOGD("%s(), enable=%d, output_device=0x%x", __func__, enable, output_device); |
| if (enable == g_is_speech_on) { |
| ALOGE("%s(), speech on status no change! g_is_speech_on: %d", |
| __func__, g_is_speech_on); |
| return 0; |
| } |
| |
| g_is_speech_on = enable; |
| if (output_device == AUDIO_DEVICE_OUT_SPEAKER) { |
| input_device = AUDIO_DEVICE_IN_BUILTIN_MIC; |
| g_current_output_device = AUDIO_DEVICE_OUT_SPEAKER; |
| } else { |
| input_device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET; |
| g_current_output_device = AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET; |
| } |
| |
| do { |
| if (enable || !g_record_buf) { |
| //force to speaker , main mic |
| ret = speechdrv_set_speech_on(enable, input_device, g_current_output_device); |
| ++retry_ite; |
| if (!ret) { |
| break; |
| } |
| } else { //recording!! |
| ALOGE("%s(), record is still on, Will auto sppech off after record off, don't worry!", __func__); |
| g_want_to_speech_off_after_record_off = 1; |
| ret = 0; |
| break; |
| } |
| usleep(SPEECH_DRV_RETRY_US); |
| } while (retry_ite < SPEECH_DRV_RETRY_TIME); |
| |
| if (ret) { |
| return ret; |
| } |
| |
| if (enable) { |
| if (output_device == AUDIO_DEVICE_OUT_SPEAKER) { |
| device_mode = get_default_device(); |
| enable_phone_call_AFE_path(device_mode); |
| usleep(100 * 1000);//100ms |
| updateVolume(XML_SPEECH_VOLUME); |
| } else { |
| enable_phone_call_AFE_path(DEV_BT); |
| usleep(100 * 1000);//100ms |
| updateDigitalGain(); |
| } |
| } else { |
| disable_phone_call_AFE_path(); |
| } |
| |
| return 0; |
| } |
| |
| int audio_ctrl_service_M2M_Call_on_inner(int enable) { |
| int ret; |
| int retry_ite = 0; |
| int input_device; |
| |
| ALOGD("%s(), enable=%d", __func__, enable); |
| if (enable == g_is_speech_on) { |
| ALOGE("%s(), speech on status no change! g_is_speech_on: %d", |
| __func__, g_is_speech_on); |
| return 0; |
| } |
| |
| g_is_speech_on = enable; |
| |
| input_device = AUDIO_DEVICE_IN_BUILTIN_MIC; |
| g_current_output_device = AUDIO_DEVICE_OUT_SPEAKER; |
| |
| do { |
| if (enable || !g_record_buf) { |
| //force to speaker , main mic |
| ret = speechdrv_set_speech_on(enable, input_device, g_current_output_device); |
| ++retry_ite; |
| if (!ret) { |
| break; |
| } |
| } else { //recording!! |
| ALOGE("%s(), record is still on, Will auto sppech off after record off, don't worry!", __func__); |
| g_want_to_speech_off_after_record_off = 1; |
| ret = 0; |
| break; |
| } |
| usleep(SPEECH_DRV_RETRY_US); |
| } while (retry_ite < SPEECH_DRV_RETRY_TIME); |
| |
| if (ret) { |
| return ret; |
| } |
| |
| return 0; |
| } |
| |
| int audio_ctrl_service_ECall_on_inner(int enable) { |
| int ret; |
| int retry_ite = 0; |
| int device_mode = 0; |
| int input_device; |
| int outputDevice; |
| |
| ALOGD("%s(), enable=%d", __func__, enable); |
| if (enable == g_is_speech_on) { |
| ALOGE("%s(), speech on status no change! g_is_speech_on: %d", |
| __func__, g_is_speech_on); |
| return 0; |
| } |
| |
| g_is_speech_on = enable; |
| input_device = AUDIO_DEVICE_IN_BUILTIN_MIC; |
| g_current_output_device = AUDIO_DEVICE_OUT_SPEAKER; |
| |
| do { |
| if (enable || !g_record_buf) { |
| //force to speaker , main mic |
| ret = speechdrv_set_speech_on(enable, input_device, g_current_output_device); |
| ++retry_ite; |
| if (!ret) { |
| break; |
| } |
| } else { //recording!! |
| ALOGE("%s(), record is still on, Will auto sppech off after record off, don't worry!", __func__); |
| g_want_to_speech_off_after_record_off = 1; |
| ret = 0; |
| break; |
| } |
| usleep(SPEECH_DRV_RETRY_US); |
| } while (retry_ite < SPEECH_DRV_RETRY_TIME); |
| |
| if (ret) { |
| return ret; |
| } |
| |
| if (enable) { |
| device_mode = get_default_device(); |
| enable_phone_call_AFE_path(device_mode); |
| usleep(100 * 1000);//100ms |
| updateVolume(XML_SPEECH_VOLUME); |
| } else { |
| disable_phone_call_AFE_path(); |
| } |
| |
| return 0; |
| } |
| |
| int audio_ctrl_service_set_volume_index_inner(int volumeIdx) { |
| ALOGD("%s(), volumeIdx=%d, valid range (%d~%d)", __func__, volumeIdx, DL_VOLUME_IDX_MIN, DL_VOLUME_IDX_MAX); |
| if (volumeIdx > DL_VOLUME_IDX_MAX || volumeIdx < DL_VOLUME_IDX_MIN) { |
| ALOGE("%s(), Invalid DL gain value: %d, valid range (%d~%d)", |
| __func__, volumeIdx, DL_VOLUME_IDX_MIN, DL_VOLUME_IDX_MAX); |
| return -1; |
| } |
| g_volume_index = volumeIdx; |
| updateVolume(XML_SPEECH_VOLUME); |
| return 0; |
| } |
| |
| int audio_ctrl_service_set_speaker_type_inner(int type) { |
| if (g_speaker_type == type) { |
| AUDIO_V_LOG("%s(), the same speaker type(0x%x), return.", __func__, g_speaker_type); |
| return 0; |
| } |
| speechdrv_set_speaker_type(type); |
| return 0; |
| } |
| |
| int audio_ctrl_service_get_volume_index_inner() { |
| AUDIO_V_LOG("%s()", __func__); |
| return g_volume_index; |
| } |
| |
| #if defined(MTK_SPEECH_RECORD_SUPPORT) |
| int audio_ctrl_service_inCall_record_start_inner(int buf_size) { |
| int ret; |
| |
| AUDIO_V_LOG("%s()", __func__); |
| if (buf_size > MAX_REC_BUF_SIZE || buf_size <= 0 || buf_size % 2) { |
| return -EINVAL; |
| } |
| if (g_record_buf) { |
| ALOGE("%s(), record already open!", __func__); |
| return -EBUSY; |
| } |
| g_record_buf_size = buf_size; |
| g_record_buf = malloc(g_record_buf_size); |
| g_record_read_virt_idx = 0; |
| g_record_write_virt_idx = 0; |
| g_record_virt_boundry = buf_size * 1000; |
| |
| #ifndef RECORD_USE_UT_SOURCE |
| // ret = speechdrv_set_RecordOn(RECORD_TYPE_MIX); |
| #else |
| ret = tmp_recordOn(); |
| #endif |
| |
| if (ret < 0) { |
| free(g_record_buf); |
| } |
| |
| return ret; |
| } |
| |
| int audio_ctrl_service_inCall_record_stop_inner() { |
| int ret; |
| |
| AUDIO_V_LOG("%s()", __func__); |
| if (!g_record_buf) { |
| ALOGE("%s(), record not start!", __func__); |
| return -EINVAL; |
| } |
| #ifndef RECORD_USE_UT_SOURCE |
| |
| // ret = speechdrv_set_RecordOff(RECORD_TYPE_MIX); |
| |
| if (g_want_to_speech_off_after_record_off) { |
| // int ret_speech_off = speechdrv_set_speech_on(0, 0); |
| if (ret_speech_off) { |
| ALOGE("%s(), speechdrv_set_speech_on failed! err %d", __func__, |
| ret_speech_off); |
| } |
| g_want_to_speech_off_after_record_off = 0; |
| } |
| #else |
| ret = tmp_recordOff(); |
| #endif |
| free(g_record_buf); |
| g_record_buf = 0; |
| return ret; |
| } |
| |
| |
| int audio_ctrl_service_inCall_record_get_watermark_inner() { |
| int watermark; |
| |
| if (!g_record_buf) { |
| ALOGE("%s(), record not start!", __func__); |
| return -EINVAL; |
| } |
| watermark = (g_record_write_virt_idx - g_record_read_virt_idx + g_record_virt_boundry) % g_record_virt_boundry; |
| if (watermark > g_record_buf_size) { //XRUN |
| ALOGE("%s(), XRUN reset ptr", __func__); |
| g_record_write_virt_idx = g_record_read_virt_idx; |
| return -EPIPE; |
| } |
| |
| return watermark; |
| } |
| |
| int audio_ctrl_service_inCall_record_pointer_inner() { |
| int watermark; |
| |
| AUDIO_V_LOG("%s()", __func__); |
| if (!g_record_buf) { |
| ALOGE("%s(), record not start!", __func__); |
| return -EINVAL; |
| } |
| |
| watermark = audio_ctrl_service_inCall_record_get_watermark_inner(); |
| if (watermark < 0) { |
| return watermark; |
| } |
| return (g_record_write_virt_idx % g_record_buf_size); |
| } |
| |
| int check_copy_twice(int virt_ptr, int buf_size, int size) { |
| if (virt_ptr % buf_size + size > buf_size) { |
| return 1; |
| } else { |
| return 0; |
| } |
| } |
| |
| int audio_ctrl_service_inCall_record_get_data_inner(int data_size, char *dest) { |
| int watermark; |
| int size_to_take; |
| int copy_twice = 0; |
| int read_phy_idx = g_record_read_virt_idx % g_record_buf_size; |
| int first_copy_size; |
| |
| AUDIO_V_LOG("%s()", __func__); |
| if (!g_record_buf) { |
| ALOGE("%s(), record not start!", __func__); |
| return -EINVAL; |
| } |
| |
| watermark = audio_ctrl_service_inCall_record_get_watermark_inner(); |
| if (watermark < 0) { |
| return watermark; |
| } |
| |
| size_to_take = (data_size < watermark) ? data_size : watermark; |
| copy_twice = check_copy_twice(g_record_read_virt_idx, g_record_buf_size, size_to_take); |
| |
| if (!copy_twice) { |
| memcpy(dest, g_record_buf + read_phy_idx, size_to_take); |
| } else { |
| first_copy_size = g_record_buf_size - read_phy_idx; |
| memcpy(dest, g_record_buf + read_phy_idx, first_copy_size); |
| dest += first_copy_size; |
| memcpy(dest, g_record_buf, size_to_take - first_copy_size); |
| } |
| g_record_read_virt_idx += size_to_take; |
| g_record_read_virt_idx %= g_record_virt_boundry; |
| return size_to_take; |
| } |
| |
| int audio_ctrl_service_inCall_record_data_cb_pcm(int data_size, char *data) { |
| int copy_twice = 0; |
| int write_phy_idx = g_record_write_virt_idx % g_record_buf_size; |
| int first_copy_size; |
| |
| if (!g_record_buf) { |
| return -EINVAL; |
| } |
| |
| copy_twice = check_copy_twice(g_record_write_virt_idx, g_record_buf_size, data_size); |
| if (!copy_twice) { |
| memcpy(g_record_buf + write_phy_idx, data, data_size); |
| } else { |
| first_copy_size = g_record_buf_size - write_phy_idx; |
| memcpy(g_record_buf + write_phy_idx, data, first_copy_size); |
| data += first_copy_size; |
| memcpy(g_record_buf, data, data_size - first_copy_size); |
| } |
| |
| g_record_write_virt_idx += data_size; |
| g_record_write_virt_idx %= g_record_virt_boundry; |
| return data_size; |
| } |
| |
| int16_t *do_record_8k_to_16k_src(int16_t *src, int size_byte) { |
| int offset, err; |
| int16_t *dst_buf; |
| assert(size_byte == RECORD_SRC_BUF_SIZE * 2); |
| if (!g_incall_record_src_state) { //not init |
| g_incall_record_src_state = src_new(g_converter_type, 1, &err); |
| if (!g_incall_record_src_state) { |
| ALOGE("%s(), src_new failed err=%d", __func__, err); |
| return NULL; |
| } |
| assert(!g_incall_record_src_buffer); |
| assert(!g_incall_record_dst_buffer); |
| g_incall_record_src_buffer = calloc(1, sizeof(float) * RECORD_SRC_BUF_SIZE); |
| g_incall_record_dst_buffer = calloc(1, sizeof(float) * RECORD_DST_BUF_SIZE); |
| |
| g_incall_record_src_data.data_in = g_incall_record_src_buffer; |
| g_incall_record_src_data.data_out = g_incall_record_dst_buffer; |
| g_incall_record_src_data.src_ratio = RECORD_SRC_RATIO; |
| g_incall_record_src_data.end_of_input = 0; |
| } |
| |
| /* do convert */ |
| g_incall_record_src_data.input_frames = RECORD_SRC_BUF_SIZE; |
| g_incall_record_src_data.output_frames = RECORD_DST_BUF_SIZE; |
| src_short_to_float_array(src, g_incall_record_src_buffer, RECORD_SRC_BUF_SIZE); |
| err = src_process(g_incall_record_src_state, &g_incall_record_src_data); |
| if (err) { |
| ALOGE("%s(), src_process failed %d", __func__, err); |
| return NULL; |
| } |
| |
| dst_buf = g_incall_record_dst_int_buffer; |
| if (g_incall_record_src_data.output_frames > g_incall_record_src_data.output_frames_gen) { |
| offset = g_incall_record_src_data.output_frames - g_incall_record_src_data.output_frames_gen; |
| } else { |
| offset = 0; |
| } |
| |
| src_float_to_short_array(g_incall_record_dst_buffer, dst_buf + offset, |
| g_incall_record_src_data.output_frames_gen); |
| |
| return dst_buf; |
| } |
| |
| int audio_ctrl_service_inCall_record_data_cb_inner(int data_size, char *data) { |
| MD_PCM_RECORD_HEADER *md_pcm_record_header; |
| char *data_process_ptr = data; |
| char *pcm_data_ptr; |
| uint16_t syncWord; |
| uint16_t rawPcmDir; |
| uint16_t freq; |
| uint16_t pcmLength; |
| uint16_t channel; |
| uint16_t bitFormat; |
| |
| int16_t *ul_data_ptr = 0; |
| int ul_data_ptr_size; |
| int ul_data_rate; |
| int16_t *dl_data_ptr = 0; |
| int dl_data_ptr_size; |
| int dl_data_rate; |
| |
| int total_data_size; |
| int16_t *total_data_ptr; |
| |
| int i, j; |
| int ret; |
| |
| while (data_process_ptr < data + data_size) { |
| md_pcm_record_header = (MD_PCM_RECORD_HEADER *)data_process_ptr; |
| syncWord = md_pcm_record_header->u16SyncWord; |
| rawPcmDir = md_pcm_record_header->u16RawPcmDir; |
| freq = md_pcm_record_header->u16Freq; |
| pcmLength = md_pcm_record_header->u16Length; |
| channel = md_pcm_record_header->u16Channel; |
| bitFormat = md_pcm_record_header->u16BitFormat; |
| pcm_data_ptr = data_process_ptr + sizeof(MD_PCM_RECORD_HEADER); |
| |
| if (syncWord != MD_PCM_RECORD_HEADER_SYNC) { |
| ALOGE("%s(), Invalid packet, sync word: 0x%x", __func__, syncWord); |
| return 0; |
| } |
| |
| if (rawPcmDir == RECORD_TYPE_UL) { |
| assert(!ul_data_ptr); |
| ul_data_ptr = (uint16_t *)pcm_data_ptr; |
| ul_data_ptr_size = pcmLength; |
| ul_data_rate = freq; |
| assert(channel == 1); |
| } else { |
| assert(!dl_data_ptr); |
| dl_data_ptr = (uint16_t *)pcm_data_ptr; |
| dl_data_ptr_size = pcmLength; |
| dl_data_rate = freq; |
| assert(channel == 1); |
| } |
| |
| data_process_ptr += sizeof(MD_PCM_RECORD_HEADER) + pcmLength; |
| } |
| |
| assert(ul_data_ptr); |
| assert(dl_data_ptr); |
| //only UL can be 8k or 16k, DL must be 16k |
| total_data_size = dl_data_ptr_size; |
| assert(!(total_data_size % ul_data_ptr_size)); |
| |
| total_data_ptr = malloc(total_data_size); |
| |
| if (ul_data_ptr_size < total_data_size) { |
| ul_data_ptr = do_record_8k_to_16k_src(ul_data_ptr, ul_data_ptr_size); |
| if (!ul_data_ptr) { |
| return -EINVAL; |
| } |
| ul_data_ptr_size *= 2; |
| } |
| |
| assert(total_data_size == ul_data_ptr_size); |
| //MIX sound |
| for (i = 0; i < ul_data_ptr_size / 2; ++i) { |
| total_data_ptr[i] = ul_data_ptr[i] >> 1; |
| } |
| |
| for (i = 0; i < dl_data_ptr_size / 2; ++i) { |
| total_data_ptr[i] += dl_data_ptr[i] >> 1; |
| } |
| |
| //write data |
| ret = audio_ctrl_service_inCall_record_data_cb_pcm(total_data_size, total_data_ptr); |
| free(total_data_ptr); |
| return ret; |
| } |
| #endif |
| |
| #if defined(MTK_SPEECH_BGS_SUPPORT) |
| int audio_ctrl_service_inCall_playback_start_inner() { |
| #ifndef PLAYBACK_USE_UT_SINK |
| int ret; |
| AUDIO_V_LOG("%s()", __func__); |
| if (!g_is_bgs_on) { |
| ret = speechdrv_bgs_open(PHONECALL_SAMPLE_RATE); |
| g_is_bgs_on = 1; |
| } else { |
| ALOGE("%s(), already start!", __func__); |
| return 0; |
| } |
| return 0; |
| #else |
| return UT_BGSOn(); |
| #endif |
| } |
| |
| int audio_ctrl_service_inCall_playback_stop_inner() { |
| #ifndef PLAYBACK_USE_UT_SINK |
| AUDIO_V_LOG("%s()", __func__); |
| speechdrv_bgs_close(); |
| g_is_bgs_on = 0; |
| return 0; |
| #else |
| return UT_BGSOff(); |
| #endif |
| } |
| static const uint16_t table_1k_tone_16000_hz[] = { |
| 0x0000, 0x30FC, 0x5A82, 0x7641, |
| 0x7FFF, 0x7641, 0x5A82, 0x30FB, |
| 0x0001, 0xCF05, 0xA57E, 0x89C0, |
| 0x8001, 0x89BF, 0xA57E, 0xCF05 |
| }; |
| static const uint32_t kSizeSinewaveTable = sizeof(table_1k_tone_16000_hz); |
| |
| int audio_ctrl_service_inCall_playback_send_data_inner(int data_size, void *data_buf) { |
| #ifndef PLAYBACK_USE_UT_SINK |
| int ret; |
| int write_size; |
| int written_size = 0; |
| int try_cnt = 20; |
| if (!g_is_bgs_on) { |
| ALOGE("%s(), not running!", __func__); |
| return 0; |
| } |
| |
| while (data_size > 0) { |
| write_size = (data_size > PLAYBACK_BUF_SIZE) ? PLAYBACK_BUF_SIZE : data_size; |
| AUDIO_V_LOG("%s(), sample rate: %d, data_size: %d, write_size: %d", |
| __func__, PHONECALL_SAMPLE_RATE, data_size, write_size); |
| ret = speechdrv_bgs_write(data_buf, write_size); |
| if (ret < 0) { |
| ALOGE("%s(), write to BGS error! ret: %d", __func__, ret); |
| break; |
| } |
| data_size -= ret; |
| data_buf += ret; |
| written_size += ret; |
| --try_cnt; |
| if (try_cnt <= 0) { |
| break; |
| } |
| usleep(SPEECH_DRV_BGS_INTERVAL_US); |
| } |
| return written_size; |
| |
| #else |
| return UT_BGSSendData(data_buf, data_size); |
| #endif |
| } |
| |
| int audio_ctrl_service_inCall_playback_simulation(int data_ms) { |
| uint32_t total_size = PHONECALL_SAMPLE_RATE * 2 * data_ms / 1000; |
| uint32_t buffer_size = PLAYBACK_PERIOD_SIZE; |
| uint32_t total_left = total_size, buffer_count = buffer_size, consume_byte = 0; |
| char buffer[PLAYBACK_PERIOD_SIZE] = {0}; |
| |
| ALOGD("+%s(), data_ms = %d, total_size = %d, buffer_size = %d", |
| __func__, data_ms, total_size, buffer_size); |
| audio_ctrl_service_inCall_playback_start_inner(); |
| while (total_left > 0) { |
| uint32_t count = 0; |
| if (total_left > buffer_size) { |
| buffer_count = buffer_size; |
| } else { |
| buffer_count = total_left; |
| } |
| while (buffer_count > kSizeSinewaveTable) { |
| memcpy(buffer + count, table_1k_tone_16000_hz, kSizeSinewaveTable); |
| count += kSizeSinewaveTable; |
| buffer_count -= kSizeSinewaveTable; |
| } |
| if (buffer_count > 0) { |
| memcpy(buffer + count, table_1k_tone_16000_hz, buffer_count); |
| count += buffer_count; |
| } |
| consume_byte = audio_ctrl_service_inCall_playback_send_data_inner(buffer_size, buffer); |
| total_left -= count; |
| } |
| audio_ctrl_service_inCall_playback_stop_inner(); |
| ALOGD("-%s(), data_ms = %d, total_size = %d, total_left = %d", |
| __func__, data_ms, total_size, total_left); |
| return total_size; |
| } |
| #endif |
| |
| int audio_ctrl_service_is_speech_on_inner(int output_device) { |
| int result = 0; |
| if (!g_is_speech_on) { |
| result = 0; |
| return result; |
| } |
| if (output_device == g_current_output_device) { |
| result = 1; |
| } else { |
| result = 0; |
| } |
| AUDIO_V_LOG("%s(), result = %d, output_device=0x%x", __func__, result, output_device); |
| return result; |
| } |
| |
| int audio_ctrl_service_get_record_period_size_inner() { |
| AUDIO_V_LOG("%s()", __func__); |
| return RECORD_PERIOD_SIZE; |
| } |
| |
| int audio_ctrl_service_get_playback_period_size_inner() { |
| AUDIO_V_LOG("%s()", __func__); |
| return PLAYBACK_PERIOD_SIZE; |
| } |
| |
| int audio_ctrl_service_get_record_max_buffer_size_inner() { |
| AUDIO_V_LOG("%s()", __func__); |
| return RECORD_MAX_BUFFER_SIZE; |
| } |
| |
| int audio_ctrl_service_get_playback_max_buffer_size_inner() { |
| ALOGE("%s()", __func__); |
| return PLAYBACK_MAX_BUFFER_SIZE; |
| } |
| |
| #if defined(MTK_SPEECH_VM_SUPPORT) |
| /* for vmlog, need to record if vmlog on */ |
| int g_vmlog_on; |
| int audio_ctrl_service_vmlog_on_inner(int vmlog_on) { |
| g_vmlog_on = vmlog_on; |
| return speechdrv_set_vm_on(vmlog_on); |
| } |
| |
| int audio_ctrl_service_get_vmlog_on_inner() { |
| return g_vmlog_on; |
| } |
| #endif |
| |
| /* for BT setting */ |
| int audio_ctrl_service_set_bt_wbs_inner(int bt_wbs_on) { |
| AUDIO_V_LOG("%s()", __func__); |
| g_bt_wbs_on = !!bt_wbs_on; |
| set_BT_WB(g_bt_wbs_on); |
| speechdrv_set_bt_wbs(g_bt_wbs_on); |
| return 0; |
| } |
| |
| int audio_ctrl_service_get_bt_wbs_inner() { |
| AUDIO_V_LOG("%s()", __func__); |
| return g_bt_wbs_on; |
| } |
| |
| int audio_ctrl_service_set_bt_client_has_ecnr_inner(int bt_client_ecnr_on) { |
| if (g_bt_client_has_ecnr == bt_client_ecnr_on) { |
| AUDIO_V_LOG("%s(), the same bt_nrec(0x%x) during voice call.", __func__, g_current_output_device); |
| return 0; |
| } |
| AUDIO_V_LOG("%s(), bt_client_ecnr_on(%d->%d)", __func__, g_bt_client_has_ecnr, bt_client_ecnr_on); |
| g_bt_client_has_ecnr = bt_client_ecnr_on; |
| |
| return speechdrv_set_bt_nrec(bt_client_ecnr_on); |
| } |
| |
| int audio_ctrl_service_get_bt_client_has_ecnr_inner() { |
| AUDIO_V_LOG("%s()", __func__); |
| return g_bt_client_has_ecnr; |
| } |
| |
| #if !defined(MTK_AUDIO_BRINGUP) |
| int audio_ctrl_service_set_use_bt_in_call_inner(int turn_on_bt_in_call) { |
| AUDIO_V_LOG("%s()", __func__); |
| int new_output_device = AUDIO_DEVICE_NONE; |
| int input_device = AUDIO_DEVICE_NONE; |
| |
| //if not in call, do nothing |
| if (!g_is_speech_on) { return 0; } |
| if (turn_on_bt_in_call) { |
| new_output_device = AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET; |
| } else { |
| new_output_device = AUDIO_DEVICE_OUT_SPEAKER; |
| } |
| if (new_output_device == g_current_output_device) { |
| AUDIO_V_LOG("%s(), the same output device(0x%x) during voice call.", |
| __func__, g_current_output_device); |
| return 0; |
| } |
| g_current_output_device = new_output_device; |
| if (g_current_output_device == AUDIO_DEVICE_OUT_SPEAKER) { |
| input_device = AUDIO_DEVICE_IN_BUILTIN_MIC; |
| } else { |
| input_device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET; |
| } |
| |
| AUDIO_V_LOG("%s(), output device(0x%x), input_device(0x%x).", |
| __func__, g_current_output_device, input_device); |
| if (g_current_output_device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) { |
| dynamic_switch_phone_call_path(DEV_BT); |
| } else { |
| dynamic_switch_phone_call_path(get_default_device()); |
| } |
| speechdrv_change_speech_device(input_device, g_current_output_device); |
| updateVolume(XML_SPEECH_VOLUME); |
| |
| return 0; |
| } |
| #endif |
| |
| int audio_ctrl_service_get_use_bt_in_call_inner() { |
| AUDIO_V_LOG("%s()", __func__); |
| if (!g_is_speech_on) { return 0; } |
| return (g_current_output_device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET); |
| } |
| |
| int audio_ctrl_service_reset_inner() { |
| AUDIO_V_LOG("%s()", __func__); |
| g_want_to_speech_off_after_record_off = 0; |
| if (g_is_speech_on) { |
| disable_phone_call_AFE_path(); |
| } |
| g_is_speech_on = 0; |
| return 0; |
| } |
| |
| /* DL:0 UL:1 */ |
| int g_dl_mute_on; |
| int g_ul_mute_on; |
| int audio_ctrl_service_set_mute_inner(int path, int is_mute) { |
| AUDIO_V_LOG("%s()", __func__); |
| if (path == SPEECH_DL) { |
| g_dl_mute_on = is_mute; |
| speechdrv_set_dl_mute(g_dl_mute_on); |
| } else { |
| g_ul_mute_on = is_mute; |
| speechdrv_set_ul_mute(g_ul_mute_on); |
| } |
| return 0; |
| } |
| |
| int audio_ctrl_service_get_mute_inner(int path) { |
| AUDIO_V_LOG("%s()", __func__); |
| if (path == SPEECH_DL) { |
| return g_dl_mute_on; |
| } else { |
| return g_ul_mute_on; |
| } |
| } |
| |
| #if defined(MTK_SPEECH_BGS_SUPPORT) |
| /* for BGS UT */ |
| |
| static const char const *g_BGS_file_path = "/tmp/bgs_UT.pcm"; |
| FILE *g_UT_file; |
| |
| int UT_BGSOn() { |
| g_UT_file = fopen(g_BGS_file_path, "w"); |
| if (!g_UT_file) { |
| return -EIO; |
| } |
| return 0; |
| } |
| int UT_BGSOff() { |
| if (g_UT_file) { |
| fclose(g_UT_file); |
| } |
| g_UT_file = 0; |
| return 0; |
| } |
| int UT_BGSSendData(void *buf, int buf_size) { |
| int sleep_time_ms = buf_size * 1000 / PHONECALL_SAMPLE_RATE / 2; |
| if (!g_UT_file) { |
| ALOGE("%s(), plz send data after turn on", __func__); |
| return 0; |
| } |
| fwrite(buf, 1, buf_size, g_UT_file); |
| return buf_size; |
| } |
| #endif |