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

Commit 06761ddc authored by Zhou Song's avatar Zhou Song Committed by Gerrit - the friendly Code Review server
Browse files

hal: get correspoding sample rate per device when sending cal data

For combo devices, each of the sound device may have different
sample rate, so calibration data should be sent with its own
sample rate value.
Use the sample rate per sound device for calibration.

Change-Id: If1989b8ceb166a905f3e438161765b4b3a6dc5f5
parent ad672adc
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -157,7 +157,7 @@ typedef int (*fp_platform_get_snd_device_name_extn_t)(void *platform, snd_device
                                      char *device_name);
typedef int (*fp_platform_get_default_app_type_v2_t)(void *, usecase_type_t);
typedef int (*fp_platform_send_audio_calibration_t)(void *, struct audio_usecase *,
                                                   int, int);
                                                   int);
typedef int (*fp_platform_get_pcm_device_id_t)(audio_usecase_t, int);
typedef const char *(*fp_platform_get_snd_device_name_t)(snd_device_t);
typedef int (*fp_platform_spkr_prot_is_wsa_analog_mode_t)(void *);
@@ -801,6 +801,8 @@ int audio_extn_utils_get_sample_rate_from_string(const char *);
int audio_extn_utils_get_channels_from_string(const char *);
void audio_extn_utils_release_snd_device(snd_device_t snd_device);
int audio_extn_utils_is_vendor_enhanced_fwk();
int audio_extn_utils_get_app_sample_rate_for_device(struct audio_device *adev,
                                    struct audio_usecase *usecase, int snd_device);

#ifdef DS2_DOLBY_DAP_ENABLED
#define LIB_DS2_DAP_HAL "vendor/lib/libhwdaphal.so"
+4 −6
Original line number Diff line number Diff line
@@ -1030,7 +1030,7 @@ exit:
            app_type = fp_platform_get_default_app_type_v2(adev->platform,
                                                PCM_CAPTURE);
            fp_platform_send_audio_calibration(adev->platform, uc_info_tx,
                                                    app_type, 8000);
                                                    app_type);
        }
        if (!v_validation) {
            if (!status.status) {
@@ -2281,6 +2281,8 @@ int spkr_prot_start_processing(snd_device_t snd_device)
    if (!uc_info_tx) {
        return -ENOMEM;
    }
    uc_info_tx->id = USECASE_AUDIO_SPKR_CALIB_TX;
    uc_info_tx->type = PCM_CAPTURE;

    if (fp_platform_get_snd_device_name_extn(adev->platform, snd_device, device_name) < 0) {
        ALOGE("%s: Invalid sound device returned", __func__);
@@ -2293,8 +2295,6 @@ int spkr_prot_start_processing(snd_device_t snd_device)

    pthread_mutex_lock(&handle.mutex_spkr_prot);
    if (handle.spkr_processing_state == SPKR_PROCESSING_IN_IDLE) {
        uc_info_tx->id = USECASE_AUDIO_SPKR_CALIB_TX;
        uc_info_tx->type = PCM_CAPTURE;
        uc_info_tx->in_snd_device = in_snd_device;
        uc_info_tx->out_snd_device = SND_DEVICE_NONE;
        handle.pcm_tx = NULL;
@@ -2333,15 +2333,13 @@ exit:
        app_type = fp_platform_get_default_app_type_v2(adev->platform,
                                            PCM_CAPTURE);
        fp_platform_send_audio_calibration(adev->platform, uc_info_tx,
                                                app_type, 8000);
                                                app_type);
    }
    if (ret) {
        if (handle.pcm_tx)
            pcm_close(handle.pcm_tx);
        handle.pcm_tx = NULL;
        list_remove(&uc_info_tx->list);
        uc_info_tx->id = USECASE_AUDIO_SPKR_CALIB_TX;
        uc_info_tx->type = PCM_CAPTURE;
        uc_info_tx->in_snd_device = in_snd_device;
        uc_info_tx->out_snd_device = SND_DEVICE_NONE;
        fp_disable_snd_device(adev, in_snd_device);
+88 −95
Original line number Diff line number Diff line
@@ -1025,6 +1025,87 @@ exit_send_app_type_cfg:
    return rc;
}

int audio_extn_utils_get_app_sample_rate_for_device(
                              struct audio_device *adev,
                              struct audio_usecase *usecase, int snd_device)
{
    char value[PROPERTY_VALUE_MAX] = {0};
    int sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;

    if ((usecase->type == PCM_PLAYBACK) && (usecase->stream.out != NULL)) {
        property_get("vendor.audio.playback.mch.downsample",value,"");
        if (!strncmp("true", value, sizeof("true"))) {
            if ((popcount(usecase->stream.out->channel_mask) > 2) &&
                (usecase->stream.out->app_type_cfg.sample_rate > CODEC_BACKEND_DEFAULT_SAMPLE_RATE) &&
                !(usecase->stream.out->flags &
                            (audio_output_flags_t)AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH))
               sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
        }

        if (usecase->id == USECASE_AUDIO_PLAYBACK_VOIP) {
            usecase->stream.out->app_type_cfg.sample_rate = usecase->stream.out->sample_rate;
        } else if (usecase->stream.out->devices & AUDIO_DEVICE_OUT_SPEAKER) {
            usecase->stream.out->app_type_cfg.sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
        } else if ((snd_device == SND_DEVICE_OUT_HDMI ||
                    snd_device == SND_DEVICE_OUT_USB_HEADSET ||
                    snd_device == SND_DEVICE_OUT_DISPLAY_PORT) &&
                   (usecase->stream.out->sample_rate >= OUTPUT_SAMPLING_RATE_44100)) {
             /*
              * To best utlize DSP, check if the stream sample rate is supported/multiple of
              * configured device sample rate, if not update the COPP rate to be equal to the
              * device sample rate, else open COPP at stream sample rate
              */
              platform_check_and_update_copp_sample_rate(adev->platform, snd_device,
                                      usecase->stream.out->sample_rate,
                                      &usecase->stream.out->app_type_cfg.sample_rate);
        } else if (((snd_device != SND_DEVICE_OUT_HEADPHONES_44_1 &&
                     !audio_is_this_native_usecase(usecase)) &&
            usecase->stream.out->sample_rate == OUTPUT_SAMPLING_RATE_44100) ||
            (usecase->stream.out->sample_rate < OUTPUT_SAMPLING_RATE_44100)) {
            /* Reset to default if no native stream is active*/
            usecase->stream.out->app_type_cfg.sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
        } else if (usecase->stream.out->devices & AUDIO_DEVICE_OUT_ALL_A2DP) {
                 /*
                  * For a2dp playback get encoder sampling rate and set copp sampling rate,
                  * for bit width use the stream param only.
                  */
                   audio_extn_a2dp_get_enc_sample_rate(&usecase->stream.out->app_type_cfg.sample_rate);
                   ALOGI("%s using %d sample rate rate for A2DP CoPP",
                        __func__, usecase->stream.out->app_type_cfg.sample_rate);
        }
        audio_extn_btsco_get_sample_rate(snd_device, &usecase->stream.out->app_type_cfg.sample_rate);
        sample_rate = usecase->stream.out->app_type_cfg.sample_rate;

        if (((usecase->stream.out->format == AUDIO_FORMAT_E_AC3) ||
            (usecase->stream.out->format == AUDIO_FORMAT_E_AC3_JOC) ||
            (usecase->stream.out->format == AUDIO_FORMAT_DOLBY_TRUEHD))
            && audio_extn_passthru_is_passthrough_stream(usecase->stream.out)
            && !audio_extn_passthru_is_convert_supported(adev, usecase->stream.out)) {
            sample_rate = sample_rate * 4;
            if (sample_rate > HDMI_PASSTHROUGH_MAX_SAMPLE_RATE)
                sample_rate = HDMI_PASSTHROUGH_MAX_SAMPLE_RATE;
        }
    } else if (usecase->type == PCM_CAPTURE) {
        if (usecase->stream.in != NULL) {
            if (usecase->id == USECASE_AUDIO_RECORD_VOIP)
                usecase->stream.in->app_type_cfg.sample_rate = usecase->stream.in->sample_rate;
            if (voice_is_in_call_rec_stream(usecase->stream.in)) {
                audio_extn_btsco_get_sample_rate(usecase->in_snd_device,
                                                 &usecase->stream.in->app_type_cfg.sample_rate);
            } else {
                audio_extn_btsco_get_sample_rate(snd_device,
                                                 &usecase->stream.in->app_type_cfg.sample_rate);
            }
            sample_rate = usecase->stream.in->app_type_cfg.sample_rate;
        } else if (usecase->id == USECASE_AUDIO_SPKR_CALIB_TX) {
            sample_rate = SAMPLE_RATE_8000;
        }
    } else if (usecase->type == TRANSCODE_LOOPBACK_RX) {
        sample_rate = usecase->stream.inout->out_config.sample_rate;
    }
    return sample_rate;
}

static int send_app_type_cfg_for_device(struct audio_device *adev,
                                        struct audio_usecase *usecase,
                                        int split_snd_device)
@@ -1036,7 +1117,6 @@ static int send_app_type_cfg_for_device(struct audio_device *adev,
    int pcm_device_id = 0, acdb_dev_id, app_type;
    int snd_device = split_snd_device, snd_device_be_idx = -1;
    int32_t sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
    char value[PROPERTY_VALUE_MAX] = {0};
    struct streams_io_cfg *s_info = NULL;
    struct listnode *node = NULL;
    int bd_app_type = 0;
@@ -1111,58 +1191,9 @@ static int send_app_type_cfg_for_device(struct audio_device *adev,
              snd_device_be_idx);
    }

    if ((usecase->type == PCM_PLAYBACK) && (usecase->stream.out != NULL)) {

        property_get("vendor.audio.playback.mch.downsample",value,"");
        if (!strncmp("true", value, sizeof("true"))) {
            if ((popcount(usecase->stream.out->channel_mask) > 2) &&
                   (usecase->stream.out->app_type_cfg.sample_rate > CODEC_BACKEND_DEFAULT_SAMPLE_RATE) &&
                   !(usecase->stream.out->flags &
                            (audio_output_flags_t)AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH))
               sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
        }

        if (usecase->id == USECASE_AUDIO_PLAYBACK_VOIP) {
            usecase->stream.out->app_type_cfg.sample_rate = usecase->stream.out->sample_rate;
        } else if (usecase->stream.out->devices & AUDIO_DEVICE_OUT_SPEAKER) {
            if (platform_spkr_use_default_sample_rate(adev->platform)) {
                 usecase->stream.out->app_type_cfg.sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
            } else {
                 platform_check_and_update_copp_sample_rate(adev->platform, snd_device,
                                      usecase->stream.out->sample_rate,
                                      &usecase->stream.out->app_type_cfg.sample_rate);
            }

        } else if ((snd_device == SND_DEVICE_OUT_HDMI ||
                    snd_device == SND_DEVICE_OUT_USB_HEADSET ||
                    snd_device == SND_DEVICE_OUT_DISPLAY_PORT) &&
                   (usecase->stream.out->sample_rate >= OUTPUT_SAMPLING_RATE_44100)) {
             /*
              * To best utlize DSP, check if the stream sample rate is supported/multiple of
              * configured device sample rate, if not update the COPP rate to be equal to the
              * device sample rate, else open COPP at stream sample rate
              */
              platform_check_and_update_copp_sample_rate(adev->platform, snd_device,
                                      usecase->stream.out->sample_rate,
                                      &usecase->stream.out->app_type_cfg.sample_rate);
        } else if (((snd_device != SND_DEVICE_OUT_HEADPHONES_44_1 &&
                     !audio_is_this_native_usecase(usecase)) &&
            usecase->stream.out->sample_rate == OUTPUT_SAMPLING_RATE_44100) ||
            (usecase->stream.out->sample_rate < OUTPUT_SAMPLING_RATE_44100)) {
            /* Reset to default if no native stream is active*/
            usecase->stream.out->app_type_cfg.sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
        } else if (usecase->stream.out->devices & AUDIO_DEVICE_OUT_ALL_A2DP) {
                 /*
                  * For a2dp playback get encoder sampling rate and set copp sampling rate,
                  * for bit width use the stream param only.
                  */
                   audio_extn_a2dp_get_enc_sample_rate(&usecase->stream.out->app_type_cfg.sample_rate);
                   ALOGI("%s using %d sample rate rate for A2DP CoPP",
                        __func__, usecase->stream.out->app_type_cfg.sample_rate);
        }
        audio_extn_btsco_get_sample_rate(snd_device, &usecase->stream.out->app_type_cfg.sample_rate);
        sample_rate = usecase->stream.out->app_type_cfg.sample_rate;
    sample_rate = audio_extn_utils_get_app_sample_rate_for_device(adev, usecase, snd_device);

    if ((usecase->type == PCM_PLAYBACK) && (usecase->stream.out != NULL)) {
        /* Interactive streams are supported with only direct app type id.
         * Get Direct profile app type and use it for interactive streams
         */
@@ -1179,16 +1210,6 @@ static int send_app_type_cfg_for_device(struct audio_device *adev,
            app_type = usecase->stream.out->app_type_cfg.app_type;
        app_type_cfg[len++] = app_type;
        app_type_cfg[len++] = acdb_dev_id;
        if (((usecase->stream.out->format == AUDIO_FORMAT_E_AC3) ||
            (usecase->stream.out->format == AUDIO_FORMAT_E_AC3_JOC) ||
            (usecase->stream.out->format == AUDIO_FORMAT_DOLBY_TRUEHD))
            && audio_extn_passthru_is_passthrough_stream(usecase->stream.out)
            && !audio_extn_passthru_is_convert_supported(adev, usecase->stream.out)) {

            sample_rate = sample_rate * 4;
            if (sample_rate > HDMI_PASSTHROUGH_MAX_SAMPLE_RATE)
                sample_rate = HDMI_PASSTHROUGH_MAX_SAMPLE_RATE;
        }
        app_type_cfg[len++] = sample_rate;

        if (snd_device_be_idx > 0)
@@ -1201,19 +1222,6 @@ static int send_app_type_cfg_for_device(struct audio_device *adev,
        app_type = usecase->stream.in->app_type_cfg.app_type;
        app_type_cfg[len++] = app_type;
        app_type_cfg[len++] = acdb_dev_id;
        if (usecase->id == USECASE_AUDIO_RECORD_VOIP)
            usecase->stream.in->app_type_cfg.sample_rate = usecase->stream.in->sample_rate;
        if (voice_is_in_call_rec_stream(usecase->stream.in)) {
            audio_extn_btsco_get_sample_rate(usecase->in_snd_device, &usecase->stream.in->app_type_cfg.sample_rate);
        } else {
            audio_extn_btsco_get_sample_rate(snd_device, &usecase->stream.in->app_type_cfg.sample_rate);
        }
        if (usecase->stream.in->device & AUDIO_DEVICE_IN_BLUETOOTH_A2DP & ~AUDIO_DEVICE_BIT_IN) {
            audio_extn_a2dp_get_dec_sample_rate(&usecase->stream.in->app_type_cfg.sample_rate);
            ALOGI("%s using %d sample rate rate for A2DP dec CoPP",
                  __func__, usecase->stream.in->app_type_cfg.sample_rate);
        }
        sample_rate = usecase->stream.in->app_type_cfg.sample_rate;
        app_type_cfg[len++] = sample_rate;
        if (snd_device_be_idx > 0)
            app_type_cfg[len++] = snd_device_be_idx;
@@ -1222,7 +1230,6 @@ static int send_app_type_cfg_for_device(struct audio_device *adev,
    } else {
        app_type = platform_get_default_app_type_v2(adev->platform, usecase->type);
        if(usecase->type == TRANSCODE_LOOPBACK_RX) {
            sample_rate = usecase->stream.inout->out_config.sample_rate;
            app_type = usecase->stream.inout->out_app_type_cfg.app_type;
        }
        app_type_cfg[len++] = app_type;
@@ -1582,29 +1589,15 @@ void audio_extn_utils_send_audio_calibration(struct audio_device *adev,
    int type = usecase->type;

    if (type == PCM_PLAYBACK && usecase->stream.out != NULL) {
        struct stream_out *out = usecase->stream.out;
        int snd_device = usecase->out_snd_device;
        snd_device = (snd_device == SND_DEVICE_OUT_SPEAKER) ?
                     platform_get_spkr_prot_snd_device(snd_device) : snd_device;
        platform_send_audio_calibration(adev->platform, usecase,
                                        out->app_type_cfg.app_type,
                                        usecase->stream.out->app_type_cfg.sample_rate);
                         usecase->stream.out->app_type_cfg.app_type);
    } else if (type == PCM_CAPTURE && usecase->stream.in != NULL) {
        platform_send_audio_calibration(adev->platform, usecase,
                         usecase->stream.in->app_type_cfg.app_type,
                         usecase->stream.in->app_type_cfg.sample_rate);
    } else if (type == PCM_HFP_CALL || type == PCM_CAPTURE) {
        /* when app type is default. the sample rate is not used to send cal */
        platform_send_audio_calibration(adev->platform, usecase,
                         platform_get_default_app_type_v2(adev->platform, usecase->type),
                         48000);
    } else if (type == TRANSCODE_LOOPBACK_RX && usecase->stream.inout != NULL) {
        int snd_device = usecase->out_snd_device;
        snd_device = (snd_device == SND_DEVICE_OUT_SPEAKER) ?
                     platform_get_spkr_prot_snd_device(snd_device) : snd_device;
                         usecase->stream.in->app_type_cfg.app_type);
    } else if ((type == PCM_HFP_CALL) || (type == PCM_CAPTURE) ||
               (type == TRANSCODE_LOOPBACK_RX && usecase->stream.inout != NULL)) {
        platform_send_audio_calibration(adev->platform, usecase,
                         platform_get_default_app_type_v2(adev->platform, usecase->type),
                         usecase->stream.inout->out_config.sample_rate);
                         platform_get_default_app_type_v2(adev->platform, usecase->type));
    } else {
        /* No need to send audio calibration for voice and voip call usecases */
        if ((type != VOICE_CALL) && (type != VOIP_CALL))
+9 −3
Original line number Diff line number Diff line
@@ -3618,7 +3618,7 @@ int platform_get_backend_index(snd_device_t snd_device)
}

int platform_send_audio_calibration(void *platform, struct audio_usecase *usecase,
                                    int app_type, int sample_rate)
                                    int app_type)
{
    struct platform_data *my_data = (struct platform_data *)platform;
    int acdb_dev_id, acdb_dev_type;
@@ -3627,6 +3627,7 @@ int platform_send_audio_calibration(void *platform, struct audio_usecase *usecas
    int i, num_devices = 1;
    bool is_incall_rec_usecase = false;
    snd_device_t incall_rec_device;
    int sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;

    if (voice_is_in_call(my_data->adev))
        is_incall_rec_usecase = voice_is_in_call_rec_stream(usecase->stream.in);
@@ -3656,11 +3657,16 @@ int platform_send_audio_calibration(void *platform, struct audio_usecase *usecas
    }

    for (i = 0; i < num_devices; i++) {
        if (!is_incall_rec_usecase)
        if (!is_incall_rec_usecase) {
            acdb_dev_id = acdb_device_table[platform_get_spkr_prot_snd_device(new_snd_device[i])];
        else
            sample_rate = audio_extn_utils_get_app_sample_rate_for_device(my_data->adev, usecase,
                                                          new_snd_device[i]);
        } else {
            // Use in_call_rec snd_device to extract the ACDB device ID instead of split snd devices
            acdb_dev_id = acdb_device_table[platform_get_spkr_prot_snd_device(snd_device)];
            sample_rate = audio_extn_utils_get_app_sample_rate_for_device(my_data->adev, usecase,
                                                          snd_device);
        }

        // Do not use Rx path default app type for TX path
        if ((usecase->type == PCM_CAPTURE) && (app_type == DEFAULT_APP_TYPE_RX_PATH)) {
+1 −1
Original line number Diff line number Diff line
@@ -522,7 +522,7 @@ int platform_get_default_app_type(void *platform __unused)
}

int platform_send_audio_calibration(void *platform, struct audio_usecase *usecase,
                                    int app_type __unused, int sample_rate __unused)
                                    int app_type __unused)
{
    struct platform_data *my_data = (struct platform_data *)platform;
    int acdb_dev_id, acdb_dev_type;
Loading