Loading hal/audio_extn/audio_extn.h +3 −0 Original line number Diff line number Diff line Loading @@ -358,4 +358,7 @@ typedef enum { #ifndef AUDIO_FORMAT_E_AC3_JOC #define AUDIO_FORMAT_E_AC3_JOC 0x19000000UL #endif int b64decode(char *inp, int ilen, uint8_t* outp); int b64encode(uint8_t *inp, int ilen, char* outp); #endif /* AUDIO_EXTN_H */ hal/audio_extn/utils.c +154 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,9 @@ #define STRING_TO_ENUM(string) { #string, string } #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) #define BASE_TABLE_SIZE 64 #define MAX_BASEINDEX_LEN 256 struct string_to_enum { const char *name; uint32_t value; Loading Loading @@ -97,6 +100,15 @@ const struct string_to_enum s_format_name_to_enum_table[] = { #endif }; static char bTable[BASE_TABLE_SIZE] = { 'A','B','C','D','E','F','G','H','I','J','K','L', 'M','N','O','P','Q','R','S','T','U','V','W','X', 'Y','Z','a','b','c','d','e','f','g','h','i','j', 'k','l','m','n','o','p','q','r','s','t','u','v', 'w','x','y','z','0','1','2','3','4','5','6','7', '8','9','+','/' }; static uint32_t string_to_enum(const struct string_to_enum *table, size_t size, const char *name) { Loading Loading @@ -567,3 +579,145 @@ void audio_extn_utils_send_audio_calibration(struct audio_device *adev, } } // Base64 Encode and Decode // Not all features supported. This must be used only with following conditions. // Decode Modes: Support with and without padding // CRLF not handling. So no CRLF in string to decode. // Encode Modes: Supports only padding int b64decode(char *inp, int ilen, uint8_t* outp) { int i, j, k, ii, num; int rem, pcnt; uint32_t res=0; uint8_t getIndex[MAX_BASEINDEX_LEN]; uint8_t tmp, cflag; if(inp == NULL || outp == NULL || ilen <= 0) { ALOGE("[%s] received NULL pointer or zero length",__func__); return -1; } memset(getIndex, MAX_BASEINDEX_LEN-1, sizeof(getIndex)); for(i=0;i<BASE_TABLE_SIZE;i++) { getIndex[(uint8_t)bTable[i]] = (uint8_t)i; } getIndex[(uint8_t)'=']=0; j=0;k=0; num = ilen/4; rem = ilen%4; if(rem==0) num = num-1; cflag=0; for(i=0; i<num; i++) { res=0; for(ii=0;ii<4;ii++) { res = res << 6; tmp = getIndex[(uint8_t)inp[j++]]; res = res | tmp; cflag = cflag | tmp; } outp[k++] = (res >> 16)&0xFF; outp[k++] = (res >> 8)&0xFF; outp[k++] = res & 0xFF; } // Handle last bytes special pcnt=0; if(rem == 0) { //With padding or full data res = 0; for(ii=0;ii<4;ii++) { if(inp[j] == '=') pcnt++; res = res << 6; tmp = getIndex[(uint8_t)inp[j++]]; res = res | tmp; cflag = cflag | tmp; } outp[k++] = res >> 16; if(pcnt == 2) goto done; outp[k++] = (res>>8)&0xFF; if(pcnt == 1) goto done; outp[k++] = res&0xFF; } else { //without padding res = 0; for(i=0;i<rem;i++) { res = res << 6; tmp = getIndex[(uint8_t)inp[j++]]; res = res | tmp; cflag = cflag | tmp; } for(i=rem;i<4;i++) { res = res << 6; pcnt++; } outp[k++] = res >> 16; if(pcnt == 2) goto done; outp[k++] = (res>>8)&0xFF; if(pcnt == 1) goto done; outp[k++] = res&0xFF; } done: if(cflag == 0xFF) { ALOGE("[%s] base64 decode failed. Invalid character found %s", __func__, inp); return 0; } return k; } int b64encode(uint8_t *inp, int ilen, char* outp) { int i,j,k, num; int rem=0; uint32_t res=0; if(inp == NULL || outp == NULL || ilen<=0) { ALOGE("[%s] received NULL pointer or zero input length",__func__); return -1; } num = ilen/3; rem = ilen%3; j=0;k=0; for(i=0; i<num; i++) { //prepare index res = inp[j++]<<16; res = res | inp[j++]<<8; res = res | inp[j++]; //get output map from index outp[k++] = (char) bTable[(res>>18)&0x3F]; outp[k++] = (char) bTable[(res>>12)&0x3F]; outp[k++] = (char) bTable[(res>>6)&0x3F]; outp[k++] = (char) bTable[res&0x3F]; } switch(rem) { case 1: res = inp[j++]<<16; outp[k++] = (char) bTable[res>>18]; outp[k++] = (char) bTable[(res>>12)&0x3F]; //outp[k++] = '='; //outp[k++] = '='; break; case 2: res = inp[j++]<<16; res = res | inp[j++]<<8; outp[k++] = (char) bTable[res>>18]; outp[k++] = (char) bTable[(res>>12)&0x3F]; outp[k++] = (char) bTable[(res>>6)&0x3F]; //outp[k++] = '='; break; default: break; } done: outp[k] = '\0'; return k; } hal/msm8974/platform.c +277 −7 Original line number Diff line number Diff line Loading @@ -91,10 +91,16 @@ #define SAMPLE_RATE_8KHZ 8000 #define SAMPLE_RATE_16KHZ 16000 #define MAX_SET_CAL_BYTE_SIZE 65536 #define AUDIO_PARAMETER_KEY_FLUENCE_TYPE "fluence" #define AUDIO_PARAMETER_KEY_SLOWTALK "st_enable" #define AUDIO_PARAMETER_KEY_HD_VOICE "hd_voice" #define AUDIO_PARAMETER_KEY_VOLUME_BOOST "volume_boost" #define AUDIO_PARAMETER_KEY_AUD_CALDATA "cal_data" #define AUDIO_PARAMETER_KEY_AUD_CALRESULT "cal_result" /* Query external audio device connection status */ #define AUDIO_PARAMETER_KEY_EXT_AUDIO_DEVICE "ext_audio_device" Loading @@ -120,6 +126,19 @@ struct audio_block_header int length; }; typedef struct acdb_audio_cal_cfg { uint32_t persist; uint32_t snd_dev_id; audio_devices_t dev_id; int32_t acdb_dev_id; uint32_t app_type; uint32_t topo_id; uint32_t sampling_rate; uint32_t cal_type; uint32_t module_id; uint32_t param_id; } acdb_audio_cal_cfg_t; /* Audio calibration related functions */ typedef void (*acdb_deallocate_t)(); typedef int (*acdb_init_t)(const char *, char *); Loading @@ -129,6 +148,8 @@ typedef int (*acdb_reload_vocvoltable_t)(int); typedef int (*acdb_get_default_app_type_t)(void); typedef int (*acdb_loader_get_calibration_t)(char *attr, int size, void *data); acdb_loader_get_calibration_t acdb_loader_get_calibration; typedef int (*acdb_set_audio_cal_t) (void *, void *, uint32_t); typedef int (*acdb_get_audio_cal_t) (void *, void *, uint32_t*); struct platform_data { struct audio_device *adev; Loading @@ -152,6 +173,8 @@ struct platform_data { acdb_init_t acdb_init; acdb_deallocate_t acdb_deallocate; acdb_send_audio_cal_t acdb_send_audio_cal; acdb_set_audio_cal_t acdb_set_audio_cal; acdb_get_audio_cal_t acdb_get_audio_cal; acdb_send_voice_cal_t acdb_send_voice_cal; acdb_reload_vocvoltable_t acdb_reload_vocvoltable; acdb_get_default_app_type_t acdb_get_default_app_type; Loading Loading @@ -1068,6 +1091,18 @@ void *platform_init(struct audio_device *adev) ALOGE("%s: Could not find the symbol acdb_send_audio_cal from %s", __func__, LIB_ACDB_LOADER); my_data->acdb_set_audio_cal = (acdb_set_audio_cal_t)dlsym(my_data->acdb_handle, "acdb_loader_set_audio_cal_v2"); if (!my_data->acdb_set_audio_cal) ALOGE("%s: Could not find the symbol acdb_set_audio_cal_v2 from %s", __func__, LIB_ACDB_LOADER); my_data->acdb_get_audio_cal = (acdb_get_audio_cal_t)dlsym(my_data->acdb_handle, "acdb_loader_get_audio_cal_v2"); if (!my_data->acdb_get_audio_cal) ALOGE("%s: Could not find the symbol acdb_get_audio_cal_v2 from %s", __func__, LIB_ACDB_LOADER); my_data->acdb_send_voice_cal = (acdb_send_voice_cal_t)dlsym(my_data->acdb_handle, "acdb_loader_send_voice_cal"); if (!my_data->acdb_send_voice_cal) Loading Loading @@ -2285,18 +2320,150 @@ static int update_external_device_status(struct platform_data *my_data, return ret; } static int parse_audiocal_cfg(struct str_parms *parms, acdb_audio_cal_cfg_t *cal) { int err; unsigned int val; char value[64]; int ret = 0; if(parms == NULL || cal == NULL) return ret; err = str_parms_get_str(parms, "cal_persist", value, sizeof(value)); if (err >= 0) { str_parms_del(parms, "cal_persist"); cal->persist = (uint32_t) strtoul(value, NULL, 0); ret = ret | 0x1; } err = str_parms_get_str(parms, "cal_apptype", value, sizeof(value)); if (err >= 0) { str_parms_del(parms, "cal_apptype"); cal->app_type = (uint32_t) strtoul(value, NULL, 0); ret = ret | 0x2; } err = str_parms_get_str(parms, "cal_caltype", value, sizeof(value)); if (err >= 0) { str_parms_del(parms, "cal_caltype"); cal->cal_type = (uint32_t) strtoul(value, NULL, 0); ret = ret | 0x4; } err = str_parms_get_str(parms, "cal_samplerate", value, sizeof(value)); if (err >= 0) { str_parms_del(parms, "cal_samplerate"); cal->sampling_rate = (uint32_t) strtoul(value, NULL, 0); ret = ret | 0x8; } err = str_parms_get_str(parms, "cal_devid", value, sizeof(value)); if (err >= 0) { str_parms_del(parms, "cal_devid"); cal->dev_id = (uint32_t) strtoul(value, NULL, 0); ret = ret | 0x10; } err = str_parms_get_str(parms, "cal_snddevid", value, sizeof(value)); if (err >= 0) { str_parms_del(parms, "cal_snddevid"); cal->snd_dev_id = (uint32_t) strtoul(value, NULL, 0); ret = ret | 0x20; } err = str_parms_get_str(parms, "cal_topoid", value, sizeof(value)); if (err >= 0) { str_parms_del(parms, "cal_topoid"); cal->topo_id = (uint32_t) strtoul(value, NULL, 0); ret = ret | 0x40; } err = str_parms_get_str(parms, "cal_moduleid", value, sizeof(value)); if (err >= 0) { str_parms_del(parms, "cal_moduleid"); cal->module_id = (uint32_t) strtoul(value, NULL, 0); ret = ret | 0x80; } err = str_parms_get_str(parms, "cal_paramid", value, sizeof(value)); if (err >= 0) { str_parms_del(parms, "cal_paramid"); cal->param_id = (uint32_t) strtoul(value, NULL, 0); ret = ret | 0x100; } return ret; } static void set_audiocal(void *platform, struct str_parms *parms, char *value, int len) { struct platform_data *my_data = (struct platform_data *)platform; acdb_audio_cal_cfg_t cal={0}; uint8_t *dptr = NULL; int32_t dlen; int err, ret; if(value == NULL || platform == NULL || parms == NULL) { ALOGE("[%s] received null pointer, failed",__func__); goto done_key_audcal; } /* parse audio calibration keys */ ret = parse_audiocal_cfg(parms, &cal); /* handle audio calibration data now */ err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_AUD_CALDATA, value, len); if (err >= 0) { str_parms_del(parms, AUDIO_PARAMETER_KEY_AUD_CALDATA); dlen = strlen(value); if(dlen <= 0) { ALOGE("[%s] null data received",__func__); goto done_key_audcal; } dptr = (uint8_t*) calloc(dlen, sizeof(uint8_t)); if(dptr == NULL) { ALOGE("[%s] memory allocation failed for %d",__func__, dlen); goto done_key_audcal; } dlen = b64decode(value, strlen(value), dptr); if(dlen<=0) { ALOGE("[%s] data decoding failed %d", __func__, dlen); goto done_key_audcal; } if(cal.dev_id) { if(audio_is_input_device(cal.dev_id)) { cal.snd_dev_id = platform_get_input_snd_device(platform, cal.dev_id); } else { cal.snd_dev_id = platform_get_output_snd_device(platform, cal.dev_id); } } cal.acdb_dev_id = platform_get_snd_device_acdb_id(cal.snd_dev_id); ALOGD("Setting audio calibration for snd_device(%d) acdb_id(%d)", cal.snd_dev_id, cal.acdb_dev_id); if(cal.acdb_dev_id == -EINVAL) { ALOGE("[%s] Invalid acdb_device id %d for snd device id %d", __func__, cal.acdb_dev_id, cal.snd_dev_id); goto done_key_audcal; } if(my_data->acdb_set_audio_cal) { ret = my_data->acdb_set_audio_cal((void *)&cal, (void*)dptr, dlen); } } done_key_audcal: if(dptr != NULL) free(dptr); } int platform_set_parameters(void *platform, struct str_parms *parms) { struct platform_data *my_data = (struct platform_data *)platform; char *str; char value[256] = {0}; int val; char *value=NULL; int val, len; int ret = 0, err; char *kv_pairs = str_parms_to_str(parms); ALOGV_IF(kv_pairs != NULL, "%s: enter: %s", __func__, kv_pairs); err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_SLOWTALK, value, sizeof(value)); len = strlen(kv_pairs); value = (char*)calloc(len, sizeof(char)); if(value == NULL) { ret = -ENOMEM; ALOGE("[%s] failed to allocate memory",__func__); goto done; } err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_SLOWTALK, value, len); if (err >= 0) { bool state = false; if (!strncmp("true", value, sizeof("true"))) { Loading @@ -2309,7 +2476,7 @@ int platform_set_parameters(void *platform, struct str_parms *parms) ALOGE("%s: Failed to set slow talk err: %d", __func__, ret); } err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_HD_VOICE, value, sizeof(value)); err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_HD_VOICE, value, len); if (err >= 0) { bool state = false; if (!strncmp("true", value, sizeof("true"))) { Loading @@ -2327,7 +2494,7 @@ int platform_set_parameters(void *platform, struct str_parms *parms) } err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_VOLUME_BOOST, value, sizeof(value)); value, len); if (err >= 0) { str_parms_del(parms, AUDIO_PARAMETER_KEY_VOLUME_BOOST); Loading @@ -2345,7 +2512,7 @@ int platform_set_parameters(void *platform, struct str_parms *parms) } err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_EXT_AUDIO_DEVICE, value, sizeof(value)); value, len); if (err >= 0) { char *event_name, *status_str; bool status = false; Loading @@ -2361,8 +2528,14 @@ int platform_set_parameters(void *platform, struct str_parms *parms) update_external_device_status(my_data, event_name, status); } /* handle audio calibration parameters */ set_audiocal(platform, parms, value, len); done: ALOGV("%s: exit with code(%d)", __func__, ret); free(kv_pairs); if(value != NULL) free(value); return ret; } Loading Loading @@ -2466,13 +2639,106 @@ int platform_update_lch(void *platform, struct voice_session *session, return ret; } static void get_audiocal(void *platform, void *keys, void *pReply) { struct platform_data *my_data = (struct platform_data *)platform; struct str_parms *query = (struct str_parms *)keys; struct str_parms *reply=(struct str_parms *)pReply; acdb_audio_cal_cfg_t cal={0}; uint8_t *dptr = NULL; char value[512] = {0}; char *rparms=NULL; int ret=0, err; uint32_t param_len; if(query==NULL || platform==NULL || reply==NULL) { ALOGE("[%s] received null pointer",__func__); ret=-EINVAL; goto done; } /* parse audiocal configuration keys */ ret = parse_audiocal_cfg(query, &cal); if(ret == 0) { /* No calibration keys found */ goto done; } err = str_parms_get_str(query, AUDIO_PARAMETER_KEY_AUD_CALDATA, value, sizeof(value)); if (err >= 0) { str_parms_del(query, AUDIO_PARAMETER_KEY_AUD_CALDATA); } else { goto done; } if(cal.dev_id & AUDIO_DEVICE_BIT_IN) { cal.snd_dev_id = platform_get_input_snd_device(platform, cal.dev_id); } else if(cal.dev_id) { cal.snd_dev_id = platform_get_output_snd_device(platform, cal.dev_id); } cal.acdb_dev_id = platform_get_snd_device_acdb_id(cal.snd_dev_id); if (cal.acdb_dev_id < 0) { ALOGE("%s: Failed. Could not find acdb id for snd device(%d)", __func__, cal.snd_dev_id); ret = -EINVAL; goto done_key_audcal; } ALOGD("[%s] Getting audio calibration for snd_device(%d) acdb_id(%d)", __func__, cal.snd_dev_id, cal.acdb_dev_id); param_len = MAX_SET_CAL_BYTE_SIZE; dptr = (uint8_t*)calloc(param_len, sizeof(uint8_t)); if(dptr == NULL) { ALOGE("[%s] Memory allocation failed for length %d",__func__,param_len); ret = -ENOMEM; goto done_key_audcal; } if (my_data->acdb_get_audio_cal != NULL) { ret = my_data->acdb_get_audio_cal((void*)&cal, (void*)dptr, ¶m_len); if (ret == 0) { int dlen; if(param_len == 0 || param_len == MAX_SET_CAL_BYTE_SIZE) { ret = -EINVAL; goto done_key_audcal; } /* Allocate memory for encoding */ rparms = (char*)calloc((param_len*2), sizeof(char)); if(rparms == NULL) { ALOGE("[%s] Memory allocation failed for size %d", __func__, param_len*2); ret = -ENOMEM; goto done_key_audcal; } if(cal.persist==0 && cal.module_id && cal.param_id) { err = b64encode(dptr+12, param_len-12, rparms); } else { err = b64encode(dptr, param_len, rparms); } if(err < 0) { ALOGE("[%s] failed to convert data to string", __func__); ret = -EINVAL; goto done_key_audcal; } str_parms_add_int(reply, AUDIO_PARAMETER_KEY_AUD_CALRESULT, ret); str_parms_add_str(reply, AUDIO_PARAMETER_KEY_AUD_CALDATA, rparms); } } done_key_audcal: if(ret != 0) { str_parms_add_int(reply, AUDIO_PARAMETER_KEY_AUD_CALRESULT, ret); str_parms_add_str(reply, AUDIO_PARAMETER_KEY_AUD_CALDATA, ""); } done: if(dptr != NULL) free(dptr); if(rparms != NULL) free(rparms); } void platform_get_parameters(void *platform, struct str_parms *query, struct str_parms *reply) { struct platform_data *my_data = (struct platform_data *)platform; char *str = NULL; char value[256] = {0}; char value[512] = {0}; int ret; char *kv_pairs = NULL; Loading Loading @@ -2502,6 +2768,10 @@ void platform_get_parameters(void *platform, str_parms_add_str(reply, AUDIO_PARAMETER_KEY_VOLUME_BOOST, value); } /* Handle audio calibration keys */ get_audiocal(platform, query, reply); done: kv_pairs = str_parms_to_str(reply); ALOGV_IF(kv_pairs != NULL, "%s: exit: returns - %s", __func__, kv_pairs); free(kv_pairs); Loading Loading
hal/audio_extn/audio_extn.h +3 −0 Original line number Diff line number Diff line Loading @@ -358,4 +358,7 @@ typedef enum { #ifndef AUDIO_FORMAT_E_AC3_JOC #define AUDIO_FORMAT_E_AC3_JOC 0x19000000UL #endif int b64decode(char *inp, int ilen, uint8_t* outp); int b64encode(uint8_t *inp, int ilen, char* outp); #endif /* AUDIO_EXTN_H */
hal/audio_extn/utils.c +154 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,9 @@ #define STRING_TO_ENUM(string) { #string, string } #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) #define BASE_TABLE_SIZE 64 #define MAX_BASEINDEX_LEN 256 struct string_to_enum { const char *name; uint32_t value; Loading Loading @@ -97,6 +100,15 @@ const struct string_to_enum s_format_name_to_enum_table[] = { #endif }; static char bTable[BASE_TABLE_SIZE] = { 'A','B','C','D','E','F','G','H','I','J','K','L', 'M','N','O','P','Q','R','S','T','U','V','W','X', 'Y','Z','a','b','c','d','e','f','g','h','i','j', 'k','l','m','n','o','p','q','r','s','t','u','v', 'w','x','y','z','0','1','2','3','4','5','6','7', '8','9','+','/' }; static uint32_t string_to_enum(const struct string_to_enum *table, size_t size, const char *name) { Loading Loading @@ -567,3 +579,145 @@ void audio_extn_utils_send_audio_calibration(struct audio_device *adev, } } // Base64 Encode and Decode // Not all features supported. This must be used only with following conditions. // Decode Modes: Support with and without padding // CRLF not handling. So no CRLF in string to decode. // Encode Modes: Supports only padding int b64decode(char *inp, int ilen, uint8_t* outp) { int i, j, k, ii, num; int rem, pcnt; uint32_t res=0; uint8_t getIndex[MAX_BASEINDEX_LEN]; uint8_t tmp, cflag; if(inp == NULL || outp == NULL || ilen <= 0) { ALOGE("[%s] received NULL pointer or zero length",__func__); return -1; } memset(getIndex, MAX_BASEINDEX_LEN-1, sizeof(getIndex)); for(i=0;i<BASE_TABLE_SIZE;i++) { getIndex[(uint8_t)bTable[i]] = (uint8_t)i; } getIndex[(uint8_t)'=']=0; j=0;k=0; num = ilen/4; rem = ilen%4; if(rem==0) num = num-1; cflag=0; for(i=0; i<num; i++) { res=0; for(ii=0;ii<4;ii++) { res = res << 6; tmp = getIndex[(uint8_t)inp[j++]]; res = res | tmp; cflag = cflag | tmp; } outp[k++] = (res >> 16)&0xFF; outp[k++] = (res >> 8)&0xFF; outp[k++] = res & 0xFF; } // Handle last bytes special pcnt=0; if(rem == 0) { //With padding or full data res = 0; for(ii=0;ii<4;ii++) { if(inp[j] == '=') pcnt++; res = res << 6; tmp = getIndex[(uint8_t)inp[j++]]; res = res | tmp; cflag = cflag | tmp; } outp[k++] = res >> 16; if(pcnt == 2) goto done; outp[k++] = (res>>8)&0xFF; if(pcnt == 1) goto done; outp[k++] = res&0xFF; } else { //without padding res = 0; for(i=0;i<rem;i++) { res = res << 6; tmp = getIndex[(uint8_t)inp[j++]]; res = res | tmp; cflag = cflag | tmp; } for(i=rem;i<4;i++) { res = res << 6; pcnt++; } outp[k++] = res >> 16; if(pcnt == 2) goto done; outp[k++] = (res>>8)&0xFF; if(pcnt == 1) goto done; outp[k++] = res&0xFF; } done: if(cflag == 0xFF) { ALOGE("[%s] base64 decode failed. Invalid character found %s", __func__, inp); return 0; } return k; } int b64encode(uint8_t *inp, int ilen, char* outp) { int i,j,k, num; int rem=0; uint32_t res=0; if(inp == NULL || outp == NULL || ilen<=0) { ALOGE("[%s] received NULL pointer or zero input length",__func__); return -1; } num = ilen/3; rem = ilen%3; j=0;k=0; for(i=0; i<num; i++) { //prepare index res = inp[j++]<<16; res = res | inp[j++]<<8; res = res | inp[j++]; //get output map from index outp[k++] = (char) bTable[(res>>18)&0x3F]; outp[k++] = (char) bTable[(res>>12)&0x3F]; outp[k++] = (char) bTable[(res>>6)&0x3F]; outp[k++] = (char) bTable[res&0x3F]; } switch(rem) { case 1: res = inp[j++]<<16; outp[k++] = (char) bTable[res>>18]; outp[k++] = (char) bTable[(res>>12)&0x3F]; //outp[k++] = '='; //outp[k++] = '='; break; case 2: res = inp[j++]<<16; res = res | inp[j++]<<8; outp[k++] = (char) bTable[res>>18]; outp[k++] = (char) bTable[(res>>12)&0x3F]; outp[k++] = (char) bTable[(res>>6)&0x3F]; //outp[k++] = '='; break; default: break; } done: outp[k] = '\0'; return k; }
hal/msm8974/platform.c +277 −7 Original line number Diff line number Diff line Loading @@ -91,10 +91,16 @@ #define SAMPLE_RATE_8KHZ 8000 #define SAMPLE_RATE_16KHZ 16000 #define MAX_SET_CAL_BYTE_SIZE 65536 #define AUDIO_PARAMETER_KEY_FLUENCE_TYPE "fluence" #define AUDIO_PARAMETER_KEY_SLOWTALK "st_enable" #define AUDIO_PARAMETER_KEY_HD_VOICE "hd_voice" #define AUDIO_PARAMETER_KEY_VOLUME_BOOST "volume_boost" #define AUDIO_PARAMETER_KEY_AUD_CALDATA "cal_data" #define AUDIO_PARAMETER_KEY_AUD_CALRESULT "cal_result" /* Query external audio device connection status */ #define AUDIO_PARAMETER_KEY_EXT_AUDIO_DEVICE "ext_audio_device" Loading @@ -120,6 +126,19 @@ struct audio_block_header int length; }; typedef struct acdb_audio_cal_cfg { uint32_t persist; uint32_t snd_dev_id; audio_devices_t dev_id; int32_t acdb_dev_id; uint32_t app_type; uint32_t topo_id; uint32_t sampling_rate; uint32_t cal_type; uint32_t module_id; uint32_t param_id; } acdb_audio_cal_cfg_t; /* Audio calibration related functions */ typedef void (*acdb_deallocate_t)(); typedef int (*acdb_init_t)(const char *, char *); Loading @@ -129,6 +148,8 @@ typedef int (*acdb_reload_vocvoltable_t)(int); typedef int (*acdb_get_default_app_type_t)(void); typedef int (*acdb_loader_get_calibration_t)(char *attr, int size, void *data); acdb_loader_get_calibration_t acdb_loader_get_calibration; typedef int (*acdb_set_audio_cal_t) (void *, void *, uint32_t); typedef int (*acdb_get_audio_cal_t) (void *, void *, uint32_t*); struct platform_data { struct audio_device *adev; Loading @@ -152,6 +173,8 @@ struct platform_data { acdb_init_t acdb_init; acdb_deallocate_t acdb_deallocate; acdb_send_audio_cal_t acdb_send_audio_cal; acdb_set_audio_cal_t acdb_set_audio_cal; acdb_get_audio_cal_t acdb_get_audio_cal; acdb_send_voice_cal_t acdb_send_voice_cal; acdb_reload_vocvoltable_t acdb_reload_vocvoltable; acdb_get_default_app_type_t acdb_get_default_app_type; Loading Loading @@ -1068,6 +1091,18 @@ void *platform_init(struct audio_device *adev) ALOGE("%s: Could not find the symbol acdb_send_audio_cal from %s", __func__, LIB_ACDB_LOADER); my_data->acdb_set_audio_cal = (acdb_set_audio_cal_t)dlsym(my_data->acdb_handle, "acdb_loader_set_audio_cal_v2"); if (!my_data->acdb_set_audio_cal) ALOGE("%s: Could not find the symbol acdb_set_audio_cal_v2 from %s", __func__, LIB_ACDB_LOADER); my_data->acdb_get_audio_cal = (acdb_get_audio_cal_t)dlsym(my_data->acdb_handle, "acdb_loader_get_audio_cal_v2"); if (!my_data->acdb_get_audio_cal) ALOGE("%s: Could not find the symbol acdb_get_audio_cal_v2 from %s", __func__, LIB_ACDB_LOADER); my_data->acdb_send_voice_cal = (acdb_send_voice_cal_t)dlsym(my_data->acdb_handle, "acdb_loader_send_voice_cal"); if (!my_data->acdb_send_voice_cal) Loading Loading @@ -2285,18 +2320,150 @@ static int update_external_device_status(struct platform_data *my_data, return ret; } static int parse_audiocal_cfg(struct str_parms *parms, acdb_audio_cal_cfg_t *cal) { int err; unsigned int val; char value[64]; int ret = 0; if(parms == NULL || cal == NULL) return ret; err = str_parms_get_str(parms, "cal_persist", value, sizeof(value)); if (err >= 0) { str_parms_del(parms, "cal_persist"); cal->persist = (uint32_t) strtoul(value, NULL, 0); ret = ret | 0x1; } err = str_parms_get_str(parms, "cal_apptype", value, sizeof(value)); if (err >= 0) { str_parms_del(parms, "cal_apptype"); cal->app_type = (uint32_t) strtoul(value, NULL, 0); ret = ret | 0x2; } err = str_parms_get_str(parms, "cal_caltype", value, sizeof(value)); if (err >= 0) { str_parms_del(parms, "cal_caltype"); cal->cal_type = (uint32_t) strtoul(value, NULL, 0); ret = ret | 0x4; } err = str_parms_get_str(parms, "cal_samplerate", value, sizeof(value)); if (err >= 0) { str_parms_del(parms, "cal_samplerate"); cal->sampling_rate = (uint32_t) strtoul(value, NULL, 0); ret = ret | 0x8; } err = str_parms_get_str(parms, "cal_devid", value, sizeof(value)); if (err >= 0) { str_parms_del(parms, "cal_devid"); cal->dev_id = (uint32_t) strtoul(value, NULL, 0); ret = ret | 0x10; } err = str_parms_get_str(parms, "cal_snddevid", value, sizeof(value)); if (err >= 0) { str_parms_del(parms, "cal_snddevid"); cal->snd_dev_id = (uint32_t) strtoul(value, NULL, 0); ret = ret | 0x20; } err = str_parms_get_str(parms, "cal_topoid", value, sizeof(value)); if (err >= 0) { str_parms_del(parms, "cal_topoid"); cal->topo_id = (uint32_t) strtoul(value, NULL, 0); ret = ret | 0x40; } err = str_parms_get_str(parms, "cal_moduleid", value, sizeof(value)); if (err >= 0) { str_parms_del(parms, "cal_moduleid"); cal->module_id = (uint32_t) strtoul(value, NULL, 0); ret = ret | 0x80; } err = str_parms_get_str(parms, "cal_paramid", value, sizeof(value)); if (err >= 0) { str_parms_del(parms, "cal_paramid"); cal->param_id = (uint32_t) strtoul(value, NULL, 0); ret = ret | 0x100; } return ret; } static void set_audiocal(void *platform, struct str_parms *parms, char *value, int len) { struct platform_data *my_data = (struct platform_data *)platform; acdb_audio_cal_cfg_t cal={0}; uint8_t *dptr = NULL; int32_t dlen; int err, ret; if(value == NULL || platform == NULL || parms == NULL) { ALOGE("[%s] received null pointer, failed",__func__); goto done_key_audcal; } /* parse audio calibration keys */ ret = parse_audiocal_cfg(parms, &cal); /* handle audio calibration data now */ err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_AUD_CALDATA, value, len); if (err >= 0) { str_parms_del(parms, AUDIO_PARAMETER_KEY_AUD_CALDATA); dlen = strlen(value); if(dlen <= 0) { ALOGE("[%s] null data received",__func__); goto done_key_audcal; } dptr = (uint8_t*) calloc(dlen, sizeof(uint8_t)); if(dptr == NULL) { ALOGE("[%s] memory allocation failed for %d",__func__, dlen); goto done_key_audcal; } dlen = b64decode(value, strlen(value), dptr); if(dlen<=0) { ALOGE("[%s] data decoding failed %d", __func__, dlen); goto done_key_audcal; } if(cal.dev_id) { if(audio_is_input_device(cal.dev_id)) { cal.snd_dev_id = platform_get_input_snd_device(platform, cal.dev_id); } else { cal.snd_dev_id = platform_get_output_snd_device(platform, cal.dev_id); } } cal.acdb_dev_id = platform_get_snd_device_acdb_id(cal.snd_dev_id); ALOGD("Setting audio calibration for snd_device(%d) acdb_id(%d)", cal.snd_dev_id, cal.acdb_dev_id); if(cal.acdb_dev_id == -EINVAL) { ALOGE("[%s] Invalid acdb_device id %d for snd device id %d", __func__, cal.acdb_dev_id, cal.snd_dev_id); goto done_key_audcal; } if(my_data->acdb_set_audio_cal) { ret = my_data->acdb_set_audio_cal((void *)&cal, (void*)dptr, dlen); } } done_key_audcal: if(dptr != NULL) free(dptr); } int platform_set_parameters(void *platform, struct str_parms *parms) { struct platform_data *my_data = (struct platform_data *)platform; char *str; char value[256] = {0}; int val; char *value=NULL; int val, len; int ret = 0, err; char *kv_pairs = str_parms_to_str(parms); ALOGV_IF(kv_pairs != NULL, "%s: enter: %s", __func__, kv_pairs); err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_SLOWTALK, value, sizeof(value)); len = strlen(kv_pairs); value = (char*)calloc(len, sizeof(char)); if(value == NULL) { ret = -ENOMEM; ALOGE("[%s] failed to allocate memory",__func__); goto done; } err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_SLOWTALK, value, len); if (err >= 0) { bool state = false; if (!strncmp("true", value, sizeof("true"))) { Loading @@ -2309,7 +2476,7 @@ int platform_set_parameters(void *platform, struct str_parms *parms) ALOGE("%s: Failed to set slow talk err: %d", __func__, ret); } err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_HD_VOICE, value, sizeof(value)); err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_HD_VOICE, value, len); if (err >= 0) { bool state = false; if (!strncmp("true", value, sizeof("true"))) { Loading @@ -2327,7 +2494,7 @@ int platform_set_parameters(void *platform, struct str_parms *parms) } err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_VOLUME_BOOST, value, sizeof(value)); value, len); if (err >= 0) { str_parms_del(parms, AUDIO_PARAMETER_KEY_VOLUME_BOOST); Loading @@ -2345,7 +2512,7 @@ int platform_set_parameters(void *platform, struct str_parms *parms) } err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_EXT_AUDIO_DEVICE, value, sizeof(value)); value, len); if (err >= 0) { char *event_name, *status_str; bool status = false; Loading @@ -2361,8 +2528,14 @@ int platform_set_parameters(void *platform, struct str_parms *parms) update_external_device_status(my_data, event_name, status); } /* handle audio calibration parameters */ set_audiocal(platform, parms, value, len); done: ALOGV("%s: exit with code(%d)", __func__, ret); free(kv_pairs); if(value != NULL) free(value); return ret; } Loading Loading @@ -2466,13 +2639,106 @@ int platform_update_lch(void *platform, struct voice_session *session, return ret; } static void get_audiocal(void *platform, void *keys, void *pReply) { struct platform_data *my_data = (struct platform_data *)platform; struct str_parms *query = (struct str_parms *)keys; struct str_parms *reply=(struct str_parms *)pReply; acdb_audio_cal_cfg_t cal={0}; uint8_t *dptr = NULL; char value[512] = {0}; char *rparms=NULL; int ret=0, err; uint32_t param_len; if(query==NULL || platform==NULL || reply==NULL) { ALOGE("[%s] received null pointer",__func__); ret=-EINVAL; goto done; } /* parse audiocal configuration keys */ ret = parse_audiocal_cfg(query, &cal); if(ret == 0) { /* No calibration keys found */ goto done; } err = str_parms_get_str(query, AUDIO_PARAMETER_KEY_AUD_CALDATA, value, sizeof(value)); if (err >= 0) { str_parms_del(query, AUDIO_PARAMETER_KEY_AUD_CALDATA); } else { goto done; } if(cal.dev_id & AUDIO_DEVICE_BIT_IN) { cal.snd_dev_id = platform_get_input_snd_device(platform, cal.dev_id); } else if(cal.dev_id) { cal.snd_dev_id = platform_get_output_snd_device(platform, cal.dev_id); } cal.acdb_dev_id = platform_get_snd_device_acdb_id(cal.snd_dev_id); if (cal.acdb_dev_id < 0) { ALOGE("%s: Failed. Could not find acdb id for snd device(%d)", __func__, cal.snd_dev_id); ret = -EINVAL; goto done_key_audcal; } ALOGD("[%s] Getting audio calibration for snd_device(%d) acdb_id(%d)", __func__, cal.snd_dev_id, cal.acdb_dev_id); param_len = MAX_SET_CAL_BYTE_SIZE; dptr = (uint8_t*)calloc(param_len, sizeof(uint8_t)); if(dptr == NULL) { ALOGE("[%s] Memory allocation failed for length %d",__func__,param_len); ret = -ENOMEM; goto done_key_audcal; } if (my_data->acdb_get_audio_cal != NULL) { ret = my_data->acdb_get_audio_cal((void*)&cal, (void*)dptr, ¶m_len); if (ret == 0) { int dlen; if(param_len == 0 || param_len == MAX_SET_CAL_BYTE_SIZE) { ret = -EINVAL; goto done_key_audcal; } /* Allocate memory for encoding */ rparms = (char*)calloc((param_len*2), sizeof(char)); if(rparms == NULL) { ALOGE("[%s] Memory allocation failed for size %d", __func__, param_len*2); ret = -ENOMEM; goto done_key_audcal; } if(cal.persist==0 && cal.module_id && cal.param_id) { err = b64encode(dptr+12, param_len-12, rparms); } else { err = b64encode(dptr, param_len, rparms); } if(err < 0) { ALOGE("[%s] failed to convert data to string", __func__); ret = -EINVAL; goto done_key_audcal; } str_parms_add_int(reply, AUDIO_PARAMETER_KEY_AUD_CALRESULT, ret); str_parms_add_str(reply, AUDIO_PARAMETER_KEY_AUD_CALDATA, rparms); } } done_key_audcal: if(ret != 0) { str_parms_add_int(reply, AUDIO_PARAMETER_KEY_AUD_CALRESULT, ret); str_parms_add_str(reply, AUDIO_PARAMETER_KEY_AUD_CALDATA, ""); } done: if(dptr != NULL) free(dptr); if(rparms != NULL) free(rparms); } void platform_get_parameters(void *platform, struct str_parms *query, struct str_parms *reply) { struct platform_data *my_data = (struct platform_data *)platform; char *str = NULL; char value[256] = {0}; char value[512] = {0}; int ret; char *kv_pairs = NULL; Loading Loading @@ -2502,6 +2768,10 @@ void platform_get_parameters(void *platform, str_parms_add_str(reply, AUDIO_PARAMETER_KEY_VOLUME_BOOST, value); } /* Handle audio calibration keys */ get_audiocal(platform, query, reply); done: kv_pairs = str_parms_to_str(reply); ALOGV_IF(kv_pairs != NULL, "%s: exit: returns - %s", __func__, kv_pairs); free(kv_pairs); Loading