| #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 |
| |
| //#define UT_LOG |
| #ifdef UT_LOG |
| #define AUDIO_V_LOG printf |
| #else |
| #define AUDIO_V_LOG |
| #endif |
| |
| #define PATH_BUF_SIZE 1024 |
| #define SPEECH_DRV_RETRY_TIME 3 |
| #define SPEECH_DRV_RETRY_US 20000 //20ms |
| enum |
| { |
| SPEECH_DRV_NORMAL = 0, |
| SPEECH_DRV_EARPHONE = 1, |
| SPEECH_DRV_LSPEAKER = 2, |
| SPEECH_DRV_BT_EARPHONE = 3, |
| SPEECH_DRV_BT_CORDLESS = 4, |
| SPEECH_DRV_BT_CARKIT = 5, |
| SPEECH_DRV_MAGIC_CON_CALL = 6, |
| SPEECH_DRV_PRESERVED_2 = 7, |
| SPEECH_DRV_MODE_HAC = 8, |
| SPEECH_DRV_MODE_NO_CONNECT = 9 |
| }; |
| |
| const char const *BAND_PATH_STR[BAND_NUM] = {"Band,NB","Band,WB"}; |
| const char const *PROFILE_PATH_STR[PROFILE_NUM] = |
| {"Profile,Normal","Profile,eCall", |
| "Profile,BT_ECNR"}; |
| const char const *VOLUME_PARAM_PATH = "VolumeParam,Common"; |
| |
| #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; |
| |
| #define AUDIO_FORMAT_PCM_16_BIT 0x1 |
| int g_BGSPlayer_init; |
| int g_BGSPlayerBuffer_init; |
| int g_BGSPlayerBuffer_idx; |
| |
| /* 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 AUDIO_SPEECH_MODE_NB_PARAM_STRUCT g_default_NB_SPEECH_PARA = |
| { |
| DEFAULT_SPEECH_NORMAL_MODE_PARA, |
| DEFAULT_SPEECH_EARPHONE_MODE_PARA, |
| DEFAULT_SPEECH_BT_EARPHONE_MODE_PARA, |
| DEFAULT_SPEECH_LOUDSPK_MODE_PARA, |
| DEFAULT_SPEECH_CARKIT_MODE_PARA, |
| DEFAULT_SPEECH_BT_CORDLESS_MODE_PARA, |
| DEFAULT_SPEECH_AUX1_MODE_PARA, |
| DEFAULT_SPEECH_AUX2_MODE_PARA, |
| }; |
| |
| static AUDIO_SPEECH_MODE_WB_PARAM_STRUCT g_default_WB_SPEECH_PARA = |
| { |
| DEFAULT_WB_SPEECH_NORMAL_MODE_PARA, |
| DEFAULT_WB_SPEECH_EARPHONE_MODE_PARA, |
| DEFAULT_WB_SPEECH_BT_EARPHONE_MODE_PARA, |
| DEFAULT_WB_SPEECH_LOUDSPK_MODE_PARA, |
| DEFAULT_WB_SPEECH_CARKIT_MODE_PARA, |
| DEFAULT_WB_SPEECH_BT_CORDLESS_MODE_PARA, |
| DEFAULT_WB_SPEECH_AUX1_MODE_PARA, |
| DEFAULT_WB_SPEECH_AUX2_MODE_PARA, |
| }; |
| |
| static AUDIO_FIR_NB_PARAM_STRUCT g_default_NB_FIR_PARA = |
| { |
| SPEECH_INPUT_FIR_COEF, |
| SPEECH_OUTPUT_FIR_COEF, |
| }; |
| |
| static AUDIO_FIR_WB_PARAM_STRUCT g_default_WB_FIR_PARA = |
| { |
| WB_SPEECH_INPUT_FIR_COEF, |
| WB_SPEECH_OUTPUT_FIR_COEF, |
| }; |
| |
| static AUDIO_SPEECH_MODE_NB_PARAM_STRUCT g_default_NB_SPEECH_PARA_ECALL = |
| { |
| DEFAULT_SPEECH_NORMAL_MODE_PARA, |
| DEFAULT_SPEECH_EARPHONE_MODE_PARA, |
| DEFAULT_SPEECH_BT_EARPHONE_MODE_PARA, |
| DEFAULT_SPEECH_LOUDSPK_MODE_PARA, |
| DEFAULT_SPEECH_CARKIT_MODE_PARA, |
| DEFAULT_SPEECH_BT_CORDLESS_MODE_PARA, |
| DEFAULT_SPEECH_AUX1_MODE_PARA, |
| DEFAULT_SPEECH_AUX2_MODE_PARA, |
| }; |
| |
| static AUDIO_SPEECH_MODE_WB_PARAM_STRUCT g_default_WB_SPEECH_PARA_ECALL = |
| { |
| DEFAULT_WB_SPEECH_NORMAL_MODE_PARA, |
| DEFAULT_WB_SPEECH_EARPHONE_MODE_PARA, |
| DEFAULT_WB_SPEECH_BT_EARPHONE_MODE_PARA, |
| DEFAULT_WB_SPEECH_LOUDSPK_MODE_PARA, |
| DEFAULT_WB_SPEECH_CARKIT_MODE_PARA, |
| DEFAULT_WB_SPEECH_BT_CORDLESS_MODE_PARA, |
| DEFAULT_WB_SPEECH_AUX1_MODE_PARA, |
| DEFAULT_WB_SPEECH_AUX2_MODE_PARA, |
| }; |
| |
| static AUDIO_FIR_NB_PARAM_STRUCT g_default_NB_FIR_PARA_ECALL = |
| { |
| SPEECH_INPUT_FIR_COEF, |
| SPEECH_OUTPUT_FIR_COEF, |
| }; |
| |
| static AUDIO_FIR_WB_PARAM_STRUCT g_default_WB_FIR_PARA_ECALL = |
| { |
| WB_SPEECH_INPUT_FIR_COEF, |
| WB_SPEECH_OUTPUT_FIR_COEF, |
| }; |
| |
| static Param *getParamValue(AppHandle *appHandle, char *type_name, |
| char *cat_path, char *param_name); |
| |
| static int getParamArraySize(Param *param) {return param->arraySize;} |
| |
| static unsigned short *getUShortArrayFromParam(Param *param, |
| unsigned short *ushortArrayDest); |
| |
| static short *getShortArrayFromParam(Param *param, |
| unsigned short *shortArrayDest); |
| |
| static void parseAndUpdateParameter(AppHandle *appHandle, |
| const char *audioTypeName); |
| |
| static char *getPathString(int band, int profile, char* dest); |
| |
| 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 updateSpeech48param(AppHandle *appHandle); |
| static void updateFirInParam(AppHandle *appHandle); |
| static void updateFirOutParam(AppHandle *appHandle); |
| static void updateUlGainParam(AppHandle *appHandle); |
| static void updateUlSwagcGainMapParam(AppHandle *appHandle); |
| static void updateUlPgaGainMapParam(AppHandle *appHandle); |
| static void updateDlAnalogGainMapParam(AppHandle *appHandle); |
| static void updateDlDigitalGainMapParam(AppHandle *appHandle); |
| |
| static void doUpdateDlGain(int retry); |
| static void doUpdateUlGain(void); |
| |
| |
| const struct Param_data param_data_2635[PARAM_NUM] = { |
| { |
| .id = PARAM_SPEECH, |
| .xml_type_name = XML_TYPE_SPEECH_STR, |
| .param_name = SPEECH_PARA, |
| .param_type = PARAM_TYPE_USHORT_ARRAY, |
| .update_xml_callback = updateSpeech48param, |
| }, |
| { |
| .id = PARAM_FIR_IN, |
| .xml_type_name = XML_TYPE_SPEECH_STR, |
| .param_name = FIR_IN_PARA, |
| .param_type = PARAM_TYPE_SHORT_ARRAY, |
| .update_xml_callback = updateFirInParam, |
| }, |
| { |
| .id = PARAM_FIR_OUT, |
| .xml_type_name = XML_TYPE_SPEECH_STR, |
| .param_name = FIR_OUT_PARA, |
| .param_type = PARAM_TYPE_SHORT_ARRAY, |
| .update_xml_callback = updateFirOutParam, |
| }, |
| { |
| .id = PARAM_UL_GAIN_IDX, |
| .xml_type_name = XML_TYPE_SPEECHVOL_STR, |
| .param_name = UL_GAIN_IDX_PARA, |
| .param_type = PARAM_TYPE_INT, |
| .update_xml_callback = updateUlGainParam, |
| }, |
| { |
| .id = PARAM_UL_SWAGC_GAIN_MAP, |
| .xml_type_name = XML_TYPE_VOLUME_STR, |
| .param_name = SWAGC_GAIN_MAP_PARA, |
| .param_type = PARAM_TYPE_SHORT_ARRAY, |
| .update_xml_callback = updateUlSwagcGainMapParam, |
| }, |
| { |
| .id = PARAM_UL_PGA_GAIN_MAP, |
| .xml_type_name = XML_TYPE_VOLUME_STR, |
| .param_name = UL_PGA_GAIN_MAP_PARA, |
| .param_type = PARAM_TYPE_SHORT_ARRAY, |
| .update_xml_callback = updateUlPgaGainMapParam, |
| }, |
| { |
| .id = PARAM_DL_ANALOG_GAIN_MAP, |
| .xml_type_name = XML_TYPE_VOLUMEGAINMAP_STR, |
| .param_name = DL_ANALOG_GAIN_MAP_PARA, |
| .param_type = PARAM_TYPE_SHORT_ARRAY, |
| .update_xml_callback = updateDlAnalogGainMapParam, |
| }, |
| { |
| .id = PARAM_DL_DIGITAL_GAIN_MAP, |
| .xml_type_name = XML_TYPE_VOLUMEGAINMAP_STR, |
| .param_name = DL_DIGITAL_GAIN_MAP_PARA, |
| .param_type = PARAM_TYPE_SHORT_ARRAY, |
| .update_xml_callback = updateDlDigitalGainMapParam, |
| }, |
| }; |
| |
| #define UL_GAIN_MIN 0 |
| #define UL_GAIN_MAX 45 |
| #define DL_GAIN_MIN -23 |
| #define DL_GAIN_MAX 17 |
| #define BT_DL_GAIN_MIN 0 |
| #define BT_DL_GAIN_MAX 15 |
| |
| /* table size = max - min + 1 */ |
| #define UL_GAIN_TABLE_SIZE 46 |
| #define DL_GAIN_TABLE_SIZE 41 |
| |
| static short g_ul_analog_gain_table[UL_GAIN_TABLE_SIZE]; |
| static short g_ul_digital_gain_table[UL_GAIN_TABLE_SIZE]; |
| static int g_ul_gain_idx = INT_MAX; /* ul gain setting */ |
| |
| static short g_dl_analog_gain_table[DL_GAIN_TABLE_SIZE]; |
| static short g_dl_digital_gain_table[DL_GAIN_TABLE_SIZE]; |
| static int g_dl_gain_idx = 0 - DL_GAIN_MIN; /* dl gain setting */ |
| static int g_bt_dl_gain = 10; /* BT DL gain, 0~15 */ |
| |
| static int g_is_speech_on; |
| static int g_speech_on_device; |
| static int g_bt_wbs_on = FUNC_SET_BT_WB_default; |
| static int g_bt_client_has_ecnr; |
| |
| /* record the BT ECNR setting, we might turn them off |
| and might need to restore them */ |
| |
| enum BT_ECNR_SETTING { |
| BT_ECNR_AEC, |
| BT_ECNR_RX_NR, |
| BT_ECNR_TX_NR, |
| BT_ECNR_SETTING_NUM, |
| }; |
| |
| struct BT_ECNR_recorder { |
| int id; |
| int par_location; |
| int bit; |
| int inverse; //if inverse, 1 is off |
| int value_NB; |
| int value_WB; |
| }; |
| |
| struct BT_ECNR_recorder BT_ECNR_recorder_data[BT_ECNR_SETTING_NUM] = { |
| { |
| .id = BT_ECNR_AEC, |
| .par_location = 1, |
| .bit = 8, |
| .inverse = 1, |
| .value_NB = 0, |
| .value_WB = 0, |
| }, |
| { |
| .id = BT_ECNR_RX_NR, |
| .par_location = 4, |
| .bit = 2, |
| .inverse = 0, |
| .value_NB = 1, |
| .value_WB = 1, |
| }, |
| { |
| .id = BT_ECNR_TX_NR, |
| .par_location = 4, |
| .bit = 0, |
| .inverse = 0, |
| .value_NB = 1, |
| .value_WB = 1, |
| }, |
| }; |
| |
| void update_BT_ECNR_recorder(int is_WB, unsigned short* para_arr) |
| { |
| int par_location, bit; |
| for(int i=0;i<BT_ECNR_SETTING_NUM;++i) { |
| par_location = BT_ECNR_recorder_data[i].par_location; |
| bit = BT_ECNR_recorder_data[i].bit; |
| if (!is_WB) { |
| BT_ECNR_recorder_data[i].value_NB = (para_arr[par_location] >> bit) & 0x1; |
| } else { |
| BT_ECNR_recorder_data[i].value_WB = (para_arr[par_location] >> bit) & 0x1; |
| } |
| } |
| } |
| void close_all_BT_ECNR_param(int is_WB, unsigned short* para_arr) |
| { |
| int par_location, bit, inverse; |
| unsigned short mask_bit; |
| for(int i=0;i<BT_ECNR_SETTING_NUM;++i) { |
| par_location = BT_ECNR_recorder_data[i].par_location; |
| bit = BT_ECNR_recorder_data[i].bit; |
| inverse = BT_ECNR_recorder_data[i].inverse; |
| mask_bit = 1 << bit; |
| para_arr[par_location] = para_arr[par_location] & (~mask_bit); //set the bit to 0 |
| if (inverse) { |
| para_arr[par_location] = para_arr[par_location] | mask_bit; //set to 1 |
| } |
| } |
| } |
| |
| void restore_all_BT_ECNR_param(int is_WB, unsigned short* para_arr) |
| { |
| int par_location, bit, value; |
| unsigned short mask_bit; |
| for(int i=0;i<BT_ECNR_SETTING_NUM;++i) { |
| par_location = BT_ECNR_recorder_data[i].par_location; |
| bit = BT_ECNR_recorder_data[i].bit; |
| if (!is_WB) { |
| value = BT_ECNR_recorder_data[i].value_NB; |
| } else { |
| value = BT_ECNR_recorder_data[i].value_WB; |
| } |
| mask_bit = 1 << bit; |
| para_arr[par_location] = para_arr[par_location] & (~mask_bit); //set the bit to 0 |
| if (value) { |
| para_arr[par_location] = para_arr[par_location] | mask_bit; //set to 1 |
| } |
| } |
| } |
| |
| /* 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 i; |
| AppHandle *appHandle = NULL; |
| struct stat st = {0}; |
| |
| /* Get AppHandle global instance, this API will parse xml automatically */ |
| appHandle = appHandleGetInstance(); |
| |
| /* Wait for initial done */ |
| usleep(100 * 1000);//100ms |
| |
| /* Set the debug level to warn*/ |
| appSetDebugLevel(ERR_LEVEL); |
| |
| /* register callback func */ |
| appHandleRegXmlChangedCb(appHandle, parseAndUpdateParameter); |
| |
| 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); |
| |
| /* initial setting for all param */ |
| for (i = 0 ; i < PARAM_NUM; ++i) |
| param_data_2635[i].update_xml_callback(appHandle); |
| |
| while(1) |
| sleep(1000000); |
| /* Release appHandle resources */ |
| appHandleUninit(appHandle); |
| |
| 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 |
| |
| 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); |
| |
| while(1){ |
| size = read(g_ipc_upper_rcv_handler, buf, IPC_DATA_SIZE_MAX); |
| if(!size) { |
| printf("reset fifo!\n"); |
| 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); |
| 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, 0); |
| pthread_mutex_unlock(&g_mutex_record); |
| str_output_size = sprintf(buf_response, "%d", func_result); |
| break; |
| case FUNC_AUDIO_CTRL_SERVICE_SET_DL_VOLUME: |
| first_param = atoi(first_param_str); |
| func_result = audio_ctrl_service_set_dl_volume_inner(first_param); |
| str_output_size = sprintf(buf_response, "%d", func_result); |
| break; |
| |
| 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; |
| 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_SERVICE_IS_SPEECH_ON: |
| func_result = audio_ctrl_service_is_speech_on_inner(0); |
| str_output_size = sprintf(buf_response, "%d", func_result); |
| break; |
| case FUNC_AUDIO_CTRL_SERVICE_GET_DL_GAIN: |
| func_result = audio_ctrl_service_get_dl_gain_inner(); |
| 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; |
| |
| 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; |
| case FUNC_AUDIO_CTRL_SERVICE_BT_SPEECH_ON: |
| first_param = atoi(first_param_str); |
| func_result = audio_ctrl_service_speech_on_inner(first_param, 1); |
| 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(1); |
| 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; |
| case FUNC_AUDIO_CTRL_SERVICE_SET_BT_DL_GAIN: |
| first_param = atoi(first_param_str); |
| func_result = audio_ctrl_service_set_bt_dl_gain_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_bt_dl_gain_inner(); |
| str_output_size = sprintf(buf_response, "%d", func_result); |
| break; |
| 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; |
| 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; |
| 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 |
| |
| 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) { |
| printf("reset fifo!\n"); |
| 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) { |
| 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; |
| 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; |
| 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 Param *getParamValue(AppHandle *appHandle, char *type_name, char *cat_path, |
| char *param_name) |
| { |
| AudioType *audioType = NULL; |
| ParamUnit *paramUnit = NULL; |
| Param *param = NULL; |
| |
| audioType = appHandleGetAudioTypeByName(appHandle, type_name); |
| if (!audioType) |
| { |
| printf("Error: no such audio type\n"); |
| return NULL; |
| } |
| |
| /* Read lock */ |
| audioTypeReadLock(audioType, __FUNCTION__); |
| |
| paramUnit = audioTypeGetParamUnit(audioType, cat_path); |
| if (!paramUnit) |
| { |
| printf("Error: Cannot find the param unit!\n"); |
| audioTypeUnlock(audioType); |
| return NULL; |
| } |
| |
| param = paramUnitGetParamByName(paramUnit, param_name); |
| if (!param) |
| { |
| printf("Error: Cannot find the param!\n"); |
| audioTypeUnlock(audioType); |
| return NULL; |
| } |
| |
| /* Unlock */ |
| audioTypeUnlock(audioType); |
| return param; |
| } |
| |
| static unsigned short *getUShortArrayFromParam(Param *param, |
| unsigned short *ushortArrayDest) |
| { |
| unsigned short *ushortArraySrc = (unsigned short *)param->data; |
| int arraySize = param->arraySize; |
| int i = 0; |
| |
| if (param->paramInfo->dataType != TYPE_USHORT_ARRAY) { |
| printf("%s Type not correct!\n", __func__); |
| return NULL; |
| } |
| |
| for (i = 0; i < arraySize; i++) |
| ushortArrayDest[i] = ushortArraySrc[i]; |
| |
| return ushortArrayDest; |
| } |
| |
| static short *getShortArrayFromParam(Param *param, unsigned short *shortArrayDest) |
| { |
| short *shortArraySrc = (short *)param->data; |
| int arraySize = param->arraySize; |
| int i = 0; |
| |
| if (param->paramInfo->dataType != TYPE_SHORT_ARRAY) { |
| printf("%s Type not correct!\n", __func__); |
| return NULL; |
| } |
| |
| for (i = 0; i < arraySize; i++) |
| shortArrayDest[i] = shortArraySrc[i]; |
| |
| return shortArrayDest; |
| } |
| |
| static void parseAndUpdateParameter(AppHandle *appHandle, const char *audioTypeName) |
| { |
| int i; |
| |
| if (appHandleReloadAudioType(appHandle, audioTypeName) == APP_ERROR) |
| { |
| printf("Reload xml fail! (audioType = %s)\n", audioTypeName); |
| return; |
| } |
| |
| for (i = 0 ; i < PARAM_NUM; ++i) |
| if (!strcmp(audioTypeName, param_data_2635[i].xml_type_name) |
| && param_data_2635[i].update_xml_callback) |
| param_data_2635[i].update_xml_callback(appHandle); |
| } |
| |
| static char *getPathString(int band, int profile, char* dest) |
| { |
| strcpy(dest, BAND_PATH_STR[band]); |
| strcat(dest, ","); |
| strcat(dest, PROFILE_PATH_STR[profile]); |
| return dest; |
| } |
| |
| static unsigned short *get_speech_param_arr(int band_iter, int profile_iter) |
| { |
| if (band_iter==BAND_NB && profile_iter==PROFILE_NORMAL) |
| return g_default_NB_SPEECH_PARA.speech_mode_nb_para[SPEECH_DRV_LSPEAKER]; |
| if (band_iter==BAND_WB && profile_iter==PROFILE_NORMAL) |
| return g_default_WB_SPEECH_PARA.speech_mode_wb_para[SPEECH_DRV_LSPEAKER]; |
| if (band_iter==BAND_NB && profile_iter==PROFILE_ECALL) |
| return g_default_NB_SPEECH_PARA_ECALL.speech_mode_nb_para[SPEECH_DRV_LSPEAKER]; |
| if (band_iter==BAND_WB && profile_iter==PROFILE_ECALL) |
| return g_default_WB_SPEECH_PARA_ECALL.speech_mode_wb_para[SPEECH_DRV_LSPEAKER]; |
| if (band_iter==BAND_NB && profile_iter==PROFILE_BT) |
| return g_default_NB_SPEECH_PARA.speech_mode_nb_para[SPEECH_DRV_BT_EARPHONE]; |
| if (band_iter==BAND_WB && profile_iter==PROFILE_BT) |
| return g_default_WB_SPEECH_PARA.speech_mode_wb_para[SPEECH_DRV_BT_EARPHONE]; |
| return NULL; |
| } |
| |
| static void copy_speaker_speech_para_to_hp() |
| { |
| int i; |
| for (i=0; i<SPEECH_PARA_NUM; ++i) { |
| g_default_NB_SPEECH_PARA.speech_mode_nb_para[SPEECH_DRV_EARPHONE][i] = |
| g_default_NB_SPEECH_PARA.speech_mode_nb_para[SPEECH_DRV_LSPEAKER][i]; |
| |
| g_default_WB_SPEECH_PARA.speech_mode_wb_para[SPEECH_DRV_EARPHONE][i] = |
| g_default_WB_SPEECH_PARA.speech_mode_wb_para[SPEECH_DRV_LSPEAKER][i]; |
| |
| g_default_NB_SPEECH_PARA_ECALL.speech_mode_nb_para[SPEECH_DRV_EARPHONE][i] = |
| g_default_NB_SPEECH_PARA_ECALL.speech_mode_nb_para[SPEECH_DRV_LSPEAKER][i]; |
| |
| g_default_WB_SPEECH_PARA_ECALL.speech_mode_wb_para[SPEECH_DRV_EARPHONE][i] = |
| g_default_WB_SPEECH_PARA_ECALL.speech_mode_wb_para[SPEECH_DRV_LSPEAKER][i]; |
| } |
| } |
| |
| static void updateSpeech48param(AppHandle *appHandle) |
| { |
| Param *param = NULL; |
| int arr_size, i, band_iter, profile_iter; |
| unsigned short *ushortArray; |
| char path_char[PATH_BUF_SIZE]; |
| int retry_ite = 0; |
| int ret; |
| |
| for (band_iter = 0; band_iter < BAND_NUM; ++band_iter) { |
| for (profile_iter = 0; profile_iter < PROFILE_NUM; ++profile_iter) { |
| getPathString(band_iter, profile_iter, path_char); |
| param = getParamValue(appHandle, XML_TYPE_SPEECH_STR, path_char, |
| SPEECH_PARA); |
| arr_size = getParamArraySize(param); |
| ushortArray = get_speech_param_arr(band_iter, profile_iter); |
| if (!ushortArray) { |
| printf("%s, get_speech_param_arr err, band: %d, profile: %d", |
| __func__, band_iter, profile_iter); |
| continue; |
| } |
| ushortArray = getUShortArrayFromParam(param, ushortArray); |
| } |
| } |
| |
| copy_speaker_speech_para_to_hp(); |
| update_BT_ECNR_recorder(BAND_NB, get_speech_param_arr(BAND_NB, PROFILE_BT)); |
| update_BT_ECNR_recorder(BAND_WB, get_speech_param_arr(BAND_WB, PROFILE_BT)); |
| |
| if (g_bt_client_has_ecnr) { |
| close_all_BT_ECNR_param(BAND_NB, get_speech_param_arr(BAND_NB, PROFILE_BT)); |
| close_all_BT_ECNR_param(BAND_WB, get_speech_param_arr(BAND_WB, PROFILE_BT)); |
| } |
| |
| do { |
| ret = speechdrv_set_speech_mode_nb_para(SPEECH_DRV_LSPEAKER, &g_default_NB_SPEECH_PARA); |
| ++retry_ite; |
| if (!ret) |
| break; |
| usleep(SPEECH_DRV_RETRY_US); |
| } while(retry_ite < SPEECH_DRV_RETRY_TIME); |
| |
| if (ret) { |
| printf("%s, speechdrv_set_speech_mode_nb_para err, errno: %d\n", |
| __func__, ret); |
| } |
| |
| retry_ite = 0; |
| do { |
| ret = speechdrv_set_speech_mode_nb_para(SPEECH_DRV_EARPHONE, &g_default_NB_SPEECH_PARA); |
| ++retry_ite; |
| if (!ret) |
| break; |
| usleep(SPEECH_DRV_RETRY_US); |
| } while(retry_ite < SPEECH_DRV_RETRY_TIME); |
| |
| if (ret) { |
| printf("%s, speechdrv_set_speech_mode_nb_para err, errno: %d\n", |
| __func__, ret); |
| } |
| |
| retry_ite = 0; |
| do { |
| ret = speechdrv_set_speech_mode_nb_para(SPEECH_DRV_BT_EARPHONE, &g_default_NB_SPEECH_PARA); |
| ++retry_ite; |
| if (!ret) |
| break; |
| usleep(SPEECH_DRV_RETRY_US); |
| } while(retry_ite < SPEECH_DRV_RETRY_TIME); |
| |
| if (ret) { |
| printf("%s, speechdrv_set_speech_mode_nb_para err, errno: %d\n", |
| __func__, ret); |
| } |
| |
| retry_ite = 0; |
| do { |
| ret = speechdrv_set_speech_mode_wb_para(SPEECH_DRV_LSPEAKER, &g_default_WB_SPEECH_PARA); |
| ++retry_ite; |
| if (!ret) |
| break; |
| usleep(SPEECH_DRV_RETRY_US); |
| } while(retry_ite < SPEECH_DRV_RETRY_TIME); |
| |
| if (ret) { |
| printf("%s, speechdrv_set_speech_mode_wb_para err, errno: %d\n", |
| __func__, ret); |
| } |
| |
| retry_ite = 0; |
| do { |
| ret = speechdrv_set_speech_mode_wb_para(SPEECH_DRV_EARPHONE, &g_default_WB_SPEECH_PARA); |
| ++retry_ite; |
| if (!ret) |
| break; |
| usleep(SPEECH_DRV_RETRY_US); |
| } while(retry_ite < SPEECH_DRV_RETRY_TIME); |
| |
| if (ret) { |
| printf("%s, speechdrv_set_speech_mode_wb_para err, errno: %d\n", |
| __func__, ret); |
| } |
| |
| retry_ite = 0; |
| do { |
| ret = speechdrv_set_speech_mode_wb_para(SPEECH_DRV_BT_EARPHONE, &g_default_WB_SPEECH_PARA); |
| ++retry_ite; |
| if (!ret) |
| break; |
| usleep(SPEECH_DRV_RETRY_US); |
| } while(retry_ite < SPEECH_DRV_RETRY_TIME); |
| |
| if (ret) { |
| printf("%s, speechdrv_set_speech_mode_wb_para err, errno: %d\n", |
| __func__, ret); |
| } |
| |
| #if 0 //TODO: implement ecall para switch |
| speechdrv_set_ecall_speech_mode_nb_para(SPEECH_DRV_LSPEAKER, &g_default_NB_SPEECH_PARA_ECALL); |
| speechdrv_set_ecall_speech_mode_wb_para(SPEECH_DRV_LSPEAKER, &g_default_WB_SPEECH_PARA_ECALL); |
| #endif |
| } |
| |
| static unsigned short *get_fir_in_param_arr(int band_iter, int profile_iter) |
| { |
| if (band_iter==BAND_NB && profile_iter==PROFILE_NORMAL) |
| return g_default_NB_FIR_PARA.sph_in_fir[SPEECH_DRV_LSPEAKER]; |
| if (band_iter==BAND_WB && profile_iter==PROFILE_NORMAL) |
| return g_default_WB_FIR_PARA.sph_wb_in_fir[SPEECH_DRV_LSPEAKER]; |
| if (band_iter==BAND_NB && profile_iter==PROFILE_ECALL) |
| return g_default_NB_FIR_PARA_ECALL.sph_in_fir[SPEECH_DRV_LSPEAKER]; |
| if (band_iter==BAND_WB && profile_iter==PROFILE_ECALL) |
| return g_default_WB_FIR_PARA_ECALL.sph_wb_in_fir[SPEECH_DRV_LSPEAKER]; |
| if (band_iter==BAND_NB && profile_iter==PROFILE_BT) |
| return g_default_NB_FIR_PARA.sph_in_fir[SPEECH_DRV_BT_EARPHONE]; |
| if (band_iter==BAND_WB && profile_iter==PROFILE_BT) |
| return g_default_WB_FIR_PARA.sph_wb_in_fir[SPEECH_DRV_BT_EARPHONE]; |
| return NULL; |
| } |
| |
| static void copy_speaker_fir_in_para_to_hp() |
| { |
| int i; |
| for (i=0; i<NB_FIR_NUM; ++i) { |
| g_default_NB_FIR_PARA.sph_in_fir[SPEECH_DRV_EARPHONE][i] = |
| g_default_NB_FIR_PARA.sph_in_fir[SPEECH_DRV_LSPEAKER][i]; |
| |
| g_default_NB_FIR_PARA_ECALL.sph_in_fir[SPEECH_DRV_EARPHONE][i] = |
| g_default_NB_FIR_PARA_ECALL.sph_in_fir[SPEECH_DRV_LSPEAKER][i]; |
| } |
| |
| for (i=0; i<WB_FIR_NUM; ++i) { |
| g_default_WB_FIR_PARA.sph_wb_in_fir[SPEECH_DRV_EARPHONE][i] = |
| g_default_WB_FIR_PARA.sph_wb_in_fir[SPEECH_DRV_LSPEAKER][i]; |
| |
| g_default_WB_FIR_PARA_ECALL.sph_wb_in_fir[SPEECH_DRV_EARPHONE][i] = |
| g_default_WB_FIR_PARA_ECALL.sph_wb_in_fir[SPEECH_DRV_LSPEAKER][i]; |
| } |
| } |
| |
| |
| static void updateFirInParam(AppHandle *appHandle) |
| { |
| Param *param = NULL; |
| int arr_size, i, band_iter, profile_iter; |
| short *shortArray; |
| char path_char[PATH_BUF_SIZE]; |
| int ret; |
| int retry_ite = 0; |
| |
| for (band_iter = 0; band_iter < BAND_NUM; ++band_iter) { |
| for (profile_iter = 0; profile_iter < PROFILE_NUM; ++profile_iter) { |
| getPathString(band_iter, profile_iter, path_char); |
| param = getParamValue(appHandle, XML_TYPE_SPEECH_STR, path_char, |
| FIR_IN_PARA); |
| arr_size = getParamArraySize(param); |
| shortArray = get_fir_in_param_arr(band_iter, profile_iter); |
| |
| if (!shortArray) { |
| printf("%s, get_fir_in_param_arr err, band: %d, profile: %d", |
| __func__, band_iter, profile_iter); |
| continue; |
| } |
| |
| shortArray = getShortArrayFromParam(param, shortArray); |
| } |
| } |
| |
| copy_speaker_fir_in_para_to_hp(); |
| |
| do { |
| ret = speechdrv_set_fir_nb_para(SPEECH_DRV_LSPEAKER, &g_default_NB_FIR_PARA); |
| ++retry_ite; |
| if (!ret) |
| break; |
| usleep(SPEECH_DRV_RETRY_US); |
| } while(retry_ite < SPEECH_DRV_RETRY_TIME); |
| |
| if (ret) { |
| printf("%s, speechdrv_set_fir_nb_para err, errno: %d\n", |
| __func__, ret); |
| } |
| |
| retry_ite = 0; |
| do { |
| ret = speechdrv_set_fir_nb_para(SPEECH_DRV_EARPHONE, &g_default_NB_FIR_PARA); |
| ++retry_ite; |
| if (!ret) |
| break; |
| usleep(SPEECH_DRV_RETRY_US); |
| } while(retry_ite < SPEECH_DRV_RETRY_TIME); |
| |
| if (ret) { |
| printf("%s, speechdrv_set_fir_nb_para err, errno: %d\n", |
| __func__, ret); |
| } |
| |
| retry_ite = 0; |
| do { |
| ret = speechdrv_set_fir_nb_para(SPEECH_DRV_BT_EARPHONE, &g_default_NB_FIR_PARA); |
| ++retry_ite; |
| if (!ret) |
| break; |
| usleep(SPEECH_DRV_RETRY_US); |
| } while(retry_ite < SPEECH_DRV_RETRY_TIME); |
| |
| if (ret) { |
| printf("%s, speechdrv_set_fir_nb_para err, errno: %d\n", |
| __func__, ret); |
| } |
| |
| retry_ite = 0; |
| do { |
| ret = speechdrv_set_fir_wb_para(SPEECH_DRV_LSPEAKER, &g_default_WB_FIR_PARA); |
| ++retry_ite; |
| if (!ret) |
| break; |
| usleep(SPEECH_DRV_RETRY_US); |
| } while(retry_ite < SPEECH_DRV_RETRY_TIME); |
| |
| if (ret) { |
| printf("%s, speechdrv_set_fir_wb_para err, errno: %d\n", |
| __func__, ret); |
| } |
| |
| retry_ite = 0; |
| do { |
| ret = speechdrv_set_fir_wb_para(SPEECH_DRV_EARPHONE, &g_default_WB_FIR_PARA); |
| ++retry_ite; |
| if (!ret) |
| break; |
| usleep(SPEECH_DRV_RETRY_US); |
| } while(retry_ite < SPEECH_DRV_RETRY_TIME); |
| |
| if (ret) { |
| printf("%s, speechdrv_set_fir_wb_para err, errno: %d\n", |
| __func__, ret); |
| } |
| |
| retry_ite = 0; |
| do { |
| ret = speechdrv_set_fir_wb_para(SPEECH_DRV_BT_EARPHONE, &g_default_WB_FIR_PARA); |
| ++retry_ite; |
| if (!ret) |
| break; |
| usleep(SPEECH_DRV_RETRY_US); |
| } while(retry_ite < SPEECH_DRV_RETRY_TIME); |
| |
| if (ret) { |
| printf("%s, speechdrv_set_fir_wb_para err, errno: %d\n", |
| __func__, ret); |
| } |
| |
| #if 0 //TODO: implement ecall para switch |
| speechdrv_set_ecall_fir_nb_para(SPEECH_DRV_LSPEAKER, &g_default_NB_FIR_PARA_ECALL); |
| speechdrv_set_ecall_fir_wb_para(SPEECH_DRV_LSPEAKER, &g_default_WB_FIR_PARA_ECALL); |
| #endif |
| } |
| |
| static unsigned short *get_fir_out_param_arr(int band_iter, int profile_iter) |
| { |
| if (band_iter==BAND_NB && profile_iter==PROFILE_NORMAL) |
| return g_default_NB_FIR_PARA.sph_out_fir[SPEECH_DRV_LSPEAKER]; |
| if (band_iter==BAND_WB && profile_iter==PROFILE_NORMAL) |
| return g_default_WB_FIR_PARA.sph_wb_out_fir[SPEECH_DRV_LSPEAKER]; |
| if (band_iter==BAND_NB && profile_iter==PROFILE_ECALL) |
| return g_default_NB_FIR_PARA_ECALL.sph_out_fir[SPEECH_DRV_LSPEAKER]; |
| if (band_iter==BAND_WB && profile_iter==PROFILE_ECALL) |
| return g_default_WB_FIR_PARA_ECALL.sph_wb_out_fir[SPEECH_DRV_LSPEAKER]; |
| if (band_iter==BAND_NB && profile_iter==PROFILE_BT) |
| return g_default_NB_FIR_PARA.sph_out_fir[SPEECH_DRV_BT_EARPHONE]; |
| if (band_iter==BAND_WB && profile_iter==PROFILE_BT) |
| return g_default_WB_FIR_PARA.sph_wb_out_fir[SPEECH_DRV_BT_EARPHONE]; |
| return NULL; |
| } |
| |
| static void copy_speaker_fir_out_para_to_hp() |
| { |
| int i; |
| for (i=0; i<NB_FIR_NUM; ++i) { |
| g_default_NB_FIR_PARA.sph_out_fir[SPEECH_DRV_EARPHONE][i] = |
| g_default_NB_FIR_PARA.sph_out_fir[SPEECH_DRV_LSPEAKER][i]; |
| |
| g_default_NB_FIR_PARA_ECALL.sph_out_fir[SPEECH_DRV_EARPHONE][i] = |
| g_default_NB_FIR_PARA_ECALL.sph_out_fir[SPEECH_DRV_LSPEAKER][i]; |
| } |
| |
| for (i=0; i<WB_FIR_NUM; ++i) { |
| g_default_WB_FIR_PARA.sph_wb_out_fir[SPEECH_DRV_EARPHONE][i] = |
| g_default_WB_FIR_PARA.sph_wb_out_fir[SPEECH_DRV_LSPEAKER][i]; |
| |
| g_default_WB_FIR_PARA_ECALL.sph_wb_out_fir[SPEECH_DRV_EARPHONE][i] = |
| g_default_WB_FIR_PARA_ECALL.sph_wb_out_fir[SPEECH_DRV_LSPEAKER][i]; |
| } |
| } |
| |
| static void updateFirOutParam(AppHandle *appHandle) |
| { |
| Param *param = NULL; |
| int arr_size, band_iter, profile_iter; |
| short *shortArray; |
| char path_char[PATH_BUF_SIZE]; |
| int ret; |
| int retry_ite = 0; |
| |
| for (band_iter = 0; band_iter < BAND_NUM; ++band_iter) { |
| for (profile_iter = 0; profile_iter < PROFILE_NUM; ++profile_iter) { |
| getPathString(band_iter, profile_iter, path_char); |
| param = getParamValue(appHandle, XML_TYPE_SPEECH_STR, path_char, |
| FIR_OUT_PARA); |
| arr_size = getParamArraySize(param); |
| shortArray = get_fir_out_param_arr(band_iter, profile_iter); |
| |
| if(!shortArray) { |
| printf("%s, get_fir_in_param_arr err, band: %d, profile: %d", |
| __func__, band_iter, profile_iter); |
| continue; |
| } |
| |
| shortArray = getShortArrayFromParam(param, shortArray); |
| } |
| } |
| |
| copy_speaker_fir_out_para_to_hp(); |
| |
| do { |
| ret = speechdrv_set_fir_nb_para(SPEECH_DRV_LSPEAKER, &g_default_NB_FIR_PARA); |
| ++retry_ite; |
| if (!ret) |
| break; |
| usleep(SPEECH_DRV_RETRY_US); |
| } while(retry_ite < SPEECH_DRV_RETRY_TIME); |
| |
| if (ret) { |
| printf("%s, speechdrv_set_fir_nb_para err, errno: %d\n", |
| __func__, ret); |
| } |
| |
| retry_ite = 0; |
| do { |
| ret = speechdrv_set_fir_nb_para(SPEECH_DRV_EARPHONE, &g_default_NB_FIR_PARA); |
| ++retry_ite; |
| if (!ret) |
| break; |
| usleep(SPEECH_DRV_RETRY_US); |
| } while(retry_ite < SPEECH_DRV_RETRY_TIME); |
| |
| if (ret) { |
| printf("%s, speechdrv_set_fir_nb_para err, errno: %d\n", |
| __func__, ret); |
| } |
| |
| retry_ite = 0; |
| do { |
| ret = speechdrv_set_fir_nb_para(SPEECH_DRV_BT_EARPHONE, &g_default_NB_FIR_PARA); |
| ++retry_ite; |
| if (!ret) |
| break; |
| usleep(SPEECH_DRV_RETRY_US); |
| } while(retry_ite < SPEECH_DRV_RETRY_TIME); |
| |
| if (ret) { |
| printf("%s, speechdrv_set_fir_nb_para err, errno: %d\n", |
| __func__, ret); |
| } |
| |
| retry_ite = 0; |
| do { |
| ret = speechdrv_set_fir_wb_para(SPEECH_DRV_LSPEAKER, &g_default_WB_FIR_PARA); |
| ++retry_ite; |
| if (!ret) |
| break; |
| usleep(SPEECH_DRV_RETRY_US); |
| } while(retry_ite < SPEECH_DRV_RETRY_TIME); |
| |
| if (ret) { |
| printf("%s, speechdrv_set_fir_wb_para err, errno: %d\n", |
| __func__, ret); |
| } |
| |
| retry_ite = 0; |
| do { |
| ret = speechdrv_set_fir_wb_para(SPEECH_DRV_EARPHONE, &g_default_WB_FIR_PARA); |
| ++retry_ite; |
| if (!ret) |
| break; |
| usleep(SPEECH_DRV_RETRY_US); |
| } while(retry_ite < SPEECH_DRV_RETRY_TIME); |
| |
| if (ret) { |
| printf("%s, speechdrv_set_fir_wb_para err, errno: %d\n", |
| __func__, ret); |
| } |
| |
| retry_ite = 0; |
| do { |
| ret = speechdrv_set_fir_wb_para(SPEECH_DRV_BT_EARPHONE, &g_default_WB_FIR_PARA); |
| ++retry_ite; |
| if (!ret) |
| break; |
| usleep(SPEECH_DRV_RETRY_US); |
| } while(retry_ite < SPEECH_DRV_RETRY_TIME); |
| |
| if (ret) { |
| printf("%s, speechdrv_set_fir_wb_para err, errno: %d\n", |
| __func__, ret); |
| } |
| |
| #if 0 //TODO: implement ecall para switch |
| speechdrv_set_ecall_fir_nb_para(SPEECH_DRV_LSPEAKER, &g_default_NB_FIR_PARA_ECALL); |
| speechdrv_set_ecall_fir_wb_para(SPEECH_DRV_LSPEAKER, &g_default_WB_FIR_PARA_ECALL); |
| #endif |
| |
| } |
| |
| static void updateUlGainParam(AppHandle *appHandle) |
| { |
| Param *param = NULL; |
| int arr_size, band_iter, profile_iter, ul_gain; |
| char path_char[PATH_BUF_SIZE]; |
| |
| getPathString(0, 0, path_char); |
| param = getParamValue(appHandle, XML_TYPE_SPEECHVOL_STR, path_char, |
| UL_GAIN_IDX_PARA); |
| g_ul_gain_idx = (*(int *) param->data) - UL_GAIN_MIN; |
| doUpdateUlGain(); |
| } |
| |
| static void updateUlSwagcGainMapParam(AppHandle *appHandle) |
| { |
| Param *param = NULL; |
| int arr_size, i; |
| short *shortArray; |
| |
| param = getParamValue(appHandle, XML_TYPE_VOLUME_STR, VOLUME_PARAM_PATH, |
| SWAGC_GAIN_MAP_PARA); |
| arr_size = getParamArraySize(param); |
| |
| if (arr_size != UL_GAIN_TABLE_SIZE){ |
| printf("%s, Error! size not match!\n", __func__); |
| printf("size from para: %d, size expected: %d\n", arr_size, |
| UL_GAIN_TABLE_SIZE); |
| printf("We are going to assert to prevent furthur error, plz fix it\n"); |
| assert(false); |
| } |
| |
| shortArray = g_ul_digital_gain_table; |
| shortArray = getShortArrayFromParam(param, shortArray); |
| |
| /* dB value in xml, but for modem driver, 4 = 1dB*/ |
| for (i = 0; i < arr_size; ++i) |
| shortArray[i] = shortArray[i] << 2; |
| |
| doUpdateUlGain(); |
| } |
| |
| static void updateUlPgaGainMapParam(AppHandle *appHandle) |
| { |
| Param *param = NULL; |
| int arr_size; |
| short *shortArray; |
| |
| param = getParamValue(appHandle, XML_TYPE_VOLUME_STR, VOLUME_PARAM_PATH, |
| UL_PGA_GAIN_MAP_PARA); |
| arr_size = getParamArraySize(param); |
| |
| if (arr_size != UL_GAIN_TABLE_SIZE){ |
| printf("%s, Error! size not match!\n", __func__); |
| printf("size from para: %d, size expected: %d\n", arr_size, |
| UL_GAIN_TABLE_SIZE); |
| printf("We are going to assert to prevent furthur error, plz fix it\n"); |
| assert(false); |
| } |
| |
| |
| shortArray = g_ul_analog_gain_table; |
| shortArray = getShortArrayFromParam(param, shortArray); |
| |
| doUpdateUlGain(); |
| } |
| |
| static void doUpdateUlGain(void) |
| { |
| int ret; |
| int retry_ite = 0; |
| |
| if (g_ul_gain_idx >= UL_GAIN_TABLE_SIZE) |
| return; |
| |
| /* digital part */ |
| do { |
| ret = speechdrv_set_ul_digit_volume(g_ul_digital_gain_table[g_ul_gain_idx]); |
| ++retry_ite; |
| if (!ret) |
| break; |
| usleep(SPEECH_DRV_RETRY_US); |
| } while(retry_ite < SPEECH_DRV_RETRY_TIME); |
| |
| if (ret < 0) |
| printf("%s, set ul digit volume error, gain value: %d, errno: %d\n", |
| __func__, g_ul_digital_gain_table[g_ul_gain_idx], ret); |
| |
| /* analog part */ |
| ret = set_UL_analog_gain(g_ul_analog_gain_table[g_ul_gain_idx]); |
| if (ret < 0) |
| printf("%s, set ul analog volume error, gain value: %d, errno: %d\n", |
| __func__, g_ul_analog_gain_table[g_ul_gain_idx], ret); |
| } |
| |
| |
| static void doUpdateDlGain(int retry) |
| { |
| int ret = 0, retry_counter_analog = 5; |
| int retry_speech_drv_ite = 0; |
| |
| if (g_dl_gain_idx >= DL_GAIN_TABLE_SIZE) |
| return; |
| |
| /* digital part */ |
| do { |
| if (g_speech_on_device!=DEV_BT) { |
| ret = speechdrv_set_dl_digit_volume(g_dl_digital_gain_table[g_dl_gain_idx]); |
| } |
| ++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) |
| printf("%s, set dl digit volume error, gain value: %d, errno: %d\n", |
| __func__, g_dl_digital_gain_table[g_dl_gain_idx], ret); |
| |
| /* analog part */ |
| |
| do{ |
| ret = set_DL_analog_gain(g_dl_analog_gain_table[g_dl_gain_idx]); |
| if (!ret) |
| break; |
| usleep(200 * 1000); //prevent write failed for libmodem-ctrl-service |
| --retry_counter_analog; |
| } while(retry && retry_counter_analog); |
| |
| if (ret < 0) |
| printf("%s, set dl analog volume error, gain value: %d, errno: %d\n", |
| __func__, g_dl_analog_gain_table[g_dl_gain_idx], ret); |
| } |
| |
| static void updateDlAnalogGainMapParam(AppHandle *appHandle) |
| { |
| Param *param = NULL; |
| int arr_size; |
| short *shortArray; |
| char path_char[PATH_BUF_SIZE]; |
| |
| /* gain table are the same for all mode*/ |
| getPathString(0, 0, path_char); |
| param = getParamValue(appHandle, XML_TYPE_VOLUMEGAINMAP_STR, path_char, |
| DL_ANALOG_GAIN_MAP_PARA); |
| arr_size = getParamArraySize(param); |
| if (arr_size != DL_GAIN_TABLE_SIZE){ |
| printf("%s, Error! size not match!\n", __func__); |
| printf("size from para: %d, size expected: %d\n", arr_size, |
| DL_GAIN_TABLE_SIZE); |
| printf("We are going to assert to prevent furthur error, plz fix it\n"); |
| assert(false); |
| } |
| shortArray = g_dl_analog_gain_table; |
| shortArray = getShortArrayFromParam(param, shortArray); |
| |
| doUpdateDlGain(0); |
| } |
| |
| static void updateDlDigitalGainMapParam(AppHandle *appHandle) |
| { |
| Param *param = NULL; |
| int arr_size, i; |
| short *shortArray; |
| char path_char[PATH_BUF_SIZE]; |
| |
| /* gain table are the same for all mode*/ |
| getPathString(0, 0, path_char); |
| param = getParamValue(appHandle, XML_TYPE_VOLUMEGAINMAP_STR, path_char, |
| DL_DIGITAL_GAIN_MAP_PARA); |
| arr_size = getParamArraySize(param); |
| if (arr_size != DL_GAIN_TABLE_SIZE){ |
| printf("%s, Error! size not match!\n", __func__); |
| printf("size from para: %d, size expected: %d\n", arr_size, |
| DL_GAIN_TABLE_SIZE); |
| printf("We are going to assert to prevent furthur error, plz fix it\n"); |
| assert(false); |
| } |
| |
| shortArray = g_dl_digital_gain_table; |
| shortArray = getShortArrayFromParam(param, shortArray); |
| |
| /* dB value in xml, but for modem driver, -4 = -1dB*/ |
| for (i = 0; i < arr_size; ++i) |
| shortArray[i] = shortArray[i] << 2; |
| |
| doUpdateDlGain(0); |
| } |
| |
| int audio_ctrl_service_speech_on_inner(int speech_on, int is_BT) |
| { |
| int speech_bool = !!speech_on; |
| int ret; |
| int retry_ite = 0; |
| int device_mode; |
| int speech_dev_mode; |
| |
| if (speech_bool == g_is_speech_on) { |
| printf("speech on status no change! g_is_speech_on: %d\n", |
| g_is_speech_on); |
| return 0; |
| } |
| |
| g_is_speech_on = speech_bool; |
| |
| if (!is_BT) { |
| speech_dev_mode = SPEECH_MODE_LOUD_SPEAKER; |
| speechdrv_set_mdside_sample_rate(16000); |
| } else { |
| speech_dev_mode = SPEECH_MODE_BT_EARPHONE; |
| speechdrv_set_mdside_sample_rate(g_bt_wbs_on? 16000: 8000); |
| } |
| |
| do { |
| speechdrv_set_speech_mode(speech_dev_mode); |
| if (speech_bool || !g_record_buf) { |
| ret = speechdrv_set_speech_on(speech_bool, 0); |
| ++retry_ite; |
| if (!ret) |
| break; |
| } else { //recording!! |
| printf("%s, record is still on\n", __func__); |
| printf("Will auto sppech off after record off, don't worry!\n"); |
| 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 (speech_bool) { |
| if (!is_BT) { |
| device_mode = get_default_device(); |
| g_speech_on_device = device_mode; |
| enable_phone_call_AFE_path(device_mode); |
| } else { |
| device_mode = DEV_BT; |
| g_speech_on_device = device_mode; |
| enable_phone_call_AFE_path(device_mode); |
| } |
| } else { |
| disable_phone_call_AFE_path(); |
| } |
| |
| usleep(100 * 1000);//100ms |
| |
| if (speech_bool) { |
| if (g_speech_on_device!=DEV_BT) { |
| doUpdateDlGain(1); |
| doUpdateUlGain(); |
| } else { |
| speechdrv_set_dl_digit_volume((BT_DL_GAIN_MAX-g_bt_dl_gain) * -256 / (BT_DL_GAIN_MAX-BT_DL_GAIN_MIN)); |
| } |
| } |
| return 0; |
| } |
| |
| int audio_ctrl_service_set_dl_volume_inner(int Db) |
| { |
| if (Db > DL_GAIN_MAX || Db < DL_GAIN_MIN) { |
| printf("Invalid DL gain value: %d\n", Db); |
| return -1; |
| } |
| g_dl_gain_idx = Db - DL_GAIN_MIN; |
| doUpdateDlGain(0); |
| return 0; |
| } |
| |
| int audio_ctrl_service_inCall_record_start_inner(int buf_size) |
| { |
| int ret; |
| |
| AUDIO_V_LOG("%s\n", __func__); |
| if (buf_size > MAX_REC_BUF_SIZE || buf_size <= 0 || buf_size % 2) |
| return -EINVAL; |
| if (g_record_buf) { |
| printf("%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\n", __func__); |
| if (!g_record_buf) { |
| printf("%s, record not start!\n", __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) { |
| printf("%s, speechdrv_set_speech_on failed! err %d\n", __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) { |
| printf("%s, record not start!\n", __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 |
| printf("XRUN reset ptr %s\n", __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\n", __func__); |
| if (!g_record_buf) { |
| printf("%s, record not start!\n", __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\n", __func__); |
| if (!g_record_buf) { |
| printf("%s, record not start!\n", __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) { |
| printf("%s, src_new failed %d\n", __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) { |
| printf("%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) |
| { |
| printf("%s, Invalid packet, sync word: 0x%x\n", __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; |
| } |
| |
| int audio_ctrl_service_inCall_playback_start_inner() |
| { |
| #ifndef PLAYBACK_USE_UT_SINK |
| int ret; |
| |
| AUDIO_V_LOG("%s\n", __func__); |
| if (!g_BGSPlayer_init) { |
| ret = speechdrv_BGSPlayer_Init(); |
| /* TODO: change it when libspeech_drv interface fix*/ |
| /* |
| if (!ret) { |
| printf("%s, BGSPlayer_Init failed\n", __func__); |
| return ret; |
| } |
| */ |
| g_BGSPlayer_init = 1; |
| } |
| |
| if (!g_BGSPlayerBuffer_init) { |
| g_BGSPlayerBuffer_idx = speechdrv_CreateBGSPlayBuffer(16000, 1, AUDIO_FORMAT_PCM_16_BIT); |
| g_BGSPlayerBuffer_init = 1; |
| } else { |
| printf("%s, already start!\n", __func__); |
| return 0; |
| } |
| /* TODO: change it when libspeech_drv interface fix*/ |
| ret = speechdrv_BGSPlayer_Open(0x0, 0xFF); |
| /* |
| if (ret) |
| return 0; |
| else |
| return -EINVAL; |
| */ |
| return 0; |
| #else |
| return UT_BGSOn(); |
| #endif |
| } |
| |
| int audio_ctrl_service_inCall_playback_stop_inner() |
| { |
| #ifndef PLAYBACK_USE_UT_SINK |
| AUDIO_V_LOG("%s\n", __func__); |
| if (!g_BGSPlayerBuffer_init) { |
| printf("%s, already stop!\n", __func__); |
| return 0; |
| } |
| speechdrv_BGSPlayer_Close(); |
| |
| g_BGSPlayerBuffer_init = 0; |
| speechdrv_DestroyBGSPlayBuffer(g_BGSPlayerBuffer_idx); |
| g_BGSPlayerBuffer_idx = 0; |
| |
| return 0; |
| #else |
| return UT_BGSOff(); |
| #endif |
| } |
| |
| int audio_ctrl_service_inCall_playback_send_data_inner(int data_size, const char* data_buf) |
| { |
| #ifndef PLAYBACK_USE_UT_SINK |
| int ret; |
| int write_size; |
| int written_size = 0; |
| int try_cnt = 20; |
| AUDIO_V_LOG("%s\n", __func__); |
| if (!g_BGSPlayerBuffer_init) { |
| printf("%s, not running!\n", __func__); |
| return 0; |
| } |
| |
| while(data_size){ |
| write_size = (data_size>1024)? 1024:data_size; |
| //ret = speechdrv_BGSPlayer_Write(g_BGSPlayerBuffer_idx, data_buf, data_size); |
| ret = speechdrv_BGSPlayer_Write(g_BGSPlayerBuffer_idx, data_buf, write_size); |
| if (ret < 0) { |
| printf("%s, write to BGS error! ret: %d\n", __func__, ret); |
| break; |
| } |
| data_size -= ret; |
| data_buf += ret; |
| written_size += ret; |
| |
| --try_cnt; |
| if(!try_cnt) |
| break; |
| } |
| return written_size; |
| |
| #else |
| return UT_BGSSendData(data_buf, data_size); |
| #endif |
| } |
| |
| int audio_ctrl_service_is_speech_on_inner(int is_BT) |
| { |
| if (!g_is_speech_on) |
| return false; |
| if (!is_BT) |
| return (g_speech_on_device!=DEV_BT); |
| else |
| return (g_speech_on_device==DEV_BT); |
| } |
| |
| int audio_ctrl_service_get_dl_gain_inner() |
| { |
| return g_dl_gain_idx + DL_GAIN_MIN; |
| } |
| |
| int audio_ctrl_service_get_record_period_size_inner() |
| { |
| return RECORD_PERIOD_SIZE; |
| } |
| |
| int audio_ctrl_service_get_playback_period_size_inner() |
| { |
| return PLAYBACK_PERIOD_SIZE; |
| } |
| |
| int audio_ctrl_service_get_record_max_buffer_size_inner() |
| { |
| return RECORD_MAX_BUFFER_SIZE; |
| } |
| |
| int audio_ctrl_service_get_playback_max_buffer_size_inner() |
| { |
| return PLAYBACK_MAX_BUFFER_SIZE; |
| } |
| |
| /* 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_vmlog_record(vmlog_on); |
| } |
| |
| int audio_ctrl_service_get_vmlog_on_inner() |
| { |
| return g_vmlog_on; |
| } |
| |
| /* for BT setting */ |
| int audio_ctrl_service_set_bt_wbs_inner(int bt_wbs_on) |
| { |
| g_bt_wbs_on = !!bt_wbs_on; |
| set_BT_WB(g_bt_wbs_on); |
| return 0; |
| } |
| |
| int audio_ctrl_service_get_bt_wbs_inner() |
| { |
| return g_bt_wbs_on; |
| } |
| |
| int audio_ctrl_service_set_bt_dl_gain_inner(int vol) |
| { |
| if (vol > BT_DL_GAIN_MAX || vol < BT_DL_GAIN_MIN) { |
| printf("Invalid BT DL gain value: %d\n", vol); |
| return -1; |
| } |
| g_bt_dl_gain = vol; |
| |
| if (g_speech_on_device == DEV_BT) |
| speechdrv_set_dl_digit_volume((BT_DL_GAIN_MAX-vol) * -256 / (BT_DL_GAIN_MAX-BT_DL_GAIN_MIN)); |
| |
| return 0; |
| } |
| |
| int audio_ctrl_service_get_bt_dl_gain_inner() |
| { |
| return g_bt_dl_gain; |
| } |
| |
| 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)) { |
| if (bt_client_ecnr_on) { |
| close_all_BT_ECNR_param(BAND_NB, get_speech_param_arr(BAND_NB, PROFILE_BT)); |
| close_all_BT_ECNR_param(BAND_WB, get_speech_param_arr(BAND_WB, PROFILE_BT)); |
| } else { |
| restore_all_BT_ECNR_param(BAND_NB, get_speech_param_arr(BAND_NB, PROFILE_BT)); |
| restore_all_BT_ECNR_param(BAND_WB, get_speech_param_arr(BAND_WB, PROFILE_BT)); |
| } |
| g_bt_client_has_ecnr = !!bt_client_ecnr_on; |
| |
| speechdrv_set_speech_mode_nb_para(SPEECH_DRV_BT_EARPHONE, &g_default_NB_SPEECH_PARA); |
| speechdrv_set_speech_mode_wb_para(SPEECH_DRV_BT_EARPHONE, &g_default_WB_SPEECH_PARA); |
| } |
| return 0; |
| } |
| |
| int audio_ctrl_service_get_bt_client_has_ecnr_inner() |
| { |
| return g_bt_client_has_ecnr; |
| } |
| |
| int audio_ctrl_service_set_use_bt_in_call_inner(int turn_on_bt_in_call) |
| { |
| //if not in call, do nothing |
| if (!g_is_speech_on) return 0; |
| if (turn_on_bt_in_call && g_speech_on_device!=DEV_BT) { |
| g_speech_on_device = DEV_BT; |
| speechdrv_set_speech_mode(SPEECH_MODE_BT_EARPHONE); |
| dynamic_switch_phone_call_path(DEV_BT); |
| speechdrv_set_dl_digit_volume((BT_DL_GAIN_MAX-g_bt_dl_gain) * -256 / (BT_DL_GAIN_MAX-BT_DL_GAIN_MIN)); |
| |
| } else if ( !turn_on_bt_in_call && g_speech_on_device==DEV_BT) { |
| speechdrv_set_speech_mode(SPEECH_MODE_LOUD_SPEAKER); |
| g_speech_on_device = get_default_device(); |
| dynamic_switch_phone_call_path(g_speech_on_device); |
| doUpdateDlGain(1); |
| doUpdateUlGain(); |
| } |
| return 0; |
| } |
| |
| int audio_ctrl_service_get_use_bt_in_call_inner() |
| { |
| if (!g_is_speech_on) return 0; |
| return (g_speech_on_device==DEV_BT); |
| } |
| |
| int audio_ctrl_service_reset_inner() |
| { |
| 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; |
| } |
| |
| /* 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 / 16000 / 2; |
| if (!g_UT_file) { |
| printf("plz send data after turn on\n"); |
| return 0; |
| } |
| fwrite(buf, 1, buf_size, g_UT_file); |
| return buf_size; |
| } |
| |