Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 918e1e1c authored by Juyu Chen's avatar Juyu Chen Committed by George Gao
Browse files

audio-hal: use audio source to get delay latency



Bug: 138918061
Test: CTS testSynchronizedRecord pass

Change-Id: Icb9babf7e6a63c1f3d1af73c42ef21fb8b7d211b
Signed-off-by: default avatarJuyu Chen <juyuchen@google.com>
(cherry picked from commit 1a5c6d674d85a35890c33ea5e1a505a970cebb57)
Signed-off-by: default avatarAniket Kumar Lata <alata@codeaurora.org>
parent 5821554a
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -952,10 +952,10 @@ static int qaf_get_rendered_frames(struct stream_out *out, uint64_t *frames)

        if (qaf_mod->stream_out[QAF_OUT_OFFLOAD])
            platform_latency =
                platform_render_latency(qaf_mod->stream_out[QAF_OUT_OFFLOAD]->usecase);
                platform_render_latency(qaf_mod->stream_out[QAF_OUT_OFFLOAD]);
        else
            platform_latency =
                platform_render_latency(qaf_mod->stream_out[QAF_OUT_OFFLOAD_MCH]->usecase);
                platform_render_latency(qaf_mod->stream_out[QAF_OUT_OFFLOAD_MCH]);

        dsp_latency = (platform_latency * sample_rate) / 1000000LL;
    } else if (qaf_mod->stream_out[QAF_OUT_TRANSCODE_PASSTHROUGH] != NULL) {
+74 −6
Original line number Diff line number Diff line
@@ -1034,6 +1034,22 @@ static int msm_device_to_be_id_external_codec [][NO_COLS] = {
#define ULL_PLATFORM_DELAY (6*1000LL)
#define MMAP_PLATFORM_DELAY (3*1000LL)

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 const char *platform_get_mixer_control(struct mixer_ctl *);

static void update_interface(const char *snd_card_name) {
@@ -3215,6 +3231,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)
@@ -5766,10 +5787,34 @@ unsigned char* platform_get_license(void *platform __unused, int *size __unused)
    return NULL;
}


void platform_set_snd_device_delay(snd_device_t snd_device __unused, int delay_ms __unused)
{
}

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];
}

int64_t platform_capture_latency(struct audio_device *adev __unused,
                                 audio_usecase_t usecase)
{
@@ -5779,21 +5824,44 @@ int64_t platform_capture_latency(struct audio_device *adev __unused,
int64_t platform_render_latency(struct audio_device *adev __unused,
                                audio_usecase_t usecase)
{
    int64_t delay = 0LL;

    switch (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;
        case USECASE_AUDIO_PLAYBACK_OFFLOAD:
        case USECASE_AUDIO_PLAYBACK_OFFLOAD2:
            return PCM_OFFLOAD_PLATFORM_DELAY;
            delay = PCM_OFFLOAD_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->device could be used to add delay time if it's necessary */
    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_update_usecase_from_source(int source, int usecase)
+44 −0
Original line number Diff line number Diff line
@@ -1527,6 +1527,22 @@ static int snd_device_delay_ms[SND_DEVICE_MAX] = {0};
#define ULL_PLATFORM_DELAY         (3*1000LL)
#define MMAP_PLATFORM_DELAY        (3*1000LL)

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 bool is_usb_snd_dev(snd_device_t snd_device)
{
    if (snd_device < SND_DEVICE_IN_BEGIN) {
@@ -4633,6 +4649,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);
}

void platform_add_operator_specific_device(snd_device_t snd_device,
                                           const char *operator,
                                           const char *mixer_path,
@@ -8591,6 +8612,29 @@ int64_t platform_get_snd_device_delay(snd_device_t snd_device)
    return 1000LL * (int64_t)snd_device_delay_ms[snd_device];
}

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];
}

/* Delay in Us */
/* Delay in Us, only to be used for PCM formats */
int64_t platform_render_latency(struct audio_device *adev, audio_usecase_t usecase)
+4 −0
Original line number Diff line number Diff line
@@ -421,4 +421,8 @@ int platform_set_hdmi_channels_v2(void *platform, int channel_count,
int platform_get_display_port_ctl_index(int controller, int stream);
bool platform_is_call_proxy_snd_device(snd_device_t snd_device);
void platform_set_snd_device_delay(snd_device_t snd_device, int delay_ms);
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);

#endif // AUDIO_PLATFORM_API_H
+33 −1
Original line number Diff line number Diff line
@@ -78,6 +78,7 @@ typedef enum {
    CUSTOM_MTMX_PARAM_IN_CH_INFO,
    MMSECNS,
    SND_DEV_DELAY,
    AUDIO_SOURCE_DELAY,
} section_t;

typedef void (* section_process_fn)(const XML_Char **attr);
@@ -106,6 +107,7 @@ static void process_custom_mtmx_in_params(const XML_Char **attr);
static void process_custom_mtmx_param_in_ch_info(const XML_Char **attr);
static void process_fluence_mmsecns(const XML_Char **attr);
static void process_snd_device_delay(const XML_Char **attr);
static void process_audio_source_delay(const XML_Char **attr);

static section_process_fn section_table[] = {
    [ROOT] = process_root,
@@ -131,6 +133,7 @@ static section_process_fn section_table[] = {
    [CUSTOM_MTMX_PARAM_IN_CH_INFO] = process_custom_mtmx_param_in_ch_info,
    [MMSECNS] = process_fluence_mmsecns,
    [SND_DEV_DELAY] = process_snd_device_delay,
    [AUDIO_SOURCE_DELAY] = process_audio_source_delay,
};

static section_t section;
@@ -704,7 +707,6 @@ done:
    return;
}


static void process_snd_device_delay(const XML_Char **attr)
{
    snd_device_t snd_device = SND_DEVICE_NONE;
@@ -732,6 +734,33 @@ 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_config_params(const XML_Char **attr)
{
    if (strcmp(attr[0], "key") != 0) {
@@ -1471,6 +1500,9 @@ static void start_tag(void *userdata __unused, const XML_Char *tag_name,
        } else if (strcmp(tag_name, "snd_device_delay") == 0) {
            section = SND_DEV_DELAY;
        } else if (strcmp(tag_name, "device_delay") == 0) {
        } 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);
        }