blob: 8674cc9378819a26b987fe8dd27510f9b5fa1ed0 [file] [log] [blame]
#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;
}