Loading hal/audio_extn/audio_defs.h +27 −1 Original line number Diff line number Diff line Loading @@ -140,16 +140,42 @@ struct aptx_dec_param { struct aptx_dec_bt_addr bt_addr; }; struct audio_avt_device_drift_param { /* Flag to indicate if resync is required on the client side for * drift correction. Flag is set to TRUE for the first get_param response * after device interface starts. This flag value can be used by client * to identify if device interface restart has happened and if any * re-sync is required at their end for drift correction. */ uint32_t resync_flag; /* Accumulated drift value in microseconds. This value is updated * every 100th ms. * Positive drift value indicates AV timer is running faster than device. * Negative drift value indicates AV timer is running slower than device. */ int32_t avt_device_drift_value; /* Lower 32 bits of the 64-bit absolute timestamp of reference * timer in microseconds. */ uint32_t ref_timer_abs_ts_lsw; /* Upper 32 bits of the 64-bit absolute timestamp of reference * timer in microseconds. */ uint32_t ref_timer_abs_ts_msw; }; typedef union { struct source_tracking_param st_params; struct sound_focus_param sf_params; struct aptx_dec_param aptx_params; struct audio_avt_device_drift_param drift_params; } audio_extn_param_payload; typedef enum { AUDIO_EXTN_PARAM_SOURCE_TRACK, AUDIO_EXTN_PARAM_SOUND_FOCUS, AUDIO_EXTN_PARAM_APTX_DEC AUDIO_EXTN_PARAM_APTX_DEC, AUDIO_EXTN_PARAM_AVT_DEVICE_DRIFT } audio_extn_param_id; #endif /* AUDIO_DEFS_H */ hal/audio_extn/audio_extn.h +3 −0 Original line number Diff line number Diff line Loading @@ -820,4 +820,7 @@ static void audio_extn_parse_aptx_dec_bt_addr(char *value); int audio_extn_set_aptx_dec_params(struct aptx_dec_param *payload); #endif int audio_extn_utils_get_avt_device_drift( struct audio_usecase *usecase, struct audio_avt_device_drift_param *drift_param); #endif /* AUDIO_EXTN_H */ hal/audio_extn/utils.c +83 −0 Original line number Diff line number Diff line Loading @@ -156,6 +156,17 @@ const struct string_to_enum s_format_name_to_enum_table[] = { #endif }; /* payload structure avt_device drift query */ struct audio_avt_device_drift_stats { uint32_t minor_version; /* Indicates the device interface direction as either * source (Tx) or sink (Rx). */ uint16_t device_direction; /*params exposed to client */ struct audio_avt_device_drift_param drift_param; }; 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', Loading Loading @@ -1564,3 +1575,75 @@ void audio_utils_set_hdmi_channel_status(struct stream_out *out, char * buffer, } #endif int audio_extn_utils_get_avt_device_drift( struct audio_usecase *usecase, struct audio_avt_device_drift_param *drift_param) { int ret = 0, count = 0; char avt_device_drift_mixer_ctl_name[MIXER_PATH_MAX_LENGTH] = {0}; struct mixer_ctl *ctl = NULL; struct audio_avt_device_drift_stats drift_stats; struct audio_device *adev = NULL; if (usecase != NULL && usecase->type == PCM_PLAYBACK) { adev = usecase->stream.out->dev; switch(usecase->out_snd_device) { case SND_DEVICE_OUT_HDMI: strlcpy(avt_device_drift_mixer_ctl_name, "HDMI RX Drift", MIXER_PATH_MAX_LENGTH); break; case SND_DEVICE_OUT_DISPLAY_PORT: strlcpy(avt_device_drift_mixer_ctl_name, "DISPLAY Port RX Drift", MIXER_PATH_MAX_LENGTH); break; default : ALOGE("%s: Unsupported device %d",__func__, usecase->stream.out->devices); ret = -EINVAL; } } else { ALOGE("%s: Invalid usecase %d ",__func__, usecase->type); ret = -EINVAL; } if(ret) goto done; ctl = mixer_get_ctl_by_name(adev->mixer, avt_device_drift_mixer_ctl_name); if (!ctl) { ALOGE("%s: Could not get ctl for mixer cmd - %s", __func__, avt_device_drift_mixer_ctl_name); ret = -EINVAL; goto done; } ALOGV("%s: Getting AV Timer vs Device Drift mixer ctrl name %s", __func__, avt_device_drift_mixer_ctl_name); mixer_ctl_update(ctl); count = mixer_ctl_get_num_values(ctl); if (count != sizeof(struct audio_avt_device_drift_stats)) { ALOGE("%s: mixer_ctl_get_num_values() invalid drift_stats data size", __func__); ret = -EINVAL; goto done; } ret = mixer_ctl_get_array(ctl, (void *)&drift_stats, count); if (ret != 0) { ALOGE("%s: mixer_ctl_get_array() failed to get drift_stats Params", __func__); ret = -EINVAL; goto done; } memcpy(drift_param, &drift_stats.drift_param, sizeof(struct audio_avt_device_drift_param)); done: return ret; } hal/audio_hw_extn_api.c +55 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,61 @@ uint64_t timestamp; }; #endif static void lock_output_stream(struct stream_out *out) { pthread_mutex_lock(&out->pre_lock); pthread_mutex_lock(&out->lock); pthread_mutex_unlock(&out->pre_lock); } /* API to send playback stream specific config parameters */ int qahwi_out_set_param_data(struct audio_stream_out *stream __unused, audio_extn_param_id param_id __unused, audio_extn_param_payload *payload __unused) { return -ENOSYS; } /* API to get playback stream specific config parameters */ int qahwi_out_get_param_data(struct audio_stream_out *stream, audio_extn_param_id param_id, audio_extn_param_payload *payload) { int ret = -EINVAL; struct stream_out *out = (struct stream_out *)stream; struct audio_usecase *uc_info; if (!stream || !payload) { ALOGE("%s:: Invalid Param",__func__); return ret; } lock_output_stream(out); ALOGD("%s: enter: stream (%p) usecase(%d: %s) param_id %d", __func__, stream, out->usecase, use_case_table[out->usecase], param_id); switch (param_id) { case AUDIO_EXTN_PARAM_AVT_DEVICE_DRIFT: uc_info = get_usecase_from_list(out->dev, out->usecase); if (uc_info == NULL) { ALOGE("%s: Could not find the usecase (%d) in the list", __func__, out->usecase); ret = -EINVAL; } else { ret = audio_extn_utils_get_avt_device_drift(uc_info, (struct audio_avt_device_drift_param *)payload); if(ret) ALOGE("%s:: avdrift query failed error %d", __func__, ret); } break; default: ALOGE("%s:: unsupported param_id %d", __func__, param_id); break; } pthread_mutex_unlock(&out->lock); return ret; } int qahwi_get_param_data(const struct audio_hw_device *adev, audio_extn_param_id param_id, audio_extn_param_payload *payload) Loading qahw_api/inc/qahw_api.h +10 −1 Original line number Diff line number Diff line Loading @@ -141,6 +141,16 @@ int qahw_out_set_parameters(qahw_stream_handle_t *stream, const char*kv_pairs); char* qahw_out_get_parameters(const qahw_stream_handle_t *stream, const char *keys); /* API to set playback stream specific config parameters */ int qahw_out_set_param_data(qahw_stream_handle_t *out_handle, qahw_param_id param_id, qahw_param_payload *payload); /* API to get playback stream specific config parameters */ int qahw_out_get_param_data(qahw_stream_handle_t *out_handle, qahw_param_id param_id, qahw_param_payload *payload); /* * Return the audio hardware driver estimated latency in milliseconds. */ Loading Loading @@ -270,7 +280,6 @@ int qahw_open_input_stream(qahw_module_handle_t *hw_module, int qahw_close_input_stream(qahw_stream_handle_t *in_handle); /* * Return the sampling rate in Hz - eg. 44100. */ Loading Loading
hal/audio_extn/audio_defs.h +27 −1 Original line number Diff line number Diff line Loading @@ -140,16 +140,42 @@ struct aptx_dec_param { struct aptx_dec_bt_addr bt_addr; }; struct audio_avt_device_drift_param { /* Flag to indicate if resync is required on the client side for * drift correction. Flag is set to TRUE for the first get_param response * after device interface starts. This flag value can be used by client * to identify if device interface restart has happened and if any * re-sync is required at their end for drift correction. */ uint32_t resync_flag; /* Accumulated drift value in microseconds. This value is updated * every 100th ms. * Positive drift value indicates AV timer is running faster than device. * Negative drift value indicates AV timer is running slower than device. */ int32_t avt_device_drift_value; /* Lower 32 bits of the 64-bit absolute timestamp of reference * timer in microseconds. */ uint32_t ref_timer_abs_ts_lsw; /* Upper 32 bits of the 64-bit absolute timestamp of reference * timer in microseconds. */ uint32_t ref_timer_abs_ts_msw; }; typedef union { struct source_tracking_param st_params; struct sound_focus_param sf_params; struct aptx_dec_param aptx_params; struct audio_avt_device_drift_param drift_params; } audio_extn_param_payload; typedef enum { AUDIO_EXTN_PARAM_SOURCE_TRACK, AUDIO_EXTN_PARAM_SOUND_FOCUS, AUDIO_EXTN_PARAM_APTX_DEC AUDIO_EXTN_PARAM_APTX_DEC, AUDIO_EXTN_PARAM_AVT_DEVICE_DRIFT } audio_extn_param_id; #endif /* AUDIO_DEFS_H */
hal/audio_extn/audio_extn.h +3 −0 Original line number Diff line number Diff line Loading @@ -820,4 +820,7 @@ static void audio_extn_parse_aptx_dec_bt_addr(char *value); int audio_extn_set_aptx_dec_params(struct aptx_dec_param *payload); #endif int audio_extn_utils_get_avt_device_drift( struct audio_usecase *usecase, struct audio_avt_device_drift_param *drift_param); #endif /* AUDIO_EXTN_H */
hal/audio_extn/utils.c +83 −0 Original line number Diff line number Diff line Loading @@ -156,6 +156,17 @@ const struct string_to_enum s_format_name_to_enum_table[] = { #endif }; /* payload structure avt_device drift query */ struct audio_avt_device_drift_stats { uint32_t minor_version; /* Indicates the device interface direction as either * source (Tx) or sink (Rx). */ uint16_t device_direction; /*params exposed to client */ struct audio_avt_device_drift_param drift_param; }; 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', Loading Loading @@ -1564,3 +1575,75 @@ void audio_utils_set_hdmi_channel_status(struct stream_out *out, char * buffer, } #endif int audio_extn_utils_get_avt_device_drift( struct audio_usecase *usecase, struct audio_avt_device_drift_param *drift_param) { int ret = 0, count = 0; char avt_device_drift_mixer_ctl_name[MIXER_PATH_MAX_LENGTH] = {0}; struct mixer_ctl *ctl = NULL; struct audio_avt_device_drift_stats drift_stats; struct audio_device *adev = NULL; if (usecase != NULL && usecase->type == PCM_PLAYBACK) { adev = usecase->stream.out->dev; switch(usecase->out_snd_device) { case SND_DEVICE_OUT_HDMI: strlcpy(avt_device_drift_mixer_ctl_name, "HDMI RX Drift", MIXER_PATH_MAX_LENGTH); break; case SND_DEVICE_OUT_DISPLAY_PORT: strlcpy(avt_device_drift_mixer_ctl_name, "DISPLAY Port RX Drift", MIXER_PATH_MAX_LENGTH); break; default : ALOGE("%s: Unsupported device %d",__func__, usecase->stream.out->devices); ret = -EINVAL; } } else { ALOGE("%s: Invalid usecase %d ",__func__, usecase->type); ret = -EINVAL; } if(ret) goto done; ctl = mixer_get_ctl_by_name(adev->mixer, avt_device_drift_mixer_ctl_name); if (!ctl) { ALOGE("%s: Could not get ctl for mixer cmd - %s", __func__, avt_device_drift_mixer_ctl_name); ret = -EINVAL; goto done; } ALOGV("%s: Getting AV Timer vs Device Drift mixer ctrl name %s", __func__, avt_device_drift_mixer_ctl_name); mixer_ctl_update(ctl); count = mixer_ctl_get_num_values(ctl); if (count != sizeof(struct audio_avt_device_drift_stats)) { ALOGE("%s: mixer_ctl_get_num_values() invalid drift_stats data size", __func__); ret = -EINVAL; goto done; } ret = mixer_ctl_get_array(ctl, (void *)&drift_stats, count); if (ret != 0) { ALOGE("%s: mixer_ctl_get_array() failed to get drift_stats Params", __func__); ret = -EINVAL; goto done; } memcpy(drift_param, &drift_stats.drift_param, sizeof(struct audio_avt_device_drift_param)); done: return ret; }
hal/audio_hw_extn_api.c +55 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,61 @@ uint64_t timestamp; }; #endif static void lock_output_stream(struct stream_out *out) { pthread_mutex_lock(&out->pre_lock); pthread_mutex_lock(&out->lock); pthread_mutex_unlock(&out->pre_lock); } /* API to send playback stream specific config parameters */ int qahwi_out_set_param_data(struct audio_stream_out *stream __unused, audio_extn_param_id param_id __unused, audio_extn_param_payload *payload __unused) { return -ENOSYS; } /* API to get playback stream specific config parameters */ int qahwi_out_get_param_data(struct audio_stream_out *stream, audio_extn_param_id param_id, audio_extn_param_payload *payload) { int ret = -EINVAL; struct stream_out *out = (struct stream_out *)stream; struct audio_usecase *uc_info; if (!stream || !payload) { ALOGE("%s:: Invalid Param",__func__); return ret; } lock_output_stream(out); ALOGD("%s: enter: stream (%p) usecase(%d: %s) param_id %d", __func__, stream, out->usecase, use_case_table[out->usecase], param_id); switch (param_id) { case AUDIO_EXTN_PARAM_AVT_DEVICE_DRIFT: uc_info = get_usecase_from_list(out->dev, out->usecase); if (uc_info == NULL) { ALOGE("%s: Could not find the usecase (%d) in the list", __func__, out->usecase); ret = -EINVAL; } else { ret = audio_extn_utils_get_avt_device_drift(uc_info, (struct audio_avt_device_drift_param *)payload); if(ret) ALOGE("%s:: avdrift query failed error %d", __func__, ret); } break; default: ALOGE("%s:: unsupported param_id %d", __func__, param_id); break; } pthread_mutex_unlock(&out->lock); return ret; } int qahwi_get_param_data(const struct audio_hw_device *adev, audio_extn_param_id param_id, audio_extn_param_payload *payload) Loading
qahw_api/inc/qahw_api.h +10 −1 Original line number Diff line number Diff line Loading @@ -141,6 +141,16 @@ int qahw_out_set_parameters(qahw_stream_handle_t *stream, const char*kv_pairs); char* qahw_out_get_parameters(const qahw_stream_handle_t *stream, const char *keys); /* API to set playback stream specific config parameters */ int qahw_out_set_param_data(qahw_stream_handle_t *out_handle, qahw_param_id param_id, qahw_param_payload *payload); /* API to get playback stream specific config parameters */ int qahw_out_get_param_data(qahw_stream_handle_t *out_handle, qahw_param_id param_id, qahw_param_payload *payload); /* * Return the audio hardware driver estimated latency in milliseconds. */ Loading Loading @@ -270,7 +280,6 @@ int qahw_open_input_stream(qahw_module_handle_t *hw_module, int qahw_close_input_stream(qahw_stream_handle_t *in_handle); /* * Return the sampling rate in Hz - eg. 44100. */ Loading