diff options
author | millerliang <millerliang@google.com> | 2020-05-04 06:07:45 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2020-05-04 06:07:45 +0000 |
commit | 9ebc9fcbfca6925f9bacdecae4ec914a4f21726a (patch) | |
tree | 34b1dfec3e6125bdb671056f91b96f6fad28ca87 | |
parent | 129fa9a43d0f51af0caa563aea00ce3735a4be29 (diff) | |
parent | 680f560798af7c170e29cd30b37c585117cdc26e (diff) | |
download | audio-9ebc9fcbfca6925f9bacdecae4ec914a4f21726a.tar.gz |
hal: Fix AudioRecord and AudioTrack timestamps incorrect am: 680f560798
Change-Id: I1d8e8c53bfa0653457062f19bbe7f28f2442db33
-rw-r--r-- | hal/audio_hw.c | 7 | ||||
-rw-r--r-- | hal/msm8916/platform.c | 101 | ||||
-rw-r--r-- | hal/msm8960/platform.c | 101 | ||||
-rw-r--r-- | hal/msm8974/platform.c | 107 | ||||
-rw-r--r-- | hal/platform_api.h | 9 | ||||
-rw-r--r-- | hal/platform_info.c | 71 |
6 files changed, 375 insertions, 21 deletions
diff --git a/hal/audio_hw.c b/hal/audio_hw.c index 1e3bb91..035b14e 100644 --- a/hal/audio_hw.c +++ b/hal/audio_hw.c @@ -3286,7 +3286,7 @@ static uint32_t out_get_latency(const struct audio_stream_out *stream) // return a smaller number period_ms = (out->af_period_multiplier * out->config.period_size * 1000) / (out->config.rate); - hw_delay = platform_render_latency(out->usecase)/1000; + hw_delay = platform_render_latency(out)/1000; return period_ms + hw_delay; } @@ -3770,7 +3770,7 @@ static int out_get_presentation_position(const struct audio_stream_out *stream, // This adjustment accounts for buffering after app processor. // It is based on estimated DSP latency per use case, rather than exact. signed_frames -= - (platform_render_latency(out->usecase) * out->sample_rate / 1000000LL); + (platform_render_latency(out) * out->sample_rate / 1000000LL); // Adjustment accounts for A2DP encoder latency with non-offload usecases // Note: Encoder latency is returned in ms, while platform_render_latency in us. @@ -4490,7 +4490,8 @@ static int in_get_capture_position(const struct audio_stream_in *stream, unsigned int avail; if (pcm_get_htimestamp(in->pcm, &avail, ×tamp) == 0) { *frames = in->frames_read + avail; - *time = timestamp.tv_sec * 1000000000LL + timestamp.tv_nsec; + *time = timestamp.tv_sec * 1000000000LL + timestamp.tv_nsec + - platform_capture_latency(in) * 1000LL; ret = 0; } } diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c index 8600b7d..1a62ac3 100644 --- a/hal/msm8916/platform.c +++ b/hal/msm8916/platform.c @@ -554,6 +554,24 @@ static struct name_to_index usecase_name_index[AUDIO_USECASE_MAX] = { #define DEEP_BUFFER_PLATFORM_DELAY (29*1000LL) #define LOW_LATENCY_PLATFORM_DELAY (13*1000LL) +static int audio_usecase_delay_ms[AUDIO_USECASE_MAX] = {0}; + +static int audio_source_delay_ms[AUDIO_SOURCE_CNT] = {0}; + +static struct name_to_index audio_source_index[AUDIO_SOURCE_CNT] = { + {TO_NAME_INDEX(AUDIO_SOURCE_DEFAULT)}, + {TO_NAME_INDEX(AUDIO_SOURCE_MIC)}, + {TO_NAME_INDEX(AUDIO_SOURCE_VOICE_UPLINK)}, + {TO_NAME_INDEX(AUDIO_SOURCE_VOICE_DOWNLINK)}, + {TO_NAME_INDEX(AUDIO_SOURCE_VOICE_CALL)}, + {TO_NAME_INDEX(AUDIO_SOURCE_CAMCORDER)}, + {TO_NAME_INDEX(AUDIO_SOURCE_VOICE_RECOGNITION)}, + {TO_NAME_INDEX(AUDIO_SOURCE_VOICE_COMMUNICATION)}, + {TO_NAME_INDEX(AUDIO_SOURCE_REMOTE_SUBMIX)}, + {TO_NAME_INDEX(AUDIO_SOURCE_UNPROCESSED)}, + {TO_NAME_INDEX(AUDIO_SOURCE_VOICE_PERFORMANCE)}, +}; + static void query_platform(const char *snd_card_name, char *mixer_xml_path) { @@ -1453,6 +1471,11 @@ int platform_get_usecase_index(const char *usecase_name) return find_index(usecase_name_index, AUDIO_USECASE_MAX, usecase_name); } +int platform_get_audio_source_index(const char *audio_source_name) +{ + return find_index(audio_source_index, AUDIO_SOURCE_CNT, audio_source_name); +} + int platform_get_effect_config_data(snd_device_t snd_device, struct audio_effect_config *effect_config, effect_type_t effect_type) @@ -2559,17 +2582,85 @@ done: return ret; } +void platform_set_audio_source_delay(audio_source_t audio_source, int delay_ms) +{ + if ((audio_source < AUDIO_SOURCE_DEFAULT) || + (audio_source > AUDIO_SOURCE_MAX)) { + ALOGE("%s: Invalid audio_source = %d", __func__, audio_source); + return; + } + + audio_source_delay_ms[audio_source] = delay_ms; +} + +/* Delay in Us */ +int64_t platform_get_audio_source_delay(audio_source_t audio_source) +{ + if ((audio_source < AUDIO_SOURCE_DEFAULT) || + (audio_source > AUDIO_SOURCE_MAX)) { + ALOGE("%s: Invalid audio_source = %d", __func__, audio_source); + return 0; + } + + return 1000LL * audio_source_delay_ms[audio_source]; +} + +void platform_set_audio_usecase_delay(audio_usecase_t usecase, int delay_ms) +{ + if ((usecase <= USECASE_INVALID) || (usecase >= AUDIO_USECASE_MAX)) { + ALOGE("%s: invalid usecase case idx %d", __func__, usecase); + return; + } + + audio_usecase_delay_ms[usecase] = delay_ms; +} + +/* Delay in Us */ +int64_t platform_get_audio_usecase_delay(audio_usecase_t usecase) +{ + if ((usecase <= USECASE_INVALID) || (usecase >= AUDIO_USECASE_MAX)) { + ALOGE("%s: invalid usecase case idx %d", __func__, usecase); + return 0; + } + + return 1000LL * audio_usecase_delay_ms[usecase] ; +} + /* Delay in Us */ -int64_t platform_render_latency(audio_usecase_t usecase) +int64_t platform_render_latency(struct stream_out *out) { - switch (usecase) { + int64_t delay = 0LL; + + if (!out) + return delay; + + switch (out->usecase) { case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER: - return DEEP_BUFFER_PLATFORM_DELAY; + delay = DEEP_BUFFER_PLATFORM_DELAY; + break; case USECASE_AUDIO_PLAYBACK_LOW_LATENCY: - return LOW_LATENCY_PLATFORM_DELAY; + delay = LOW_LATENCY_PLATFORM_DELAY; + break; default: - return 0; + break; } + +/* out->usecase could be used to add delay time if it's necessary */ + delay += platform_get_audio_usecase_delay(out->usecase); + return delay; +} + +int64_t platform_capture_latency(struct stream_in *in) +{ + int64_t delay = 0LL; + + if (!in) + return delay; + + delay = platform_get_audio_source_delay(in->source); + +/* in->device could be used to add delay time if it's necessary */ + return delay; } int platform_set_snd_device_backend(snd_device_t device, const char *backend, const char * hw_interface) diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c index ae65ef2..6cc5411 100644 --- a/hal/msm8960/platform.c +++ b/hal/msm8960/platform.c @@ -226,6 +226,24 @@ static const int acdb_device_table[SND_DEVICE_MAX] = { #define DEEP_BUFFER_PLATFORM_DELAY (29*1000LL) #define LOW_LATENCY_PLATFORM_DELAY (13*1000LL) +static int audio_usecase_delay_ms[AUDIO_USECASE_MAX] = {0}; + +static int audio_source_delay_ms[AUDIO_SOURCE_CNT] = {0}; + +static struct name_to_index audio_source_index[AUDIO_SOURCE_CNT] = { + {TO_NAME_INDEX(AUDIO_SOURCE_DEFAULT)}, + {TO_NAME_INDEX(AUDIO_SOURCE_MIC)}, + {TO_NAME_INDEX(AUDIO_SOURCE_VOICE_UPLINK)}, + {TO_NAME_INDEX(AUDIO_SOURCE_VOICE_DOWNLINK)}, + {TO_NAME_INDEX(AUDIO_SOURCE_VOICE_CALL)}, + {TO_NAME_INDEX(AUDIO_SOURCE_CAMCORDER)}, + {TO_NAME_INDEX(AUDIO_SOURCE_VOICE_RECOGNITION)}, + {TO_NAME_INDEX(AUDIO_SOURCE_VOICE_COMMUNICATION)}, + {TO_NAME_INDEX(AUDIO_SOURCE_REMOTE_SUBMIX)}, + {TO_NAME_INDEX(AUDIO_SOURCE_UNPROCESSED)}, + {TO_NAME_INDEX(AUDIO_SOURCE_VOICE_PERFORMANCE)}, +}; + static pthread_once_t check_op_once_ctl = PTHREAD_ONCE_INIT; static bool is_tmus = false; @@ -1026,17 +1044,85 @@ int platform_set_parameters(void *platform __unused, return -ENOSYS; } +void platform_set_audio_source_delay(audio_source_t audio_source, int delay_ms) +{ + if ((audio_source < AUDIO_SOURCE_DEFAULT) || + (audio_source > AUDIO_SOURCE_MAX)) { + ALOGE("%s: Invalid audio_source = %d", __func__, audio_source); + return; + } + + audio_source_delay_ms[audio_source] = delay_ms; +} + /* Delay in Us */ -int64_t platform_render_latency(audio_usecase_t usecase) +int64_t platform_get_audio_source_delay(audio_source_t audio_source) { - switch (usecase) { + if ((audio_source < AUDIO_SOURCE_DEFAULT) || + (audio_source > AUDIO_SOURCE_MAX)) { + ALOGE("%s: Invalid audio_source = %d", __func__, audio_source); + return 0; + } + + return 1000LL * audio_source_delay_ms[audio_source]; +} + +void platform_set_audio_usecase_delay(audio_usecase_t usecase, int delay_ms) +{ + if ((usecase <= USECASE_INVALID) || (usecase >= AUDIO_USECASE_MAX)) { + ALOGE("%s: invalid usecase case idx %d", __func__, usecase); + return; + } + + audio_usecase_delay_ms[usecase] = delay_ms; +} + +/* Delay in Us */ +int64_t platform_get_audio_usecase_delay(audio_usecase_t usecase) +{ + if ((usecase <= USECASE_INVALID) || (usecase >= AUDIO_USECASE_MAX)) { + ALOGE("%s: invalid usecase case idx %d", __func__, usecase); + return 0; + } + + return 1000LL * audio_usecase_delay_ms[usecase] ; +} + +/* Delay in Us */ +int64_t platform_render_latency(struct stream_out *out) +{ + int64_t delay = 0LL; + + if (!out) + return delay; + + switch (out->usecase) { case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER: - return DEEP_BUFFER_PLATFORM_DELAY; + delay = DEEP_BUFFER_PLATFORM_DELAY; + break; case USECASE_AUDIO_PLAYBACK_LOW_LATENCY: - return LOW_LATENCY_PLATFORM_DELAY; + delay = LOW_LATENCY_PLATFORM_DELAY; + break; default: - return 0; + break; } + +/* out->usecase could be used to add delay time if it's necessary */ + delay += platform_get_audio_usecase_delay(out->usecase); + return delay; +} + +int64_t platform_capture_latency(struct stream_in *in) +{ + int64_t delay = 0LL; + + if (!in) + return delay; + + delay = platform_get_audio_source_delay(in->source); + +/* in->device could be used to add delay time if it's necessary */ + return delay; } int platform_switch_voice_call_enable_device_config(void *platform __unused, @@ -1063,6 +1149,11 @@ int platform_get_usecase_index(const char * usecase __unused) return -ENOSYS; } +int platform_get_audio_source_index(const char *audio_source_name) +{ + return find_index(audio_source_index, AUDIO_SOURCE_CNT, audio_source_name); +} + int platform_set_usecase_pcm_id(audio_usecase_t usecase __unused, int32_t type __unused, int32_t pcm_id __unused) { diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c index d8ec06a..8fa9826 100644 --- a/hal/msm8974/platform.c +++ b/hal/msm8974/platform.c @@ -741,6 +741,24 @@ static struct listnode app_type_entry_list; #define ULL_PLATFORM_DELAY (3*1000LL) #define MMAP_PLATFORM_DELAY (3*1000LL) +static int audio_usecase_delay_ms[AUDIO_USECASE_MAX] = {0}; + +static int audio_source_delay_ms[AUDIO_SOURCE_CNT] = {0}; + +static struct name_to_index audio_source_index[AUDIO_SOURCE_CNT] = { + {TO_NAME_INDEX(AUDIO_SOURCE_DEFAULT)}, + {TO_NAME_INDEX(AUDIO_SOURCE_MIC)}, + {TO_NAME_INDEX(AUDIO_SOURCE_VOICE_UPLINK)}, + {TO_NAME_INDEX(AUDIO_SOURCE_VOICE_DOWNLINK)}, + {TO_NAME_INDEX(AUDIO_SOURCE_VOICE_CALL)}, + {TO_NAME_INDEX(AUDIO_SOURCE_CAMCORDER)}, + {TO_NAME_INDEX(AUDIO_SOURCE_VOICE_RECOGNITION)}, + {TO_NAME_INDEX(AUDIO_SOURCE_VOICE_COMMUNICATION)}, + {TO_NAME_INDEX(AUDIO_SOURCE_REMOTE_SUBMIX)}, + {TO_NAME_INDEX(AUDIO_SOURCE_UNPROCESSED)}, + {TO_NAME_INDEX(AUDIO_SOURCE_VOICE_PERFORMANCE)}, +}; + static pthread_once_t check_op_once_ctl = PTHREAD_ONCE_INIT; static bool is_tmus = false; @@ -2254,6 +2272,11 @@ done: return ret; } +int platform_get_audio_source_index(const char *audio_source_name) +{ + return find_index(audio_source_index, AUDIO_SOURCE_CNT, audio_source_name); +} + void platform_add_operator_specific_device(snd_device_t snd_device, const char *operator, const char *mixer_path, @@ -3828,22 +3851,92 @@ done: return ret; } +void platform_set_audio_source_delay(audio_source_t audio_source, int delay_ms) +{ + if ((audio_source < AUDIO_SOURCE_DEFAULT) || + (audio_source > AUDIO_SOURCE_MAX)) { + ALOGE("%s: Invalid audio_source = %d", __func__, audio_source); + return; + } + + audio_source_delay_ms[audio_source] = delay_ms; +} + /* Delay in Us */ -int64_t platform_render_latency(audio_usecase_t usecase) +int64_t platform_get_audio_source_delay(audio_source_t audio_source) { - switch (usecase) { + if ((audio_source < AUDIO_SOURCE_DEFAULT) || + (audio_source > AUDIO_SOURCE_MAX)) { + ALOGE("%s: Invalid audio_source = %d", __func__, audio_source); + return 0; + } + + return 1000LL * audio_source_delay_ms[audio_source]; +} + +void platform_set_audio_usecase_delay(audio_usecase_t usecase, int delay_ms) +{ + if ((usecase <= USECASE_INVALID) || (usecase >= AUDIO_USECASE_MAX)) { + ALOGE("%s: invalid usecase case idx %d", __func__, usecase); + return; + } + + audio_usecase_delay_ms[usecase] = delay_ms; +} + +/* Delay in Us */ +int64_t platform_get_audio_usecase_delay(audio_usecase_t usecase) +{ + if ((usecase <= USECASE_INVALID) || (usecase >= AUDIO_USECASE_MAX)) { + ALOGE("%s: invalid usecase case idx %d", __func__, usecase); + return 0; + } + + return 1000LL * audio_usecase_delay_ms[usecase] ; +} + +/* Delay in Us */ +int64_t platform_render_latency(struct stream_out *out) +{ + int64_t delay = 0LL; + + if (!out) + return delay; + + switch (out->usecase) { case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER: - return DEEP_BUFFER_PLATFORM_DELAY; + delay = DEEP_BUFFER_PLATFORM_DELAY; + break; case USECASE_AUDIO_PLAYBACK_LOW_LATENCY: case USECASE_AUDIO_PLAYBACK_WITH_HAPTICS: - return LOW_LATENCY_PLATFORM_DELAY; + delay = LOW_LATENCY_PLATFORM_DELAY; + break; case USECASE_AUDIO_PLAYBACK_ULL: - return ULL_PLATFORM_DELAY; + delay = ULL_PLATFORM_DELAY; + break; case USECASE_AUDIO_PLAYBACK_MMAP: - return MMAP_PLATFORM_DELAY; + delay = MMAP_PLATFORM_DELAY; + break; default: - return 0; + break; } + +/* out->usecase could be used to add delay time if it's necessary */ + delay += platform_get_audio_usecase_delay(out->usecase); + return delay; +} + +int64_t platform_capture_latency(struct stream_in *in) +{ + int64_t delay = 0LL; + + if (!in) + return delay; + + delay = platform_get_audio_source_delay(in->source); + +/* in->device could be used to add delay time if it's necessary */ + return delay; } int platform_set_snd_device_backend(snd_device_t device, const char *backend_tag, diff --git a/hal/platform_api.h b/hal/platform_api.h index 1d46c31..008e9a6 100644 --- a/hal/platform_api.h +++ b/hal/platform_api.h @@ -127,7 +127,8 @@ int platform_get_gain_level_mapping(struct amp_db_and_gain_table *mapping_tbl, int table_size); /* returns the latency for a usecase in Us */ -int64_t platform_render_latency(audio_usecase_t usecase); +int64_t platform_render_latency(struct stream_out *out); +int64_t platform_capture_latency(struct stream_in *in); int platform_set_incall_recording_session_id(void *platform, uint32_t session_id, int rec_mode); @@ -209,6 +210,12 @@ int platform_get_usb_service_interval(void *platform, unsigned long *service_interval); int platform_get_haptics_pcm_device_id(); +void platform_set_audio_source_delay(audio_source_t audio_source, int delay_ms); + +int platform_get_audio_source_index(const char *audio_source_name); + +void platform_set_audio_usecase_delay(audio_usecase_t usecase, int delay_ms); + /* callback functions from platform to common audio HAL */ struct stream_in *adev_get_active_input(const struct audio_device *adev); diff --git a/hal/platform_info.c b/hal/platform_info.c index 5159d6d..fd8f745 100644 --- a/hal/platform_info.c +++ b/hal/platform_info.c @@ -55,6 +55,8 @@ typedef enum { MIC_INFO, ACDB_METAINFO_KEY, EXTERNAL_DEVICE_SPECIFIC, + AUDIO_SOURCE_DELAY, + AUDIO_OUTPUT_USECASE_DELAY, } section_t; typedef void (* section_process_fn)(const XML_Char **attr); @@ -75,6 +77,8 @@ static void process_snd_dev(const XML_Char **attr); static void process_mic_info(const XML_Char **attr); static void process_acdb_metainfo_key(const XML_Char **attr); static void process_external_dev(const XML_Char **attr); +static void process_audio_source_delay(const XML_Char **attr); +static void process_audio_usecase_delay(const XML_Char **attr); static section_process_fn section_table[] = { [ROOT] = process_root, @@ -92,6 +96,8 @@ static section_process_fn section_table[] = { [MIC_INFO] = process_mic_info, [ACDB_METAINFO_KEY] = process_acdb_metainfo_key, [EXTERNAL_DEVICE_SPECIFIC] = process_external_dev, + [AUDIO_SOURCE_DELAY] = process_audio_source_delay, + [AUDIO_OUTPUT_USECASE_DELAY] = process_audio_usecase_delay, }; static section_t section; @@ -523,6 +529,61 @@ done: return; } +static void process_audio_source_delay(const XML_Char **attr) +{ + audio_source_t audio_source = -1; + + if (strcmp(attr[0], "name") != 0) { + ALOGE("%s: 'name' not found", __func__); + goto done; + } + + audio_source = platform_get_audio_source_index((const char *)attr[1]); + + if (audio_source < 0) { + ALOGE("%s: audio_source %s is not defined", + __func__, (char *)attr[1]); + goto done; + } + + if (strcmp(attr[2], "delay") != 0) { + ALOGE("%s: 'delay' not found", __func__); + goto done; + } + + platform_set_audio_source_delay(audio_source, atoi((char *)attr[3])); + +done: + return; +} + +static void process_audio_usecase_delay(const XML_Char **attr) +{ + int index; + + if (strcmp(attr[0], "name") != 0) { + ALOGE("%s: 'name' not found", __func__); + goto done; + } + + index = platform_get_usecase_index((char *)attr[1]); + if (index < 0) { + ALOGE("%s: usecase %s in %s not found!", + __func__, attr[1], PLATFORM_INFO_XML_PATH); + goto done; + } + + if (strcmp(attr[2], "delay") != 0) { + ALOGE("%s: 'delay' not found", __func__); + goto done; + } + + platform_set_audio_usecase_delay(index, atoi((char *)attr[3])); + +done: + return; +} + /* platform specific configuration key-value pairs */ static void process_config_params(const XML_Char **attr) { @@ -954,6 +1015,16 @@ static void start_tag(void *userdata __unused, const XML_Char *tag_name, return; } section = NS; + } else if (strcmp(tag_name, "audio_input_source_delay") == 0) { + section = AUDIO_SOURCE_DELAY; + } else if (strcmp(tag_name, "audio_source_delay") == 0) { + section_process_fn fn = section_table[section]; + fn(attr); + } else if (strcmp(tag_name, "audio_output_usecase_delay") == 0) { + section = AUDIO_OUTPUT_USECASE_DELAY; + } else if (strcmp(tag_name, "audio_usecase_delay") == 0) { + section_process_fn fn = section_table[section]; + fn(attr); } } else { if(strcmp(tag_name, "config_params") == 0) { |